Unverified Commit 7f7c00a4 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Enable web foundation tests (#34032)

parent f3e698fb
...@@ -79,6 +79,11 @@ task: ...@@ -79,6 +79,11 @@ task:
- name: web_tests-linux - name: web_tests-linux
env: env:
SHARD: web_tests SHARD: web_tests
test_script:
- dart --enable-asserts ./dev/bots/test.dart
container:
cpu: 4
memory: 12G
- name: build_tests-linux - name: build_tests-linux
env: env:
SHARD: build_tests SHARD: build_tests
......
...@@ -341,15 +341,8 @@ Future<void> _runTests() async { ...@@ -341,15 +341,8 @@ Future<void> _runTests() async {
} }
Future<void> _runWebTests() async { Future<void> _runWebTests() async {
final List<String> testfiles = <String>[]; await _runFlutterWebTest(path.join(flutterRoot, 'packages', 'flutter'), expectFailure: false, tests: <String>[
final Directory foundation = Directory(path.join(flutterRoot, 'packages', 'flutter', 'test', 'foundation')); 'test/foundation/',
for (FileSystemEntity entity in foundation.listSync(recursive: true)) {
if (entity is File) {
testfiles.add(entity.path);
}
}
await _runFlutterWebTest(path.join(flutterRoot, 'packages', 'flutter'), expectFailure: true, tests: <String>[
path.join('test', 'foundation'),
]); ]);
} }
...@@ -612,23 +605,30 @@ Future<void> _runFlutterWebTest(String workingDirectory, { ...@@ -612,23 +605,30 @@ Future<void> _runFlutterWebTest(String workingDirectory, {
Duration timeout = _kLongTimeout, Duration timeout = _kLongTimeout,
List<String> tests, List<String> tests,
}) async { }) async {
final List<String> args = <String>['test', '--platform=chrome']; final List<String> args = <String>['test', '-v', '--platform=chrome'];
if (flutterTestArgs != null && flutterTestArgs.isNotEmpty) if (flutterTestArgs != null && flutterTestArgs.isNotEmpty)
args.addAll(flutterTestArgs); args.addAll(flutterTestArgs);
args.add('--machine');
args.addAll(tests); args.addAll(tests);
await runCommand( // TODO(jonahwilliams): fix relative path issues to make this unecessary.
flutter, final Directory oldCurrent = Directory.current;
args, Directory.current = Directory(path.join(flutterRoot, 'packages', 'flutter'));
workingDirectory: workingDirectory, try {
expectNonZeroExit: expectFailure, await runCommand(
timeout: timeout, flutter,
environment: <String, String>{ args,
'FLUTTER_WEB': 'true', workingDirectory: workingDirectory,
}, expectNonZeroExit: expectFailure,
); timeout: timeout,
environment: <String, String>{
'FLUTTER_WEB': 'true',
'FLUTTER_LOW_RESOURCE_MODE': 'true',
},
);
} finally {
Directory.current = oldCurrent;
}
} }
Future<void> _runFlutterTest(String workingDirectory, { Future<void> _runFlutterTest(String workingDirectory, {
......
...@@ -12,3 +12,6 @@ export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; ...@@ -12,3 +12,6 @@ export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf;
/// A matcher that compares the type of the actual value to the type argument T. /// A matcher that compares the type of the actual value to the type argument T.
Matcher isInstanceOf<T>() => test_package.TypeMatcher<T>(); Matcher isInstanceOf<T>() => test_package.TypeMatcher<T>();
/// Whether we are running in a web browser.
const bool isBrowser = identical(0, 0.0);
...@@ -14,7 +14,7 @@ void main() { ...@@ -14,7 +14,7 @@ void main() {
}); });
expect(log[0], contains('Example label')); expect(log[0], contains('Example label'));
expect(log[1], contains('debugPrintStack')); expect(log[1], contains('debugPrintStack'));
}); }, skip: isBrowser);
test('debugPrintStack', () { test('debugPrintStack', () {
final List<String> log = captureOutput(() { final List<String> log = captureOutput(() {
...@@ -39,7 +39,7 @@ void main() { ...@@ -39,7 +39,7 @@ void main() {
expect(joined, contains('captureOutput')); expect(joined, contains('captureOutput'));
expect(joined, contains('\nExample information\n')); expect(joined, contains('\nExample information\n'));
}); }, skip: isBrowser);
test('FlutterErrorDetails.toString', () { test('FlutterErrorDetails.toString', () {
expect( expect(
......
...@@ -102,7 +102,7 @@ void main() { ...@@ -102,7 +102,7 @@ void main() {
expect(log, <String>['badListener', 'listener1', 'listener2']); expect(log, <String>['badListener', 'listener1', 'listener2']);
expect(tester.takeException(), isNullThrownError); expect(tester.takeException(), isNullThrownError);
log.clear(); log.clear();
}); }, skip: isBrowser);
test('ChangeNotifier with mutating listener', () { test('ChangeNotifier with mutating listener', () {
final TestNotifier test = TestNotifier(); final TestNotifier test = TestNotifier();
......
...@@ -1187,7 +1187,7 @@ void main() { ...@@ -1187,7 +1187,7 @@ void main() {
expect(missing.isFiltered(DiagnosticLevel.info), isFalse); expect(missing.isFiltered(DiagnosticLevel.info), isFalse);
validateObjectFlagPropertyJsonSerialization(present); validateObjectFlagPropertyJsonSerialization(present);
validateObjectFlagPropertyJsonSerialization(missing); validateObjectFlagPropertyJsonSerialization(missing);
}); }, skip: isBrowser);
test('describe bool property', () { test('describe bool property', () {
final FlagProperty yes = FlagProperty( final FlagProperty yes = FlagProperty(
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@TestOn('!chrome')
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
......
...@@ -161,7 +161,20 @@ final List<core.BuilderApplication> builders = <core.BuilderApplication>[ ...@@ -161,7 +161,20 @@ final List<core.BuilderApplication> builders = <core.BuilderApplication>[
defaultGenerateFor: const InputSet( defaultGenerateFor: const InputSet(
include: <String>[ include: <String>[
'lib/**', 'lib/**',
'web/**', ],
),
),
core.apply(
'flutter_tools|test_entrypoint',
<BuilderFactory>[
(BuilderOptions options) => FlutterWebTestEntrypointBuilder(
options.config['targets'] ?? const <String>[]
),
],
core.toRoot(),
hideOutput: true,
defaultGenerateFor: const InputSet(
include: <String>[
'test/**_test.dart.browser_test.dart', 'test/**_test.dart.browser_test.dart',
], ],
), ),
...@@ -213,6 +226,7 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy { ...@@ -213,6 +226,7 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy {
skipBuildScriptCheck: true, skipBuildScriptCheck: true,
trackPerformance: false, trackPerformance: false,
deleteFilesByDefault: true, deleteFilesByDefault: true,
enableLowResourcesMode: platform.environment['FLUTTER_LOW_RESOURCE_MODE']?.toLowerCase() == 'true',
); );
final Set<core.BuildDirectory> buildDirs = <core.BuildDirectory>{ final Set<core.BuildDirectory> buildDirs = <core.BuildDirectory>{
if (testOutputDir != null) if (testOutputDir != null)
...@@ -290,6 +304,10 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy { ...@@ -290,6 +304,10 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy {
'targets': targets, 'targets': targets,
'release': release, 'release': release,
}, },
'flutter_tools|test_entrypoint': <String, dynamic>{
'targets': targets,
'release': release,
},
'flutter_tools|shell': <String, dynamic>{ 'flutter_tools|shell': <String, dynamic>{
'targets': targets, 'targets': targets,
} }
...@@ -347,6 +365,40 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy { ...@@ -347,6 +365,40 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy {
} }
} }
/// A ddc-only entrypoint builder that respects the Flutter target flag.
class FlutterWebTestEntrypointBuilder implements Builder {
const FlutterWebTestEntrypointBuilder(this.targets);
final List<String> targets;
@override
Map<String, List<String>> get buildExtensions => const <String, List<String>>{
'.dart': <String>[
ddcBootstrapExtension,
jsEntrypointExtension,
jsEntrypointSourceMapExtension,
jsEntrypointArchiveExtension,
digestsEntrypointExtension,
],
};
@override
Future<void> build(BuildStep buildStep) async {
bool matches = false;
for (String target in targets) {
if (buildStep.inputId.path.contains(target)) {
matches = true;
break;
}
}
if (!matches) {
return;
}
log.info('building for target ${buildStep.inputId.path}');
await bootstrapDdc(buildStep, platform: flutterWebPlatform);
}
}
/// A ddc-only entrypoint builder that respects the Flutter target flag. /// A ddc-only entrypoint builder that respects the Flutter target flag.
class FlutterWebEntrypointBuilder implements Builder { class FlutterWebEntrypointBuilder implements Builder {
const FlutterWebEntrypointBuilder(this.targets, this.release); const FlutterWebEntrypointBuilder(this.targets, this.release);
......
...@@ -110,6 +110,7 @@ class TestCommand extends FastFlutterCommand { ...@@ -110,6 +110,7 @@ class TestCommand extends FastFlutterCommand {
@override @override
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => <DevelopmentArtifact>{ Future<Set<DevelopmentArtifact>> get requiredArtifacts async => <DevelopmentArtifact>{
DevelopmentArtifact.universal, DevelopmentArtifact.universal,
DevelopmentArtifact.web,
}; };
@override @override
......
...@@ -73,13 +73,16 @@ Future<int> runTests( ...@@ -73,13 +73,16 @@ Future<int> runTests(
.absolute .absolute
.uri .uri
.toFilePath(); .toFilePath();
await webCompilationProxy.initialize( final bool result = await webCompilationProxy.initialize(
projectDirectory: flutterProject.directory, projectDirectory: flutterProject.directory,
testOutputDir: tempBuildDir, testOutputDir: tempBuildDir,
targets: testFiles.map((String testFile) { targets: testFiles.map((String testFile) {
return fs.path.relative(testFile, from: flutterProject.directory.path); return fs.path.relative(testFile, from: flutterProject.directory.path);
}).toList(), }).toList(),
); );
if (!result) {
throwToolExit('Failed to compile tests');
}
testArgs.add('--platform=chrome'); testArgs.add('--platform=chrome');
testArgs.add('--precompiled=$tempBuildDir'); testArgs.add('--precompiled=$tempBuildDir');
testArgs.add('--'); testArgs.add('--');
......
...@@ -98,16 +98,19 @@ class ChromeLauncher { ...@@ -98,16 +98,19 @@ class ChromeLauncher {
'--disable-default-apps', '--disable-default-apps',
'--disable-translate', '--disable-translate',
if (headless) if (headless)
...<String>['--headless', '--disable-gpu'], ...<String>['--headless', '--disable-gpu', '--no-sandbox'],
url, url,
]; ];
final Process process = await processManager.start(args);
final Process process = await processManager.start(args, runInShell: true);
// Wait until the DevTools are listening before trying to connect. // Wait until the DevTools are listening before trying to connect.
await process.stderr await process.stderr
.transform(utf8.decoder) .transform(utf8.decoder)
.transform(const LineSplitter()) .transform(const LineSplitter())
.firstWhere((String line) => line.startsWith('DevTools listening')) .firstWhere((String line) => line.startsWith('DevTools listening'), orElse: () {
return 'Failed to spawn stderr';
})
.timeout(const Duration(seconds: 60), onTimeout: () { .timeout(const Duration(seconds: 60), onTimeout: () {
throwToolExit('Unable to connect to Chrome DevTools.'); throwToolExit('Unable to connect to Chrome DevTools.');
return null; return null;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment