From c13cd895ca06ba0e60cbce34f5ec68b6162eada0 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Fri, 10 Feb 2023 15:19:34 -0800 Subject: [PATCH 01/44] Wrote felt_config file and parsing. --- lib/web_ui/dev/felt_config.dart | 230 ++++++++++++++++++++++++++ lib/web_ui/dev/test_runner.dart | 35 ++-- lib/web_ui/test/felt_config.yaml | 266 +++++++++++++++++++++++++++++++ 3 files changed, 521 insertions(+), 10 deletions(-) create mode 100644 lib/web_ui/dev/felt_config.dart create mode 100644 lib/web_ui/test/felt_config.yaml diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart new file mode 100644 index 0000000000000..518515b6511b5 --- /dev/null +++ b/lib/web_ui/dev/felt_config.dart @@ -0,0 +1,230 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io' as io; +import 'package:yaml/yaml.dart'; + +enum Compiler { + dart2js, + dart2wasm +} + +enum Renderer { + html, + canvaskit, + skwasm, +} + +class CompileConfiguration { + CompileConfiguration(this.name, this.compiler, this.renderer); + + final String name; + final Compiler compiler; + final Renderer renderer; +} + +class TestSet { + TestSet(this.name, this.directory); + + final String name; + final String directory; +} + +class TestBundle { + TestBundle(this.name, this.testSet, this.compileConfig); + + final String name; + final TestSet testSet; + final CompileConfiguration compileConfig; +} + +enum CanvasKitVariant { + full, + chromium, +} + +enum Browser { + chrome, + edge, + firefox, + safari, +} + +class RunConfiguration { + RunConfiguration(this.name, this.browser, this.variant); + + final String name; + final Browser browser; + final CanvasKitVariant? variant; +} + +class ArtifactDependencies { + ArtifactDependencies({ + required this.canvasKit, + required this.canvasKitChromium, + required this.skwasm + }); + final bool canvasKit; + final bool canvasKitChromium; + final bool skwasm; +} + +class TestSuite { + TestSuite( + this.name, + this.testBundle, + this.runConfig, + this.artifactDependencies + ); + + String name; + TestBundle testBundle; + RunConfiguration runConfig; + ArtifactDependencies artifactDependencies; +} + +class FeltConfig { + FeltConfig( + this.compileConfigs, + this.testSets, + this.testBundles, + this.runConfigs, + this.testSuites, + ); + + factory FeltConfig.fromFile(String filePath) { + final io.File configFile = io.File(filePath); + final YamlMap yaml = loadYaml(configFile.readAsStringSync()) as YamlMap; + + final List compileConfigs = []; + final Map compileConfigsByName = {}; + for (final dynamic node in yaml['compile-configs'] as YamlList) { + final YamlMap configYaml = node as YamlMap; + final String name = configYaml['name'] as String; + final Compiler compiler = Compiler.values.byName(configYaml['compiler'] as String); + final Renderer renderer = Renderer.values.byName(configYaml['renderer'] as String); + final CompileConfiguration config = CompileConfiguration(name, compiler, renderer); + compileConfigs.add(config); + if (compileConfigsByName.containsKey(name)) { + throw AssertionError('Duplicate compile config name: $name'); + } + compileConfigsByName[name] = config; + } + + final List testSets = []; + final Map testSetsByName = {}; + for (final dynamic node in yaml['test-sets'] as YamlList) { + final YamlMap testSetYaml = node as YamlMap; + final String name = testSetYaml['name'] as String; + final String directory = testSetYaml['directory'] as String; + final TestSet testSet = TestSet(name, directory); + testSets.add(testSet); + if (testSetsByName.containsKey(name)) { + throw AssertionError('Duplicate test set name: $name'); + } + testSetsByName[name] = testSet; + } + + final List testBundles = []; + final Map testBundlesByName = {}; + for (final dynamic node in yaml['test-bundles'] as YamlList) { + final YamlMap testBundleYaml = node as YamlMap; + final String name = testBundleYaml['name'] as String; + final String testSetName = testBundleYaml['test-set'] as String; + final TestSet? testSet = testSetsByName[testSetName]; + if (testSet == null) { + throw AssertionError('Test set not found with name: $testSetName'); + } + final String compileConfigName = testBundleYaml['compile-config'] as String; + final CompileConfiguration? compileConfig = compileConfigsByName[compileConfigName]; + if (compileConfig == null) { + throw AssertionError('Compile config not found with name: $compileConfigName'); + } + final TestBundle bundle = TestBundle(name, testSet, compileConfig); + testBundles.add(bundle); + if (testBundlesByName.containsKey(name)) { + throw AssertionError('Duplicate test bundle name: $name'); + } + testBundlesByName[name] = bundle; + } + + final List runConfigs = []; + final Map runConfigsByName = {}; + for (final dynamic node in yaml['run-configs'] as YamlList) { + final YamlMap runConfigYaml = node as YamlMap; + final String name = runConfigYaml['name'] as String; + final Browser browser = Browser.values.byName(runConfigYaml['browser'] as String); + final dynamic variantNode = runConfigYaml['canvaskit-variant']; + final CanvasKitVariant? variant = variantNode == null + ? null + : CanvasKitVariant.values.byName(variantNode as String); + final RunConfiguration runConfig = RunConfiguration(name, browser, variant); + runConfigs.add(runConfig); + if (runConfigsByName.containsKey(name)) { + throw AssertionError('Duplicate run config name: $name'); + } + runConfigsByName[name] = runConfig; + } + + final List testSuites = []; + for (final dynamic node in yaml['test-suites'] as YamlList) { + final YamlMap testSuiteYaml = node as YamlMap; + final String name = testSuiteYaml['name'] as String; + final String testBundleName = testSuiteYaml['test-bundle'] as String; + final TestBundle? bundle = testBundlesByName[testBundleName]; + if (bundle == null) { + throw AssertionError('Test bundle not found with name: $testBundleName'); + } + final String runConfigName = testSuiteYaml['run-config'] as String; + final RunConfiguration? runConfig = runConfigsByName[runConfigName]; + if (runConfig == null) { + throw AssertionError('Run config not found with name: $testBundleName'); + } + bool canvasKit = false; + bool canvasKitChromium = false; + bool skwasm = false; + final dynamic depsNode = testSuiteYaml['artifact-deps']; + if (depsNode != null) { + for (final dynamic dep in depsNode as YamlList) { + switch (dep as String) { + case 'canvaskit': + if (canvasKit) { + throw AssertionError('Artifact dep $dep listed twice in suite $name.'); + } + canvasKit = true; + break; + case 'canvaskit_chromium': + if (canvasKitChromium) { + throw AssertionError('Artifact dep $dep listed twice in suite $name.'); + } + canvasKitChromium = true; + break; + case 'skwasm': + if (skwasm) { + throw AssertionError('Artifact dep $dep listed twice in suite $name.'); + } + skwasm = true; + break; + default: + throw AssertionError('Unrecognized artifact dependency: $dep'); + } + } + } + final ArtifactDependencies artifactDeps = ArtifactDependencies( + canvasKit: canvasKit, + canvasKitChromium: canvasKitChromium, + skwasm: skwasm + ); + final TestSuite suite = TestSuite(name, bundle, runConfig, artifactDeps); + testSuites.add(suite); + } + return FeltConfig(compileConfigs, testSets, testBundles, runConfigs, testSuites); + } + + List compileConfigs; + List testSets; + List testBundles; + List runConfigs; + List testSuites; +} diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index f3756a82ba480..374a6b0152238 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -10,6 +10,8 @@ import 'package:path/path.dart' as path; import 'package:watcher/src/watch_event.dart'; +import 'environment.dart'; +import 'felt_config.dart'; import 'pipeline.dart'; import 'steps/compile_tests_step.dart'; import 'steps/run_tests_step.dart'; @@ -32,16 +34,12 @@ class TestCommand extends Command with ArgUtils { 'made.', ) ..addFlag( - 'use-system-flutter', - help: 'integration tests are using flutter repository for various tasks' - ', such as flutter drive, flutter pub get. If this flag is set, felt ' - 'will use flutter command without cloning the repository. This flag ' - 'can save internet bandwidth. However use with caution. Note that ' - 'since flutter repo is always synced to youngest commit older than ' - 'the engine commit for the tests running in CI, the tests results ' - "won't be consistent with CIs when this flag is set. flutter " - 'command should be set in the PATH for this flag to be useful.' - 'This flag can also be used to test local Flutter changes.') + 'list', + help: + 'Lists the bundles that would be compiled and the suites that' + 'will be run as part of this invocation, without actually' + 'compiling or running them.' + ) ..addFlag( 'require-skia-gold', help: @@ -93,6 +91,8 @@ class TestCommand extends Command with ArgUtils { bool get isWatchMode => boolArg('watch'); + bool get isList => boolArg('list'); + bool get failEarly => boolArg('fail-early'); bool get isWasm => boolArg('wasm'); @@ -131,6 +131,21 @@ class TestCommand extends Command with ArgUtils { @override Future run() async { + final FeltConfig config = FeltConfig.fromFile( + path.join(environment.webUiTestDir.path, 'felt_config.yaml') + ); + if (isList) { + print('Bundles:'); + for (final TestBundle bundle in config.testBundles) { + print(' ${bundle.name}'); + } + print(''); + print('Suites:'); + for (final TestSuite suite in config.testSuites) { + print(' ${suite.name}'); + } + return true; + } final List testFiles = runAllTests ? findAllTests() : targetFiles; diff --git a/lib/web_ui/test/felt_config.yaml b/lib/web_ui/test/felt_config.yaml new file mode 100644 index 0000000000000..0a77e4d3d9ed8 --- /dev/null +++ b/lib/web_ui/test/felt_config.yaml @@ -0,0 +1,266 @@ +compile-configs: + - name: dart2js-html + compiler: dart2js + renderer: html + + - name: dart2js-canvaskit + compiler: dart2js + renderer: canvaskit + + - name: dart2js-skwasm + compiler: dart2js + renderer: skwasm + + - name: dart2wasm-html + compiler: dart2wasm + renderer: html + + - name: dart2wasm-canvaskit + compiler: dart2wasm + renderer: canvaskit + + - name: dart2wasm-skwasm + compiler: dart2wasm + renderer: skwasm + +test-sets: + # Tests for non-renderer logic + - name: engine + directory: engine + + # Tests for canvaskit-renderer-specific functionality + - name: canvaskit + directory: canvaskit + + # Tests for html-renderer-specific functionality + - name: html + directory: html + + # Tests for renderer functionality that can be run on any renderer + - name: ui + directory: ui + + # This just has a single test that makes sure the skwasm stub renderer is + # included when compiling to JS + - name: skwasm_stub + directory: skwasm_stub + +test-bundles: + - name: dart2js-html-engine + test-set: engine + compile-config: dart2js-html + + - name: dart2js-html-html + test-set: html + compile-config: dart2js-html + + - name: dart2js-html-ui + test-set: ui + compile-config: dart2js-html + + - name: dart2js-canvaskit-canvaskit + test-set: canvaskit + compile-config: dart2js-canvaskit + + - name: dart2js-canvaskit-ui + test-set: ui + compile-config: dart2js-canvaskit + + - name: dart2js-skwasm-skwasm_stub + test-set: skwasm_stub + compile-config: dart2js-skwasm + + - name: dart2wasm-html-engine + test-set: engine + compile-config: dart2wasm-html + + - name: dart2wasm-html-html + test-set: html + compile-config: dart2wasm-html + + - name: dart2wasm-html-ui + test-set: ui + compile-config: dart2wasm-html + + - name: dart2wasm-canvaskit-canvaskit + test-set: canvaskit + compile-config: dart2wasm-canvaskit + + - name: dart2wasm-canvaskit-ui + test-set: ui + compile-config: dart2wasm-canvaskit + + - name: dart2wasm-skwasm-ui + test-set: ui + compile-config: dart2wasm-skwasm + +run-configs: + - name: chrome + browser: chrome + + - name: chrome-full + browser: chrome + canvaskit-variant: full + + - name: edge + browser: edge + + - name: edge-full + browser: edge + canvaskit-variant: full + + - name: firefox + browser: firefox + + - name: safari + browser: safari + +test-suites: + - name: chrome-dart2js-html-engine + test-bundle: dart2js-html-engine + run-config: chrome + + - name: chrome-dart2js-html-html + test-bundle: dart2js-html-html + run-config: chrome + + - name: chrome-dart2js-html-ui + test-bundle: dart2js-html-ui + run-config: chrome + + - name: chrome-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: chrome + artifact-deps: [ canvaskit_chromium ] + + - name: chrome-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: chrome + artifact-deps: [ canvaskit_chromium ] + + - name: chrome-dart2js-skwasm-skwasm_stub + test-bundle: dart2js-skwasm-skwasm_stub + run-config: chrome + + - name: chrome-full-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: chrome-full + artifact-deps: [ canvaskit ] + + - name: chrome-full-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: chrome-full + artifact-deps: [ canvaskit ] + + - name: edge-dart2js-html-engine + test-bundle: dart2js-html-engine + run-config: edge + + - name: edge-dart2js-html-html + test-bundle: dart2js-html-html + run-config: edge + + - name: edge-dart2js-html-ui + test-bundle: dart2js-html-ui + run-config: edge + + - name: edge-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: edge + artifact-deps: [ canvaskit_chromium ] + + - name: edge-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: edge + artifact-deps: [ canvaskit_chromium ] + + - name: edge-full-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: edge-full + artifact-deps: [ canvaskit ] + + - name: edge-full-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: edge-full + artifact-deps: [ canvaskit ] + + - name: firefox-dart2js-html-engine + test-bundle: dart2js-html-engine + run-config: firefox + + - name: firefox-dart2js-html-html + test-bundle: dart2js-html-html + run-config: firefox + + - name: firefox-dart2js-html-ui + test-bundle: dart2js-html-ui + run-config: firefox + + - name: firefox-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: firefox + artifact-deps: [ canvaskit ] + + - name: firefox-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: firefox + artifact-deps: [ canvaskit ] + + - name: safari-dart2js-html-engine + test-bundle: dart2js-html-engine + run-config: safari + + - name: safari-dart2js-html-html + test-bundle: dart2js-html-html + run-config: safari + + - name: safari-dart2js-html-ui + test-bundle: dart2js-html-ui + run-config: safari + + - name: safari-dart2js-canvaskit-canvaskit + test-bundle: dart2js-canvaskit-canvaskit + run-config: safari + artifact-deps: [ canvaskit ] + + - name: safari-dart2js-canvaskit-ui + test-bundle: dart2js-canvaskit-ui + run-config: safari + artifact-deps: [ canvaskit ] + + - name: chrome-dart2wasm-html-engine + test-bundle: dart2wasm-html-engine + run-config: chrome + + - name: chrome-dart2wasm-html-html + test-bundle: dart2wasm-html-html + run-config: chrome + + - name: chrome-dart2wasm-html-ui + test-bundle: dart2wasm-html-ui + run-config: chrome + + - name: chrome-dart2wasm-canvaskit-canvaskit + test-bundle: dart2wasm-canvaskit-canvaskit + run-config: chrome + artifact-deps: [ canvaskit_chromium ] + + - name: chrome-dart2wasm-canvaskit-ui + test-bundle: dart2wasm-canvaskit-ui + run-config: chrome + artifact-deps: [ canvaskit_chromium ] + + - name: chrome-dart2wasm-skwasm-ui + test-bundle: dart2wasm-skwasm-ui + run-config: chrome + artifact-deps: [ skwasm ] + + - name: chrome-full-dart2wasm-canvaskit-canvaskit + test-bundle: dart2wasm-canvaskit-canvaskit + run-config: chrome-full + artifact-deps: [ canvaskit ] + + - name: chrome-full-dart2wasm-canvaskit-ui + test-bundle: dart2wasm-canvaskit-ui + run-config: chrome-full + artifact-deps: [ canvaskit ] From b60b1b4f4cb2f725429198b09c7abf3819e669e1 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Mon, 13 Feb 2023 17:36:21 -0800 Subject: [PATCH 02/44] Some suite filtering and copy artifacts step refactor. --- lib/web_ui/dev/felt_config.dart | 21 ++ lib/web_ui/dev/steps/compile_tests_step.dart | 281 ----------------- lib/web_ui/dev/steps/copy_artifacts_step.dart | 285 ++++++++++++++++++ lib/web_ui/dev/suite_filter.dart | 85 ++++++ lib/web_ui/dev/test_runner.dart | 82 ++++- lib/web_ui/dev/utils.dart | 22 ++ 6 files changed, 487 insertions(+), 289 deletions(-) create mode 100644 lib/web_ui/dev/steps/copy_artifacts_step.dart create mode 100644 lib/web_ui/dev/suite_filter.dart diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart index 518515b6511b5..c9dd303a7ba70 100644 --- a/lib/web_ui/dev/felt_config.dart +++ b/lib/web_ui/dev/felt_config.dart @@ -65,9 +65,30 @@ class ArtifactDependencies { required this.canvasKitChromium, required this.skwasm }); + + ArtifactDependencies.none() + : canvasKit = false + , canvasKitChromium = false + , skwasm = false; final bool canvasKit; final bool canvasKitChromium; final bool skwasm; + + ArtifactDependencies operator|(ArtifactDependencies other) { + return ArtifactDependencies( + canvasKit: canvasKit || other.canvasKit, + canvasKitChromium: canvasKitChromium || other.canvasKitChromium, + skwasm: skwasm || other.skwasm, + ); + } + + ArtifactDependencies operator&(ArtifactDependencies other) { + return ArtifactDependencies( + canvasKit: canvasKit && other.canvasKit, + canvasKitChromium: canvasKitChromium && other.canvasKitChromium, + skwasm: skwasm && other.skwasm, + ); + } } class TestSuite { diff --git a/lib/web_ui/dev/steps/compile_tests_step.dart b/lib/web_ui/dev/steps/compile_tests_step.dart index 19b9759e785c0..dd227af1a7dad 100644 --- a/lib/web_ui/dev/steps/compile_tests_step.dart +++ b/lib/web_ui/dev/steps/compile_tests_step.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:convert' show JsonEncoder; import 'dart:io' as io; import 'package:path/path.dart' as pathlib; @@ -25,15 +24,12 @@ import '../utils.dart'; class CompileTestsStep implements PipelineStep { CompileTestsStep({ this.testFiles, - this.useLocalCanvasKit = false, this.isWasm = false }); final List? testFiles; final bool isWasm; - final bool useLocalCanvasKit; - @override String get description => 'compile_tests'; @@ -47,192 +43,10 @@ class CompileTestsStep implements PipelineStep { @override Future run() async { - await environment.webUiBuildDir.create(); - if (isWasm) { - await copyDart2WasmTestScript(); - await copySkwasm(); - } - await copyCanvasKitFiles(useLocalCanvasKit: useLocalCanvasKit); - await buildHostPage(); - await copyTestFonts(); - await copySkiaTestImages(); await compileTests(testFiles ?? findAllTests(), isWasm); } } -const Map _kTestFonts = { - 'Ahem': 'ahem.ttf', - 'Roboto': 'Roboto-Regular.ttf', - 'RobotoVariable': 'RobotoSlab-VariableFont_wght.ttf', - 'Noto Naskh Arabic UI': 'NotoNaskhArabic-Regular.ttf', - 'Noto Color Emoji': 'NotoColorEmoji.ttf', -}; - -Future copyTestFonts() async { - final String fontsPath = pathlib.join( - environment.flutterDirectory.path, - 'third_party', - 'txt', - 'third_party', - 'fonts', - ); - - final List fontManifest = []; - for (final MapEntry fontEntry in _kTestFonts.entries) { - final String family = fontEntry.key; - final String fontFile = fontEntry.value; - - fontManifest.add({ - 'family': family, - 'fonts': [ - { - 'asset': 'fonts/$fontFile', - }, - ], - }); - - final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile)); - final io.File destinationTtf = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'assets', - 'fonts', - fontFile, - )); - await destinationTtf.create(recursive: true); - await sourceTtf.copy(destinationTtf.path); - } - - final io.File fontManifestFile = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'assets', - 'FontManifest.json', - )); - await fontManifestFile.create(recursive: true); - await fontManifestFile.writeAsString( - const JsonEncoder.withIndent(' ').convert(fontManifest), - ); -} - -Future copySkiaTestImages() async { - final io.Directory testImagesDir = io.Directory(pathlib.join( - environment.engineSrcDir.path, - 'third_party', - 'skia', - 'resources', - 'images', - )); - - for (final io.File imageFile in testImagesDir.listSync(recursive: true).whereType()) { - final io.File destination = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'test_images', - pathlib.relative(imageFile.path, from: testImagesDir.path), - )); - destination.createSync(recursive: true); - await imageFile.copy(destination.path); - } -} - -Future copyDart2WasmTestScript() async { - final io.File sourceFile = io.File(pathlib.join( - environment.webUiDevDir.path, - 'test_dart2wasm.js', - )); - final io.File targetFile = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'test_dart2wasm.js', - )); - await sourceFile.copy(targetFile.path); -} - -Future copySkwasm() async { - final io.Directory targetDir = io.Directory(pathlib.join( - environment.webUiBuildDir.path, - 'skwasm', - )); - - await targetDir.create(recursive: true); - - for (final String fileName in [ - 'skwasm.wasm', - 'skwasm.js', - 'skwasm.worker.js', - ]) { - final io.File sourceFile = io.File(pathlib.join( - environment.wasmReleaseOutDir.path, - fileName, - )); - final io.File targetFile = io.File(pathlib.join( - targetDir.path, - fileName, - )); - await sourceFile.copy(targetFile.path); - } -} - -final io.Directory _localCanvasKitDir = io.Directory(pathlib.join( - environment.wasmReleaseOutDir.path, - 'canvaskit', -)); -final io.File _localCanvasKitWasm = io.File(pathlib.join( - _localCanvasKitDir.path, - 'canvaskit.wasm', -)); - -Future copyCanvasKitFiles({bool useLocalCanvasKit = false}) async { - // If CanvasKit has been built locally, use that instead of the CIPD version. - final bool localCanvasKitExists = _localCanvasKitWasm.existsSync(); - if (useLocalCanvasKit && !localCanvasKitExists) { - throw ArgumentError('Requested to use local CanvasKit but could not find the ' - 'built CanvasKit at ${_localCanvasKitWasm.path}. Falling back to ' - 'CanvasKit from CIPD.'); - } - - final io.Directory targetDir = io.Directory(pathlib.join( - environment.webUiBuildDir.path, - 'canvaskit', - )); - - if (useLocalCanvasKit) { - final Iterable canvasKitFiles = - _localCanvasKitDir.listSync(recursive: true).whereType(); - for (final io.File file in canvasKitFiles) { - if (!file.path.endsWith('.wasm') && !file.path.endsWith('.js')) { - // We only need the .wasm and .js files. - continue; - } - final String relativePath = - pathlib.relative(file.path, from: _localCanvasKitDir.path); - final io.File normalTargetFile = - io.File(pathlib.join(targetDir.path, relativePath)); - await normalTargetFile.create(recursive: true); - await file.copy(normalTargetFile.path); - } - } else { - final io.Directory canvasKitDir = io.Directory(pathlib.join( - environment.engineSrcDir.path, - 'third_party', - 'web_dependencies', - 'canvaskit', - )); - - final Iterable canvasKitFiles = canvasKitDir - .listSync(recursive: true) - .whereType(); - - for (final io.File file in canvasKitFiles) { - final String relativePath = - pathlib.relative(file.path, from: canvasKitDir.path); - final io.File targetFile = io.File(pathlib.join( - targetDir.path, - relativePath, - )); - await targetFile.create(recursive: true); - await file.copy(targetFile.path); - } - } -} - /// Compiles the specified unit tests. Future compileTests(List testFiles, bool isWasm) async { final Stopwatch stopwatch = Stopwatch()..start(); @@ -407,98 +221,3 @@ Future compileUnitTestToWasm(FilePath input, {required Renderer renderer}) return true; } } - -Future buildHostPage() async { - final String hostDartPath = pathlib.join('lib', 'static', 'host.dart'); - final io.File hostDartFile = io.File(pathlib.join( - environment.webEngineTesterRootDir.path, - hostDartPath, - )); - final String targetDirectoryPath = pathlib.join( - environment.webUiBuildDir.path, - 'host', - ); - io.Directory(targetDirectoryPath).createSync(recursive: true); - final String targetFilePath = pathlib.join( - targetDirectoryPath, - 'host.dart', - ); - - const List staticFiles = [ - 'favicon.ico', - 'host.css', - 'index.html', - ]; - for (final String staticFilePath in staticFiles) { - final io.File source = io.File(pathlib.join( - environment.webEngineTesterRootDir.path, - 'lib', - 'static', - staticFilePath, - )); - final io.File destination = io.File(pathlib.join( - targetDirectoryPath, - staticFilePath, - )); - await source.copy(destination.path); - } - - final io.File timestampFile = io.File(pathlib.join( - environment.webEngineTesterRootDir.path, - '$targetFilePath.js.timestamp', - )); - - final String timestamp = - hostDartFile.statSync().modified.millisecondsSinceEpoch.toString(); - if (timestampFile.existsSync()) { - final String lastBuildTimestamp = timestampFile.readAsStringSync(); - if (lastBuildTimestamp == timestamp) { - // The file is still fresh. No need to rebuild. - return; - } else { - // Record new timestamp, but don't return. We need to rebuild. - print('${hostDartFile.path} timestamp changed. Rebuilding.'); - } - } else { - print('Building ${hostDartFile.path}.'); - } - - int exitCode = await runProcess( - environment.dartExecutable, - [ - 'pub', - 'get', - ], - workingDirectory: environment.webEngineTesterRootDir.path - ); - - if (exitCode != 0) { - throw ToolExit( - 'Failed to run pub get for web_engine_tester, exit code $exitCode', - exitCode: exitCode, - ); - } - - exitCode = await runProcess( - environment.dartExecutable, - [ - 'compile', - 'js', - hostDartPath, - '-o', - '$targetFilePath.js', - ], - workingDirectory: environment.webEngineTesterRootDir.path, - ); - - if (exitCode != 0) { - throw ToolExit( - 'Failed to compile ${hostDartFile.path}. Compiler ' - 'exited with exit code $exitCode', - exitCode: exitCode, - ); - } - - // Record the timestamp to avoid rebuilding unless the file changes. - timestampFile.writeAsStringSync(timestamp); -} diff --git a/lib/web_ui/dev/steps/copy_artifacts_step.dart b/lib/web_ui/dev/steps/copy_artifacts_step.dart new file mode 100644 index 0000000000000..99f53a3445f71 --- /dev/null +++ b/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -0,0 +1,285 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert' show JsonEncoder; +import 'dart:io' as io; + +import 'package:path/path.dart' as pathlib; + +import '../environment.dart'; +import '../exceptions.dart'; +import '../felt_config.dart'; +import '../pipeline.dart'; +import '../utils.dart'; + +class CopyArtifactsStep implements PipelineStep { + CopyArtifactsStep(this.artifactDeps); + + final ArtifactDependencies artifactDeps; + + @override + String get description => 'copy_artifacts'; + + @override + bool get isSafeToInterrupt => true; + + @override + Future interrupt() async { + await cleanup(); + } + + @override + Future run() async { + await environment.webUiBuildDir.create(); + await copyDart2WasmTestScript(); + await buildHostPage(); + await copyTestFonts(); + await copySkiaTestImages(); + if (artifactDeps.canvasKit) { + await copyCanvasKitFiles('canvaskit'); + } + if (artifactDeps.canvasKitChromium) { + await copyCanvasKitFiles('canvaskit_chromium'); + } + if (artifactDeps.skwasm) { + await copySkwasm(); + } + } +} + +Future copyDart2WasmTestScript() async { + final io.File sourceFile = io.File(pathlib.join( + environment.webUiDevDir.path, + 'test_dart2wasm.js', + )); + final io.File targetFile = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'test_dart2wasm.js', + )); + await sourceFile.copy(targetFile.path); +} + +const Map _kTestFonts = { + 'Ahem': 'ahem.ttf', + 'Roboto': 'Roboto-Regular.ttf', + 'RobotoVariable': 'RobotoSlab-VariableFont_wght.ttf', + 'Noto Naskh Arabic UI': 'NotoNaskhArabic-Regular.ttf', + 'Noto Color Emoji': 'NotoColorEmoji.ttf', +}; + +Future copyTestFonts() async { + final String fontsPath = pathlib.join( + environment.flutterDirectory.path, + 'third_party', + 'txt', + 'third_party', + 'fonts', + ); + + final List fontManifest = []; + for (final MapEntry fontEntry in _kTestFonts.entries) { + final String family = fontEntry.key; + final String fontFile = fontEntry.value; + + fontManifest.add({ + 'family': family, + 'fonts': [ + { + 'asset': 'fonts/$fontFile', + }, + ], + }); + + final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile)); + final io.File destinationTtf = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'assets', + 'fonts', + fontFile, + )); + await destinationTtf.create(recursive: true); + await sourceTtf.copy(destinationTtf.path); + } + + final io.File fontManifestFile = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'assets', + 'FontManifest.json', + )); + await fontManifestFile.create(recursive: true); + await fontManifestFile.writeAsString( + const JsonEncoder.withIndent(' ').convert(fontManifest), + ); +} + +Future copySkiaTestImages() async { + final io.Directory testImagesDir = io.Directory(pathlib.join( + environment.engineSrcDir.path, + 'third_party', + 'skia', + 'resources', + 'images', + )); + + for (final io.File imageFile in testImagesDir.listSync(recursive: true).whereType()) { + final io.File destination = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'test_images', + pathlib.relative(imageFile.path, from: testImagesDir.path), + )); + destination.createSync(recursive: true); + await imageFile.copy(destination.path); + } +} + +Future copyCanvasKitFiles(String subdirectory) async { + final String sourceDirectoryPath = pathlib.join( + environment.wasmReleaseOutDir.path, + subdirectory, + ); + + final String targetDirectoryPath = pathlib.join( + environment.webUiBuildDir.path, + subdirectory, + ); + + for (final String filename in [ + 'canvaskit.js', + 'canvaskit.wasm', + ]) { + final io.File sourceFile = io.File(pathlib.join( + sourceDirectoryPath, + filename, + )); + final io.File targetFile = io.File(pathlib.join( + targetDirectoryPath, + filename, + )); + if (!sourceFile.existsSync()) { + throw ToolExit('Built CanvasKit artifact not found at path "$sourceFile".'); + } + await targetFile.create(recursive: true); + await sourceFile.copy(targetFile.path); + } +} + +Future copySkwasm() async { + final io.Directory targetDir = io.Directory(pathlib.join( + environment.webUiBuildDir.path, + 'skwasm', + )); + + await targetDir.create(recursive: true); + + for (final String fileName in [ + 'skwasm.wasm', + 'skwasm.js', + 'skwasm.worker.js', + ]) { + final io.File sourceFile = io.File(pathlib.join( + environment.wasmReleaseOutDir.path, + fileName, + )); + final io.File targetFile = io.File(pathlib.join( + targetDir.path, + fileName, + )); + await sourceFile.copy(targetFile.path); + } +} + +Future buildHostPage() async { + final String hostDartPath = pathlib.join('lib', 'static', 'host.dart'); + final io.File hostDartFile = io.File(pathlib.join( + environment.webEngineTesterRootDir.path, + hostDartPath, + )); + final String targetDirectoryPath = pathlib.join( + environment.webUiBuildDir.path, + 'host', + ); + io.Directory(targetDirectoryPath).createSync(recursive: true); + final String targetFilePath = pathlib.join( + targetDirectoryPath, + 'host.dart', + ); + + const List staticFiles = [ + 'favicon.ico', + 'host.css', + 'index.html', + ]; + for (final String staticFilePath in staticFiles) { + final io.File source = io.File(pathlib.join( + environment.webEngineTesterRootDir.path, + 'lib', + 'static', + staticFilePath, + )); + final io.File destination = io.File(pathlib.join( + targetDirectoryPath, + staticFilePath, + )); + await source.copy(destination.path); + } + + final io.File timestampFile = io.File(pathlib.join( + environment.webEngineTesterRootDir.path, + '$targetFilePath.js.timestamp', + )); + + final String timestamp = + hostDartFile.statSync().modified.millisecondsSinceEpoch.toString(); + if (timestampFile.existsSync()) { + final String lastBuildTimestamp = timestampFile.readAsStringSync(); + if (lastBuildTimestamp == timestamp) { + // The file is still fresh. No need to rebuild. + return; + } else { + // Record new timestamp, but don't return. We need to rebuild. + print('${hostDartFile.path} timestamp changed. Rebuilding.'); + } + } else { + print('Building ${hostDartFile.path}.'); + } + + int exitCode = await runProcess( + environment.dartExecutable, + [ + 'pub', + 'get', + ], + workingDirectory: environment.webEngineTesterRootDir.path + ); + + if (exitCode != 0) { + throw ToolExit( + 'Failed to run pub get for web_engine_tester, exit code $exitCode', + exitCode: exitCode, + ); + } + + exitCode = await runProcess( + environment.dartExecutable, + [ + 'compile', + 'js', + hostDartPath, + '-o', + '$targetFilePath.js', + ], + workingDirectory: environment.webEngineTesterRootDir.path, + ); + + if (exitCode != 0) { + throw ToolExit( + 'Failed to compile ${hostDartFile.path}. Compiler ' + 'exited with exit code $exitCode', + exitCode: exitCode, + ); + } + + // Record the timestamp to avoid rebuilding unless the file changes. + timestampFile.writeAsStringSync(timestamp); +} diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart new file mode 100644 index 0000000000000..429d6f14859f2 --- /dev/null +++ b/lib/web_ui/dev/suite_filter.dart @@ -0,0 +1,85 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io' as io; + +import 'felt_config.dart'; + +class SuiteFilterResult { + SuiteFilterResult.accepted(); + SuiteFilterResult.rejected(String reason) : rejectReason = reason; + + String? rejectReason; + + bool get isAccepted => rejectReason == null; +} + +abstract class SuiteFilter { + SuiteFilterResult filterSuite(TestSuite suite); +} + +bool _macOSSupportsBrowser(Browser browser) { + switch (browser) { + case Browser.chrome: + case Browser.firefox: + case Browser.safari: + return true; + case Browser.edge: + return false; + } +} + +bool _linuxSupportsBrowser(Browser browser) { + switch (browser) { + case Browser.chrome: + case Browser.firefox: + return true; + case Browser.edge: + case Browser.safari: + return false; + } +} + +bool _windowsSupportsBrowser(Browser browser) { + switch (browser) { + case Browser.chrome: + case Browser.edge: + return true; + case Browser.firefox: + case Browser.safari: + return false; + } +} + +typedef BrowserSupportCheck = bool Function(Browser browser); + +BrowserSupportCheck get _platformBrowserSupportCheck { + if (io.Platform.isLinux) { + return _linuxSupportsBrowser; + } else if (io.Platform.isMacOS) { + return _macOSSupportsBrowser; + } else if (io.Platform.isWindows) { + return _windowsSupportsBrowser; + } else { + throw AssertionError('Unsupported OS: ${io.Platform.operatingSystem}'); + } +} + +class PlatformSuiteFilter implements SuiteFilter { + PlatformSuiteFilter() : _browserCheck = _platformBrowserSupportCheck; + + final BrowserSupportCheck _browserCheck; + + @override + SuiteFilterResult filterSuite(TestSuite suite) { + final Browser browser = suite.runConfig.browser; + if (_browserCheck(browser)) { + return SuiteFilterResult.accepted(); + } else { + return SuiteFilterResult.rejected( + 'Current platform (${io.Platform.operatingSystem}) does not support browser $browser' + ); + } + } +} diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 374a6b0152238..514687d577a7d 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -14,7 +14,9 @@ import 'environment.dart'; import 'felt_config.dart'; import 'pipeline.dart'; import 'steps/compile_tests_step.dart'; +import 'steps/copy_artifacts_step.dart'; import 'steps/run_tests_step.dart'; +import 'suite_filter.dart'; import 'utils.dart'; /// Runs tests. @@ -27,6 +29,11 @@ class TestCommand extends Command with ArgUtils { 'opportunity to add breakpoints or inspect loaded code before ' 'running the code.', ) + ..addFlag( + 'verbose', + abbr: 'v', + help: 'Enable verbose output.' + ) ..addFlag( 'watch', abbr: 'w', @@ -103,6 +110,8 @@ class TestCommand extends Command with ArgUtils { /// you set breakpoints or inspect the code. bool get isDebug => boolArg('debug'); + bool get isVerbose => boolArg('verbose'); + /// Paths to targets to run, e.g. a single test. List get targets => argResults!.rest; @@ -129,21 +138,78 @@ class TestCommand extends Command with ArgUtils { /// Whether or not to use the locally built version of CanvasKit. bool get useLocalCanvasKit => boolArg('use-local-canvaskit'); + List get suiteFilters { + return [ + PlatformSuiteFilter() + // TODO(jacksongardner): Add more filters + // Add browser filter from CLI + // Add suite filter from CLI + // Add compiler filter from CLI + // Add file filter from CLI + // Add renderer filter from CLI + ]; + } + + List _filterTestSuites(List suites) { + if (isVerbose) { + print('Filtering suites...'); + } + final List filters = suiteFilters; + final List filteredSuites = suites.where((TestSuite suite) { + for (final SuiteFilter filter in filters) { + final SuiteFilterResult result = filter.filterSuite(suite); + if (!result.isAccepted) { + if (isVerbose) { + print(' ${suite.name.ansiCyan} rejected for reason: ${result.rejectReason}'); + } + return false; + } + } + return true; + }).toList(); + return filteredSuites; + } + + List _filterBundlesForSuites(List bundles, List suites) { + final Set seenBundles = + Set.from(suites.map((TestSuite suite) => suite.testBundle)); + return bundles.where((TestBundle bundle) => seenBundles.contains(bundle)).toList(); + } + + ArtifactDependencies _artifactsForSuites(List suites) { + return suites.fold(ArtifactDependencies.none(), + (ArtifactDependencies deps, TestSuite suite) => deps | suite.artifactDependencies); + } + @override Future run() async { final FeltConfig config = FeltConfig.fromFile( path.join(environment.webUiTestDir.path, 'felt_config.yaml') ); - if (isList) { + final List filteredSuites = _filterTestSuites(config.testSuites); + final List bundles = _filterBundlesForSuites(config.testBundles, filteredSuites); + final ArtifactDependencies artifacts = _artifactsForSuites(config.testSuites); + if (isList || isVerbose) { + print('Suites:'); + for (final TestSuite suite in filteredSuites) { + print(' ${suite.name.ansiCyan}'); + } print('Bundles:'); - for (final TestBundle bundle in config.testBundles) { - print(' ${bundle.name}'); + for (final TestBundle bundle in bundles) { + print(' ${bundle.name.ansiMagenta}'); } - print(''); - print('Suites:'); - for (final TestSuite suite in config.testSuites) { - print(' ${suite.name}'); + print('Artifacts:'); + if (artifacts.canvasKit) { + print(' canvaskit'.ansiYellow); + } + if (artifacts.canvasKitChromium) { + print(' canvaskit_chromium'.ansiYellow); + } + if (artifacts.skwasm) { + print(' skwasm'.ansiYellow); } + } + if (isList) { return true; } final List testFiles = runAllTests @@ -152,9 +218,9 @@ class TestCommand extends Command with ArgUtils { final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), + CopyArtifactsStep(artifacts), CompileTestsStep( testFiles: testFiles, - useLocalCanvasKit: useLocalCanvasKit, isWasm: isWasm ), RunTestsStep( diff --git a/lib/web_ui/dev/utils.dart b/lib/web_ui/dev/utils.dart index 2fe7244c20d98..75d5727aadeb2 100644 --- a/lib/web_ui/dev/utils.dart +++ b/lib/web_ui/dev/utils.dart @@ -447,3 +447,25 @@ String getBuildDirForRenderer(Renderer renderer) { return 'skwasm_tests'; } } + +extension AnsiColors on String { + static bool shouldEscape = io.stdout.hasTerminal && io.stdout.supportsAnsiEscapes; + + static const String _noColorCode = '\u001b[39m'; + + String _wrapText(String prefix, String suffix) => shouldEscape + ? '$prefix$this$suffix' : this; + + String _colorText(String colorCode) => _wrapText(colorCode, _noColorCode); + + String get ansiBlack => _colorText('\u001b[30m'); + String get ansiRed => _colorText('\u001b[31m'); + String get ansiGreen => _colorText('\u001b[32m'); + String get ansiYellow => _colorText('\u001b[33m'); + String get ansiBlue => _colorText('\u001b[34m'); + String get ansiMagenta => _colorText('\u001b[35m'); + String get ansiCyan => _colorText('\u001b[36m'); + String get ansiWhite => _colorText('\u001b[37m'); + + String get ansiBold => _wrapText('\u001b[1m', '\u001b[0m'); +} From 8760d77093972544131c057aab4159a3f8c77b08 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 15 Feb 2023 17:34:50 -0800 Subject: [PATCH 03/44] CompileBundleStep implemented. --- lib/web_ui/dev/steps/compile_bundle_step.dart | 284 ++++++++++++++++++ lib/web_ui/dev/test_runner.dart | 3 + .../{skwasm => skwasm_stub}/smoke_test.dart | 0 3 files changed, 287 insertions(+) create mode 100644 lib/web_ui/dev/steps/compile_bundle_step.dart rename lib/web_ui/test/{skwasm => skwasm_stub}/smoke_test.dart (100%) diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart new file mode 100644 index 0000000000000..77610e5b6f59d --- /dev/null +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -0,0 +1,284 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io' as io; + +import 'package:path/path.dart' as pathlib; +import 'package:pool/pool.dart'; + +import '../environment.dart'; +import '../exceptions.dart'; +import '../felt_config.dart'; +import '../pipeline.dart'; +import '../utils.dart' show AnsiColors, FilePath, ProcessManager, cleanup, startProcess; + +/// Compiles a web test bundle into web_ui/build/test_bundles/. +class CompileBundleStep implements PipelineStep { + CompileBundleStep({ + required this.bundle, + this.testFiles, + }); + + final TestBundle bundle; + final Set? testFiles; + + // Maximum number of concurrent compile processes to use. + static final int _compileConcurrency = int.parse(io.Platform.environment['FELT_COMPILE_CONCURRENCY'] ?? '8'); + final Pool compilePool = Pool(_compileConcurrency); + + @override + String get description => 'compile_bundle'; + + @override + bool get isSafeToInterrupt => true; + + @override + Future interrupt() async { + await cleanup(); + } + + io.Directory get testSetDirectory => io.Directory( + pathlib.join(environment.webUiTestDir.path, bundle.testSet.directory) + ); + + io.Directory get outputBundleDirectory => io.Directory( + pathlib.join( + environment.webUiBuildDir.path, + 'test_bundles', + bundle.name, + ) + ); + + List _findTestFiles() { + final io.Directory testDirectory = testSetDirectory; + if (!testDirectory.existsSync()) { + throw ToolExit('Test directory "${testDirectory.path}" for bundle ${bundle.name.ansiMagenta} does not exist.'); + } + return testDirectory + .listSync(recursive: true) + .whereType() + .where((io.File f) => f.path.endsWith('_test.dart')) + .map((io.File f) => FilePath.fromWebUi( + pathlib.relative(f.path, from: environment.webUiRootDir.path))) + .toList(); + } + + TestCompiler _createCompiler() { + switch (bundle.compileConfig.compiler) { + case Compiler.dart2js: + return Dart2JSCompiler( + testSetDirectory, + outputBundleDirectory, + renderer: bundle.compileConfig.renderer, + ); + case Compiler.dart2wasm: + return Dart2WasmCompiler( + testSetDirectory, + outputBundleDirectory, + renderer: bundle.compileConfig.renderer, + ); + } + } + + @override + Future run() async { + print('Compiling test bundle ${bundle.name.ansiMagenta}...'); + final List allTests = _findTestFiles(); + final TestCompiler compiler = _createCompiler(); + final Stopwatch stopwatch = Stopwatch()..start(); + final String testSetDirectoryPath = testSetDirectory.path; + + // Clear out old bundle compilations, if they exist + if (outputBundleDirectory.existsSync()) { + outputBundleDirectory.deleteSync(recursive: true ); + } + + final List>> pendingResults = >>[]; + for (final FilePath testFile in allTests) { + final String relativePath = pathlib.relative( + testFile.absolute, + from: testSetDirectoryPath); + final Future> result = compilePool.withResource(() async { + if (testFiles != null && !testFiles!.contains(testFile)) { + return MapEntry(relativePath, CompileResult.filtered); + } + final bool success = await compiler.compileTest(testFile); + const int maxTestNameLength = 80; + final String truncatedPath = relativePath.length > maxTestNameLength + ? relativePath.replaceRange(maxTestNameLength - 3, relativePath.length, '...') + : relativePath; + final String expandedPath = truncatedPath.padRight(maxTestNameLength); + io.stdout.write('\r ${success ? expandedPath.ansiGreen : expandedPath.ansiRed}'); + return success + ? MapEntry(relativePath, CompileResult.success) + : MapEntry(relativePath, CompileResult.compilationFailure); + }); + pendingResults.add(result); + } + final Map results = Map.fromEntries(await Future.wait(pendingResults)); + stopwatch.stop(); + + final String resultsJson = const JsonEncoder.withIndent(' ').convert({ + 'name': bundle.name, + 'directory': bundle.testSet.directory, + 'compiler': bundle.compileConfig.compiler.name, + 'renderer': bundle.compileConfig.renderer.name, + 'compileTimeInMs': stopwatch.elapsedMilliseconds, + 'results': results.map((String k, CompileResult v) => MapEntry(k, v.name)), + }); + final io.File outputResultsFile = io.File(pathlib.join( + outputBundleDirectory.path, + 'results.json', + )); + outputResultsFile.writeAsStringSync(resultsJson); + print('\rCompleted compilation of ${bundle.name.ansiMagenta} in ${stopwatch.elapsedMilliseconds}ms.'.padRight(82)); + } +} + +enum CompileResult { + success, + compilationFailure, + filtered, +} + +abstract class TestCompiler { + TestCompiler( + this.inputTestSetDirectory, + this.outputTestBundleDirectory, + {required this.renderer} + ); + + final io.Directory inputTestSetDirectory; + final io.Directory outputTestBundleDirectory; + final Renderer renderer; + + Future compileTest(FilePath input); +} + +class Dart2JSCompiler extends TestCompiler { + Dart2JSCompiler( + super.inputTestSetDirectory, + super.outputTestBundleDirectory, + {required super.renderer} + ); + + @override + Future compileTest(FilePath input) async { + final String relativePath = pathlib.relative( + input.absolute, + from: inputTestSetDirectory.path + ); + + final String targetFileName = pathlib.join( + outputTestBundleDirectory.path, + '$relativePath.browser_test.dart.js', + ); + + final io.Directory outputDirectory = io.File(targetFileName).parent; + if (!outputDirectory.existsSync()) { + outputDirectory.createSync(recursive: true); + } + + final List arguments = [ + 'compile', + 'js', + '--no-minify', + '--disable-inlining', + '--enable-asserts', + + // We do not want to auto-select a renderer in tests. As of today, tests + // are designed to run in one specific mode. So instead, we specify the + // renderer explicitly. + '-DFLUTTER_WEB_AUTO_DETECT=false', + '-DFLUTTER_WEB_USE_SKIA=${renderer == Renderer.canvaskit}', + '-DFLUTTER_WEB_USE_SKWASM=${renderer == Renderer.skwasm}', + + '-O2', + '-o', + targetFileName, // target path. + relativePath, // current path. + ]; + + final ProcessManager process = await startProcess( + environment.dartExecutable, + arguments, + workingDirectory: inputTestSetDirectory.path, + evalOutput: true, + ); + final int exitCode = await process.wait(); + if (exitCode != 0) { + io.stderr.writeln('ERROR: Failed to compile test $input. ' + 'Dart2js exited with exit code $exitCode'); + return false; + } else { + return true; + } + } +} + +class Dart2WasmCompiler extends TestCompiler { + Dart2WasmCompiler( + super.inputTestSetDirectory, + super.outputTestBundleDirectory, + {required super.renderer} + ); + + @override + Future compileTest(FilePath input) async { + final String relativePath = pathlib.relative( + input.absolute, + from: inputTestSetDirectory.path + ); + + final String targetFileName = pathlib.join( + outputTestBundleDirectory.path, + '$relativePath.browser_test.dart.wasm', + ); + + final io.Directory outputDirectory = io.File(targetFileName).parent; + if (!outputDirectory.existsSync()) { + outputDirectory.createSync(recursive: true); + } + + final List arguments = [ + environment.dart2wasmSnapshotPath, + + '--dart-sdk=${environment.dartSdkDir.path}', + '--enable-asserts', + + // We do not want to auto-select a renderer in tests. As of today, tests + // are designed to run in one specific mode. So instead, we specify the + // renderer explicitly. + '-DFLUTTER_WEB_AUTO_DETECT=false', + '-DFLUTTER_WEB_USE_SKIA=${renderer == Renderer.canvaskit}', + '-DFLUTTER_WEB_USE_SKWASM=${renderer == Renderer.skwasm}', + + if (renderer == Renderer.skwasm) + ...[ + '--import-shared-memory', + '--shared-memory-max-pages=32768', + ], + + relativePath, // current path. + targetFileName, // target path. + ]; + + final ProcessManager process = await startProcess( + environment.dartAotRuntimePath, + arguments, + workingDirectory: inputTestSetDirectory.path, + evalOutput: true, + ); + final int exitCode = await process.wait(); + + if (exitCode != 0) { + io.stderr.writeln('ERROR: Failed to compile test $input. ' + 'dart2wasm exited with exit code $exitCode'); + return false; + } else { + return true; + } + } +} diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 514687d577a7d..3998646425e60 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -13,6 +13,7 @@ import 'package:watcher/src/watch_event.dart'; import 'environment.dart'; import 'felt_config.dart'; import 'pipeline.dart'; +import 'steps/compile_bundle_step.dart'; import 'steps/compile_tests_step.dart'; import 'steps/copy_artifacts_step.dart'; import 'steps/run_tests_step.dart'; @@ -219,6 +220,8 @@ class TestCommand extends Command with ArgUtils { final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), CopyArtifactsStep(artifacts), + for (final TestBundle bundle in bundles) + CompileBundleStep(bundle: bundle), CompileTestsStep( testFiles: testFiles, isWasm: isWasm diff --git a/lib/web_ui/test/skwasm/smoke_test.dart b/lib/web_ui/test/skwasm_stub/smoke_test.dart similarity index 100% rename from lib/web_ui/test/skwasm/smoke_test.dart rename to lib/web_ui/test/skwasm_stub/smoke_test.dart From 752547d4a9078e7d2fd4e8c6f3b92342b7b8fcac Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 04/44] Suites running, but assets alongside tests are not being served. --- lib/web_ui/dev/common.dart | 12 +- lib/web_ui/dev/felt.dart | 2 - lib/web_ui/dev/felt_config.dart | 6 +- lib/web_ui/dev/run.dart | 111 ------- lib/web_ui/dev/steps/compile_bundle_step.dart | 10 +- lib/web_ui/dev/steps/compile_tests_step.dart | 223 -------------- lib/web_ui/dev/steps/run_suite_step.dart | 203 ++++++++++++ lib/web_ui/dev/steps/run_tests_step.dart | 290 ------------------ lib/web_ui/dev/suite_filter.dart | 34 +- lib/web_ui/dev/test_platform.dart | 139 ++++----- lib/web_ui/dev/test_runner.dart | 56 ++-- lib/web_ui/dev/utils.dart | 92 +----- web_sdk/web_test_utils/lib/image_compare.dart | 1 - 13 files changed, 346 insertions(+), 833 deletions(-) delete mode 100644 lib/web_ui/dev/run.dart delete mode 100644 lib/web_ui/dev/steps/compile_tests_step.dart create mode 100644 lib/web_ui/dev/steps/run_suite_step.dart delete mode 100644 lib/web_ui/dev/steps/run_tests_step.dart diff --git a/lib/web_ui/dev/common.dart b/lib/web_ui/dev/common.dart index eab1360ac87c2..cd61c8f39e196 100644 --- a/lib/web_ui/dev/common.dart +++ b/lib/web_ui/dev/common.dart @@ -11,6 +11,7 @@ import 'browser_lock.dart'; import 'chrome.dart'; import 'edge.dart'; import 'environment.dart'; +import 'felt_config.dart'; import 'firefox.dart'; import 'safari_macos.dart'; @@ -261,16 +262,15 @@ const List kAllBrowserNames = [ /// Creates an environment for a browser. /// /// The [browserName] matches the browser name passed as the `--browser` option. -BrowserEnvironment getBrowserEnvironment(String browserName, { required bool enableWasmGC }) { +BrowserEnvironment getBrowserEnvironment(BrowserName browserName, { required bool enableWasmGC }) { switch (browserName) { - case kChrome: + case BrowserName.chrome: return ChromeEnvironment(enableWasmGC); - case kEdge: + case BrowserName.edge: return EdgeEnvironment(); - case kFirefox: + case BrowserName.firefox: return FirefoxEnvironment(); - case kSafari: + case BrowserName.safari: return SafariMacOsEnvironment(); } - throw UnsupportedError('Browser $browserName is not supported.'); } diff --git a/lib/web_ui/dev/felt.dart b/lib/web_ui/dev/felt.dart index 1dc0ccbb74d00..3ed0837fe2af0 100644 --- a/lib/web_ui/dev/felt.dart +++ b/lib/web_ui/dev/felt.dart @@ -12,7 +12,6 @@ import 'clean.dart'; import 'exceptions.dart'; import 'generate_fallback_font_data.dart'; import 'licenses.dart'; -import 'run.dart'; import 'test_runner.dart'; import 'utils.dart'; @@ -25,7 +24,6 @@ CommandRunner runner = CommandRunner( ..addCommand(CleanCommand()) ..addCommand(GenerateFallbackFontDataCommand()) ..addCommand(LicensesCommand()) - ..addCommand(RunCommand()) ..addCommand(TestCommand()); Future main(List rawArgs) async { diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart index c9dd303a7ba70..cbcf3f6f161e9 100644 --- a/lib/web_ui/dev/felt_config.dart +++ b/lib/web_ui/dev/felt_config.dart @@ -44,7 +44,7 @@ enum CanvasKitVariant { chromium, } -enum Browser { +enum BrowserName { chrome, edge, firefox, @@ -55,7 +55,7 @@ class RunConfiguration { RunConfiguration(this.name, this.browser, this.variant); final String name; - final Browser browser; + final BrowserName browser; final CanvasKitVariant? variant; } @@ -175,7 +175,7 @@ class FeltConfig { for (final dynamic node in yaml['run-configs'] as YamlList) { final YamlMap runConfigYaml = node as YamlMap; final String name = runConfigYaml['name'] as String; - final Browser browser = Browser.values.byName(runConfigYaml['browser'] as String); + final BrowserName browser = BrowserName.values.byName(runConfigYaml['browser'] as String); final dynamic variantNode = runConfigYaml['canvaskit-variant']; final CanvasKitVariant? variant = variantNode == null ? null diff --git a/lib/web_ui/dev/run.dart b/lib/web_ui/dev/run.dart deleted file mode 100644 index eaed34bfbf80c..0000000000000 --- a/lib/web_ui/dev/run.dart +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:io' as io; - -import 'package:args/command_runner.dart'; - -import 'common.dart'; -import 'pipeline.dart'; -import 'steps/compile_tests_step.dart'; -import 'steps/run_tests_step.dart'; -import 'utils.dart'; - -/// Runs build and test steps. -/// -/// This command is designed to be invoked by the LUCI build graph. However, it -/// is also usable locally. -/// -/// Usage: -/// -/// felt run name_of_build_step -class RunCommand extends Command with ArgUtils { - RunCommand() { - argParser.addFlag( - 'list', - abbr: 'l', - help: 'Lists all available build steps.', - ); - argParser.addFlag( - 'require-skia-gold', - help: 'Whether we require Skia Gold to be available or not. When this ' - 'flag is true, the tests will fail if Skia Gold is not available.', - ); - argParser.addFlag( - 'wasm', - help: 'Whether the test we are running are compiled to webassembly.' - ); - } - - @override - String get name => 'run'; - - bool get isWasm => boolArg('wasm'); - - bool get isListSteps => boolArg('list'); - - /// When running screenshot tests, require Skia Gold to be available and - /// reachable. - bool get requireSkiaGold => boolArg('require-skia-gold'); - - @override - String get description => 'Runs a build step.'; - - /// Build steps to run, in order specified. - List get stepNames => argResults!.rest; - - @override - FutureOr run() async { - // All available build steps. - final Map buildSteps = { - 'compile_tests': CompileTestsStep(), - for (final String browserName in kAllBrowserNames) - 'run_tests_$browserName': RunTestsStep( - browserName: browserName, - isDebug: false, - isWasm: isWasm, - doUpdateScreenshotGoldens: false, - requireSkiaGold: requireSkiaGold, - overridePathToCanvasKit: null, - ), - }; - - if (isListSteps) { - buildSteps.keys.forEach(print); - return true; - } - - if (stepNames.isEmpty) { - throw UsageException('No build steps specified.', argParser.usage); - } - - final List unrecognizedStepNames = []; - for (final String stepName in stepNames) { - if (!buildSteps.containsKey(stepName)) { - unrecognizedStepNames.add(stepName); - } - } - if (unrecognizedStepNames.isNotEmpty) { - io.stderr.writeln( - 'Unknown build steps specified: ${unrecognizedStepNames.join(', ')}', - ); - return false; - } - - final List steps = []; - print('Running steps ${steps.join(', ')}'); - for (final String stepName in stepNames) { - steps.add(buildSteps[stepName]!); - } - - final Stopwatch stopwatch = Stopwatch()..start(); - final Pipeline pipeline = Pipeline(steps: steps); - await pipeline.run(); - stopwatch.stop(); - print('Finished running steps in ${stopwatch.elapsedMilliseconds / 1000} seconds.'); - - return true; - } -} diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart index 77610e5b6f59d..197a673da535f 100644 --- a/lib/web_ui/dev/steps/compile_bundle_step.dart +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -12,7 +12,7 @@ import '../environment.dart'; import '../exceptions.dart'; import '../felt_config.dart'; import '../pipeline.dart'; -import '../utils.dart' show AnsiColors, FilePath, ProcessManager, cleanup, startProcess; +import '../utils.dart' show AnsiColors, FilePath, ProcessManager, cleanup, getBundleBuildDirectory, startProcess; /// Compiles a web test bundle into web_ui/build/test_bundles/. class CompileBundleStep implements PipelineStep { @@ -43,13 +43,7 @@ class CompileBundleStep implements PipelineStep { pathlib.join(environment.webUiTestDir.path, bundle.testSet.directory) ); - io.Directory get outputBundleDirectory => io.Directory( - pathlib.join( - environment.webUiBuildDir.path, - 'test_bundles', - bundle.name, - ) - ); + io.Directory get outputBundleDirectory => getBundleBuildDirectory(bundle); List _findTestFiles() { final io.Directory testDirectory = testSetDirectory; diff --git a/lib/web_ui/dev/steps/compile_tests_step.dart b/lib/web_ui/dev/steps/compile_tests_step.dart deleted file mode 100644 index dd227af1a7dad..0000000000000 --- a/lib/web_ui/dev/steps/compile_tests_step.dart +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io' as io; - -import 'package:path/path.dart' as pathlib; -import 'package:pool/pool.dart'; - -import '../environment.dart'; -import '../exceptions.dart'; -import '../pipeline.dart'; -import '../utils.dart'; - -/// Compiles web tests and their dependencies into web_ui/build/. -/// -/// Outputs of this step: -/// -/// * canvaskit/ - CanvasKit artifacts -/// * assets/ - test fonts -/// * host/ - compiled test host page and static artifacts -/// * test/ - compiled test code -/// * test_images/ - test images copied from Skis sources. -class CompileTestsStep implements PipelineStep { - CompileTestsStep({ - this.testFiles, - this.isWasm = false - }); - - final List? testFiles; - final bool isWasm; - - @override - String get description => 'compile_tests'; - - @override - bool get isSafeToInterrupt => true; - - @override - Future interrupt() async { - await cleanup(); - } - - @override - Future run() async { - await compileTests(testFiles ?? findAllTests(), isWasm); - } -} - -/// Compiles the specified unit tests. -Future compileTests(List testFiles, bool isWasm) async { - final Stopwatch stopwatch = Stopwatch()..start(); - - final TestsByRenderer sortedTests = sortTestsByRenderer(testFiles, isWasm); - - await Future.wait(>[ - if (sortedTests.htmlTests.isNotEmpty) - _compileTestsInParallel(targets: sortedTests.htmlTests, isWasm: isWasm), - if (sortedTests.canvasKitTests.isNotEmpty) - _compileTestsInParallel(targets: sortedTests.canvasKitTests, renderer: Renderer.canvasKit, isWasm: isWasm), - if (sortedTests.skwasmTests.isNotEmpty) - _compileTestsInParallel(targets: sortedTests.skwasmTests, renderer: Renderer.skwasm, isWasm: isWasm), - ]); - - stopwatch.stop(); - - final int targetCount = sortedTests.numTargetsToCompile; - print( - 'Built $targetCount tests in ${stopwatch.elapsedMilliseconds ~/ 1000} ' - 'seconds using $_dart2jsConcurrency concurrent compile processes.', - ); -} - -// Maximum number of concurrent dart2js processes to use. -int _dart2jsConcurrency = int.parse(io.Platform.environment['FELT_DART2JS_CONCURRENCY'] ?? '8'); - -final Pool _dart2jsPool = Pool(_dart2jsConcurrency); - -/// Spawns multiple dart2js processes to compile [targets] in parallel. -Future _compileTestsInParallel({ - required List targets, - Renderer renderer = Renderer.html, - bool isWasm = false, -}) async { - final Stream results = _dart2jsPool.forEach( - targets, - (FilePath file) => compileUnitTest(file, renderer: renderer, isWasm: isWasm), - ); - await for (final bool isSuccess in results) { - if (!isSuccess) { - throw ToolExit('Failed to compile tests.'); - } - } -} - -Future compileUnitTest(FilePath input, {required Renderer renderer, required bool isWasm}) async { - return isWasm ? compileUnitTestToWasm(input, renderer: renderer) - : compileUnitTestToJS(input, renderer: renderer); -} - -/// Compiles one unit test using `dart2js`. -/// -/// When building for CanvasKit we have to use extra argument -/// `DFLUTTER_WEB_USE_SKIA=true`. -/// -/// Dart2js creates the following outputs: -/// - target.browser_test.dart.js -/// - target.browser_test.dart.js.deps -/// - target.browser_test.dart.js.map -/// under the same directory with test file. If all these files are not in -/// the same directory, Chrome dev tools cannot load the source code during -/// debug. -/// -/// All the files under test already copied from /test directory to /build -/// directory before test are build. See [_copyFilesFromTestToBuild]. -/// -/// Later the extra files will be deleted in [_cleanupExtraFilesUnderTestDir]. -Future compileUnitTestToJS(FilePath input, {required Renderer renderer}) async { - // Compile to different directories for different renderers. This allows us - // to run the same test in multiple renderers. - final String targetFileName = pathlib.join( - environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - '${input.relativeToWebUi}.browser_test.dart.js', - ); - - final io.Directory directoryToTarget = io.Directory(pathlib.join( - environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - pathlib.dirname(input.relativeToWebUi))); - - if (!directoryToTarget.existsSync()) { - directoryToTarget.createSync(recursive: true); - } - - final List arguments = [ - 'compile', - 'js', - '--no-minify', - '--disable-inlining', - '--enable-asserts', - - // We do not want to auto-select a renderer in tests. As of today, tests - // are designed to run in one specific mode. So instead, we specify the - // renderer explicitly. - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=${renderer == Renderer.canvasKit}', - '-DFLUTTER_WEB_USE_SKWASM=${renderer == Renderer.skwasm}', - - '-O2', - '-o', - targetFileName, // target path. - input.relativeToWebUi, // current path. - ]; - - final int exitCode = await runProcess( - environment.dartExecutable, - arguments, - workingDirectory: environment.webUiRootDir.path, - ); - - if (exitCode != 0) { - io.stderr.writeln('ERROR: Failed to compile test $input. ' - 'Dart2js exited with exit code $exitCode'); - return false; - } else { - return true; - } -} - -Future compileUnitTestToWasm(FilePath input, {required Renderer renderer}) async { - final String targetFileName = pathlib.join( - environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - '${input.relativeToWebUi}.browser_test.dart.wasm', - ); - - final io.Directory directoryToTarget = io.Directory(pathlib.join( - environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - pathlib.dirname(input.relativeToWebUi))); - - if (!directoryToTarget.existsSync()) { - directoryToTarget.createSync(recursive: true); - } - - final List arguments = [ - environment.dart2wasmSnapshotPath, - - '--dart-sdk=${environment.dartSdkDir.path}', - '--enable-asserts', - - // We do not want to auto-select a renderer in tests. As of today, tests - // are designed to run in one specific mode. So instead, we specify the - // renderer explicitly. - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=${renderer == Renderer.canvasKit}', - '-DFLUTTER_WEB_USE_SKWASM=${renderer == Renderer.skwasm}', - - if (renderer == Renderer.skwasm) - ...[ - '--import-shared-memory', - '--shared-memory-max-pages=32768', - ], - - input.relativeToWebUi, // current path. - targetFileName, // target path. - ]; - - final int exitCode = await runProcess( - environment.dartAotRuntimePath, - arguments, - workingDirectory: environment.webUiRootDir.path, - ); - - if (exitCode != 0) { - io.stderr.writeln('ERROR: Failed to compile test $input. ' - 'dart2wasm exited with exit code $exitCode'); - return false; - } else { - return true; - } -} diff --git a/lib/web_ui/dev/steps/run_suite_step.dart b/lib/web_ui/dev/steps/run_suite_step.dart new file mode 100644 index 0000000000000..ca3aafa4b1cf7 --- /dev/null +++ b/lib/web_ui/dev/steps/run_suite_step.dart @@ -0,0 +1,203 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io' as io; + +import 'package:path/path.dart' as pathlib; +// TODO(yjbanov): remove hacks when this is fixed: +// https://github.com/dart-lang/test/issues/1521 +import 'package:skia_gold_client/skia_gold_client.dart'; +import 'package:test_api/src/backend/runtime.dart' as hack; +import 'package:test_core/src/executable.dart' as test; +import 'package:test_core/src/runner/hack_register_platform.dart' as hack; + +import '../browser.dart'; +import '../common.dart'; +import '../environment.dart'; +import '../exceptions.dart'; +import '../felt_config.dart'; +import '../pipeline.dart'; +import '../test_platform.dart'; +import '../utils.dart'; + +/// Runs a test suite. +/// +/// Assumes the artifacts from previous steps are available, either from +/// running them prior to this step locally, or by having the build graph copy +/// them from another bot. +class RunSuiteStep implements PipelineStep { + RunSuiteStep(this.suite, { + required this.isDebug, + required this.doUpdateScreenshotGoldens, + required this.requireSkiaGold, + this.testFiles, + required this.overridePathToCanvasKit, + }); + + final TestSuite suite; + final Set? testFiles; + final bool isDebug; + final bool doUpdateScreenshotGoldens; + final String? overridePathToCanvasKit; + + /// Require Skia Gold to be available and reachable. + final bool requireSkiaGold; + + bool get isWasm => suite.testBundle.compileConfig.compiler == Compiler.dart2wasm; + + @override + String get description => 'run_suite'; + + @override + bool get isSafeToInterrupt => true; + + @override + Future interrupt() async {} + + @override + Future run() async { + _prepareTestResultsDirectory(); + final BrowserEnvironment browserEnvironment = getBrowserEnvironment( + suite.runConfig.browser, + enableWasmGC: isWasm); + await browserEnvironment.prepare(); + + final SkiaGoldClient? skiaClient = await _createSkiaClient(); + final String configurationFilePath = pathlib.join( + environment.webUiRootDir.path, + browserEnvironment.packageTestConfigurationYamlFile, + ); + final String bundleBuildPath = getBundleBuildDirectory(suite.testBundle).path; + final List testArgs = [ + ...['-r', 'compact'], + // Disable concurrency. Running with concurrency proved to be flaky. + '--concurrency=1', + if (isDebug) '--pause-after-load', + '--platform=${browserEnvironment.packageTestRuntime.identifier}', + '--precompiled=$bundleBuildPath', + '--configuration=$configurationFilePath', + '--', + ..._collectTestPaths(), + ]; + + hack.registerPlatformPlugin([ + browserEnvironment.packageTestRuntime, + ], () { + return BrowserPlatform.start( + suite, + browserEnvironment: browserEnvironment, + doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, + skiaClient: skiaClient, + overridePathToCanvasKit: overridePathToCanvasKit, + isWasm: isWasm, + ); + }); + + print('[${suite.name.ansiCyan}] Running...'); + + // We want to run tests with the test set's directory as a working directory. + final io.Directory testSetDirectory = io.Directory(pathlib.join( + environment.webUiTestDir.path, + suite.testBundle.testSet.directory, + )); + final dynamic originalCwd = io.Directory.current; + io.Directory.current = testSetDirectory; + try { + await test.main(testArgs); + } finally { + io.Directory.current = originalCwd; + } + + await browserEnvironment.cleanup(); + + if (io.exitCode != 0) { + print('[${suite.name.ansiCyan}] ${'Some tests failed.'.ansiRed}'); + io.exitCode = 0; + } else { + print('[${suite.name.ansiCyan}] ${'All tests passed!'.ansiGreen}'); + } + } + + io.Directory _prepareTestResultsDirectory() { + final io.Directory resultsDirectory = io.Directory(pathlib.join( + environment.webUiTestResultsDirectory.path, + suite.name, + )); + if (resultsDirectory.existsSync()) { + resultsDirectory.deleteSync(recursive: true); + } + resultsDirectory.createSync(recursive: true); + return resultsDirectory; + } + + List _collectTestPaths() { + final io.Directory bundleBuild = getBundleBuildDirectory(suite.testBundle); + final io.File resultsJsonFile = io.File(pathlib.join( + bundleBuild.path, + 'results.json', + )); + if (!resultsJsonFile.existsSync()) { + throw ToolExit('Could not find built bundle ${suite.testBundle.name.ansiMagenta} for suite ${suite.name.ansiCyan}.'); + } + final String jsonString = resultsJsonFile.readAsStringSync(); + final dynamic jsonContents = const JsonDecoder().convert(jsonString); + final dynamic results = jsonContents['results']; + final List testPaths = []; + results.forEach((dynamic k, dynamic v) { + final String result = v as String; + if (result == 'success') { + testPaths.add(k as String); + } + }); + return testPaths; + } + + Future _createSkiaClient() async { + final SkiaGoldClient skiaClient = SkiaGoldClient( + environment.webUiSkiaGoldDirectory, + dimensions: { + 'Browser': suite.runConfig.browser.name, + if (isWasm) 'Wasm': 'true', + }, + ); + + if (await _checkSkiaClient(skiaClient)) { + return skiaClient; + } + + if (requireSkiaGold) { + throw ToolExit('Skia Gold is required but is unavailable.'); + } + + return null; + } + + /// Checks whether the Skia Client is usable in this environment. + Future _checkSkiaClient(SkiaGoldClient skiaClient) async { + // Now let's check whether Skia Gold is reachable or not. + if (isLuci) { + if (isSkiaGoldClientAvailable) { + try { + await skiaClient.auth(); + return true; + } catch (e) { + print(e); + } + } + } else { + try { + // Check if we can reach Gold. + await skiaClient.getExpectationForTest(''); + return true; + } on io.OSError catch (_) { + print('OSError occurred, could not reach Gold.'); + } on io.SocketException catch (_) { + print('SocketException occurred, could not reach Gold.'); + } + } + + return false; + } +} diff --git a/lib/web_ui/dev/steps/run_tests_step.dart b/lib/web_ui/dev/steps/run_tests_step.dart deleted file mode 100644 index 196a5617d2a97..0000000000000 --- a/lib/web_ui/dev/steps/run_tests_step.dart +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io' as io; - -import 'package:path/path.dart' as pathlib; -// TODO(yjbanov): remove hacks when this is fixed: -// https://github.com/dart-lang/test/issues/1521 -import 'package:skia_gold_client/skia_gold_client.dart'; -import 'package:test_api/src/backend/group.dart' as hack; -import 'package:test_api/src/backend/live_test.dart' as hack; -import 'package:test_api/src/backend/runtime.dart' as hack; -import 'package:test_core/src/executable.dart' as test; -import 'package:test_core/src/runner/configuration/reporters.dart' as hack; -import 'package:test_core/src/runner/engine.dart' as hack; -import 'package:test_core/src/runner/hack_register_platform.dart' as hack; -import 'package:test_core/src/runner/reporter.dart' as hack; - -import '../browser.dart'; -import '../common.dart'; -import '../environment.dart'; -import '../exceptions.dart'; -import '../pipeline.dart'; -import '../test_platform.dart'; -import '../utils.dart'; - -/// Runs web tests. -/// -/// Assumes the artifacts from [CompileTestsStep] are available, either from -/// running it prior to this step locally, or by having the build graph copy -/// them from another bot. -class RunTestsStep implements PipelineStep { - RunTestsStep({ - required this.browserName, - required this.isDebug, - required this.doUpdateScreenshotGoldens, - required this.requireSkiaGold, - this.testFiles, - required this.overridePathToCanvasKit, - required this.isWasm - }); - - final String browserName; - final List? testFiles; - final bool isDebug; - final bool isWasm; - final bool doUpdateScreenshotGoldens; - final String? overridePathToCanvasKit; - - /// Require Skia Gold to be available and reachable. - final bool requireSkiaGold; - - @override - String get description => 'run_tests'; - - @override - bool get isSafeToInterrupt => true; - - @override - Future interrupt() async {} - - @override - Future run() async { - await _prepareTestResultsDirectory(); - - final BrowserEnvironment browserEnvironment = getBrowserEnvironment(browserName, enableWasmGC: isWasm); - await browserEnvironment.prepare(); - - final SkiaGoldClient? skiaClient = await _createSkiaClient(); - final List testFiles = this.testFiles ?? findAllTests(); - - final TestsByRenderer sortedTests = sortTestsByRenderer(testFiles, isWasm); - - bool testsPassed = true; - - if (sortedTests.htmlTests.isNotEmpty) { - await _runTestBatch( - testFiles: sortedTests.htmlTests, - renderer: Renderer.html, - browserEnvironment: browserEnvironment, - expectFailure: false, - isDebug: isDebug, - isWasm: isWasm, - doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, - skiaClient: skiaClient, - overridePathToCanvasKit: overridePathToCanvasKit, - ); - testsPassed &= io.exitCode == 0; - } - - if (sortedTests.canvasKitTests.isNotEmpty) { - await _runTestBatch( - testFiles: sortedTests.canvasKitTests, - renderer: Renderer.canvasKit, - browserEnvironment: browserEnvironment, - expectFailure: false, - isDebug: isDebug, - isWasm: isWasm, - doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, - skiaClient: skiaClient, - overridePathToCanvasKit: overridePathToCanvasKit, - ); - testsPassed &= io.exitCode == 0; - } - - // TODO(jacksongardner): enable this test suite on safari - // For some reason, Safari is flaky when running the Skwasm test suite - // See https://github.com/flutter/flutter/issues/115312 - if (browserName != kSafari && sortedTests.skwasmTests.isNotEmpty) { - await _runTestBatch( - testFiles: sortedTests.skwasmTests, - renderer: Renderer.skwasm, - browserEnvironment: browserEnvironment, - expectFailure: false, - isDebug: isDebug, - isWasm: isWasm, - doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, - skiaClient: skiaClient, - overridePathToCanvasKit: overridePathToCanvasKit, - ); - testsPassed &= io.exitCode == 0; - } - - await browserEnvironment.cleanup(); - - if (!testsPassed) { - throw ToolExit('Some tests failed'); - } - } - - Future _createSkiaClient() async { - final SkiaGoldClient skiaClient = SkiaGoldClient( - environment.webUiSkiaGoldDirectory, - dimensions: { - 'Browser': browserName, - if (isWasm) 'Wasm': 'true', - }, - ); - - if (await _checkSkiaClient(skiaClient)) { - return skiaClient; - } - - if (requireSkiaGold) { - throw ToolExit('Skia Gold is required but is unavailable.'); - } - - return null; - } - - /// Checks whether the Skia Client is usable in this environment. - Future _checkSkiaClient(SkiaGoldClient skiaClient) async { - // Now let's check whether Skia Gold is reachable or not. - if (isLuci) { - if (isSkiaGoldClientAvailable) { - try { - await skiaClient.auth(); - return true; - } catch (e) { - print(e); - } - } - } else { - try { - // Check if we can reach Gold. - await skiaClient.getExpectationForTest(''); - return true; - } on io.OSError catch (_) { - print('OSError occurred, could not reach Gold.'); - } on io.SocketException catch (_) { - print('SocketException occurred, could not reach Gold.'); - } - } - - return false; - } -} - -Future _prepareTestResultsDirectory() async { - if (environment.webUiTestResultsDirectory.existsSync()) { - environment.webUiTestResultsDirectory.deleteSync(recursive: true); - } - environment.webUiTestResultsDirectory.createSync(recursive: true); -} - -/// Runs a batch of tests. -/// -/// Unless [expectFailure] is set to false, sets [io.exitCode] to a non-zero -/// value if any tests fail. -Future _runTestBatch({ - required List testFiles, - required Renderer renderer, - required bool isDebug, - required bool isWasm, - required BrowserEnvironment browserEnvironment, - required bool doUpdateScreenshotGoldens, - required bool expectFailure, - required SkiaGoldClient? skiaClient, - required String? overridePathToCanvasKit, -}) async { - final String configurationFilePath = pathlib.join( - environment.webUiRootDir.path, - browserEnvironment.packageTestConfigurationYamlFile, - ); - final String precompiledBuildDir = pathlib.join( - environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - ); - final List testArgs = [ - ...['-r', 'compact'], - // Disable concurrency. Running with concurrency proved to be flaky. - '--concurrency=1', - if (isDebug) '--pause-after-load', - // Don't pollute logs with output from tests that are expected to fail. - if (expectFailure) - '--reporter=name-only', - '--platform=${browserEnvironment.packageTestRuntime.identifier}', - '--precompiled=$precompiledBuildDir', - '--configuration=$configurationFilePath', - '--', - ...testFiles.map((FilePath f) => f.relativeToWebUi), - ]; - - if (expectFailure) { - hack.registerReporter( - 'name-only', - hack.ReporterDetails( - 'Prints the name of the test, but suppresses all other test output.', - (_, hack.Engine engine, __) => NameOnlyReporter(engine)), - ); - } - - hack.registerPlatformPlugin([ - browserEnvironment.packageTestRuntime, - ], () { - return BrowserPlatform.start( - browserEnvironment: browserEnvironment, - renderer: renderer, - // It doesn't make sense to update a screenshot for a test that is - // expected to fail. - doUpdateScreenshotGoldens: !expectFailure && doUpdateScreenshotGoldens, - skiaClient: skiaClient, - overridePathToCanvasKit: overridePathToCanvasKit, - isWasm: isWasm, - ); - }); - - // We want to run tests with `web_ui` as a working directory. - final dynamic originalCwd = io.Directory.current; - io.Directory.current = environment.webUiRootDir.path; - try { - await test.main(testArgs); - } finally { - io.Directory.current = originalCwd; - } - - if (expectFailure) { - if (io.exitCode != 0) { - // It failed, as expected. - print('Test successfully failed, as expected.'); - io.exitCode = 0; - } else { - io.stderr.writeln( - 'Tests ${testFiles.join(', ')} did not fail. Expected failure.', - ); - io.exitCode = 1; - } - } -} - -/// Prints the name of the test, but suppresses all other test output. -/// -/// This is useful to prevent pollution of logs by tests that are expected to -/// fail. -class NameOnlyReporter implements hack.Reporter { - NameOnlyReporter(hack.Engine testEngine) { - testEngine.onTestStarted.listen(_printTestName); - } - - void _printTestName(hack.LiveTest test) { - print('Running ${test.groups.map((hack.Group group) => group.name).join(' ')} ${test.individualName}'); - } - - @override - void pause() {} - - @override - void resume() {} -} diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart index 429d6f14859f2..f9a9c645237f2 100644 --- a/lib/web_ui/dev/suite_filter.dart +++ b/lib/web_ui/dev/suite_filter.dart @@ -19,40 +19,40 @@ abstract class SuiteFilter { SuiteFilterResult filterSuite(TestSuite suite); } -bool _macOSSupportsBrowser(Browser browser) { +bool _macOSSupportsBrowser(BrowserName browser) { switch (browser) { - case Browser.chrome: - case Browser.firefox: - case Browser.safari: + case BrowserName.chrome: + case BrowserName.firefox: + case BrowserName.safari: return true; - case Browser.edge: + case BrowserName.edge: return false; } } -bool _linuxSupportsBrowser(Browser browser) { +bool _linuxSupportsBrowser(BrowserName browser) { switch (browser) { - case Browser.chrome: - case Browser.firefox: + case BrowserName.chrome: + case BrowserName.firefox: return true; - case Browser.edge: - case Browser.safari: + case BrowserName.edge: + case BrowserName.safari: return false; } } -bool _windowsSupportsBrowser(Browser browser) { +bool _windowsSupportsBrowser(BrowserName browser) { switch (browser) { - case Browser.chrome: - case Browser.edge: + case BrowserName.chrome: + case BrowserName.edge: return true; - case Browser.firefox: - case Browser.safari: + case BrowserName.firefox: + case BrowserName.safari: return false; } } -typedef BrowserSupportCheck = bool Function(Browser browser); +typedef BrowserSupportCheck = bool Function(BrowserName browser); BrowserSupportCheck get _platformBrowserSupportCheck { if (io.Platform.isLinux) { @@ -73,7 +73,7 @@ class PlatformSuiteFilter implements SuiteFilter { @override SuiteFilterResult filterSuite(TestSuite suite) { - final Browser browser = suite.runConfig.browser; + final BrowserName browser = suite.runConfig.browser; if (_browserCheck(browser)) { return SuiteFilterResult.accepted(); } else { diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 16e161e9229ad..8fa723c2384eb 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -38,6 +38,7 @@ import 'package:web_test_utils/image_compare.dart'; import 'browser.dart'; import 'environment.dart' as env; +import 'felt_config.dart'; import 'utils.dart'; const Map coopCoepHeaders = { @@ -47,12 +48,10 @@ const Map coopCoepHeaders = { /// Custom test platform that serves web engine unit tests. class BrowserPlatform extends PlatformPlugin { - BrowserPlatform._({ + BrowserPlatform._(this.suite, { required this.browserEnvironment, required this.server, - required this.renderer, required this.isDebug, - required this.isWasm, required this.doUpdateScreenshotGoldens, required this.packageConfig, required this.skiaClient, @@ -74,8 +73,14 @@ class BrowserPlatform extends PlatformPlugin { .add(_packageUrlHandler) .add(_canvasKitOverrideHandler) + // Serves files from the bundle's output build directory + .add(createSimpleDirectoryHandler(getBundleBuildDirectory(suite.testBundle))) + // Serves files from the web_ui/build/ directory at the root (/) URL path. - .add(buildDirectoryHandler) + .add(createSimpleDirectoryHandler(env.environment.webUiBuildDir)) + + // Serves files from thes test set directory + .add(createSimpleDirectoryHandler(getTestSetDirectory(suite.testBundle.testSet))) .add(_testImageListingHandler) // Serves the initial HTML for the test. @@ -112,9 +117,8 @@ class BrowserPlatform extends PlatformPlugin { /// /// If [doUpdateScreenshotGoldens] is true updates screenshot golden files /// instead of failing the test on screenshot mismatches. - static Future start({ + static Future start(TestSuite suite, { required BrowserEnvironment browserEnvironment, - required Renderer renderer, required bool doUpdateScreenshotGoldens, required SkiaGoldClient? skiaClient, required String? overridePathToCanvasKit, @@ -123,11 +127,10 @@ class BrowserPlatform extends PlatformPlugin { final shelf_io.IOServer server = shelf_io.IOServer(await HttpMultiServer.loopback(0)); return BrowserPlatform._( + suite, browserEnvironment: browserEnvironment, - renderer: renderer, server: server, isDebug: Configuration.current.pauseAfterLoad, - isWasm: isWasm, doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, packageConfig: await loadPackageConfigUri((await Isolate.packageConfig)!), skiaClient: skiaClient, @@ -135,25 +138,25 @@ class BrowserPlatform extends PlatformPlugin { ); } + final TestSuite suite; + /// If true, runs the browser with a visible windows (i.e. not headless) and /// pauses before running the tests to give the developer a chance to set /// breakpoints in the code. final bool isDebug; - final bool isWasm; - /// The underlying server. final shelf.Server server; /// Provides the environment for the browser running tests. final BrowserEnvironment browserEnvironment; - /// The renderer that tests are running under. - final Renderer renderer; - /// The URL for this server. Uri get url => server.url.resolve('/'); + bool get isWasm => suite.testBundle.compileConfig.compiler == Compiler.dart2wasm; + bool get needsCrossOriginIsolated => isWasm && suite.testBundle.compileConfig.renderer == Renderer.skwasm; + /// A [OneOffHandler] for servicing WebSocket connections for /// [BrowserManager]s. /// @@ -443,52 +446,44 @@ class BrowserPlatform extends PlatformPlugin { '.woff2': 'font/woff2', }; - /// A simple file handler that serves files whose URLs and paths are + /// Creates a simple file handler that serves files whose URLs and paths are /// statically known. /// /// This is used for trivial use-cases, such as `favicon.ico`, host pages, etc. - shelf.Response buildDirectoryHandler(shelf.Request request) { - File fileInBuild = File(p.join( - env.environment.webUiBuildDir.path, - getBuildDirForRenderer(renderer), - request.url.path, - )); - - // If we can't find the file in the renderer-specific `build` subdirectory, - // then it may be in the top-level `build` subdirectory. - if (!fileInBuild.existsSync()) { - fileInBuild = File(p.join( - env.environment.webUiBuildDir.path, + shelf.Handler createSimpleDirectoryHandler(Directory directory) { + return (shelf.Request request) { + final File fileInDirectory = File(p.join( + directory.path, request.url.path, )); - } - if (!fileInBuild.existsSync()) { - return shelf.Response.notFound('File not found: ${request.url.path}'); - } + if (!fileInDirectory.existsSync()) { + return shelf.Response.notFound('File not found: ${request.url.path}'); + } - final String extension = p.extension(fileInBuild.path); - final String? contentType = contentTypes[extension]; + final String extension = p.extension(fileInDirectory.path); + final String? contentType = contentTypes[extension]; - if (contentType == null) { - final String error = - 'Failed to determine Content-Type for "${request.url.path}".'; - stderr.writeln(error); - return shelf.Response.internalServerError(body: error); - } + if (contentType == null) { + final String error = + 'Failed to determine Content-Type for "${request.url.path}".'; + stderr.writeln(error); + return shelf.Response.internalServerError(body: error); + } - final bool needsCoopCoep = - extension == '.js' || - extension == '.mjs' || - extension == '.html'; - return shelf.Response.ok( - fileInBuild.readAsBytesSync(), - headers: { - HttpHeaders.contentTypeHeader: contentType, - if (needsCoopCoep && isWasm && renderer == Renderer.skwasm) - ...coopCoepHeaders, - }, - ); + final bool isScript = + extension == '.js' || + extension == '.mjs' || + extension == '.html'; + return shelf.Response.ok( + fileInDirectory.readAsBytesSync(), + headers: { + HttpHeaders.contentTypeHeader: contentType, + if (isScript && needsCrossOriginIsolated) + ...coopCoepHeaders, + }, + ); + }; } /// Serves the HTML file that bootstraps the test. @@ -498,9 +493,10 @@ class BrowserPlatform extends PlatformPlugin { if (path.endsWith('.html')) { final String test = '${p.withoutExtension(path)}.dart'; + final bool linkSkwasm = suite.testBundle.compileConfig.renderer == Renderer.skwasm; // Link to the Dart wrapper. final String scriptBase = htmlEscape.convert(p.basename(test)); - final String link = ''; + final String link = ''; final String testRunner = isWasm ? '/test_dart2wasm.js' : 'packages/test/dart.js'; @@ -521,7 +517,7 @@ class BrowserPlatform extends PlatformPlugin { ''', headers: { 'Content-Type': 'text/html', - if (isWasm && renderer == Renderer.skwasm) + if (needsCrossOriginIsolated) ...coopCoepHeaders }); } @@ -554,8 +550,7 @@ class BrowserPlatform extends PlatformPlugin { } _checkNotClosed(); - final Uri suiteUrl = url.resolveUri(p.toUri('${p.withoutExtension( - p.relative(path, from: env.environment.webUiBuildDir.path))}.html')); + final Uri suiteUrl = url.resolveUri(p.toUri('${p.withoutExtension(path)}.html')); _checkNotClosed(); final BrowserManager? browserManager = await _startBrowserManager(); @@ -565,10 +560,10 @@ class BrowserPlatform extends PlatformPlugin { } _checkNotClosed(); - final RunnerSuite suite = + final RunnerSuite runnerSuite = await browserManager.load(path, suiteUrl, suiteConfig, message); _checkNotClosed(); - return suite; + return runnerSuite; } Future? _browserManager; @@ -598,9 +593,8 @@ class BrowserPlatform extends PlatformPlugin { url: hostUrl, future: completer.future, packageConfig: packageConfig, - isWasm: isWasm, debug: isDebug, - renderer: renderer, + sourceMapDirectory: isWasm ? null : getBundleBuildDirectory(suite.testBundle), ); // Store null values for browsers that error out so we know not to load them @@ -696,7 +690,7 @@ class BrowserManager { /// Creates a new BrowserManager that communicates with the browser over /// [webSocket]. BrowserManager._(this.packageConfig, this._browser, this._browserEnvironment, - this._renderer, this._isWasm, WebSocketChannel webSocket) { + this._sourceMapDirectory, WebSocketChannel webSocket) { // The duration should be short enough that the debugging console is open as // soon as the user is done setting breakpoints, but long enough that a test // doing a lot of synchronous work doesn't trigger a false positive. @@ -742,8 +736,8 @@ class BrowserManager { /// The browser environment for this test. final BrowserEnvironment _browserEnvironment; - /// The renderer for this test. - final Renderer _renderer; + /// The directory containing sourcemaps for test files + final Directory? _sourceMapDirectory; /// The channel used to communicate with the browser. /// @@ -768,9 +762,6 @@ class BrowserManager { /// Whether the channel to the browser has closed. bool _closed = false; - /// Whether we are running tests that have been compiled to WebAssembly. - final bool _isWasm; - /// The completer for [_BrowserEnvironment.displayPause]. /// /// This will be `null` as long as the browser isn't displaying a pause @@ -812,8 +803,7 @@ class BrowserManager { required Uri url, required Future future, required PackageConfig packageConfig, - required Renderer renderer, - required bool isWasm, + Directory? sourceMapDirectory, bool debug = false, }) async { final Browser browser = @@ -824,8 +814,7 @@ class BrowserManager { future: future, packageConfig: packageConfig, browser: browser, - renderer: renderer, - isWasm: isWasm, + sourceMapDirectory: sourceMapDirectory, debug: debug); } @@ -835,8 +824,7 @@ class BrowserManager { required Future future, required PackageConfig packageConfig, required Browser browser, - required Renderer renderer, - required bool isWasm, + Directory? sourceMapDirectory, bool debug = false, }) { final Completer completer = Completer(); @@ -858,7 +846,7 @@ class BrowserManager { return; } completer.complete(BrowserManager._( - packageConfig, browser, browserEnvironment, renderer, isWasm, webSocket)); + packageConfig, browser, browserEnvironment, sourceMapDirectory, webSocket)); }).catchError((Object error, StackTrace stackTrace) { browser.close(); if (completer.isCompleted) { @@ -942,7 +930,7 @@ class BrowserManager { suiteChannel, message); - if (_isWasm) { + if (_sourceMapDirectory == null) { // We don't have mapping for wasm yet. But we should send a message // to let the host page move forward. controller!.channel('test.browser.mapper').sink.add(null); @@ -951,8 +939,11 @@ class BrowserManager { '${p.basename(path)}.browser_test.dart.js.map'; final String pathToTest = p.dirname(path); - final String mapPath = p.join(env.environment.webUiRootDir.path, - 'build', getBuildDirForRenderer(_renderer), pathToTest, sourceMapFileName); + final String mapPath = p.join( + _sourceMapDirectory!.path, + pathToTest, + sourceMapFileName + ); final Map packageMap = { for (Package p in packageConfig.packages) p.name: p.packageUriRoot diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 3998646425e60..455309fcd3f96 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -14,9 +14,8 @@ import 'environment.dart'; import 'felt_config.dart'; import 'pipeline.dart'; import 'steps/compile_bundle_step.dart'; -import 'steps/compile_tests_step.dart'; import 'steps/copy_artifacts_step.dart'; -import 'steps/run_tests_step.dart'; +import 'steps/run_suite_step.dart'; import 'suite_filter.dart'; import 'utils.dart'; @@ -44,10 +43,22 @@ class TestCommand extends Command with ArgUtils { ..addFlag( 'list', help: - 'Lists the bundles that would be compiled and the suites that' - 'will be run as part of this invocation, without actually' + 'Lists the bundles that would be compiled and the suites that ' + 'will be run as part of this invocation, without actually ' 'compiling or running them.' ) + ..addFlag( + 'compile', + help: + 'Compile test bundles. If this is specified on its own, we will ' + 'only compile and not run the suites.' + ) + ..addFlag( + 'run', + help: + 'Run test suites. If this is specified on its own, we will only ' + 'run the suites and not compile the bundles.' + ) ..addFlag( 'require-skia-gold', help: @@ -213,28 +224,29 @@ class TestCommand extends Command with ArgUtils { if (isList) { return true; } - final List testFiles = runAllTests - ? findAllTests() - : targetFiles; + bool shouldRun = boolArg('run'); + bool shouldCompile = boolArg('compile'); + if (!shouldRun && !shouldCompile) { + // If neither is specified, we should assume we need to both compile and run. + shouldRun = true; + shouldCompile = true; + } final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), CopyArtifactsStep(artifacts), - for (final TestBundle bundle in bundles) - CompileBundleStep(bundle: bundle), - CompileTestsStep( - testFiles: testFiles, - isWasm: isWasm - ), - RunTestsStep( - browserName: browserName, - testFiles: testFiles, - isDebug: isDebug, - isWasm: isWasm, - doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, - requireSkiaGold: requireSkiaGold, - overridePathToCanvasKit: overridePathToCanvasKit, - ), + if (shouldCompile) + for (final TestBundle bundle in bundles) + CompileBundleStep(bundle: bundle), + if (shouldRun) + for (final TestSuite suite in filteredSuites) + RunSuiteStep( + suite, + isDebug: isDebug, + doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, + requireSkiaGold: requireSkiaGold, + overridePathToCanvasKit: overridePathToCanvasKit, + ), ]); try { diff --git a/lib/web_ui/dev/utils.dart b/lib/web_ui/dev/utils.dart index 75d5727aadeb2..ece47b85c71ca 100644 --- a/lib/web_ui/dev/utils.dart +++ b/lib/web_ui/dev/utils.dart @@ -12,6 +12,7 @@ import 'package:path/path.dart' as path; import 'environment.dart'; import 'exceptions.dart'; +import 'felt_config.dart'; class FilePath { FilePath.fromCwd(String relativePath) @@ -368,84 +369,23 @@ Future cleanup() async { } } -/// Scans the test/ directory for test files and returns them. -List findAllTests() { - return environment.webUiTestDir - .listSync(recursive: true) - .whereType() - .where((io.File f) => f.path.endsWith('_test.dart')) - .map((io.File f) => FilePath.fromWebUi( - path.relative(f.path, from: environment.webUiRootDir.path))) - .toList(); -} - -/// The renderer used to run the test. -enum Renderer { - html, - canvasKit, - skwasm, -} - -/// The `FilePath`s for all the tests, organized by renderer. -class TestsByRenderer { - TestsByRenderer(this.htmlTests, this.canvasKitTests, this.skwasmTests); - - /// Tests which should be run with the HTML renderer. - final List htmlTests; - - /// Tests which should be run with the CanvasKit renderer. - final List canvasKitTests; - - /// Tests which should be run with the Skwasm renderer. - final List skwasmTests; - - /// The total number of targets to compile. - /// - /// The number of uiTests is doubled since they are compiled twice: once for - /// the HTML renderer and once for the CanvasKit renderer. - int get numTargetsToCompile => htmlTests.length + canvasKitTests.length + skwasmTests.length; -} - -/// Given a list of test files, organizes them by which renderer should run them. -TestsByRenderer sortTestsByRenderer(List testFiles, bool forWasm) { - final List htmlTargets = []; - final List canvasKitTargets = []; - final List skwasmTargets = []; - final String canvasKitTestDirectory = - path.join(environment.webUiTestDir.path, 'canvaskit'); - final String skwasmTestDirectory = - path.join(environment.webUiTestDir.path, 'skwasm'); - final String uiTestDirectory = - path.join(environment.webUiTestDir.path, 'ui'); - for (final FilePath testFile in testFiles) { - if (path.isWithin(canvasKitTestDirectory, testFile.absolute)) { - canvasKitTargets.add(testFile); - } else if (path.isWithin(skwasmTestDirectory, testFile.absolute)) { - skwasmTargets.add(testFile); - } else if (path.isWithin(uiTestDirectory, testFile.absolute)) { - htmlTargets.add(testFile); - canvasKitTargets.add(testFile); - if (forWasm) { - // Only add these tests in wasm mode, since JS mode has a stub renderer. - skwasmTargets.add(testFile); - } - } else { - htmlTargets.add(testFile); - } - } - return TestsByRenderer(htmlTargets, canvasKitTargets, skwasmTargets); +io.Directory getTestSetDirectory(TestSet testSet) { + return io.Directory( + path.join( + environment.webUiBuildDir.path, + testSet.directory, + ) + ); } -/// The build directory to compile a test into given the renderer. -String getBuildDirForRenderer(Renderer renderer) { - switch (renderer) { - case Renderer.html: - return 'html_tests'; - case Renderer.canvasKit: - return 'canvaskit_tests'; - case Renderer.skwasm: - return 'skwasm_tests'; - } +io.Directory getBundleBuildDirectory(TestBundle bundle) { + return io.Directory( + path.join( + environment.webUiBuildDir.path, + 'test_bundles', + bundle.name, + ) + ); } extension AnsiColors on String { diff --git a/web_sdk/web_test_utils/lib/image_compare.dart b/web_sdk/web_test_utils/lib/image_compare.dart index c2ac523552db8..af7b5f39e03a6 100644 --- a/web_sdk/web_test_utils/lib/image_compare.dart +++ b/web_sdk/web_test_utils/lib/image_compare.dart @@ -69,7 +69,6 @@ Future compareImage( // At the moment, we don't support local screenshot testing because we use // Skia Gold to handle our screenshots and diffing. In the future, we might // implement local screenshot testing if there's a need. - print('Screenshot generated: file://$screenshotPath'); // ignore: avoid_print return 'OK'; } From 1bdd4424fd16e81f5cd940adc4e34d00138ce4d4 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 05/44] Reduce verbosity and fix serving assets from test directory. --- lib/web_ui/dev/steps/compile_bundle_step.dart | 22 +++++++++++++++---- lib/web_ui/dev/steps/run_suite_step.dart | 3 +++ lib/web_ui/dev/test_platform.dart | 19 +++++++++++----- lib/web_ui/dev/test_runner.dart | 6 ++++- lib/web_ui/dev/utils.dart | 2 +- 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart index 197a673da535f..d8916e272e22c 100644 --- a/lib/web_ui/dev/steps/compile_bundle_step.dart +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -18,10 +18,12 @@ import '../utils.dart' show AnsiColors, FilePath, ProcessManager, cleanup, getBu class CompileBundleStep implements PipelineStep { CompileBundleStep({ required this.bundle, + required this.isVerbose, this.testFiles, }); final TestBundle bundle; + final bool isVerbose; final Set? testFiles; // Maximum number of concurrent compile processes to use. @@ -66,12 +68,14 @@ class CompileBundleStep implements PipelineStep { testSetDirectory, outputBundleDirectory, renderer: bundle.compileConfig.renderer, + isVerbose: isVerbose, ); case Compiler.dart2wasm: return Dart2WasmCompiler( testSetDirectory, outputBundleDirectory, renderer: bundle.compileConfig.renderer, + isVerbose: isVerbose, ); } } @@ -141,12 +145,16 @@ abstract class TestCompiler { TestCompiler( this.inputTestSetDirectory, this.outputTestBundleDirectory, - {required this.renderer} + { + required this.renderer, + required this.isVerbose, + } ); final io.Directory inputTestSetDirectory; final io.Directory outputTestBundleDirectory; final Renderer renderer; + final bool isVerbose; Future compileTest(FilePath input); } @@ -155,7 +163,10 @@ class Dart2JSCompiler extends TestCompiler { Dart2JSCompiler( super.inputTestSetDirectory, super.outputTestBundleDirectory, - {required super.renderer} + { + required super.renderer, + required super.isVerbose, + } ); @override @@ -199,7 +210,7 @@ class Dart2JSCompiler extends TestCompiler { environment.dartExecutable, arguments, workingDirectory: inputTestSetDirectory.path, - evalOutput: true, + evalOutput: !isVerbose, ); final int exitCode = await process.wait(); if (exitCode != 0) { @@ -216,7 +227,10 @@ class Dart2WasmCompiler extends TestCompiler { Dart2WasmCompiler( super.inputTestSetDirectory, super.outputTestBundleDirectory, - {required super.renderer} + { + required super.renderer, + required super.isVerbose, + } ); @override diff --git a/lib/web_ui/dev/steps/run_suite_step.dart b/lib/web_ui/dev/steps/run_suite_step.dart index ca3aafa4b1cf7..dde3b7bd2470f 100644 --- a/lib/web_ui/dev/steps/run_suite_step.dart +++ b/lib/web_ui/dev/steps/run_suite_step.dart @@ -30,6 +30,7 @@ import '../utils.dart'; class RunSuiteStep implements PipelineStep { RunSuiteStep(this.suite, { required this.isDebug, + required this.isVerbose, required this.doUpdateScreenshotGoldens, required this.requireSkiaGold, this.testFiles, @@ -39,6 +40,7 @@ class RunSuiteStep implements PipelineStep { final TestSuite suite; final Set? testFiles; final bool isDebug; + final bool isVerbose; final bool doUpdateScreenshotGoldens; final String? overridePathToCanvasKit; @@ -92,6 +94,7 @@ class RunSuiteStep implements PipelineStep { skiaClient: skiaClient, overridePathToCanvasKit: overridePathToCanvasKit, isWasm: isWasm, + isVerbose: isVerbose, ); }); diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 8fa723c2384eb..d156f5bfc8779 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -52,6 +52,7 @@ class BrowserPlatform extends PlatformPlugin { required this.browserEnvironment, required this.server, required this.isDebug, + required this.isVerbose, required this.doUpdateScreenshotGoldens, required this.packageConfig, required this.skiaClient, @@ -123,6 +124,7 @@ class BrowserPlatform extends PlatformPlugin { required SkiaGoldClient? skiaClient, required String? overridePathToCanvasKit, required bool isWasm, + required bool isVerbose, }) async { final shelf_io.IOServer server = shelf_io.IOServer(await HttpMultiServer.loopback(0)); @@ -131,6 +133,7 @@ class BrowserPlatform extends PlatformPlugin { browserEnvironment: browserEnvironment, server: server, isDebug: Configuration.current.pauseAfterLoad, + isVerbose: isVerbose, doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, packageConfig: await loadPackageConfigUri((await Isolate.packageConfig)!), skiaClient: skiaClient, @@ -145,6 +148,8 @@ class BrowserPlatform extends PlatformPlugin { /// breakpoints in the code. final bool isDebug; + final bool isVerbose; + /// The underlying server. final shelf.Server server; @@ -255,7 +260,9 @@ class BrowserPlatform extends PlatformPlugin { } Future _fileNotFoundCatcher(shelf.Request request) async { - print('HTTP 404: ${request.url}'); + if (isVerbose) { + print('HTTP 404: ${request.url}'); + } return shelf.Response.notFound('File not found'); } @@ -386,10 +393,12 @@ class BrowserPlatform extends PlatformPlugin { final String filename = requestData['filename'] as String; if (!(await browserManager).supportsScreenshots) { - print( - 'Skipping screenshot check for $filename. Current browser/OS ' - 'combination does not support screenshots.', - ); + if (isVerbose) { + print( + 'Skipping screenshot check for $filename. Current browser/OS ' + 'combination does not support screenshots.', + ); + } return shelf.Response.ok(json.encode('OK')); } diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 455309fcd3f96..7c5bbb53ed5dc 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -237,12 +237,16 @@ class TestCommand extends Command with ArgUtils { CopyArtifactsStep(artifacts), if (shouldCompile) for (final TestBundle bundle in bundles) - CompileBundleStep(bundle: bundle), + CompileBundleStep( + bundle: bundle, + isVerbose: isVerbose + ), if (shouldRun) for (final TestSuite suite in filteredSuites) RunSuiteStep( suite, isDebug: isDebug, + isVerbose: isVerbose, doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, requireSkiaGold: requireSkiaGold, overridePathToCanvasKit: overridePathToCanvasKit, diff --git a/lib/web_ui/dev/utils.dart b/lib/web_ui/dev/utils.dart index ece47b85c71ca..e5605d67d6459 100644 --- a/lib/web_ui/dev/utils.dart +++ b/lib/web_ui/dev/utils.dart @@ -372,7 +372,7 @@ Future cleanup() async { io.Directory getTestSetDirectory(TestSet testSet) { return io.Directory( path.join( - environment.webUiBuildDir.path, + environment.webUiTestDir.path, testSet.directory, ) ); From b6e520ee69c38d550b1c3c679d991236cde7e7b4 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 06/44] All filters except file filters are implemented. --- lib/web_ui/dev/suite_filter.dart | 111 +++++++++++++++----------- lib/web_ui/dev/test_runner.dart | 129 +++++++++++++++++++++++-------- 2 files changed, 163 insertions(+), 77 deletions(-) diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart index f9a9c645237f2..fbd97a0f65600 100644 --- a/lib/web_ui/dev/suite_filter.dart +++ b/lib/web_ui/dev/suite_filter.dart @@ -19,67 +19,88 @@ abstract class SuiteFilter { SuiteFilterResult filterSuite(TestSuite suite); } -bool _macOSSupportsBrowser(BrowserName browser) { - switch (browser) { - case BrowserName.chrome: - case BrowserName.firefox: - case BrowserName.safari: - return true; - case BrowserName.edge: - return false; +abstract class AllowListSuiteFilter implements SuiteFilter { + AllowListSuiteFilter({ required this.allowList }); + + final Set allowList; + + T getAttributeForSuite(TestSuite suite); + + String rejectReason(TestSuite suite) { + return '${getAttributeForSuite(suite)} does not match filter.'; } -} -bool _linuxSupportsBrowser(BrowserName browser) { - switch (browser) { - case BrowserName.chrome: - case BrowserName.firefox: - return true; - case BrowserName.edge: - case BrowserName.safari: - return false; + @override + SuiteFilterResult filterSuite(TestSuite suite) { + if (allowList.contains(getAttributeForSuite(suite))) { + return SuiteFilterResult.accepted(); + } else { + return SuiteFilterResult.rejected(rejectReason(suite)); + } } } -bool _windowsSupportsBrowser(BrowserName browser) { - switch (browser) { - case BrowserName.chrome: - case BrowserName.edge: - return true; - case BrowserName.firefox: - case BrowserName.safari: - return false; - } +class BrowserSuiteFilter extends AllowListSuiteFilter { + BrowserSuiteFilter({required super.allowList}); + + @override + BrowserName getAttributeForSuite(TestSuite suite) => suite.runConfig.browser; +} + +class SuiteNameFilter extends AllowListSuiteFilter { + SuiteNameFilter({required super.allowList}); + + @override + String getAttributeForSuite(TestSuite suite) => suite.name; } -typedef BrowserSupportCheck = bool Function(BrowserName browser); +class BundleNameFilter extends AllowListSuiteFilter { + BundleNameFilter({required super.allowList}); -BrowserSupportCheck get _platformBrowserSupportCheck { + @override + String getAttributeForSuite(TestSuite suite) => suite.testBundle.name; +} + +class CompilerFilter extends AllowListSuiteFilter { + CompilerFilter({required super.allowList}); + + @override + Compiler getAttributeForSuite(TestSuite suite) => suite.testBundle.compileConfig.compiler; +} + +class RendererFilter extends AllowListSuiteFilter { + RendererFilter({required super.allowList}); + + @override + Renderer getAttributeForSuite(TestSuite suite) => suite.testBundle.compileConfig.renderer; +} + +Set get _supportedPlatformBrowsers { if (io.Platform.isLinux) { - return _linuxSupportsBrowser; + return { + BrowserName.chrome, + BrowserName.firefox + }; } else if (io.Platform.isMacOS) { - return _macOSSupportsBrowser; + return { + BrowserName.chrome, + BrowserName.firefox, + BrowserName.safari, + }; } else if (io.Platform.isWindows) { - return _windowsSupportsBrowser; + return { + BrowserName.chrome, + BrowserName.edge, + }; } else { throw AssertionError('Unsupported OS: ${io.Platform.operatingSystem}'); } } -class PlatformSuiteFilter implements SuiteFilter { - PlatformSuiteFilter() : _browserCheck = _platformBrowserSupportCheck; - - final BrowserSupportCheck _browserCheck; +class PlatformBrowserFilter extends BrowserSuiteFilter { + PlatformBrowserFilter() : super(allowList: _supportedPlatformBrowsers); @override - SuiteFilterResult filterSuite(TestSuite suite) { - final BrowserName browser = suite.runConfig.browser; - if (_browserCheck(browser)) { - return SuiteFilterResult.accepted(); - } else { - return SuiteFilterResult.rejected( - 'Current platform (${io.Platform.operatingSystem}) does not support browser $browser' - ); - } - } + String rejectReason(TestSuite suite) => + 'Current platform (${io.Platform.operatingSystem}) does not support browser ${suite.runConfig.browser}'; } diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 7c5bbb53ed5dc..0b2fe2c3af559 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -11,6 +11,7 @@ import 'package:path/path.dart' as path; import 'package:watcher/src/watch_event.dart'; import 'environment.dart'; +import 'exceptions.dart'; import 'felt_config.dart'; import 'pipeline.dart'; import 'steps/compile_bundle_step.dart'; @@ -72,11 +73,25 @@ class TestCommand extends Command with ArgUtils { '.dart_tool/goldens. Use this option to bulk-update all screenshots, ' 'for example, when a new browser version affects pixels.', ) - ..addOption( + ..addMultiOption( 'browser', - defaultsTo: 'chrome', - help: 'An option to choose a browser to run the tests. By default ' - 'tests run in Chrome.', + help: 'Filter test suites by browser.', + ) + ..addMultiOption( + 'compiler', + help: 'Filter test suites by compiler.', + ) + ..addMultiOption( + 'renderer', + help: 'Filter test suites by renderer.', + ) + ..addMultiOption( + 'suite', + help: 'Filter test suites by suite name.', + ) + ..addMultiOption( + 'bundle', + help: 'Filter test suites by bundle name.', ) ..addFlag( 'fail-early', @@ -94,11 +109,6 @@ class TestCommand extends Command with ArgUtils { ..addFlag( 'wasm', help: 'Whether the test we are running are compiled to webassembly.' - ) - ..addFlag( - 'use-local-canvaskit', - help: 'Optional. Whether or not to use the locally built version of ' - 'CanvasKit in the tests.', ); } @@ -114,8 +124,6 @@ class TestCommand extends Command with ArgUtils { bool get failEarly => boolArg('fail-early'); - bool get isWasm => boolArg('wasm'); - /// Whether to start the browser in debug mode. /// /// In this mode the browser pauses before running the test to allow @@ -133,9 +141,6 @@ class TestCommand extends Command with ArgUtils { /// Whether all tests should run. bool get runAllTests => targets.isEmpty; - /// The name of the browser to run tests in. - String get browserName => stringArg('browser'); - /// When running screenshot tests, require Skia Gold to be available and /// reachable. bool get requireSkiaGold => boolArg('require-skia-gold'); @@ -147,27 +152,90 @@ class TestCommand extends Command with ArgUtils { /// Path to a CanvasKit build. Overrides the default CanvasKit. String? get overridePathToCanvasKit => argResults!['canvaskit-path'] as String?; - /// Whether or not to use the locally built version of CanvasKit. - bool get useLocalCanvasKit => boolArg('use-local-canvaskit'); + final FeltConfig config = FeltConfig.fromFile( + path.join(environment.webUiTestDir.path, 'felt_config.yaml') + ); + + BrowserSuiteFilter? makeBrowserFilter() { + final List? browserArgs = argResults!['browser'] as List?; + if (browserArgs == null || browserArgs.isEmpty) { + return null; + } + final Set browserNames = Set.from(browserArgs.map((String arg) => BrowserName.values.byName(arg))); + return BrowserSuiteFilter(allowList: browserNames); + } + + CompilerFilter? makeCompilerFilter() { + final List? compilerArgs = argResults!['compiler'] as List?; + if (compilerArgs == null || compilerArgs.isEmpty) { + return null; + } + final Set compilers = Set.from(compilerArgs.map((String arg) => Compiler.values.byName(arg))); + return CompilerFilter(allowList: compilers); + } + + RendererFilter? makeRendererFilter() { + final List? rendererArgs = argResults!['renderer'] as List?; + if (rendererArgs == null || rendererArgs.isEmpty) { + return null; + } + final Set renderers = Set.from(rendererArgs.map((String arg) => Renderer.values.byName(arg))); + return RendererFilter(allowList: renderers); + } + + SuiteNameFilter? makeSuiteNameFilter() { + final List? suiteNameArgs = argResults!['suite'] as List?; + if (suiteNameArgs == null || suiteNameArgs.isEmpty) { + return null; + } + + final Iterable allSuiteNames = config.testSuites.map((TestSuite suite) => suite.name); + for (final String suiteName in suiteNameArgs) { + if (!allSuiteNames.contains(suiteName)) { + throw ToolExit('No suite found named $suiteName'); + } + } + return SuiteNameFilter(allowList: Set.from(suiteNameArgs)); + } + + BundleNameFilter? makeBundleNameFilter() { + final List? bundleNameArgs = argResults!['bundle'] as List?; + if (bundleNameArgs == null || bundleNameArgs.isEmpty) { + return null; + } + + final Iterable allBundleNames = config.testSuites.map((TestSuite suite) => suite.name); + for (final String bundleName in bundleNameArgs) { + if (!allBundleNames.contains(bundleName)) { + throw ToolExit('No bundle found named $bundleName'); + } + } + return BundleNameFilter(allowList: Set.from(bundleNameArgs)); + } List get suiteFilters { + final BrowserSuiteFilter? browserFilter = makeBrowserFilter(); + final CompilerFilter? compilerFilter = makeCompilerFilter(); + final RendererFilter? rendererFilter = makeRendererFilter(); + final SuiteNameFilter? suiteNameFilter = makeSuiteNameFilter(); + final BundleNameFilter? bundleNameFilter = makeBundleNameFilter(); return [ - PlatformSuiteFilter() - // TODO(jacksongardner): Add more filters - // Add browser filter from CLI - // Add suite filter from CLI - // Add compiler filter from CLI + PlatformBrowserFilter(), + if (browserFilter != null) browserFilter, + if (compilerFilter != null) compilerFilter, + if (rendererFilter != null) rendererFilter, + if (suiteNameFilter != null) suiteNameFilter, + if (bundleNameFilter != null) bundleNameFilter, // Add file filter from CLI - // Add renderer filter from CLI ]; } - List _filterTestSuites(List suites) { + List _filterTestSuites() { if (isVerbose) { print('Filtering suites...'); } final List filters = suiteFilters; - final List filteredSuites = suites.where((TestSuite suite) { + final List filteredSuites = config.testSuites.where((TestSuite suite) { for (final SuiteFilter filter in filters) { final SuiteFilterResult result = filter.filterSuite(suite); if (!result.isAccepted) { @@ -182,10 +250,10 @@ class TestCommand extends Command with ArgUtils { return filteredSuites; } - List _filterBundlesForSuites(List bundles, List suites) { + List _filterBundlesForSuites(List suites) { final Set seenBundles = Set.from(suites.map((TestSuite suite) => suite.testBundle)); - return bundles.where((TestBundle bundle) => seenBundles.contains(bundle)).toList(); + return config.testBundles.where((TestBundle bundle) => seenBundles.contains(bundle)).toList(); } ArtifactDependencies _artifactsForSuites(List suites) { @@ -195,12 +263,9 @@ class TestCommand extends Command with ArgUtils { @override Future run() async { - final FeltConfig config = FeltConfig.fromFile( - path.join(environment.webUiTestDir.path, 'felt_config.yaml') - ); - final List filteredSuites = _filterTestSuites(config.testSuites); - final List bundles = _filterBundlesForSuites(config.testBundles, filteredSuites); - final ArtifactDependencies artifacts = _artifactsForSuites(config.testSuites); + final List filteredSuites = _filterTestSuites(); + final List bundles = _filterBundlesForSuites(filteredSuites); + final ArtifactDependencies artifacts = _artifactsForSuites(filteredSuites); if (isList || isVerbose) { print('Suites:'); for (final TestSuite suite in filteredSuites) { From e26e6a3204144f471d7ca14d363193a722612358 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 07/44] File filter implemented. --- lib/web_ui/dev/steps/run_suite_step.dart | 8 ++++- lib/web_ui/dev/suite_filter.dart | 9 +++++ lib/web_ui/dev/test_runner.dart | 42 +++++++++++++++++++----- lib/web_ui/dev/utils.dart | 2 ++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/lib/web_ui/dev/steps/run_suite_step.dart b/lib/web_ui/dev/steps/run_suite_step.dart index dde3b7bd2470f..1a5ecbe427989 100644 --- a/lib/web_ui/dev/steps/run_suite_step.dart +++ b/lib/web_ui/dev/steps/run_suite_step.dart @@ -150,8 +150,14 @@ class RunSuiteStep implements PipelineStep { final List testPaths = []; results.forEach((dynamic k, dynamic v) { final String result = v as String; + final String testPath = k as String; + if (testFiles != null) { + if (!testFiles!.contains(FilePath.fromTestSet(suite.testBundle.testSet, testPath))) { + return; + } + } if (result == 'success') { - testPaths.add(k as String); + testPaths.add(testPath); } }); return testPaths; diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart index fbd97a0f65600..e2837e342d3d1 100644 --- a/lib/web_ui/dev/suite_filter.dart +++ b/lib/web_ui/dev/suite_filter.dart @@ -61,6 +61,15 @@ class BundleNameFilter extends AllowListSuiteFilter { String getAttributeForSuite(TestSuite suite) => suite.testBundle.name; } +class FileFilter extends BundleNameFilter { + FileFilter({required super.allowList}); + + @override + String rejectReason(TestSuite suite) { + return "Doesn't contain any of the indicated files."; + } +} + class CompilerFilter extends AllowListSuiteFilter { CompilerFilter({required super.allowList}); diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 0b2fe2c3af559..599dcb80f3e88 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -132,14 +132,8 @@ class TestCommand extends Command with ArgUtils { bool get isVerbose => boolArg('verbose'); - /// Paths to targets to run, e.g. a single test. - List get targets => argResults!.rest; - /// The target test files to run. - List get targetFiles => targets.map((String t) => FilePath.fromCwd(t)).toList(); - - /// Whether all tests should run. - bool get runAllTests => targets.isEmpty; + List get targetFiles => argResults!.rest.map((String t) => FilePath.fromCwd(t)).toList(); /// When running screenshot tests, require Skia Gold to be available and /// reachable. @@ -213,12 +207,38 @@ class TestCommand extends Command with ArgUtils { return BundleNameFilter(allowList: Set.from(bundleNameArgs)); } + FileFilter? makeFileFilter() { + final List tests = targetFiles; + if (tests.isEmpty) { + return null; + } + final Set bundleNames = {}; + for (final FilePath testPath in tests) { + if (!io.File(testPath.absolute).existsSync()) { + throw ToolExit('Test path not found: $testPath'); + } + bool bundleFound = false; + for (final TestBundle bundle in config.testBundles) { + final String testSetPath = getTestSetDirectory(bundle.testSet).path; + if (path.isWithin(testSetPath, testPath.absolute)) { + bundleFound = true; + bundleNames.add(bundle.name); + } + } + if (!bundleFound) { + throw ToolExit('Test path not in any known test bundle: $testPath'); + } + }; + return FileFilter(allowList: bundleNames); + } + List get suiteFilters { final BrowserSuiteFilter? browserFilter = makeBrowserFilter(); final CompilerFilter? compilerFilter = makeCompilerFilter(); final RendererFilter? rendererFilter = makeRendererFilter(); final SuiteNameFilter? suiteNameFilter = makeSuiteNameFilter(); final BundleNameFilter? bundleNameFilter = makeBundleNameFilter(); + final FileFilter? fileFilter = makeFileFilter(); return [ PlatformBrowserFilter(), if (browserFilter != null) browserFilter, @@ -226,7 +246,7 @@ class TestCommand extends Command with ArgUtils { if (rendererFilter != null) rendererFilter, if (suiteNameFilter != null) suiteNameFilter, if (bundleNameFilter != null) bundleNameFilter, - // Add file filter from CLI + if (fileFilter != null) fileFilter, ]; } @@ -297,6 +317,8 @@ class TestCommand extends Command with ArgUtils { shouldRun = true; shouldCompile = true; } + + final Set? testFiles = targetFiles.isEmpty ? null : Set.from(targetFiles); final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), CopyArtifactsStep(artifacts), @@ -304,7 +326,8 @@ class TestCommand extends Command with ArgUtils { for (final TestBundle bundle in bundles) CompileBundleStep( bundle: bundle, - isVerbose: isVerbose + isVerbose: isVerbose, + testFiles: testFiles, ), if (shouldRun) for (final TestSuite suite in filteredSuites) @@ -315,6 +338,7 @@ class TestCommand extends Command with ArgUtils { doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, requireSkiaGold: requireSkiaGold, overridePathToCanvasKit: overridePathToCanvasKit, + testFiles: testFiles, ), ]); diff --git a/lib/web_ui/dev/utils.dart b/lib/web_ui/dev/utils.dart index e5605d67d6459..2907dffd3a859 100644 --- a/lib/web_ui/dev/utils.dart +++ b/lib/web_ui/dev/utils.dart @@ -19,6 +19,8 @@ class FilePath { : _absolutePath = path.absolute(relativePath); FilePath.fromWebUi(String relativePath) : _absolutePath = path.join(environment.webUiRootDir.path, relativePath); + FilePath.fromTestSet(TestSet testSet, String relativePath) + : _absolutePath = path.join(getTestSetDirectory(testSet).path, relativePath); final String _absolutePath; From c2d464d70093f23b80c736acab261261d694f753 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 08/44] Move around tests themselves. --- lib/web_ui/dev/test_runner.dart | 2 +- lib/web_ui/test/canvaskit/canvaskit_api_test.dart | 2 +- .../test/canvaskit/canvaskit_api_tt_on_test.dart | 2 +- lib/web_ui/test/canvaskit/frame_timings_test.dart | 2 +- lib/web_ui/test/canvaskit/image_golden_test.dart | 2 +- .../test/canvaskit/skia_objects_cache_test.dart | 4 ++-- .../test/{ => common}/frame_timings_common.dart | 0 .../test/{ => common}/keyboard_test_common.dart | 0 lib/web_ui/test/{ => common}/matchers.dart | 0 lib/web_ui/test/{ => common}/mock_engine_canvas.dart | 0 lib/web_ui/test/{ => common}/spy.dart | 0 lib/web_ui/test/{ => engine}/alarm_clock_test.dart | 0 .../test/{ => engine}/browser_detect_test.dart | 0 lib/web_ui/test/{ => engine}/canvas_test.dart | 2 +- .../test/{ => engine}/channel_buffers_test.dart | 0 lib/web_ui/test/{ => engine}/clipboard_test.dart | 0 lib/web_ui/test/{ => engine}/composition_test.dart | 0 lib/web_ui/test/engine/configuration_test.dart | 2 +- lib/web_ui/test/{ => engine}/embedder_test.dart | 0 lib/web_ui/test/{ => engine}/geometry_test.dart | 2 +- .../test/{ => engine}/gesture_settings_test.dart | 0 lib/web_ui/test/{ => engine}/hash_codes_test.dart | 0 lib/web_ui/test/engine/history_test.dart | 2 +- .../test/{ => engine}/initialization_test.dart | 0 .../test/{ => engine}/keyboard_converter_test.dart | 2 +- lib/web_ui/test/{ => engine}/lerp_test.dart | 2 +- lib/web_ui/test/{ => engine}/locale_test.dart | 0 lib/web_ui/test/engine/platform_dispatcher_test.dart | 2 +- .../engine/platform_views/content_manager_test.dart | 2 +- lib/web_ui/test/engine/pointer_binding_test.dart | 2 +- lib/web_ui/test/engine/profiler_test.dart | 2 +- lib/web_ui/test/{ => engine}/raw_keyboard_test.dart | 0 lib/web_ui/test/engine/recording_canvas_test.dart | 2 +- .../{window_test.dart => engine/routing_test.dart} | 4 ++-- .../test/engine/semantics/semantics_tester.dart | 2 +- .../test/engine/surface/frame_timings_test.dart | 2 +- .../test/engine/surface/platform_view_test.dart | 2 +- .../test/engine/surface/scene_builder_test.dart | 2 +- lib/web_ui/test/{ => engine}/text_editing_test.dart | 2 +- .../html/compositing/compositing_golden_test.dart | 2 +- lib/web_ui/test/html/path_metrics_golden_test.dart | 2 +- lib/web_ui/test/{ => html}/path_test.dart | 2 +- .../test/html/recording_canvas_golden_test.dart | 2 +- lib/web_ui/test/{ => html}/text_test.dart | 4 ++-- lib/web_ui/test/skwasm_stub/smoke_test.dart | 5 +---- lib/web_ui/test/ui/canvas_test.dart | 2 +- lib/web_ui/test/{ => ui}/gradient_test.dart | 12 ++++++++---- lib/web_ui/test/{ => ui}/paragraph_builder_test.dart | 0 lib/web_ui/test/ui/path_metrics_test.dart | 2 +- lib/web_ui/test/ui/utils.dart | 3 +++ 50 files changed, 45 insertions(+), 41 deletions(-) rename lib/web_ui/test/{ => common}/frame_timings_common.dart (100%) rename lib/web_ui/test/{ => common}/keyboard_test_common.dart (100%) rename lib/web_ui/test/{ => common}/matchers.dart (100%) rename lib/web_ui/test/{ => common}/mock_engine_canvas.dart (100%) rename lib/web_ui/test/{ => common}/spy.dart (100%) rename lib/web_ui/test/{ => engine}/alarm_clock_test.dart (100%) rename lib/web_ui/test/{ => engine}/browser_detect_test.dart (100%) rename lib/web_ui/test/{ => engine}/canvas_test.dart (98%) rename lib/web_ui/test/{ => engine}/channel_buffers_test.dart (100%) rename lib/web_ui/test/{ => engine}/clipboard_test.dart (100%) rename lib/web_ui/test/{ => engine}/composition_test.dart (100%) rename lib/web_ui/test/{ => engine}/embedder_test.dart (100%) rename lib/web_ui/test/{ => engine}/geometry_test.dart (99%) rename lib/web_ui/test/{ => engine}/gesture_settings_test.dart (100%) rename lib/web_ui/test/{ => engine}/hash_codes_test.dart (100%) rename lib/web_ui/test/{ => engine}/initialization_test.dart (100%) rename lib/web_ui/test/{ => engine}/keyboard_converter_test.dart (99%) rename lib/web_ui/test/{ => engine}/lerp_test.dart (99%) rename lib/web_ui/test/{ => engine}/locale_test.dart (100%) rename lib/web_ui/test/{ => engine}/raw_keyboard_test.dart (100%) rename lib/web_ui/test/{window_test.dart => engine/routing_test.dart} (99%) rename lib/web_ui/test/{ => engine}/text_editing_test.dart (99%) rename lib/web_ui/test/{ => html}/path_test.dart (99%) rename lib/web_ui/test/{ => html}/text_test.dart (99%) rename lib/web_ui/test/{ => ui}/gradient_test.dart (93%) rename lib/web_ui/test/{ => ui}/paragraph_builder_test.dart (100%) diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 599dcb80f3e88..dc4e31f7c407c 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -228,7 +228,7 @@ class TestCommand extends Command with ArgUtils { if (!bundleFound) { throw ToolExit('Test path not in any known test bundle: $testPath'); } - }; + } return FileFilter(allowList: bundleNames); } diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index add81a14cff23..f54fa28fec11a 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -12,7 +12,7 @@ import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; import 'package:web_engine_tester/golden_tester.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'common.dart'; import 'test_data.dart'; diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_tt_on_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_tt_on_test.dart index 05dee0bfa6962..d0a2a54bd7408 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_tt_on_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_tt_on_test.dart @@ -6,7 +6,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'canvaskit_api_test.dart'; final bool isBlink = browserEngine == BrowserEngine.blink; diff --git a/lib/web_ui/test/canvaskit/frame_timings_test.dart b/lib/web_ui/test/canvaskit/frame_timings_test.dart index 7cab6bc8f0247..a22189b527946 100644 --- a/lib/web_ui/test/canvaskit/frame_timings_test.dart +++ b/lib/web_ui/test/canvaskit/frame_timings_test.dart @@ -5,7 +5,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import '../frame_timings_common.dart'; +import '../common/frame_timings_common.dart'; import 'common.dart'; void main() { diff --git a/lib/web_ui/test/canvaskit/image_golden_test.dart b/lib/web_ui/test/canvaskit/image_golden_test.dart index 6940776132b8d..101e7165312d5 100644 --- a/lib/web_ui/test/canvaskit/image_golden_test.dart +++ b/lib/web_ui/test/canvaskit/image_golden_test.dart @@ -11,7 +11,7 @@ import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; import 'package:web_engine_tester/golden_tester.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'common.dart'; import 'test_data.dart'; diff --git a/lib/web_ui/test/canvaskit/skia_objects_cache_test.dart b/lib/web_ui/test/canvaskit/skia_objects_cache_test.dart index b58fe26cc8b30..0645284039acf 100644 --- a/lib/web_ui/test/canvaskit/skia_objects_cache_test.dart +++ b/lib/web_ui/test/canvaskit/skia_objects_cache_test.dart @@ -10,8 +10,8 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; -import '../matchers.dart'; -import '../spy.dart'; +import '../common/matchers.dart'; +import '../common/spy.dart'; import 'common.dart'; void main() { diff --git a/lib/web_ui/test/frame_timings_common.dart b/lib/web_ui/test/common/frame_timings_common.dart similarity index 100% rename from lib/web_ui/test/frame_timings_common.dart rename to lib/web_ui/test/common/frame_timings_common.dart diff --git a/lib/web_ui/test/keyboard_test_common.dart b/lib/web_ui/test/common/keyboard_test_common.dart similarity index 100% rename from lib/web_ui/test/keyboard_test_common.dart rename to lib/web_ui/test/common/keyboard_test_common.dart diff --git a/lib/web_ui/test/matchers.dart b/lib/web_ui/test/common/matchers.dart similarity index 100% rename from lib/web_ui/test/matchers.dart rename to lib/web_ui/test/common/matchers.dart diff --git a/lib/web_ui/test/mock_engine_canvas.dart b/lib/web_ui/test/common/mock_engine_canvas.dart similarity index 100% rename from lib/web_ui/test/mock_engine_canvas.dart rename to lib/web_ui/test/common/mock_engine_canvas.dart diff --git a/lib/web_ui/test/spy.dart b/lib/web_ui/test/common/spy.dart similarity index 100% rename from lib/web_ui/test/spy.dart rename to lib/web_ui/test/common/spy.dart diff --git a/lib/web_ui/test/alarm_clock_test.dart b/lib/web_ui/test/engine/alarm_clock_test.dart similarity index 100% rename from lib/web_ui/test/alarm_clock_test.dart rename to lib/web_ui/test/engine/alarm_clock_test.dart diff --git a/lib/web_ui/test/browser_detect_test.dart b/lib/web_ui/test/engine/browser_detect_test.dart similarity index 100% rename from lib/web_ui/test/browser_detect_test.dart rename to lib/web_ui/test/engine/browser_detect_test.dart diff --git a/lib/web_ui/test/canvas_test.dart b/lib/web_ui/test/engine/canvas_test.dart similarity index 98% rename from lib/web_ui/test/canvas_test.dart rename to lib/web_ui/test/engine/canvas_test.dart index 432f0741c5d2e..324dae7c1c215 100644 --- a/lib/web_ui/test/canvas_test.dart +++ b/lib/web_ui/test/engine/canvas_test.dart @@ -8,7 +8,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import 'mock_engine_canvas.dart'; +import '../common/mock_engine_canvas.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/channel_buffers_test.dart b/lib/web_ui/test/engine/channel_buffers_test.dart similarity index 100% rename from lib/web_ui/test/channel_buffers_test.dart rename to lib/web_ui/test/engine/channel_buffers_test.dart diff --git a/lib/web_ui/test/clipboard_test.dart b/lib/web_ui/test/engine/clipboard_test.dart similarity index 100% rename from lib/web_ui/test/clipboard_test.dart rename to lib/web_ui/test/engine/clipboard_test.dart diff --git a/lib/web_ui/test/composition_test.dart b/lib/web_ui/test/engine/composition_test.dart similarity index 100% rename from lib/web_ui/test/composition_test.dart rename to lib/web_ui/test/engine/composition_test.dart diff --git a/lib/web_ui/test/engine/configuration_test.dart b/lib/web_ui/test/engine/configuration_test.dart index 33aaa35e381c2..43c3431369246 100644 --- a/lib/web_ui/test/engine/configuration_test.dart +++ b/lib/web_ui/test/engine/configuration_test.dart @@ -10,7 +10,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/embedder_test.dart b/lib/web_ui/test/engine/embedder_test.dart similarity index 100% rename from lib/web_ui/test/embedder_test.dart rename to lib/web_ui/test/engine/embedder_test.dart diff --git a/lib/web_ui/test/geometry_test.dart b/lib/web_ui/test/engine/geometry_test.dart similarity index 99% rename from lib/web_ui/test/geometry_test.dart rename to lib/web_ui/test/engine/geometry_test.dart index 80df3611c3af8..d1a9d89580d76 100644 --- a/lib/web_ui/test/geometry_test.dart +++ b/lib/web_ui/test/engine/geometry_test.dart @@ -13,7 +13,7 @@ import 'package:test/test.dart'; import 'package:ui/ui.dart'; -import 'matchers.dart'; +import '../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/gesture_settings_test.dart b/lib/web_ui/test/engine/gesture_settings_test.dart similarity index 100% rename from lib/web_ui/test/gesture_settings_test.dart rename to lib/web_ui/test/engine/gesture_settings_test.dart diff --git a/lib/web_ui/test/hash_codes_test.dart b/lib/web_ui/test/engine/hash_codes_test.dart similarity index 100% rename from lib/web_ui/test/hash_codes_test.dart rename to lib/web_ui/test/engine/hash_codes_test.dart diff --git a/lib/web_ui/test/engine/history_test.dart b/lib/web_ui/test/engine/history_test.dart index 2995efe8d09ab..1b917034e913f 100644 --- a/lib/web_ui/test/engine/history_test.dart +++ b/lib/web_ui/test/engine/history_test.dart @@ -16,7 +16,7 @@ import 'package:ui/src/engine/navigation.dart'; import 'package:ui/src/engine/services.dart'; import 'package:ui/src/engine/test_embedding.dart'; -import '../spy.dart'; +import '../common/spy.dart'; Map _wrapOriginState(dynamic state) { return {'origin': true, 'state': state}; diff --git a/lib/web_ui/test/initialization_test.dart b/lib/web_ui/test/engine/initialization_test.dart similarity index 100% rename from lib/web_ui/test/initialization_test.dart rename to lib/web_ui/test/engine/initialization_test.dart diff --git a/lib/web_ui/test/keyboard_converter_test.dart b/lib/web_ui/test/engine/keyboard_converter_test.dart similarity index 99% rename from lib/web_ui/test/keyboard_converter_test.dart rename to lib/web_ui/test/engine/keyboard_converter_test.dart index a5c81b39bd96e..90922c5cbcf5e 100644 --- a/lib/web_ui/test/keyboard_converter_test.dart +++ b/lib/web_ui/test/engine/keyboard_converter_test.dart @@ -9,7 +9,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import 'keyboard_test_common.dart'; +import '../common/keyboard_test_common.dart'; const int kLocationStandard = 0; const int kLocationLeft = 1; diff --git a/lib/web_ui/test/lerp_test.dart b/lib/web_ui/test/engine/lerp_test.dart similarity index 99% rename from lib/web_ui/test/lerp_test.dart rename to lib/web_ui/test/engine/lerp_test.dart index 65dde6513fbd7..d69d5c1ffc2ea 100644 --- a/lib/web_ui/test/lerp_test.dart +++ b/lib/web_ui/test/engine/lerp_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; import 'package:ui/ui.dart'; -import 'matchers.dart'; +import '../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/locale_test.dart b/lib/web_ui/test/engine/locale_test.dart similarity index 100% rename from lib/web_ui/test/locale_test.dart rename to lib/web_ui/test/engine/locale_test.dart diff --git a/lib/web_ui/test/engine/platform_dispatcher_test.dart b/lib/web_ui/test/engine/platform_dispatcher_test.dart index dd6b928a30953..1569f81bc75d9 100644 --- a/lib/web_ui/test/engine/platform_dispatcher_test.dart +++ b/lib/web_ui/test/engine/platform_dispatcher_test.dart @@ -10,7 +10,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import '../matchers.dart'; +import '../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/engine/platform_views/content_manager_test.dart b/lib/web_ui/test/engine/platform_views/content_manager_test.dart index 133e5e16abc5b..354471a0459aa 100644 --- a/lib/web_ui/test/engine/platform_views/content_manager_test.dart +++ b/lib/web_ui/test/engine/platform_views/content_manager_test.dart @@ -6,7 +6,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import '../../matchers.dart'; +import '../../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/engine/pointer_binding_test.dart b/lib/web_ui/test/engine/pointer_binding_test.dart index 1c9d1af957752..f818ce67e5590 100644 --- a/lib/web_ui/test/engine/pointer_binding_test.dart +++ b/lib/web_ui/test/engine/pointer_binding_test.dart @@ -9,7 +9,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import '../keyboard_converter_test.dart'; +import 'keyboard_converter_test.dart'; const int _kNoButtonChange = -1; const PointerSupportDetector _defaultSupportDetector = PointerSupportDetector(); diff --git a/lib/web_ui/test/engine/profiler_test.dart b/lib/web_ui/test/engine/profiler_test.dart index aceda511064c8..4bb03dd019f5d 100644 --- a/lib/web_ui/test/engine/profiler_test.dart +++ b/lib/web_ui/test/engine/profiler_test.dart @@ -7,7 +7,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import '../spy.dart'; +import '../common/spy.dart'; @JS('window._flutter_internal_on_benchmark') external set onBenchmark (Object? object); diff --git a/lib/web_ui/test/raw_keyboard_test.dart b/lib/web_ui/test/engine/raw_keyboard_test.dart similarity index 100% rename from lib/web_ui/test/raw_keyboard_test.dart rename to lib/web_ui/test/engine/raw_keyboard_test.dart diff --git a/lib/web_ui/test/engine/recording_canvas_test.dart b/lib/web_ui/test/engine/recording_canvas_test.dart index 46dab440bcef2..72c63f4143fa6 100644 --- a/lib/web_ui/test/engine/recording_canvas_test.dart +++ b/lib/web_ui/test/engine/recording_canvas_test.dart @@ -7,8 +7,8 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; +import '../common/mock_engine_canvas.dart'; import '../html/screenshot.dart'; -import '../mock_engine_canvas.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/window_test.dart b/lib/web_ui/test/engine/routing_test.dart similarity index 99% rename from lib/web_ui/test/window_test.dart rename to lib/web_ui/test/engine/routing_test.dart index 44a6fe6b6ee73..badda56068a85 100644 --- a/lib/web_ui/test/window_test.dart +++ b/lib/web_ui/test/engine/routing_test.dart @@ -10,8 +10,8 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart' hide window; import 'package:ui/ui.dart' as ui; -import 'engine/history_test.dart'; -import 'matchers.dart'; +import '../common/matchers.dart'; +import 'history_test.dart'; const MethodCodec codec = JSONMethodCodec(); diff --git a/lib/web_ui/test/engine/semantics/semantics_tester.dart b/lib/web_ui/test/engine/semantics/semantics_tester.dart index cee9eead3d3b0..0b7b7623c676f 100644 --- a/lib/web_ui/test/engine/semantics/semantics_tester.dart +++ b/lib/web_ui/test/engine/semantics/semantics_tester.dart @@ -14,7 +14,7 @@ import 'package:ui/src/engine/util.dart'; import 'package:ui/src/engine/vector_math.dart'; import 'package:ui/ui.dart' as ui; -import '../../matchers.dart'; +import '../../common/matchers.dart'; /// Gets the DOM host where the Flutter app is being rendered. /// diff --git a/lib/web_ui/test/engine/surface/frame_timings_test.dart b/lib/web_ui/test/engine/surface/frame_timings_test.dart index c0c295057dd96..901f1ffea73e2 100644 --- a/lib/web_ui/test/engine/surface/frame_timings_test.dart +++ b/lib/web_ui/test/engine/surface/frame_timings_test.dart @@ -6,7 +6,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import '../../frame_timings_common.dart'; +import '../../common/frame_timings_common.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/engine/surface/platform_view_test.dart b/lib/web_ui/test/engine/surface/platform_view_test.dart index 243d75025d63c..700da0c0cbe34 100644 --- a/lib/web_ui/test/engine/surface/platform_view_test.dart +++ b/lib/web_ui/test/engine/surface/platform_view_test.dart @@ -9,7 +9,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; -import '../../matchers.dart'; +import '../../common/matchers.dart'; const MethodCodec codec = StandardMethodCodec(); final EngineSingletonFlutterWindow window = EngineSingletonFlutterWindow(0, EnginePlatformDispatcher.instance); diff --git a/lib/web_ui/test/engine/surface/scene_builder_test.dart b/lib/web_ui/test/engine/surface/scene_builder_test.dart index e0535d7351847..829df162e0932 100644 --- a/lib/web_ui/test/engine/surface/scene_builder_test.dart +++ b/lib/web_ui/test/engine/surface/scene_builder_test.dart @@ -12,7 +12,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import '../../matchers.dart'; +import '../../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/text_editing_test.dart b/lib/web_ui/test/engine/text_editing_test.dart similarity index 99% rename from lib/web_ui/test/text_editing_test.dart rename to lib/web_ui/test/engine/text_editing_test.dart index 30d669bf5801c..5c84bbcdaa3e0 100644 --- a/lib/web_ui/test/text_editing_test.dart +++ b/lib/web_ui/test/engine/text_editing_test.dart @@ -21,7 +21,7 @@ import 'package:ui/src/engine/text_editing/text_editing.dart'; import 'package:ui/src/engine/util.dart'; import 'package:ui/src/engine/vector_math.dart'; -import 'spy.dart'; +import '../common/spy.dart'; /// The `keyCode` of the "Enter" key. const int _kReturnKeyCode = 13; diff --git a/lib/web_ui/test/html/compositing/compositing_golden_test.dart b/lib/web_ui/test/html/compositing/compositing_golden_test.dart index fd4e3d4791ebb..451c468a2222b 100644 --- a/lib/web_ui/test/html/compositing/compositing_golden_test.dart +++ b/lib/web_ui/test/html/compositing/compositing_golden_test.dart @@ -10,7 +10,7 @@ import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; import 'package:web_engine_tester/golden_tester.dart'; -import '../../matchers.dart'; +import '../../common/matchers.dart'; const ui.Rect region = ui.Rect.fromLTWH(0, 0, 500, 100); diff --git a/lib/web_ui/test/html/path_metrics_golden_test.dart b/lib/web_ui/test/html/path_metrics_golden_test.dart index 49410f5f9c70b..4a3ea96f7288d 100644 --- a/lib/web_ui/test/html/path_metrics_golden_test.dart +++ b/lib/web_ui/test/html/path_metrics_golden_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' hide TextStyle; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'screenshot.dart'; void main() { diff --git a/lib/web_ui/test/path_test.dart b/lib/web_ui/test/html/path_test.dart similarity index 99% rename from lib/web_ui/test/path_test.dart rename to lib/web_ui/test/html/path_test.dart index 3165c5fba13f6..416e1973a6b55 100644 --- a/lib/web_ui/test/path_test.dart +++ b/lib/web_ui/test/html/path_test.dart @@ -10,7 +10,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' hide window; -import 'matchers.dart'; +import '../common/matchers.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/html/recording_canvas_golden_test.dart b/lib/web_ui/test/html/recording_canvas_golden_test.dart index eaad748b4b8de..8c951e1aa590b 100644 --- a/lib/web_ui/test/html/recording_canvas_golden_test.dart +++ b/lib/web_ui/test/html/recording_canvas_golden_test.dart @@ -11,7 +11,7 @@ import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' hide TextStyle; import 'package:web_engine_tester/golden_tester.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'screenshot.dart'; void main() { diff --git a/lib/web_ui/test/text_test.dart b/lib/web_ui/test/html/text_test.dart similarity index 99% rename from lib/web_ui/test/text_test.dart rename to lib/web_ui/test/html/text_test.dart index f24fc2281f60a..a4563ef781b90 100644 --- a/lib/web_ui/test/text_test.dart +++ b/lib/web_ui/test/html/text_test.dart @@ -11,8 +11,8 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; -import 'html/paragraph/helper.dart'; -import 'matchers.dart'; +import '../common/matchers.dart'; +import 'paragraph/helper.dart'; void main() { internalBootstrapBrowserTest(() => testMain); diff --git a/lib/web_ui/test/skwasm_stub/smoke_test.dart b/lib/web_ui/test/skwasm_stub/smoke_test.dart index 103af64316d40..74c5a30ad7ab9 100644 --- a/lib/web_ui/test/skwasm_stub/smoke_test.dart +++ b/lib/web_ui/test/skwasm_stub/smoke_test.dart @@ -8,7 +8,6 @@ import 'dart:async'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine/browser_detection.dart'; import 'package:ui/src/engine/renderer.dart'; import 'package:ui/src/engine/skwasm/skwasm_stub/renderer.dart'; @@ -23,8 +22,6 @@ Future testMain() async { expect(() { renderer.initialize(); }, throwsUnimplementedError); - }, skip: isWasm); - // This test is specifically designed for the JS case, to make sure we - // compile to the skwasm stub renderer. + }); }); } diff --git a/lib/web_ui/test/ui/canvas_test.dart b/lib/web_ui/test/ui/canvas_test.dart index 4c294778e040c..1cb3db0ac3a99 100644 --- a/lib/web_ui/test/ui/canvas_test.dart +++ b/lib/web_ui/test/ui/canvas_test.dart @@ -10,7 +10,7 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'utils.dart'; void main() { diff --git a/lib/web_ui/test/gradient_test.dart b/lib/web_ui/test/ui/gradient_test.dart similarity index 93% rename from lib/web_ui/test/gradient_test.dart rename to lib/web_ui/test/ui/gradient_test.dart index 667e286c0106a..eb200fe3effe5 100644 --- a/lib/web_ui/test/gradient_test.dart +++ b/lib/web_ui/test/ui/gradient_test.dart @@ -7,11 +7,15 @@ import 'package:test/test.dart'; import 'package:ui/ui.dart'; +import 'utils.dart'; + void main() { internalBootstrapBrowserTest(() => testMain); } void testMain() { + setUpUiTest(); + test('Gradient.radial with no focal point', () { expect( Gradient.radial( @@ -22,7 +26,7 @@ void testMain() { TileMode.mirror), isNotNull, ); - }); + }, skip: isSkwasm); // this is just a radial gradient, focal point is discarded. test('radial center and focal == Offset.zero and focalRadius == 0.0 is ok', @@ -38,7 +42,7 @@ void testMain() { Offset.zero, ), isNotNull); - }); + }, skip: isSkwasm); test('radial center != focal and focalRadius == 0.0 is ok', () { expect( @@ -52,7 +56,7 @@ void testMain() { const Offset(2.0, 2.0), ), isNotNull); - }); + }, skip: isSkwasm); // this would result in div/0 on skia side. test('radial center and focal == Offset.zero and focalRadius != 0.0 assert', @@ -70,5 +74,5 @@ void testMain() { ), throwsA(const TypeMatcher()), ); - }); + }, skip: isSkwasm); } diff --git a/lib/web_ui/test/paragraph_builder_test.dart b/lib/web_ui/test/ui/paragraph_builder_test.dart similarity index 100% rename from lib/web_ui/test/paragraph_builder_test.dart rename to lib/web_ui/test/ui/paragraph_builder_test.dart diff --git a/lib/web_ui/test/ui/path_metrics_test.dart b/lib/web_ui/test/ui/path_metrics_test.dart index 006c59df2450e..da31eebafe203 100644 --- a/lib/web_ui/test/ui/path_metrics_test.dart +++ b/lib/web_ui/test/ui/path_metrics_test.dart @@ -8,7 +8,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/ui.dart'; -import '../matchers.dart'; +import '../common/matchers.dart'; import 'utils.dart'; const double kTolerance = 0.1; diff --git a/lib/web_ui/test/ui/utils.dart b/lib/web_ui/test/ui/utils.dart index da6c5ffb720d7..07417680ea489 100644 --- a/lib/web_ui/test/ui/utils.dart +++ b/lib/web_ui/test/ui/utils.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:ui/src/engine.dart'; +import 'package:ui/src/engine/skwasm/skwasm_stub.dart' if (dart.library.ffi) 'package:ui/src/engine/skwasm/skwasm_impl.dart'; import '../canvaskit/common.dart'; @@ -18,3 +19,5 @@ bool get isCanvasKit => renderer is CanvasKitRenderer; /// Returns [true] if this test is running in the HTML renderer. bool get isHtml => renderer is HtmlRenderer; + +bool get isSkwasm => renderer is SkwasmRenderer; From 3c9c37d8a9fdefef522faa1236819606b9c16874 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 09/44] Test against canvaskit_chromium. --- lib/web_ui/dev/test_platform.dart | 20 ++++++++++++++++++- lib/web_ui/test/ui/canvas_test.dart | 2 +- lib/web_ui/test/ui/color_test.dart | 4 ++-- lib/web_ui/test/ui/gradient_test.dart | 4 ++-- .../test/ui/paragraph_builder_test.dart | 15 +++++--------- lib/web_ui/test/ui/path_metrics_test.dart | 4 ++-- lib/web_ui/test/ui/path_test.dart | 4 ++-- lib/web_ui/test/ui/picture_test.dart | 2 +- lib/web_ui/test/ui/rect_test.dart | 4 ++-- lib/web_ui/test/ui/rrect_test.dart | 4 ++-- lib/web_ui/test/ui/title_test.dart | 4 ++-- lib/web_ui/test/ui/utils.dart | 6 ++++-- 12 files changed, 44 insertions(+), 29 deletions(-) diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index d156f5bfc8779..874652554fa4e 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -495,6 +495,24 @@ class BrowserPlatform extends PlatformPlugin { }; } + String getCanvasKitBase() { + switch (suite.runConfig.variant) { + case CanvasKitVariant.full: + return 'canvaskit'; + case CanvasKitVariant.chromium: + return 'canvaskit_chromium'; + case null: + switch (suite.runConfig.browser) { + case BrowserName.chrome: + case BrowserName.edge: + return 'canvaskit_chromium'; + case BrowserName.firefox: + case BrowserName.safari: + return 'canvaskit'; + } + } + } + /// Serves the HTML file that bootstraps the test. shelf.Response _testBootstrapHandler(shelf.Request request) { final String path = p.fromUri(request.url); @@ -517,7 +535,7 @@ class BrowserPlatform extends PlatformPlugin { $link diff --git a/lib/web_ui/test/ui/canvas_test.dart b/lib/web_ui/test/ui/canvas_test.dart index 1cb3db0ac3a99..9bba8d1c16922 100644 --- a/lib/web_ui/test/ui/canvas_test.dart +++ b/lib/web_ui/test/ui/canvas_test.dart @@ -18,7 +18,7 @@ void main() { } Future testMain() async { - setUpUiTest(); + await setUpUiTest(); final bool deviceClipRoundsOut = renderer is! HtmlRenderer; runCanvasTests(deviceClipRoundsOut: deviceClipRoundsOut); diff --git a/lib/web_ui/test/ui/color_test.dart b/lib/web_ui/test/ui/color_test.dart index 83190e5c3d6ce..05a7f66cbae14 100644 --- a/lib/web_ui/test/ui/color_test.dart +++ b/lib/web_ui/test/ui/color_test.dart @@ -16,8 +16,8 @@ class NotAColor extends Color { const NotAColor(super.value); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); test('color accessors should work', () { const Color foo = Color(0x12345678); diff --git a/lib/web_ui/test/ui/gradient_test.dart b/lib/web_ui/test/ui/gradient_test.dart index eb200fe3effe5..6bbb840abded0 100644 --- a/lib/web_ui/test/ui/gradient_test.dart +++ b/lib/web_ui/test/ui/gradient_test.dart @@ -13,8 +13,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); test('Gradient.radial with no focal point', () { expect( diff --git a/lib/web_ui/test/ui/paragraph_builder_test.dart b/lib/web_ui/test/ui/paragraph_builder_test.dart index a795a35adf686..6540cb2ccde4f 100644 --- a/lib/web_ui/test/ui/paragraph_builder_test.dart +++ b/lib/web_ui/test/ui/paragraph_builder_test.dart @@ -6,12 +6,14 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/ui.dart'; +import 'utils.dart'; + void main() { internalBootstrapBrowserTest(() => testMain); } Future testMain() async { - await webOnlyInitializePlatform(); + await setUpUiTest(); test('Should be able to build and layout a paragraph', () { final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle()); @@ -22,14 +24,7 @@ Future testMain() async { paragraph.layout(const ParagraphConstraints(width: 800.0)); expect(paragraph.width, isNonZero); expect(paragraph.height, isNonZero); - }); - - test('pushStyle should not segfault after build()', () { - final ParagraphBuilder paragraphBuilder = - ParagraphBuilder(ParagraphStyle()); - paragraphBuilder.build(); - paragraphBuilder.pushStyle(TextStyle()); - }); + }, skip: isSkwasm); test('the presence of foreground style should not throw', () { final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle()); @@ -39,5 +34,5 @@ Future testMain() async { builder.addText('hi'); expect(() => builder.build(), returnsNormally); - }); + }, skip: isSkwasm); } diff --git a/lib/web_ui/test/ui/path_metrics_test.dart b/lib/web_ui/test/ui/path_metrics_test.dart index da31eebafe203..69d0095a8e714 100644 --- a/lib/web_ui/test/ui/path_metrics_test.dart +++ b/lib/web_ui/test/ui/path_metrics_test.dart @@ -17,8 +17,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); group('PathMetric length', () { test('empty path', () { final Path path = Path(); diff --git a/lib/web_ui/test/ui/path_test.dart b/lib/web_ui/test/ui/path_test.dart index 444e591612154..10769f8b94eb6 100644 --- a/lib/web_ui/test/ui/path_test.dart +++ b/lib/web_ui/test/ui/path_test.dart @@ -14,8 +14,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); test('path getBounds', () { const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0); final Path p = Path()..addRect(r); diff --git a/lib/web_ui/test/ui/picture_test.dart b/lib/web_ui/test/ui/picture_test.dart index daa9f9d8075c9..576b0f1746cc6 100644 --- a/lib/web_ui/test/ui/picture_test.dart +++ b/lib/web_ui/test/ui/picture_test.dart @@ -13,7 +13,7 @@ void main() { } Future testMain() async { - setUpUiTest(); + await setUpUiTest(); test('Picture construction invokes onCreate once', () async { int onCreateInvokedCount = 0; diff --git a/lib/web_ui/test/ui/rect_test.dart b/lib/web_ui/test/ui/rect_test.dart index 156b6fc84363b..9bc14cf25eb33 100644 --- a/lib/web_ui/test/ui/rect_test.dart +++ b/lib/web_ui/test/ui/rect_test.dart @@ -12,8 +12,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); test('rect accessors', () { const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0); expect(r.left, equals(1.0)); diff --git a/lib/web_ui/test/ui/rrect_test.dart b/lib/web_ui/test/ui/rrect_test.dart index bdf84f1cc17a6..c82c689cc7e7e 100644 --- a/lib/web_ui/test/ui/rrect_test.dart +++ b/lib/web_ui/test/ui/rrect_test.dart @@ -12,8 +12,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); test('RRect.contains()', () { final RRect rrect = RRect.fromRectAndCorners( const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0), diff --git a/lib/web_ui/test/ui/title_test.dart b/lib/web_ui/test/ui/title_test.dart index c7caa806f5363..f9c532c7f5623 100644 --- a/lib/web_ui/test/ui/title_test.dart +++ b/lib/web_ui/test/ui/title_test.dart @@ -13,8 +13,8 @@ void main() { internalBootstrapBrowserTest(() => testMain); } -void testMain() { - setUpUiTest(); +Future testMain() async { + await setUpUiTest(); const MethodCodec codec = JSONMethodCodec(); diff --git a/lib/web_ui/test/ui/utils.dart b/lib/web_ui/test/ui/utils.dart index 07417680ea489..312d5e4bc07ea 100644 --- a/lib/web_ui/test/ui/utils.dart +++ b/lib/web_ui/test/ui/utils.dart @@ -8,9 +8,11 @@ import 'package:ui/src/engine/skwasm/skwasm_stub.dart' if (dart.library.ffi) 'pa import '../canvaskit/common.dart'; /// Initializes the renderer for this test. -void setUpUiTest() { - if (renderer is CanvasKitRenderer) { +Future setUpUiTest() async { + if (isCanvasKit) { setUpCanvasKitTest(); + } else if (isHtml) { + await initializeEngine(); } } From a7906e8362ad7c764b497355c7abdda318ec259e Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 16 Feb 2023 17:47:06 -0800 Subject: [PATCH 10/44] Added and updated documentation. --- lib/web_ui/README.md | 112 ++++++++++++++++++++++---------------- lib/web_ui/test/README.md | 50 +++++++++++++++++ 2 files changed, 115 insertions(+), 47 deletions(-) create mode 100644 lib/web_ui/test/README.md diff --git a/lib/web_ui/README.md b/lib/web_ui/README.md index f1e11e92f9a01..4e1bdb35de318 100644 --- a/lib/web_ui/README.md +++ b/lib/web_ui/README.md @@ -22,75 +22,92 @@ To tell `felt` to do anything you call `felt SUBCOMMAND`, where `SUBCOMMAND` is one of the available subcommands, which can be listed by running `felt help`. To get help for a specific subcommand, run `felt help SUBCOMMAND`. -The most useful subcommands are: - -- `felt build` - builds a local Flutter Web engine ready to be used by the - Flutter framework. To use a locally built web sdk, build with `felt build`, - then pass `--local-web-sdk=wasm_release` to the `flutter` command, or to - `dev/bots/test.dart` when running a web shard, such as `web_tests`. -- `felt test` - runs web engine tests. By default, this runs all tests using - Chromium. Passing one or more paths to specific tests would run just the - specified tests. Run `felt help test` for more options. - -`build` and `test` take the `--watch` option, which automatically reruns the -subcommand when a source file changes. This is handy when you are iterating -quickly. - -#### Examples - -Builds the web engine, the runs a Flutter app using it: - +#### `felt build` +The `build` subcommand builds web engine gn/ninja targets. Targets can be +individually specified in the command line invocation, or if none are specified, +all web engine targets are built. Common targets are as follows: + * `sdk` - The flutter_web_sdk itself. + * `canvaskit` - Flutter's version of canvakit. + * `canvaskit_chromium` - A version of canvaskit optimized for use with + chromium-based browsers. + * `skwasm` - Builds experimental skia wasm module renderer. +The output of these steps is used in unit tests, and can be used with the flutter +command via the `--local-web-sdk=wasm_release` command. + +##### Examples +Builds all web engine targets, then runs a Flutter app using it: ``` felt build cd path/to/some/app -flutter --local-web-sdk=wasm_release run -d chrome +flutter --local-web_sdk=wasm_release run -d chrome ``` -Runs all tests in Chromium: - +Builds only the `sdk` and the `canvaskit` targets: ``` -felt test +felt build sdk canvaskit ``` -Runs a specific test: - +#### `felt test` +The `test` subcommand will compile and/or run web engine unit test suites. For +information on how test suites are structured, see the test configuration +[readme][2]. + +By default, `felt test` compiles and runs all suites that are compatible with the +host system. Some useful flags supported by this command: + * `--compile` will only perform compilation of these suites without running them. + * `--run` will only run the tests and not compile them, and assume they have been + compiled in a previous run of the tool. + * `--list` will list all the test suites and test bundles and exit without + compiling or running anything. + * `--verbose` will output some extra information that may be useful for debugging. + * `--debug` will open a browser window and pause the tests before starting so that + breakpoints can be set before starting the test suites. + +Several other flags can be passed that filter which test suites should be run: + * `--browser` runs only the test suites that test on the browsers passed. Valid + values for this are `chrome`, `firefox`, `safari`, or `edge`. + * `--compiler` runs only the test suites that use a particular compiler. Valid + values for this are `dart2js` or `dart2wasm` + * `--renderer` runs only the test suites that use a particular renderer. Valid + values for this are `html`, `canvakit`, or `skwasm` + * `--suite` runs a suite by name. + * `--bundle` runs suites that target a particular test bundle. + +Filters of different types are logically ANDed together, but multiple filter flags +of the same type are logically ORed together. + +The `test` command will also accept a list of paths to specific test files to be +compiled and run. If none of these paths are specified, all tests are run, otherwise +only the tests that are specified will run. + +##### Examples +Runs all test suites in all compatible browsers: ``` -felt test test/engine/util_test.dart +felt test ``` - -Runs multiple specific tests: - +Runs a specific test on all compatible browsers: ``` -felt test test/engine/util_test.dart test/alarm_clock_test.dart +felt test test/engine/util_test.dart ``` - -Enable watch mode so that the test re-runs every time a source file changes: - +Runs multiple specific tests on all compatible browsers: ``` -felt test --watch test/engine/util_test.dart +felt test test/engine/util_test.dart test/engine/alarm_clock_test.dart ``` - -Runs tests in Firefox (requires a Linux computer): - +Runs only test suites that compile via dart2wasm: ``` -felt test --browser=firefox +felt test --compiler dart2wasm ``` - -Chromium and Firefox support debugging tests using the browser's developer -tools. To run tests in debug mode add `--debug` to the `test` command, e.g.: - +Runs only test suites that run in Chrome and Safari: ``` -felt test --debug --browser=firefox test/alarm_clock_test.dart +felt test --browser chrome --browser safari ``` ### Optimizing local builds Concurrency of various build steps can be configured via environment variables: -- `FELT_DART2JS_CONCURRENCY` specifies the number of concurrent `dart2js` +- `FELT_COMPILE_CONCURRENCY` specifies the number of concurrent compiler processes used to compile tests. Default value is 8. -- `FELT_TEST_CONCURRENCY` specifies the number of tests run concurrently. - Default value is 10. If you are a Google employee, you can use an internal instance of Goma (go/ma) to parallelize your ninja builds. Because Goma compiles code on remote servers, @@ -99,7 +116,7 @@ this option is particularly effective for building on low-powered laptops. ### Test browsers Chromium, Firefox, and Safari for iOS are version-locked using the -[browser_lock.yaml][2] configuration file. Safari for macOS is supplied by the +[browser_lock.yaml][3] configuration file. Safari for macOS is supplied by the computer's operating system. Tests can be run in Edge locally, but Edge is not enabled on LUCI. Chromium is used as a proxy for Chrome, Edge, and other Chromium-based browsers. @@ -301,7 +318,8 @@ Once you know the version for the Emscripten SDK, change the line in [1]: https://github.com/flutter/flutter/wiki/Setting-up-the-Engine-development-environment -[2]: https://github.com/flutter/engine/blob/main/lib/web_ui/dev/browser_lock.yaml +[2]: https://github.com/flutter/flutter/blob/main/lib/web_ui/test/README +[3]: https://github.com/flutter/engine/blob/main/lib/web_ui/dev/browser_lock.yaml [4]: https://chrome-infra-packages.appspot.com/p/flutter_internal [5]: https://cs.opensource.google/flutter/recipes/+/master:recipes/engine/web_engine.py [6]: https://chromium.googlesource.com/chromium/src.git/+/main/docs/cipd_and_3pp.md#What-is-CIPD diff --git a/lib/web_ui/test/README.md b/lib/web_ui/test/README.md new file mode 100644 index 0000000000000..9c3ae657a1411 --- /dev/null +++ b/lib/web_ui/test/README.md @@ -0,0 +1,50 @@ +............................................................................... +# Flutter Web Engine Test Suites +The flutter engine unit tests can be run with a number of different +configuration options that affect both compile time and run time. The +permutations of these options are specified in the `felt_config.yaml` file that +is colocated with this README. Here is an overview of the way the test suite +configurations are structured: + +## `compile-configs` +Specifies how the tests should be compiled. Each compile config specifies the +following: + * `name` - The name of the compile configuration. + * `compiler` - What compiler is used to compile the tests. Currently we support + `dart2js` and `dart2wasm` as values. + * `renderer` - Which renderer to use when compiling the tests. Currently we + support `html`, `canvaskit`, and `skwasm`. + +## `test-sets` +A group of files that contain unit tests. Each test set specifies the following: + * `name` - The name of the test set. + * `directory` - The name of the directory under `flutter/lib/web_ui/test` that + contains all the test files. + +## `test-bundles` +Specifies a group of tests and a compile configuration of those tests. The output +of the test bundles appears in `flutter/lib/web_ui/build/test_bundles/` +where `` is replaced by the name of the bundle. Each test bundle may be used +by multiple test suites. Each test bundle specifies the following: + * `name` - The name of the test bundle. + * `test-set` - The name of the test set that contains the tests to be compiled. + * `compile-config` - The name of the compile configuration to use. + +## `run-configs` +Specifies the test environment that should be provided to a unit test. Each run +config specifies the following: + * `name` - Name of the run configuration. + * `browser` - The browser with which to run the tests. Valid values for this are + `chrome`, `firefox`, `safari` or `edge`. + * `canvaskit-variant` - An optionally supplied argument that forces the tests to + use a particular variant of CanvasKit, either `full` or `chromium`. If none + is specified, the engine will select the variant based on its normal selection + logic. + +## `test-suites` +This is a fully specified run of a group of unit tests. They specify the following: + * `name` - Name of the test suite. + * `test-bundle` - Which compiled test bundle to use when running the suite. + * `run-config` - Which run configuration to use when runnin the tests. + * `artifact-deps` - Which gn/ninja build artifacts are needed to run the suite. + Valid values are `canvaskit`, `canvaskit_chromium` or `skwasm`. \ No newline at end of file From b0cfad9e268504585f338c7b2cc30d2b42b44a6d Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 1 Mar 2023 11:27:15 -0800 Subject: [PATCH 11/44] Started some CI stuff. --- .ci.yaml | 16 +-- ci/builders/web_engine.json | 108 ++++++++++++------ lib/web_ui/dev/environment.dart | 4 +- lib/web_ui/dev/felt_config.dart | 2 +- lib/web_ui/dev/steps/compile_bundle_step.dart | 2 +- lib/web_ui/dev/steps/copy_artifacts_step.dart | 12 +- lib/web_ui/dev/steps/run_suite_step.dart | 8 +- lib/web_ui/dev/suite_filter.dart | 2 +- lib/web_ui/dev/test_dart2wasm.js | 2 +- lib/web_ui/dev/test_platform.dart | 19 ++- lib/web_ui/dev/test_runner.dart | 6 +- web_sdk/BUILD.gn | 4 +- web_sdk/web_test_utils/lib/environment.dart | 5 +- 13 files changed, 115 insertions(+), 75 deletions(-) diff --git a/.ci.yaml b/.ci.yaml index cf6f5f3efd4ad..98ea66c5d1c7f 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -276,20 +276,10 @@ targets: release_build: "true" config_name: linux_android_debug_engine - - name: Linux Web Engine - recipe: engine/web_engine + - name: Linux Web Engine (V2) + recipe: engine_v2/engine_v2 properties: - add_recipes_cq: "true" - cores: "32" - gcs_goldens_bucket: flutter_logs - gclient_variables: >- - {"download_emsdk": true} - dependencies: >- - [ - {"dependency": "chrome_and_driver", "version": "version:111.0"}, - {"dependency": "firefox", "version": "version:106.0"}, - {"dependency": "goldctl", "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603"} - ] + config_name: web_engine timeout: 60 runIf: - DEPS diff --git a/ci/builders/web_engine.json b/ci/builders/web_engine.json index 1ce92ddf05c47..ccafb9e16cb19 100644 --- a/ci/builders/web_engine.json +++ b/ci/builders/web_engine.json @@ -1,41 +1,79 @@ { - "generators": { - "pub_dirs": [ - "flutter/lib/web_ui/", - "flutter/web_sdk/web_engine_tester/" - ], - "tasks": [ - { - "name": "compile web_tests", - "parameters": [ - "run", - "compile_tests" - ], - "scripts": [ - "out/host_debug_unopt/dart-sdk/bin/dart", - "flutter/lib/web_ui/dev/felt.dart" - ] + "builds": [ + { + "archives": [], + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false, + "download_emsdk": true }, - { - "name": "check licenses", - "parameters": [ - "check-licenses" - ], - "scripts": [ - "out/host_debug_unopt/dart-sdk/bin/dart", - "flutter/lib/web_ui/dev/felt.dart" + "gn": [ + "--web", + "--runtime-mode=release" + ], + "name": "wasm_release", + "ninja": { + "config": "wasm_release", + "targets": [ + "flutter/web_sdk:flutter_web_sdk_archive" ] }, - { - "name": "web engine analysis", - "parameters": [ - "analyze" - ], - "scripts": [ - "out/host_debug_unopt/dart-sdk/bin/dart", - "flutter/lib/web_ui/dev/felt.dart" + "generators": { + "tasks": [ + { + "name": "analyze web_ui", + "parameters": [ + "analyze" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "check licenses", + "parameters": [ + "check-licenses" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "compile web_tests", + "parameters": [ + "test", + "--compile" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } ] - } - ] - } + }, + "tests": [] + } + ], + "tests": [ + { + "name": "linux chrome dart2js web tests", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "parameters": [ + "--suite=chrome-dart2js-html-engine", + "--suite=chrome-dart2js-html-html", + "--suite=chrome-dart2js-html-ui", + "--suite=chrome-dart2js-canvaskit-canvaskit", + "--suite=chrome-dart2js-canvaskit-ui", + "--suite=chrome-dart2js-skwasm-skwasm_stub", + "--suite=chrome-full-dart2js-canvaskit-canvaskit", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] } diff --git a/lib/web_ui/dev/environment.dart b/lib/web_ui/dev/environment.dart index 436d8cf47dcf9..b92ebb0569c21 100644 --- a/lib/web_ui/dev/environment.dart +++ b/lib/web_ui/dev/environment.dart @@ -143,8 +143,8 @@ class Environment { /// /// This is where compiled output goes. io.Directory get webUiBuildDir => io.Directory(pathlib.join( - webUiRootDir.path, - 'build', + outDir.path, + 'web_tests', )); /// Path to the ".dart_tool" directory, generated by various Dart tools. diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart index cbcf3f6f161e9..4ecf073b69041 100644 --- a/lib/web_ui/dev/felt_config.dart +++ b/lib/web_ui/dev/felt_config.dart @@ -66,7 +66,7 @@ class ArtifactDependencies { required this.skwasm }); - ArtifactDependencies.none() + ArtifactDependencies.none() : canvasKit = false , canvasKitChromium = false , skwasm = false; diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart index d8916e272e22c..4f5830c678e57 100644 --- a/lib/web_ui/dev/steps/compile_bundle_step.dart +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -104,7 +104,7 @@ class CompileBundleStep implements PipelineStep { } final bool success = await compiler.compileTest(testFile); const int maxTestNameLength = 80; - final String truncatedPath = relativePath.length > maxTestNameLength + final String truncatedPath = relativePath.length > maxTestNameLength ? relativePath.replaceRange(maxTestNameLength - 3, relativePath.length, '...') : relativePath; final String expandedPath = truncatedPath.padRight(maxTestNameLength); diff --git a/lib/web_ui/dev/steps/copy_artifacts_step.dart b/lib/web_ui/dev/steps/copy_artifacts_step.dart index 99f53a3445f71..d9bec3a6cf9d5 100644 --- a/lib/web_ui/dev/steps/copy_artifacts_step.dart +++ b/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -37,10 +37,10 @@ class CopyArtifactsStep implements PipelineStep { await copyTestFonts(); await copySkiaTestImages(); if (artifactDeps.canvasKit) { - await copyCanvasKitFiles('canvaskit'); + await copyCanvasKitFiles('canvaskit', 'canvaskit'); } if (artifactDeps.canvasKitChromium) { - await copyCanvasKitFiles('canvaskit_chromium'); + await copyCanvasKitFiles('canvaskit_chromium', 'canvaskit/chromium'); } if (artifactDeps.skwasm) { await copySkwasm(); @@ -133,15 +133,15 @@ Future copySkiaTestImages() async { } } -Future copyCanvasKitFiles(String subdirectory) async { +Future copyCanvasKitFiles(String sourcePath, String destinationPath) async { final String sourceDirectoryPath = pathlib.join( environment.wasmReleaseOutDir.path, - subdirectory, + sourcePath, ); final String targetDirectoryPath = pathlib.join( environment.webUiBuildDir.path, - subdirectory, + destinationPath, ); for (final String filename in [ @@ -167,7 +167,7 @@ Future copyCanvasKitFiles(String subdirectory) async { Future copySkwasm() async { final io.Directory targetDir = io.Directory(pathlib.join( environment.webUiBuildDir.path, - 'skwasm', + 'canvaskit', )); await targetDir.create(recursive: true); diff --git a/lib/web_ui/dev/steps/run_suite_step.dart b/lib/web_ui/dev/steps/run_suite_step.dart index 1a5ecbe427989..3650670590bff 100644 --- a/lib/web_ui/dev/steps/run_suite_step.dart +++ b/lib/web_ui/dev/steps/run_suite_step.dart @@ -62,7 +62,7 @@ class RunSuiteStep implements PipelineStep { Future run() async { _prepareTestResultsDirectory(); final BrowserEnvironment browserEnvironment = getBrowserEnvironment( - suite.runConfig.browser, + suite.runConfig.browser, enableWasmGC: isWasm); await browserEnvironment.prepare(); @@ -146,7 +146,7 @@ class RunSuiteStep implements PipelineStep { } final String jsonString = resultsJsonFile.readAsStringSync(); final dynamic jsonContents = const JsonDecoder().convert(jsonString); - final dynamic results = jsonContents['results']; + final dynamic results = jsonContents['results']; final List testPaths = []; results.forEach((dynamic k, dynamic v) { final String result = v as String; @@ -164,11 +164,15 @@ class RunSuiteStep implements PipelineStep { } Future _createSkiaClient() async { + final Renderer renderer = suite.testBundle.compileConfig.renderer; + final CanvasKitVariant? variant = suite.runConfig.variant; final SkiaGoldClient skiaClient = SkiaGoldClient( environment.webUiSkiaGoldDirectory, dimensions: { 'Browser': suite.runConfig.browser.name, if (isWasm) 'Wasm': 'true', + 'Renderer': renderer.name, + if (variant != null) 'CanvasKitVariant': variant.name, }, ); diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart index e2837e342d3d1..32b4042eb52bb 100644 --- a/lib/web_ui/dev/suite_filter.dart +++ b/lib/web_ui/dev/suite_filter.dart @@ -75,7 +75,7 @@ class CompilerFilter extends AllowListSuiteFilter { @override Compiler getAttributeForSuite(TestSuite suite) => suite.testBundle.compileConfig.compiler; -} +} class RendererFilter extends AllowListSuiteFilter { RendererFilter({required super.allowList}); diff --git a/lib/web_ui/dev/test_dart2wasm.js b/lib/web_ui/dev/test_dart2wasm.js index 884fbc81fdecc..a9c737083f6be 100644 --- a/lib/web_ui/dev/test_dart2wasm.js +++ b/lib/web_ui/dev/test_dart2wasm.js @@ -57,7 +57,7 @@ window.onload = async function () { const isSkwasm = link.hasAttribute('skwasm'); const imports = isSkwasm ? new Promise((resolve) => { const skwasmScript = document.createElement('script'); - skwasmScript.src = '/skwasm/skwasm.js'; + skwasmScript.src = '/canvaskit/skwasm.js'; document.body.appendChild(skwasmScript); skwasmScript.addEventListener('load', async () => { diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 874652554fa4e..94e9c424a37d7 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -495,20 +495,25 @@ class BrowserPlatform extends PlatformPlugin { }; } - String getCanvasKitBase() { + String getCanvasKitVariant() { switch (suite.runConfig.variant) { case CanvasKitVariant.full: - return 'canvaskit'; + return 'full'; case CanvasKitVariant.chromium: - return 'canvaskit_chromium'; + return 'chromium'; case null: + // TODO(jacksongardner): Once the engine automatically uses the + // chromium build in chromium browsers, we should just return 'auto' + // here. For now, though, 'auto' will always select the full canvaskit + // variant, so we're simulating future behavior here by selecting the + // chromium build in our chromium browsers in the unit tests. switch (suite.runConfig.browser) { case BrowserName.chrome: case BrowserName.edge: - return 'canvaskit_chromium'; + return 'chromium'; case BrowserName.firefox: case BrowserName.safari: - return 'canvaskit'; + return 'full'; } } } @@ -527,6 +532,7 @@ class BrowserPlatform extends PlatformPlugin { final String testRunner = isWasm ? '/test_dart2wasm.js' : 'packages/test/dart.js'; + return shelf.Response.ok(''' @@ -535,7 +541,8 @@ class BrowserPlatform extends PlatformPlugin { $link diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index dc4e31f7c407c..6ee4281ade79f 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -271,13 +271,13 @@ class TestCommand extends Command with ArgUtils { } List _filterBundlesForSuites(List suites) { - final Set seenBundles = + final Set seenBundles = Set.from(suites.map((TestSuite suite) => suite.testBundle)); return config.testBundles.where((TestBundle bundle) => seenBundles.contains(bundle)).toList(); } ArtifactDependencies _artifactsForSuites(List suites) { - return suites.fold(ArtifactDependencies.none(), + return suites.fold(ArtifactDependencies.none(), (ArtifactDependencies deps, TestSuite suite) => deps | suite.artifactDependencies); } @@ -332,7 +332,7 @@ class TestCommand extends Command with ArgUtils { if (shouldRun) for (final TestSuite suite in filteredSuites) RunSuiteStep( - suite, + suite, isDebug: isDebug, isVerbose: isVerbose, doUpdateScreenshotGoldens: doUpdateScreenshotGoldens, diff --git a/web_sdk/BUILD.gn b/web_sdk/BUILD.gn index e36947b157206..b2a083c2dc68f 100644 --- a/web_sdk/BUILD.gn +++ b/web_sdk/BUILD.gn @@ -604,11 +604,11 @@ if (!is_fuchsia) { }, { source = rebase_path("$root_out_dir/canvaskit_chromium/canvaskit.js") - destination = "canvaskit/chromium/canvaskit.js" + destination = "flutter_web_sdk/canvaskit/chromium/canvaskit.js" }, { source = rebase_path("$root_out_dir/canvaskit_chromium/canvaskit.wasm") - destination = "canvaskit/chromium/canvaskit.wasm" + destination = "flutter_web_sdk/canvaskit/chromium/canvaskit.wasm" }, { source = rebase_path("$root_out_dir/skwasm.js") diff --git a/web_sdk/web_test_utils/lib/environment.dart b/web_sdk/web_test_utils/lib/environment.dart index 96702b210acba..350822b452efa 100644 --- a/web_sdk/web_test_utils/lib/environment.dart +++ b/web_sdk/web_test_utils/lib/environment.dart @@ -99,8 +99,9 @@ class Environment { /// /// This is where compiled output goes. io.Directory get webUiBuildDir => io.Directory(pathlib.join( - webUiRootDir.path, - 'build', + engineSrcDir.path, + 'out', + 'web_tests', )); /// Path to the ".dart_tool" directory, generated by various Dart tools. From 78859af22da5230e0c612f121c639e4e03ea70d8 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 1 Mar 2023 11:31:23 -0800 Subject: [PATCH 12/44] Add bringup:true to the new web engine step. --- .ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci.yaml b/.ci.yaml index 98ea66c5d1c7f..2b46fa74c1e18 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -278,6 +278,7 @@ targets: - name: Linux Web Engine (V2) recipe: engine_v2/engine_v2 + bringup: true properties: config_name: web_engine timeout: 60 From 2dd558d43e01772c4711dc734976095c59372209 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 1 Mar 2023 11:34:17 -0800 Subject: [PATCH 13/44] Change felt parameters. --- ci/builders/web_engine.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/builders/web_engine.json b/ci/builders/web_engine.json index ccafb9e16cb19..7dceafe5066a6 100644 --- a/ci/builders/web_engine.json +++ b/ci/builders/web_engine.json @@ -64,6 +64,8 @@ "os=Linux" ], "parameters": [ + "test", + "--run", "--suite=chrome-dart2js-html-engine", "--suite=chrome-dart2js-html-html", "--suite=chrome-dart2js-html-ui", @@ -73,6 +75,7 @@ "--suite=chrome-full-dart2js-canvaskit-canvaskit", "--suite=chrome-full-dart2js-canvaskit-ui" ], + "language": "bash", "script": "flutter/lib/web_ui/dev/felt" } ] From 35163cfaf57900d0d78aba2b9262a64ecbf52fec Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 1 Mar 2023 11:35:30 -0800 Subject: [PATCH 14/44] Remove old web engine builders. --- .ci.yaml | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/.ci.yaml b/.ci.yaml index 2b46fa74c1e18..d7a9e4955a013 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -414,27 +414,6 @@ targets: ios_debug: "true" timeout: 60 - - name: Mac Web Engine - recipe: engine/web_engine - properties: - add_recipes_cq: "true" - gcs_goldens_bucket: flutter_logs - gclient_variables: >- - {"download_emsdk": true} - dependencies: >- - [ - {"dependency": "goldctl", "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603"} - ] - timeout: 60 - runIf: - - DEPS - - .ci.yaml - - lib/web_ui/** - - web_sdk/** - - tools/** - - ci/** - - flutter_frontend_server/** - - name: Mac mac_ios_engine recipe: engine_v2/engine_v2 timeout: 60 @@ -492,23 +471,6 @@ targets: add_recipes_cq: "true" timeout: 75 - - name: Windows Web Engine - recipe: engine/web_engine - properties: - gclient_variables: >- - {"download_emsdk": true} - gcs_goldens_bucket: flutter_logs - dependencies: >- - [ - {"dependency": "chrome_and_driver", "version": "version:111.0"} - ] - timeout: 60 - runIf: - - DEPS - - .ci.yaml - - lib/web_ui/** - - web_sdk/** - - name: Mac iOS Engine Profile recipe: engine/engine properties: From d721f1099eaeea8a6d75c767ab44921fd11ef415 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 2 Mar 2023 13:09:21 -0800 Subject: [PATCH 15/44] Always hard code canvaskit variants for chrome and edge. --- lib/web_ui/dev/test_platform.dart | 14 +------------- lib/web_ui/test/felt_config.yaml | 2 ++ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 94e9c424a37d7..8dbb3d0c0531b 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -502,19 +502,7 @@ class BrowserPlatform extends PlatformPlugin { case CanvasKitVariant.chromium: return 'chromium'; case null: - // TODO(jacksongardner): Once the engine automatically uses the - // chromium build in chromium browsers, we should just return 'auto' - // here. For now, though, 'auto' will always select the full canvaskit - // variant, so we're simulating future behavior here by selecting the - // chromium build in our chromium browsers in the unit tests. - switch (suite.runConfig.browser) { - case BrowserName.chrome: - case BrowserName.edge: - return 'chromium'; - case BrowserName.firefox: - case BrowserName.safari: - return 'full'; - } + return 'auto'; } } diff --git a/lib/web_ui/test/felt_config.yaml b/lib/web_ui/test/felt_config.yaml index 0a77e4d3d9ed8..d7ce8dfb68972 100644 --- a/lib/web_ui/test/felt_config.yaml +++ b/lib/web_ui/test/felt_config.yaml @@ -97,6 +97,7 @@ test-bundles: run-configs: - name: chrome browser: chrome + canvaskit-variant: chromium - name: chrome-full browser: chrome @@ -104,6 +105,7 @@ run-configs: - name: edge browser: edge + canvaskit-variant: chromium - name: edge-full browser: edge From c48e279fbeafcdb16e10d9c9bca255c08b86f442 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Thu, 2 Mar 2023 17:31:28 -0500 Subject: [PATCH 16/44] improve some error messages --- lib/web_ui/dev/felt_config.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart index 4ecf073b69041..f6e1db70ac415 100644 --- a/lib/web_ui/dev/felt_config.dart +++ b/lib/web_ui/dev/felt_config.dart @@ -155,12 +155,12 @@ class FeltConfig { final String testSetName = testBundleYaml['test-set'] as String; final TestSet? testSet = testSetsByName[testSetName]; if (testSet == null) { - throw AssertionError('Test set not found with name: $testSetName'); + throw AssertionError('Test set not found with name: `$testSetName` (referenced by test bundle: `$name`)'); } final String compileConfigName = testBundleYaml['compile-config'] as String; final CompileConfiguration? compileConfig = compileConfigsByName[compileConfigName]; if (compileConfig == null) { - throw AssertionError('Compile config not found with name: $compileConfigName'); + throw AssertionError('Compile config not found with name: `$compileConfigName` (referenced by test bundle: `$name`)'); } final TestBundle bundle = TestBundle(name, testSet, compileConfig); testBundles.add(bundle); @@ -195,12 +195,12 @@ class FeltConfig { final String testBundleName = testSuiteYaml['test-bundle'] as String; final TestBundle? bundle = testBundlesByName[testBundleName]; if (bundle == null) { - throw AssertionError('Test bundle not found with name: $testBundleName'); + throw AssertionError('Test bundle not found with name: `$testBundleName` (referenced by test suite: `$name`)'); } final String runConfigName = testSuiteYaml['run-config'] as String; final RunConfiguration? runConfig = runConfigsByName[runConfigName]; if (runConfig == null) { - throw AssertionError('Run config not found with name: $testBundleName'); + throw AssertionError('Run config not found with name: `$runConfigName` (referenced by test suite: `$name`)'); } bool canvasKit = false; bool canvasKitChromium = false; From 83f67b875025e8a1b7c3e0724cb52895e1553725 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Thu, 2 Mar 2023 17:32:01 -0500 Subject: [PATCH 17/44] support filtering by canvaskit variant --- lib/web_ui/dev/suite_filter.dart | 8 ++++++++ lib/web_ui/dev/test_runner.dart | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/web_ui/dev/suite_filter.dart b/lib/web_ui/dev/suite_filter.dart index 32b4042eb52bb..25b566a1ff18d 100644 --- a/lib/web_ui/dev/suite_filter.dart +++ b/lib/web_ui/dev/suite_filter.dart @@ -84,6 +84,14 @@ class RendererFilter extends AllowListSuiteFilter { Renderer getAttributeForSuite(TestSuite suite) => suite.testBundle.compileConfig.renderer; } +class CanvasKitVariantFilter extends AllowListSuiteFilter { + CanvasKitVariantFilter({required super.allowList}); + + @override + // TODO(jackson): Is this the right default? + CanvasKitVariant getAttributeForSuite(TestSuite suite) => suite.runConfig.variant ?? CanvasKitVariant.full; +} + Set get _supportedPlatformBrowsers { if (io.Platform.isLinux) { return { diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 6ee4281ade79f..f5b272f4c6f02 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -85,6 +85,10 @@ class TestCommand extends Command with ArgUtils { 'renderer', help: 'Filter test suites by renderer.', ) + ..addMultiOption( + 'canvaskit-variant', + help: 'Filter test suites by CanvasKit variant.', + ) ..addMultiOption( 'suite', help: 'Filter test suites by suite name.', @@ -177,6 +181,15 @@ class TestCommand extends Command with ArgUtils { return RendererFilter(allowList: renderers); } + CanvasKitVariantFilter? makeCanvasKitVariantFilter() { + final List? variantArgs = argResults!['canvaskit-variant'] as List?; + if (variantArgs == null || variantArgs.isEmpty) { + return null; + } + final Set variants = Set.from(variantArgs.map((String arg) => CanvasKitVariant.values.byName(arg))); + return CanvasKitVariantFilter(allowList: variants); + } + SuiteNameFilter? makeSuiteNameFilter() { final List? suiteNameArgs = argResults!['suite'] as List?; if (suiteNameArgs == null || suiteNameArgs.isEmpty) { @@ -236,6 +249,7 @@ class TestCommand extends Command with ArgUtils { final BrowserSuiteFilter? browserFilter = makeBrowserFilter(); final CompilerFilter? compilerFilter = makeCompilerFilter(); final RendererFilter? rendererFilter = makeRendererFilter(); + final CanvasKitVariantFilter? canvaskitVariantFilter = makeCanvasKitVariantFilter(); final SuiteNameFilter? suiteNameFilter = makeSuiteNameFilter(); final BundleNameFilter? bundleNameFilter = makeBundleNameFilter(); final FileFilter? fileFilter = makeFileFilter(); @@ -244,6 +258,7 @@ class TestCommand extends Command with ArgUtils { if (browserFilter != null) browserFilter, if (compilerFilter != null) compilerFilter, if (rendererFilter != null) rendererFilter, + if (canvaskitVariantFilter != null) canvaskitVariantFilter, if (suiteNameFilter != null) suiteNameFilter, if (bundleNameFilter != null) bundleNameFilter, if (fileFilter != null) fileFilter, From 1687708936648218b03f25fd203eda1a6d059d5a Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Tue, 7 Mar 2023 15:32:31 -0800 Subject: [PATCH 18/44] Change linux_web_engine to new felt commands. --- ci/builders/linux_web_engine.json | 29 +++++++++-- ci/builders/web_engine.json | 82 ------------------------------- 2 files changed, 25 insertions(+), 86 deletions(-) delete mode 100644 ci/builders/web_engine.json diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index e1b1c1336fea7..09e14e47f5452 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -20,7 +20,6 @@ "download_emsdk": true }, "gn": [ - "--build-canvaskit", "--web", "--runtime-mode=release" ], @@ -40,8 +39,8 @@ { "name": "compile web_tests", "parameters": [ - "run", - "compile_tests" + "test", + "--compile" ], "scripts": [ "flutter/lib/web_ui/dev/felt" @@ -70,5 +69,27 @@ "tests": [] } ], - "tests": [] + "tests": [ + { + "name": "linux chrome dart2js web tests", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-engine", + "--suite=chrome-dart2js-html-html", + "--suite=chrome-dart2js-html-ui", + "--suite=chrome-dart2js-canvaskit-canvaskit", + "--suite=chrome-dart2js-canvaskit-ui", + "--suite=chrome-dart2js-skwasm-skwasm_stub", + "--suite=chrome-full-dart2js-canvaskit-canvaskit", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "language": "bash", + "script": "flutter/lib/web_ui/dev/felt" + } + ] } diff --git a/ci/builders/web_engine.json b/ci/builders/web_engine.json deleted file mode 100644 index 7dceafe5066a6..0000000000000 --- a/ci/builders/web_engine.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "builds": [ - { - "archives": [], - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false, - "download_emsdk": true - }, - "gn": [ - "--web", - "--runtime-mode=release" - ], - "name": "wasm_release", - "ninja": { - "config": "wasm_release", - "targets": [ - "flutter/web_sdk:flutter_web_sdk_archive" - ] - }, - "generators": { - "tasks": [ - { - "name": "analyze web_ui", - "parameters": [ - "analyze" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "check licenses", - "parameters": [ - "check-licenses" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "compile web_tests", - "parameters": [ - "test", - "--compile" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } - ] - }, - "tests": [] - } - ], - "tests": [ - { - "name": "linux chrome dart2js web tests", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-engine", - "--suite=chrome-dart2js-html-html", - "--suite=chrome-dart2js-html-ui", - "--suite=chrome-dart2js-canvaskit-canvaskit", - "--suite=chrome-dart2js-canvaskit-ui", - "--suite=chrome-dart2js-skwasm-skwasm_stub", - "--suite=chrome-full-dart2js-canvaskit-canvaskit", - "--suite=chrome-full-dart2js-canvaskit-ui" - ], - "language": "bash", - "script": "flutter/lib/web_ui/dev/felt" - } - ] -} From d6ec4e795bcef990ecf13524cbf4e7071325f04d Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Tue, 7 Mar 2023 16:15:13 -0800 Subject: [PATCH 19/44] Skip the legacy build path for license checks. --- lib/web_ui/dev/licenses.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/web_ui/dev/licenses.dart b/lib/web_ui/dev/licenses.dart index 21383493479a2..8ce8090d628cd 100644 --- a/lib/web_ui/dev/licenses.dart +++ b/lib/web_ui/dev/licenses.dart @@ -79,13 +79,17 @@ class LicensesCommand extends Command { } List _flatListSourceFiles(io.Directory directory) { + // This is the old path that tests used to be built into. Ignore anything + // within this path. + final String legacyBuildPath = path.join(environment.webUiRootDir.path, 'build'); return directory.listSync(recursive: true).whereType().where((io.File f) { if (!f.path.endsWith('.dart') && !f.path.endsWith('.js')) { // Not a source file we're checking. return false; } if (path.isWithin(environment.webUiBuildDir.path, f.path) || - path.isWithin(environment.webUiDartToolDir.path, f.path)) { + path.isWithin(environment.webUiDartToolDir.path, f.path) || + path.isWithin(legacyBuildPath, f.path)) { // Generated files. return false; } From 77e0119cf2abe322b09cffffeda4cbce488b8443 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 8 Mar 2023 14:09:42 -0800 Subject: [PATCH 20/44] Update lib/web_ui/dev/steps/compile_bundle_step.dart Co-authored-by: Mouad Debbar --- lib/web_ui/dev/steps/compile_bundle_step.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart index 4f5830c678e57..2e62081bd5221 100644 --- a/lib/web_ui/dev/steps/compile_bundle_step.dart +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -263,11 +263,10 @@ class Dart2WasmCompiler extends TestCompiler { '-DFLUTTER_WEB_USE_SKIA=${renderer == Renderer.canvaskit}', '-DFLUTTER_WEB_USE_SKWASM=${renderer == Renderer.skwasm}', - if (renderer == Renderer.skwasm) - ...[ - '--import-shared-memory', - '--shared-memory-max-pages=32768', - ], + if (renderer == Renderer.skwasm) ...[ + '--import-shared-memory', + '--shared-memory-max-pages=32768', + ], relativePath, // current path. targetFileName, // target path. From 7fcc94ba69724434e60a86efe26f30d04c6608f3 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Wed, 8 Mar 2023 14:10:54 -0800 Subject: [PATCH 21/44] Revert weird change to README.md --- lib/web_ui/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/README.md b/lib/web_ui/README.md index 4e1bdb35de318..798a7b6790f8f 100644 --- a/lib/web_ui/README.md +++ b/lib/web_ui/README.md @@ -39,7 +39,7 @@ Builds all web engine targets, then runs a Flutter app using it: ``` felt build cd path/to/some/app -flutter --local-web_sdk=wasm_release run -d chrome +flutter --local-web-sdk=wasm_release run -d chrome ``` Builds only the `sdk` and the `canvaskit` targets: From 55195f0f6519a707f0730abb71403b91e6c725f3 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Fri, 10 Mar 2023 10:44:14 -0800 Subject: [PATCH 22/44] Separate web_tests build out. --- ci/builders/linux_web_engine.json | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index c590302a5ec04..b0b408ff6b7c7 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -31,11 +31,15 @@ "flutter/web_sdk:flutter_web_sdk_archive" ] }, + "tests": [] + }, + { + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "name": "web_tests", "generators": { - "pub_dirs": [ - "flutter/lib/web_ui/", - "flutter/web_sdk/web_engine_tester/" - ], "tasks": [ { "name": "compile web_tests", @@ -66,8 +70,7 @@ ] } ] - }, - "tests": [] + } } ], "tests": [ From dbc98f93dc1c994c7c053824a5d9fafa40beaf9a Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Fri, 10 Mar 2023 13:04:26 -0800 Subject: [PATCH 23/44] Copy artifacts in a generator step. --- ci/builders/linux_web_engine.json | 14 ++++++++++++++ lib/web_ui/dev/steps/copy_artifacts_step.dart | 3 +++ lib/web_ui/dev/test_runner.dart | 15 ++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index b0b408ff6b7c7..bd10b2ba66941 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -73,6 +73,20 @@ } } ], + "generators": { + "tasks": [ + { + "name": "copy web_tests artifacts", + "parameters": [ + "test", + "--copy-artifacts" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, "tests": [ { "name": "linux chrome dart2js web tests", diff --git a/lib/web_ui/dev/steps/copy_artifacts_step.dart b/lib/web_ui/dev/steps/copy_artifacts_step.dart index d9bec3a6cf9d5..f6c00335014b9 100644 --- a/lib/web_ui/dev/steps/copy_artifacts_step.dart +++ b/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -37,12 +37,15 @@ class CopyArtifactsStep implements PipelineStep { await copyTestFonts(); await copySkiaTestImages(); if (artifactDeps.canvasKit) { + print('Copying CanvasKit...'); await copyCanvasKitFiles('canvaskit', 'canvaskit'); } if (artifactDeps.canvasKitChromium) { + print('Copying CanvasKit (Chromium)...'); await copyCanvasKitFiles('canvaskit_chromium', 'canvaskit/chromium'); } if (artifactDeps.skwasm) { + print('Copying Skwasm...'); await copySkwasm(); } } diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index f5b272f4c6f02..3da2980f5d85e 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -60,6 +60,13 @@ class TestCommand extends Command with ArgUtils { 'Run test suites. If this is specified on its own, we will only ' 'run the suites and not compile the bundles.' ) + ..addFlag( + 'copy-artifacts', + help: + 'Copy artifacts needed for test suites. If this is specified on ' + 'its own, we will only copy the artifacts and not compile or run' + 'the tests bundles or suites.' + ) ..addFlag( 'require-skia-gold', help: @@ -327,16 +334,18 @@ class TestCommand extends Command with ArgUtils { bool shouldRun = boolArg('run'); bool shouldCompile = boolArg('compile'); - if (!shouldRun && !shouldCompile) { - // If neither is specified, we should assume we need to both compile and run. + bool shouldCopyArtifacts = boolArg('copy-artifacts'); + if (!shouldRun && !shouldCompile && !shouldCopyArtifacts) { + // If none of these is specified, we should assume we need to do all of them. shouldRun = true; shouldCompile = true; + shouldCopyArtifacts = true; } final Set? testFiles = targetFiles.isEmpty ? null : Set.from(targetFiles); final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), - CopyArtifactsStep(artifacts), + if (shouldCopyArtifacts) CopyArtifactsStep(artifacts), if (shouldCompile) for (final TestBundle bundle in bundles) CompileBundleStep( From 0c6bf804d275c924aa6feb2847d95c7b865dc171 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Fri, 10 Mar 2023 13:32:38 -0800 Subject: [PATCH 24/44] Do copy artifacts as part of the test run. --- ci/builders/linux_web_engine.json | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index bd10b2ba66941..a583da6015f73 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -73,20 +73,7 @@ } } ], - "generators": { - "tasks": [ - { - "name": "copy web_tests artifacts", - "parameters": [ - "test", - "--copy-artifacts" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } - ] - }, + "generators": {}, "tests": [ { "name": "linux chrome dart2js web tests", @@ -97,6 +84,7 @@ "parameters": [ "test", "--run", + "--copy-artifacts", "--suite=chrome-dart2js-html-engine", "--suite=chrome-dart2js-html-html", "--suite=chrome-dart2js-html-ui", From dd3c7b95f2d8239b291f26bec6a0d22c270dd888 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Fri, 10 Mar 2023 17:10:23 -0800 Subject: [PATCH 25/44] Allow testing against wasm_profile artifacts. --- lib/web_ui/dev/steps/copy_artifacts_step.dart | 417 +++++++++--------- lib/web_ui/dev/test_runner.dart | 7 +- 2 files changed, 217 insertions(+), 207 deletions(-) diff --git a/lib/web_ui/dev/steps/copy_artifacts_step.dart b/lib/web_ui/dev/steps/copy_artifacts_step.dart index f6c00335014b9..50f1b0a2bfd14 100644 --- a/lib/web_ui/dev/steps/copy_artifacts_step.dart +++ b/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -14,9 +14,10 @@ import '../pipeline.dart'; import '../utils.dart'; class CopyArtifactsStep implements PipelineStep { - CopyArtifactsStep(this.artifactDeps); + CopyArtifactsStep(this.artifactDeps, { required this.isProfile }); final ArtifactDependencies artifactDeps; + final bool isProfile; @override String get description => 'copy_artifacts'; @@ -49,240 +50,244 @@ class CopyArtifactsStep implements PipelineStep { await copySkwasm(); } } -} - -Future copyDart2WasmTestScript() async { - final io.File sourceFile = io.File(pathlib.join( - environment.webUiDevDir.path, - 'test_dart2wasm.js', - )); - final io.File targetFile = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'test_dart2wasm.js', - )); - await sourceFile.copy(targetFile.path); -} - -const Map _kTestFonts = { - 'Ahem': 'ahem.ttf', - 'Roboto': 'Roboto-Regular.ttf', - 'RobotoVariable': 'RobotoSlab-VariableFont_wght.ttf', - 'Noto Naskh Arabic UI': 'NotoNaskhArabic-Regular.ttf', - 'Noto Color Emoji': 'NotoColorEmoji.ttf', -}; - -Future copyTestFonts() async { - final String fontsPath = pathlib.join( - environment.flutterDirectory.path, - 'third_party', - 'txt', - 'third_party', - 'fonts', - ); - - final List fontManifest = []; - for (final MapEntry fontEntry in _kTestFonts.entries) { - final String family = fontEntry.key; - final String fontFile = fontEntry.value; - - fontManifest.add({ - 'family': family, - 'fonts': [ - { - 'asset': 'fonts/$fontFile', - }, - ], - }); - final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile)); - final io.File destinationTtf = io.File(pathlib.join( + Future copyDart2WasmTestScript() async { + final io.File sourceFile = io.File(pathlib.join( + environment.webUiDevDir.path, + 'test_dart2wasm.js', + )); + final io.File targetFile = io.File(pathlib.join( environment.webUiBuildDir.path, - 'assets', - 'fonts', - fontFile, + 'test_dart2wasm.js', )); - await destinationTtf.create(recursive: true); - await sourceTtf.copy(destinationTtf.path); + await sourceFile.copy(targetFile.path); } - final io.File fontManifestFile = io.File(pathlib.join( - environment.webUiBuildDir.path, - 'assets', - 'FontManifest.json', - )); - await fontManifestFile.create(recursive: true); - await fontManifestFile.writeAsString( - const JsonEncoder.withIndent(' ').convert(fontManifest), - ); -} + Future copyTestFonts() async { + const Map testFonts = { + 'Ahem': 'ahem.ttf', + 'Roboto': 'Roboto-Regular.ttf', + 'RobotoVariable': 'RobotoSlab-VariableFont_wght.ttf', + 'Noto Naskh Arabic UI': 'NotoNaskhArabic-Regular.ttf', + 'Noto Color Emoji': 'NotoColorEmoji.ttf', + }; + + final String fontsPath = pathlib.join( + environment.flutterDirectory.path, + 'third_party', + 'txt', + 'third_party', + 'fonts', + ); + + final List fontManifest = []; + for (final MapEntry fontEntry in testFonts.entries) { + final String family = fontEntry.key; + final String fontFile = fontEntry.value; + + fontManifest.add({ + 'family': family, + 'fonts': [ + { + 'asset': 'fonts/$fontFile', + }, + ], + }); + + final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile)); + final io.File destinationTtf = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'assets', + 'fonts', + fontFile, + )); + await destinationTtf.create(recursive: true); + await sourceTtf.copy(destinationTtf.path); + } -Future copySkiaTestImages() async { - final io.Directory testImagesDir = io.Directory(pathlib.join( - environment.engineSrcDir.path, - 'third_party', - 'skia', - 'resources', - 'images', - )); - - for (final io.File imageFile in testImagesDir.listSync(recursive: true).whereType()) { - final io.File destination = io.File(pathlib.join( + final io.File fontManifestFile = io.File(pathlib.join( environment.webUiBuildDir.path, - 'test_images', - pathlib.relative(imageFile.path, from: testImagesDir.path), + 'assets', + 'FontManifest.json', )); - destination.createSync(recursive: true); - await imageFile.copy(destination.path); + await fontManifestFile.create(recursive: true); + await fontManifestFile.writeAsString( + const JsonEncoder.withIndent(' ').convert(fontManifest), + ); } -} -Future copyCanvasKitFiles(String sourcePath, String destinationPath) async { - final String sourceDirectoryPath = pathlib.join( - environment.wasmReleaseOutDir.path, - sourcePath, - ); - - final String targetDirectoryPath = pathlib.join( - environment.webUiBuildDir.path, - destinationPath, - ); - - for (final String filename in [ - 'canvaskit.js', - 'canvaskit.wasm', - ]) { - final io.File sourceFile = io.File(pathlib.join( - sourceDirectoryPath, - filename, + Future copySkiaTestImages() async { + final io.Directory testImagesDir = io.Directory(pathlib.join( + environment.engineSrcDir.path, + 'third_party', + 'skia', + 'resources', + 'images', )); - final io.File targetFile = io.File(pathlib.join( - targetDirectoryPath, - filename, - )); - if (!sourceFile.existsSync()) { - throw ToolExit('Built CanvasKit artifact not found at path "$sourceFile".'); + + for (final io.File imageFile in testImagesDir.listSync(recursive: true).whereType()) { + final io.File destination = io.File(pathlib.join( + environment.webUiBuildDir.path, + 'test_images', + pathlib.relative(imageFile.path, from: testImagesDir.path), + )); + destination.createSync(recursive: true); + await imageFile.copy(destination.path); } - await targetFile.create(recursive: true); - await sourceFile.copy(targetFile.path); } -} -Future copySkwasm() async { - final io.Directory targetDir = io.Directory(pathlib.join( - environment.webUiBuildDir.path, - 'canvaskit', - )); + Future copyCanvasKitFiles(String sourcePath, String destinationPath) async { + final String sourceDirectoryPath = pathlib.join( + outBuildPath, + sourcePath, + ); - await targetDir.create(recursive: true); + final String targetDirectoryPath = pathlib.join( + environment.webUiBuildDir.path, + destinationPath, + ); - for (final String fileName in [ - 'skwasm.wasm', - 'skwasm.js', - 'skwasm.worker.js', - ]) { - final io.File sourceFile = io.File(pathlib.join( - environment.wasmReleaseOutDir.path, - fileName, - )); - final io.File targetFile = io.File(pathlib.join( - targetDir.path, - fileName, + for (final String filename in [ + 'canvaskit.js', + 'canvaskit.wasm', + ]) { + final io.File sourceFile = io.File(pathlib.join( + sourceDirectoryPath, + filename, + )); + final io.File targetFile = io.File(pathlib.join( + targetDirectoryPath, + filename, + )); + if (!sourceFile.existsSync()) { + throw ToolExit('Built CanvasKit artifact not found at path "$sourceFile".'); + } + await targetFile.create(recursive: true); + await sourceFile.copy(targetFile.path); + } + } + + String get outBuildPath => isProfile + ? environment.wasmProfileOutDir.path + : environment.wasmReleaseOutDir.path; + + Future copySkwasm() async { + final io.Directory targetDir = io.Directory(pathlib.join( + environment.webUiBuildDir.path, + 'canvaskit', )); - await sourceFile.copy(targetFile.path); + + await targetDir.create(recursive: true); + + for (final String fileName in [ + 'skwasm.wasm', + 'skwasm.js', + 'skwasm.worker.js', + ]) { + final io.File sourceFile = io.File(pathlib.join( + outBuildPath, + fileName, + )); + final io.File targetFile = io.File(pathlib.join( + targetDir.path, + fileName, + )); + await sourceFile.copy(targetFile.path); + } } -} -Future buildHostPage() async { - final String hostDartPath = pathlib.join('lib', 'static', 'host.dart'); - final io.File hostDartFile = io.File(pathlib.join( - environment.webEngineTesterRootDir.path, - hostDartPath, - )); - final String targetDirectoryPath = pathlib.join( - environment.webUiBuildDir.path, - 'host', - ); - io.Directory(targetDirectoryPath).createSync(recursive: true); - final String targetFilePath = pathlib.join( - targetDirectoryPath, - 'host.dart', - ); - - const List staticFiles = [ - 'favicon.ico', - 'host.css', - 'index.html', - ]; - for (final String staticFilePath in staticFiles) { - final io.File source = io.File(pathlib.join( + Future buildHostPage() async { + final String hostDartPath = pathlib.join('lib', 'static', 'host.dart'); + final io.File hostDartFile = io.File(pathlib.join( environment.webEngineTesterRootDir.path, - 'lib', - 'static', - staticFilePath, + hostDartPath, )); - final io.File destination = io.File(pathlib.join( + final String targetDirectoryPath = pathlib.join( + environment.webUiBuildDir.path, + 'host', + ); + io.Directory(targetDirectoryPath).createSync(recursive: true); + final String targetFilePath = pathlib.join( targetDirectoryPath, - staticFilePath, + 'host.dart', + ); + + const List staticFiles = [ + 'favicon.ico', + 'host.css', + 'index.html', + ]; + for (final String staticFilePath in staticFiles) { + final io.File source = io.File(pathlib.join( + environment.webEngineTesterRootDir.path, + 'lib', + 'static', + staticFilePath, + )); + final io.File destination = io.File(pathlib.join( + targetDirectoryPath, + staticFilePath, + )); + await source.copy(destination.path); + } + + final io.File timestampFile = io.File(pathlib.join( + environment.webEngineTesterRootDir.path, + '$targetFilePath.js.timestamp', )); - await source.copy(destination.path); - } - final io.File timestampFile = io.File(pathlib.join( - environment.webEngineTesterRootDir.path, - '$targetFilePath.js.timestamp', - )); - - final String timestamp = - hostDartFile.statSync().modified.millisecondsSinceEpoch.toString(); - if (timestampFile.existsSync()) { - final String lastBuildTimestamp = timestampFile.readAsStringSync(); - if (lastBuildTimestamp == timestamp) { - // The file is still fresh. No need to rebuild. - return; + final String timestamp = + hostDartFile.statSync().modified.millisecondsSinceEpoch.toString(); + if (timestampFile.existsSync()) { + final String lastBuildTimestamp = timestampFile.readAsStringSync(); + if (lastBuildTimestamp == timestamp) { + // The file is still fresh. No need to rebuild. + return; + } else { + // Record new timestamp, but don't return. We need to rebuild. + print('${hostDartFile.path} timestamp changed. Rebuilding.'); + } } else { - // Record new timestamp, but don't return. We need to rebuild. - print('${hostDartFile.path} timestamp changed. Rebuilding.'); + print('Building ${hostDartFile.path}.'); } - } else { - print('Building ${hostDartFile.path}.'); - } - int exitCode = await runProcess( - environment.dartExecutable, - [ - 'pub', - 'get', - ], - workingDirectory: environment.webEngineTesterRootDir.path - ); - - if (exitCode != 0) { - throw ToolExit( - 'Failed to run pub get for web_engine_tester, exit code $exitCode', - exitCode: exitCode, + int exitCode = await runProcess( + environment.dartExecutable, + [ + 'pub', + 'get', + ], + workingDirectory: environment.webEngineTesterRootDir.path ); - } - exitCode = await runProcess( - environment.dartExecutable, - [ - 'compile', - 'js', - hostDartPath, - '-o', - '$targetFilePath.js', - ], - workingDirectory: environment.webEngineTesterRootDir.path, - ); - - if (exitCode != 0) { - throw ToolExit( - 'Failed to compile ${hostDartFile.path}. Compiler ' - 'exited with exit code $exitCode', - exitCode: exitCode, + if (exitCode != 0) { + throw ToolExit( + 'Failed to run pub get for web_engine_tester, exit code $exitCode', + exitCode: exitCode, + ); + } + + exitCode = await runProcess( + environment.dartExecutable, + [ + 'compile', + 'js', + hostDartPath, + '-o', + '$targetFilePath.js', + ], + workingDirectory: environment.webEngineTesterRootDir.path, ); - } - // Record the timestamp to avoid rebuilding unless the file changes. - timestampFile.writeAsStringSync(timestamp); + if (exitCode != 0) { + throw ToolExit( + 'Failed to compile ${hostDartFile.path}. Compiler ' + 'exited with exit code $exitCode', + exitCode: exitCode, + ); + } + + // Record the timestamp to avoid rebuilding unless the file changes. + timestampFile.writeAsStringSync(timestamp); + } } diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 3da2980f5d85e..d59e482fe6941 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -67,6 +67,11 @@ class TestCommand extends Command with ArgUtils { 'its own, we will only copy the artifacts and not compile or run' 'the tests bundles or suites.' ) + ..addFlag( + 'profile', + help: + 'Use artifacts from the profile build instead of release.' + ) ..addFlag( 'require-skia-gold', help: @@ -345,7 +350,7 @@ class TestCommand extends Command with ArgUtils { final Set? testFiles = targetFiles.isEmpty ? null : Set.from(targetFiles); final Pipeline testPipeline = Pipeline(steps: [ if (isWatchMode) ClearTerminalScreenStep(), - if (shouldCopyArtifacts) CopyArtifactsStep(artifacts), + if (shouldCopyArtifacts) CopyArtifactsStep(artifacts, isProfile: boolArg('profile')), if (shouldCompile) for (final TestBundle bundle in bundles) CompileBundleStep( From 1071c87e8b18095d53666c19b0583d9224339fce Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 12:36:17 -0700 Subject: [PATCH 26/44] Remove duplicated build step. --- ci/builders/linux_web_engine.json | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index f5777593bf20a..51af6cd30132f 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -60,23 +60,7 @@ "scripts": [ "flutter/lib/web_ui/dev/felt" ] - } - ] - }, - "tests": [] - }, - { - "archives": [], - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false - }, - "name": "web_tests", - "generators": { - "tasks": [ + }, { "name": "compile web_tests", "parameters": [ @@ -88,9 +72,9 @@ ] } ] - } + }, + "tests": [] } - ], "generators": {}, "tests": [ From 5f5ff75aeca7d433c1dd29429a0d44087c4b493c Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 13:09:21 -0700 Subject: [PATCH 27/44] Add new fields for the v2 tests. --- ci/builders/linux_web_engine.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 51af6cd30132f..6ba2a9c11fe1c 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -84,6 +84,18 @@ "device_type=none", "os=Linux" ], + "dependencies": ["wasm_release", "web_tests"], + "test_dependencies": [ + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + }, + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "recipe": "engine_v2/tester_engine", "parameters": [ "test", "--run", From 0cc002ec24605b2843053ec44f2d534ec5c90d9e Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 13:38:21 -0700 Subject: [PATCH 28/44] Put the test invocation into `tasks` --- ci/builders/linux_web_engine.json | 38 +++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 6ba2a9c11fe1c..28e82a64a9a7d 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -38,7 +38,8 @@ { "drone_dimensions": [ "device_type=none", - "os=Linux" + "os=Linux", + "cores=32" ], "name": "web_tests", "generators": { @@ -96,20 +97,27 @@ } ], "recipe": "engine_v2/tester_engine", - "parameters": [ - "test", - "--run", - "--copy-artifacts", - "--suite=chrome-dart2js-html-engine", - "--suite=chrome-dart2js-html-html", - "--suite=chrome-dart2js-html-ui", - "--suite=chrome-dart2js-canvaskit-canvaskit", - "--suite=chrome-dart2js-canvaskit-ui", - "--suite=chrome-dart2js-skwasm-skwasm_stub", - "--suite=chrome-full-dart2js-canvaskit-canvaskit", - "--suite=chrome-full-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" + "gclient_variables": { + "download_android_deps": false + }, + "tasks": [ + { + "parameters": [ + "test", + "--run", + "--copy-artifacts", + "--suite=chrome-dart2js-html-engine", + "--suite=chrome-dart2js-html-html", + "--suite=chrome-dart2js-html-ui", + "--suite=chrome-dart2js-canvaskit-canvaskit", + "--suite=chrome-dart2js-canvaskit-ui", + "--suite=chrome-dart2js-skwasm-skwasm_stub", + "--suite=chrome-full-dart2js-canvaskit-canvaskit", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] } ] } From d5a9e7a683845dade6776e06e7e8ff31e0d12c8a Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 14:43:05 -0700 Subject: [PATCH 29/44] Name the test. --- ci/builders/linux_web_engine.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 28e82a64a9a7d..a8291a0527ea0 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -85,7 +85,7 @@ "device_type=none", "os=Linux" ], - "dependencies": ["wasm_release", "web_tests"], + "dependencies": [ "wasm_release", "web_tests" ], "test_dependencies": [ { "dependency": "chrome_and_driver", @@ -102,6 +102,7 @@ }, "tasks": [ { + "name": "linux chrome js tests", "parameters": [ "test", "--run", From d84c677196dbca147bb13504ba820591969e375f Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 15:36:20 -0700 Subject: [PATCH 30/44] Try sharding compilation and tests. --- ci/builders/linux_web_engine.json | 74 ++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index a8291a0527ea0..49b7e0b06cfee 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -41,7 +41,7 @@ "os=Linux", "cores=32" ], - "name": "web_tests", + "name": "web_tests/test_bundles/dart2js-html-engine", "generators": { "tasks": [ { @@ -66,7 +66,32 @@ "name": "compile web_tests", "parameters": [ "test", - "--compile" + "--compile", + "--bundle=dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + "tests": [] + }, + { + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "name": "web_tests/test_bundles/dart2js-canvaskit-canvaskit", + "generators": { + "tasks": [ + { + "name": "compile dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-canvaskit-canvaskit" ], "scripts": [ "flutter/lib/web_ui/dev/felt" @@ -102,19 +127,46 @@ }, "tasks": [ { - "name": "linux chrome js tests", + "name": "linux chrome-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--copy-artifacts", + "--suite=chrome-dart2js-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "linux chrome dart2js web tests", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "dependencies": [ "wasm_release", "web_tests" ], + "test_dependencies": [ + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + }, + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "recipe": "engine_v2/tester_engine", + "gclient_variables": { + "download_android_deps": false + }, + "tasks": [ + { + "name": "linux chrome-dart2js-canvaskit-canvaskit", "parameters": [ "test", "--run", "--copy-artifacts", - "--suite=chrome-dart2js-html-engine", - "--suite=chrome-dart2js-html-html", - "--suite=chrome-dart2js-html-ui", - "--suite=chrome-dart2js-canvaskit-canvaskit", - "--suite=chrome-dart2js-canvaskit-ui", - "--suite=chrome-dart2js-skwasm-skwasm_stub", - "--suite=chrome-full-dart2js-canvaskit-canvaskit", - "--suite=chrome-full-dart2js-canvaskit-ui" + "--suite=chrome-dart2js-canvaskit-canvaskit" ], "script": "flutter/lib/web_ui/dev/felt" } From bb45d118da2e7c0f674d3e317667e6aee3744174 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 15:46:09 -0700 Subject: [PATCH 31/44] Fix bundle filtering. --- lib/web_ui/dev/test_runner.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index d59e482fe6941..7ca0fc7919230 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -223,7 +223,9 @@ class TestCommand extends Command with ArgUtils { return null; } - final Iterable allBundleNames = config.testSuites.map((TestSuite suite) => suite.name); + final Iterable allBundleNames = config.testSuites.map( + (TestSuite suite) => suite.testBundle.name + ); for (final String bundleName in bundleNameArgs) { if (!allBundleNames.contains(bundleName)) { throw ToolExit('No bundle found named $bundleName'); From ee890227073eea95fa87d9afead07ca7d7a1a969 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 16:13:39 -0700 Subject: [PATCH 32/44] Try making copy artifacts a subbuild. --- ci/builders/linux_web_engine.json | 55 ++++++++++++++++--- lib/web_ui/dev/environment.dart | 7 ++- lib/web_ui/dev/steps/copy_artifacts_step.dart | 16 +++--- lib/web_ui/dev/test_platform.dart | 6 +- 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 49b7e0b06cfee..2f266b48d5689 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -33,7 +33,44 @@ "flutter/web_sdk:flutter_web_sdk_archive" ] }, - "tests": [] + "tests": [], + "builds": [ + { + "name": "web_tests/artifacts", + "generators": { + "tasks": [ + { + "name": "check licenses", + "parameters": [ + "check-licenses" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "web engine analysis", + "parameters": [ + "analyze" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "copy artifacts for web tests", + "parameters": [ + "test", + "--copy-artifacts" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + } + ] }, { "drone_dimensions": [ @@ -105,12 +142,15 @@ "generators": {}, "tests": [ { - "name": "linux chrome dart2js web tests", + "name": "linux run chrome-dart2js-html-engine suite", "drone_dimensions": [ "device_type=none", "os=Linux" ], - "dependencies": [ "wasm_release", "web_tests" ], + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundle/dart2js-html-engine" + ], "test_dependencies": [ { "dependency": "chrome_and_driver", @@ -131,7 +171,6 @@ "parameters": [ "test", "--run", - "--copy-artifacts", "--suite=chrome-dart2js-html-engine" ], "script": "flutter/lib/web_ui/dev/felt" @@ -139,12 +178,15 @@ ] }, { - "name": "linux chrome dart2js web tests", + "name": "linux run chrome-dart2js-html-engine suite", "drone_dimensions": [ "device_type=none", "os=Linux" ], - "dependencies": [ "wasm_release", "web_tests" ], + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundle/dart2js-canvaskit-canvaskit" + ], "test_dependencies": [ { "dependency": "chrome_and_driver", @@ -165,7 +207,6 @@ "parameters": [ "test", "--run", - "--copy-artifacts", "--suite=chrome-dart2js-canvaskit-canvaskit" ], "script": "flutter/lib/web_ui/dev/felt" diff --git a/lib/web_ui/dev/environment.dart b/lib/web_ui/dev/environment.dart index f1f628986423e..d9aac010b64af 100644 --- a/lib/web_ui/dev/environment.dart +++ b/lib/web_ui/dev/environment.dart @@ -148,12 +148,17 @@ class Environment { /// Path to the "build" directory, generated by "package:build_runner". /// - /// This is where compiled output goes. + /// This is where compiled test output goes. io.Directory get webUiBuildDir => io.Directory(pathlib.join( outDir.path, 'web_tests', )); + io.Directory get webTestsArtifactsDir => io.Directory(pathlib.join( + webUiBuildDir.path, + 'artifacts', + )); + /// Path to the ".dart_tool" directory, generated by various Dart tools. io.Directory get webUiDartToolDir => io.Directory(pathlib.join( webUiRootDir.path, diff --git a/lib/web_ui/dev/steps/copy_artifacts_step.dart b/lib/web_ui/dev/steps/copy_artifacts_step.dart index 50f1b0a2bfd14..25c9af656ea11 100644 --- a/lib/web_ui/dev/steps/copy_artifacts_step.dart +++ b/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -32,7 +32,7 @@ class CopyArtifactsStep implements PipelineStep { @override Future run() async { - await environment.webUiBuildDir.create(); + await environment.webTestsArtifactsDir.create(recursive: true); await copyDart2WasmTestScript(); await buildHostPage(); await copyTestFonts(); @@ -57,7 +57,7 @@ class CopyArtifactsStep implements PipelineStep { 'test_dart2wasm.js', )); final io.File targetFile = io.File(pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'test_dart2wasm.js', )); await sourceFile.copy(targetFile.path); @@ -96,7 +96,7 @@ class CopyArtifactsStep implements PipelineStep { final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile)); final io.File destinationTtf = io.File(pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'assets', 'fonts', fontFile, @@ -106,7 +106,7 @@ class CopyArtifactsStep implements PipelineStep { } final io.File fontManifestFile = io.File(pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'assets', 'FontManifest.json', )); @@ -127,7 +127,7 @@ class CopyArtifactsStep implements PipelineStep { for (final io.File imageFile in testImagesDir.listSync(recursive: true).whereType()) { final io.File destination = io.File(pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'test_images', pathlib.relative(imageFile.path, from: testImagesDir.path), )); @@ -143,7 +143,7 @@ class CopyArtifactsStep implements PipelineStep { ); final String targetDirectoryPath = pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, destinationPath, ); @@ -173,7 +173,7 @@ class CopyArtifactsStep implements PipelineStep { Future copySkwasm() async { final io.Directory targetDir = io.Directory(pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'canvaskit', )); @@ -203,7 +203,7 @@ class CopyArtifactsStep implements PipelineStep { hostDartPath, )); final String targetDirectoryPath = pathlib.join( - environment.webUiBuildDir.path, + environment.webTestsArtifactsDir.path, 'host', ); io.Directory(targetDirectoryPath).createSync(recursive: true); diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 201eccb8df90f..67bc34ba8aea7 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -77,8 +77,8 @@ class BrowserPlatform extends PlatformPlugin { // Serves files from the bundle's output build directory .add(createSimpleDirectoryHandler(getBundleBuildDirectory(suite.testBundle))) - // Serves files from the out/web_tests/ directory at the root (/) URL path. - .add(createSimpleDirectoryHandler(env.environment.webUiBuildDir)) + // Serves files from the out/web_tests/artifacts directory at the root (/) URL path. + .add(createSimpleDirectoryHandler(env.environment.webTestsArtifactsDir)) // Serves files from thes test set directory .add(createSimpleDirectoryHandler(getTestSetDirectory(suite.testBundle.testSet))) @@ -238,7 +238,7 @@ class BrowserPlatform extends PlatformPlugin { } final Directory testImageDirectory = Directory(p.join( - env.environment.webUiBuildDir.path, + env.environment.webTestsArtifactsDir.path, 'test_images', )); From 164483fe7d88055f2dd4b74249b5b9742ea22f0c Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 16:37:36 -0700 Subject: [PATCH 33/44] The main build should be `web_tests/artifacts` --- ci/builders/linux_web_engine.json | 67 ++++++++++++++----------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 2f266b48d5689..0dea4605d5ad2 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -26,7 +26,7 @@ "--runtime-mode=release", "--no-goma" ], - "name": "wasm_release", + "name": "web_tests/artifacts", "ninja": { "config": "wasm_release", "targets": [ @@ -34,43 +34,38 @@ ] }, "tests": [], - "builds": [ - { - "name": "web_tests/artifacts", - "generators": { - "tasks": [ - { - "name": "check licenses", - "parameters": [ - "check-licenses" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "web engine analysis", - "parameters": [ - "analyze" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "copy artifacts for web tests", - "parameters": [ - "test", - "--copy-artifacts" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } + "generators": { + "tasks": [ + { + "name": "check licenses", + "parameters": [ + "check-licenses" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "web engine analysis", + "parameters": [ + "analyze" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "copy artifacts for web tests", + "parameters": [ + "test", + "--copy-artifacts" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" ] } - } - ] + ] + } }, { "drone_dimensions": [ From c25b4da97fc4a57b910cafe56e5045859cf5586e Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 17:13:22 -0700 Subject: [PATCH 34/44] test_bundles, not test_bundle --- ci/builders/linux_web_engine.json | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 0dea4605d5ad2..4a15279640830 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -76,24 +76,6 @@ "name": "web_tests/test_bundles/dart2js-html-engine", "generators": { "tasks": [ - { - "name": "check licenses", - "parameters": [ - "check-licenses" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "web engine analysis", - "parameters": [ - "analyze" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, { "name": "compile web_tests", "parameters": [ @@ -144,7 +126,7 @@ ], "dependencies": [ "web_tests/artifacts", - "web_tests/test_bundle/dart2js-html-engine" + "web_tests/test_bundles/dart2js-html-engine" ], "test_dependencies": [ { @@ -180,7 +162,7 @@ ], "dependencies": [ "web_tests/artifacts", - "web_tests/test_bundle/dart2js-canvaskit-canvaskit" + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" ], "test_dependencies": [ { From 97f94591fd46ab45989cc19464cc51d9ee0e3b90 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 17:35:38 -0700 Subject: [PATCH 35/44] Generate all builder json. --- ci/builders/linux_web_engine.json | 2102 +++++++++++++++++++-- lib/web_ui/dev/generate_builder_json.dart | 184 ++ lib/web_ui/dev/test_runner.dart | 12 + 3 files changed, 2113 insertions(+), 185 deletions(-) create mode 100644 lib/web_ui/dev/generate_builder_json.dart diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 4a15279640830..4f514b6509af8 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -1,194 +1,1926 @@ { - "builds": [ + "builds": [ + { + "name": "web_tests/artifacts", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "gclient_variables": { + "download_android_deps": false, + "download_emsdk": true + }, + "gn": [ + "--web", + "--runtime-mode=release", + "--no-goma" + ], + "ninja": { + "config": "wasm_release", + "targets": [ + "flutter/web_sdk:flutter_web_sdk_archive" + ] + }, + "archives": [ { - "archives": [ - { - "name": "wasm_release", - "base_path": "out/wasm_release/zip_archives/", - "type": "gcs", - "include_paths": [ - "out/wasm_release/zip_archives/flutter-web-sdk.zip" - ], - "realm": "production" - } - ], - "drone_dimensions": [ - "device_type=none", - "os=Linux", - "cores=32" - ], - "gclient_variables": { - "download_android_deps": false, - "download_emsdk": true - }, - "gn": [ - "--web", - "--runtime-mode=release", - "--no-goma" - ], - "name": "web_tests/artifacts", - "ninja": { - "config": "wasm_release", - "targets": [ - "flutter/web_sdk:flutter_web_sdk_archive" - ] - }, - "tests": [], - "generators": { - "tasks": [ - { - "name": "check licenses", - "parameters": [ - "check-licenses" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "web engine analysis", - "parameters": [ - "analyze" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - }, - { - "name": "copy artifacts for web tests", - "parameters": [ - "test", - "--copy-artifacts" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } - ] - } + "name": "wasm_release", + "base_path": "out/wasm_release/zip_archives/", + "type": "gcs", + "include_paths": [ + "out/wasm_release/zip_archives/flutter-web-sdk.zip" + ], + "realm": "production" + } + ], + "generators": { + "tasks": [ + { + "name": "check licenses", + "parameters": [ + "check-licenses" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "web engine analysis", + "parameters": [ + "analyze" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + }, + { + "name": "copy artifacts for web tests", + "parameters": [ + "test", + "--copy-artifacts" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-html-engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-html-engine", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-html-html", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-html-html", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-html-ui", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-html-ui", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-canvaskit-canvaskit", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-canvaskit-ui", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-canvaskit-ui", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2js-skwasm-skwasm_stub", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2js-skwasm-skwasm_stub", + "parameters": [ + "test", + "--compile", + "--bundle=dart2js-skwasm-skwasm_stub" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-html-engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-html-engine", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-html-html", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-html-html", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-html-ui", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-html-ui", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-canvaskit-ui", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + }, + { + "name": "web_tests/test_bundles/dart2wasm-skwasm-ui", + "drone_dimensions": [ + "device_type=none", + "os=Linux", + "cores=32" + ], + "generators": { + "tasks": [ + { + "name": "compile bundle dart2wasm-skwasm-ui", + "parameters": [ + "test", + "--compile", + "--bundle=dart2wasm-skwasm-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } + } + ], + "tests": [ + [ + { + "name": "Linux run chrome-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "drone_dimensions": [ - "device_type=none", - "os=Linux", - "cores=32" - ], - "name": "web_tests/test_bundles/dart2js-html-engine", - "generators": { - "tasks": [ - { - "name": "compile web_tests", - "parameters": [ - "test", - "--compile", - "--bundle=dart2js-html-engine" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } - ] - }, - "tests": [] + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "drone_dimensions": [ - "device_type=none", - "os=Linux", - "cores=32" - ], - "name": "web_tests/test_bundles/dart2js-canvaskit-canvaskit", - "generators": { - "tasks": [ - { - "name": "compile dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--compile", - "--bundle=dart2js-canvaskit-canvaskit" - ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] - } - ] - }, - "tests": [] - } - ], - "generators": {}, - "tests": [ - { - "name": "linux run chrome-dart2js-html-engine suite", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-engine" - ], - "test_dependencies": [ - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - }, - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "recipe": "engine_v2/tester_engine", - "gclient_variables": { - "download_android_deps": false - }, - "tasks": [ - { - "name": "linux chrome-dart2js-html-engine", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" ] + } + ] + }, + { + "name": "Linux run chrome-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "linux run chrome-dart2js-html-engine suite", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - }, - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "recipe": "engine_v2/tester_engine", - "gclient_variables": { - "download_android_deps": false - }, - "tasks": [ - { - "name": "linux chrome-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" ] - } + } + ] + }, + { + "name": "Linux run chrome-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2js-skwasm-skwasm_stub suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-skwasm-skwasm_stub", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-skwasm-skwasm_stub" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-full-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-full-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run firefox-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run firefox-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-skwasm-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-skwasm-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-skwasm-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-skwasm-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-full-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Linux run chrome-full-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "MacOS run safari-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "MacOS run safari-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2js-skwasm-skwasm_stub suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-skwasm-skwasm_stub", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-skwasm-skwasm_stub" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-full-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-full-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-engine" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-html" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-skwasm-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-skwasm-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-skwasm-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-skwasm-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-full-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + }, + { + "name": "Windows run chrome-full-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + }, + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-ui" + ], + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] + } + ] + } ] + ] } diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart new file mode 100644 index 0000000000000..406cdeacc823f --- /dev/null +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -0,0 +1,184 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; + +import 'felt_config.dart'; + +String generateBuilderJson(FeltConfig config) { + final Map outputJson = { + 'builds': [ + _getArtifactBuildStep(), + for (final TestBundle bundle in config.testBundles) + _getBundleBuildStep(bundle), + ], + 'tests': [ + _getAllTestSteps(config.testSuites) + ] + }; + return const JsonEncoder.withIndent(' ').convert(outputJson); +} + +Map _getArtifactBuildStep() { + return { + 'name': 'web_tests/artifacts', + 'drone_dimensions': [ + 'device_type=none', + 'os=Linux', + 'cores=32' + ], + 'gclient_variables': { + 'download_android_deps': false, + 'download_emsdk': true, + }, + 'gn': [ + '--web', + '--runtime-mode=release', + '--no-goma', + ], + 'ninja': { + 'config': 'wasm_release', + 'targets': [ + 'flutter/web_sdk:flutter_web_sdk_archive' + ] + }, + 'archives': [ + { + 'name': 'wasm_release', + 'base_path': 'out/wasm_release/zip_archives/', + 'type': 'gcs', + 'include_paths': [ + 'out/wasm_release/zip_archives/flutter-web-sdk.zip' + ], + 'realm': 'production', + } + ], + 'generators': { + 'tasks': [ + { + 'name': 'check licenses', + 'parameters': [ + 'check-licenses' + ], + 'scripts': [ + 'flutter/lib/web_ui/dev/felt', + ] + }, + { + 'name': 'web engine analysis', + 'parameters': [ + 'analyze' + ], + 'scripts': [ + 'flutter/lib/web_ui/dev/felt', + ] + }, + { + 'name': 'copy artifacts for web tests', + 'parameters': [ + 'test', + '--copy-artifacts', + ], + 'scripts': [ + 'flutter/lib/web_ui/dev/felt', + ] + }, + ] + } + }; +} + +Map _getBundleBuildStep(TestBundle bundle) { + return { + 'name': 'web_tests/test_bundles/${bundle.name}', + 'drone_dimensions': [ + 'device_type=none', + 'os=Linux', + 'cores=32', + ], + 'generators': { + 'tasks': [ + { + 'name': 'compile bundle ${bundle.name}', + 'parameters': [ + 'test', + '--compile', + '--bundle=${bundle.name}', + ], + 'scripts': [ + 'flutter/lib/web_ui/dev/felt', + ] + } + ] + } + }; +} + +Iterable _getAllTestSteps(List suites) { + return [ + ..._getTestStepsForPlatform(suites, 'Linux', { + BrowserName.chrome, + BrowserName.firefox, + }), + ..._getTestStepsForPlatform(suites, 'MacOS', { + BrowserName.safari, + }), + ..._getTestStepsForPlatform(suites, 'Windows', { + BrowserName.chrome, + }), + ]; +} + +Iterable _getTestStepsForPlatform( + List suites, + String platform, + Set browsers) { + return suites + .where((TestSuite suite) => browsers.contains(suite.runConfig.browser)) + .map((TestSuite suite) => { + 'name': '$platform run ${suite.name} suite', + 'recipe': 'engine_v2/tester_engine', + 'drone_dimensions': [ + 'device_type=none', + 'os=$platform', + ], + 'gclient_variables': { + 'download_android_deps': false, + }, + 'dependencies': [ + 'web_tests/artifacts', + 'web_tests/test_bundles/${suite.testBundle.name}', + ], + 'test_dependencies': [ + { + 'dependency': 'goldctl', + 'version': 'git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603', + }, + if (suite.runConfig.browser == BrowserName.chrome) + { + 'dependency': 'chrome_and_driver', + 'version': 'version:111.0', + }, + if (suite.runConfig.browser == BrowserName.firefox) + { + 'dependency': 'firefox', + 'version': 'version:106.0', + } + ], + 'tasks': [ + { + 'name': 'run suite ${suite.name}', + 'parameters': [ + 'test', + '--run', + '--suite=${suite.name}' + ], + 'scripts': [ + 'flutter/lib/web_ui/dev/felt', + ] + } + ] + } + ); +} diff --git a/lib/web_ui/dev/test_runner.dart b/lib/web_ui/dev/test_runner.dart index 7ca0fc7919230..83d9da6c3f8b6 100644 --- a/lib/web_ui/dev/test_runner.dart +++ b/lib/web_ui/dev/test_runner.dart @@ -13,6 +13,7 @@ import 'package:watcher/src/watch_event.dart'; import 'environment.dart'; import 'exceptions.dart'; import 'felt_config.dart'; +import 'generate_builder_json.dart'; import 'pipeline.dart'; import 'steps/compile_bundle_step.dart'; import 'steps/copy_artifacts_step.dart'; @@ -48,6 +49,13 @@ class TestCommand extends Command with ArgUtils { 'will be run as part of this invocation, without actually ' 'compiling or running them.' ) + ..addFlag( + 'generate-builder-json', + help: + 'Generates JSON for the engine_v2 builders to build and copy all' + 'artifacts, compile all test bundles, and run all test suites on' + 'all platforms.' + ) ..addFlag( 'compile', help: @@ -315,6 +323,10 @@ class TestCommand extends Command with ArgUtils { final List filteredSuites = _filterTestSuites(); final List bundles = _filterBundlesForSuites(filteredSuites); final ArtifactDependencies artifacts = _artifactsForSuites(filteredSuites); + if (boolArg('generate-builder-json')) { + print(generateBuilderJson(config)); + return true; + } if (isList || isVerbose) { print('Suites:'); for (final TestSuite suite in filteredSuites) { From a8bc5c4f93c744274c4e0d8cc12a5156fc66c364 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 17:53:02 -0700 Subject: [PATCH 36/44] Specify an empty tests list. --- lib/web_ui/dev/generate_builder_json.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index 406cdeacc823f..42de134c452ba 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -85,7 +85,8 @@ Map _getArtifactBuildStep() { ] }, ] - } + }, + 'tests': [], }; } @@ -111,7 +112,8 @@ Map _getBundleBuildStep(TestBundle bundle) { ] } ] - } + }, + 'tests': [], }; } From 442034dbe47e5438ab504e560acee2e2bf65f325 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 17:54:42 -0700 Subject: [PATCH 37/44] Generate the builder json again. --- ci/builders/linux_web_engine.json | 39 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 4f514b6509af8..11b75f9b8c616 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -64,7 +64,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-html-engine", @@ -87,7 +88,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-html-html", @@ -110,7 +112,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-html-ui", @@ -133,7 +136,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-canvaskit-canvaskit", @@ -156,7 +160,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-canvaskit-ui", @@ -179,7 +184,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2js-skwasm-skwasm_stub", @@ -202,7 +208,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-html-engine", @@ -225,7 +232,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-html-html", @@ -248,7 +256,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-html-ui", @@ -271,7 +280,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit", @@ -294,7 +304,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-canvaskit-ui", @@ -317,7 +328,8 @@ ] } ] - } + }, + "tests": [] }, { "name": "web_tests/test_bundles/dart2wasm-skwasm-ui", @@ -340,7 +352,8 @@ ] } ] - } + }, + "tests": [] } ], "tests": [ From eb1e3ec1f8f292bf74dd417c7d7f5a524856087d Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 18:17:40 -0700 Subject: [PATCH 38/44] script, not scripts. --- ci/builders/linux_web_engine.json | 228 ++++++---------------- lib/web_ui/dev/generate_builder_json.dart | 21 +- 2 files changed, 63 insertions(+), 186 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 11b75f9b8c616..8b9dd8450bba0 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -40,18 +40,14 @@ "parameters": [ "check-licenses" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" }, { "name": "web engine analysis", "parameters": [ "analyze" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" }, { "name": "copy artifacts for web tests", @@ -59,9 +55,7 @@ "test", "--copy-artifacts" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -83,9 +77,7 @@ "--compile", "--bundle=dart2js-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -107,9 +99,7 @@ "--compile", "--bundle=dart2js-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -131,9 +121,7 @@ "--compile", "--bundle=dart2js-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -155,9 +143,7 @@ "--compile", "--bundle=dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -179,9 +165,7 @@ "--compile", "--bundle=dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -203,9 +187,7 @@ "--compile", "--bundle=dart2js-skwasm-skwasm_stub" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -227,9 +209,7 @@ "--compile", "--bundle=dart2wasm-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -251,9 +231,7 @@ "--compile", "--bundle=dart2wasm-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -275,9 +253,7 @@ "--compile", "--bundle=dart2wasm-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -299,9 +275,7 @@ "--compile", "--bundle=dart2wasm-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -323,9 +297,7 @@ "--compile", "--bundle=dart2wasm-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -347,9 +319,7 @@ "--compile", "--bundle=dart2wasm-skwasm-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -390,9 +360,7 @@ "--run", "--suite=chrome-dart2js-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -428,9 +396,7 @@ "--run", "--suite=chrome-dart2js-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -466,9 +432,7 @@ "--run", "--suite=chrome-dart2js-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -504,9 +468,7 @@ "--run", "--suite=chrome-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -542,9 +504,7 @@ "--run", "--suite=chrome-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -580,9 +540,7 @@ "--run", "--suite=chrome-dart2js-skwasm-skwasm_stub" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -618,9 +576,7 @@ "--run", "--suite=chrome-full-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -656,9 +612,7 @@ "--run", "--suite=chrome-full-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -694,9 +648,7 @@ "--run", "--suite=firefox-dart2js-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -732,9 +684,7 @@ "--run", "--suite=firefox-dart2js-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -770,9 +720,7 @@ "--run", "--suite=firefox-dart2js-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -808,9 +756,7 @@ "--run", "--suite=firefox-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -846,9 +792,7 @@ "--run", "--suite=firefox-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -884,9 +828,7 @@ "--run", "--suite=chrome-dart2wasm-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -922,9 +864,7 @@ "--run", "--suite=chrome-dart2wasm-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -960,9 +900,7 @@ "--run", "--suite=chrome-dart2wasm-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -998,9 +936,7 @@ "--run", "--suite=chrome-dart2wasm-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1036,9 +972,7 @@ "--run", "--suite=chrome-dart2wasm-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1074,9 +1008,7 @@ "--run", "--suite=chrome-dart2wasm-skwasm-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1112,9 +1044,7 @@ "--run", "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1150,9 +1080,7 @@ "--run", "--suite=chrome-full-dart2wasm-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1184,9 +1112,7 @@ "--run", "--suite=safari-dart2js-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1218,9 +1144,7 @@ "--run", "--suite=safari-dart2js-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1252,9 +1176,7 @@ "--run", "--suite=safari-dart2js-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1286,9 +1208,7 @@ "--run", "--suite=safari-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1320,9 +1240,7 @@ "--run", "--suite=safari-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1358,9 +1276,7 @@ "--run", "--suite=chrome-dart2js-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1396,9 +1312,7 @@ "--run", "--suite=chrome-dart2js-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1434,9 +1348,7 @@ "--run", "--suite=chrome-dart2js-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1472,9 +1384,7 @@ "--run", "--suite=chrome-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1510,9 +1420,7 @@ "--run", "--suite=chrome-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1548,9 +1456,7 @@ "--run", "--suite=chrome-dart2js-skwasm-skwasm_stub" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1586,9 +1492,7 @@ "--run", "--suite=chrome-full-dart2js-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1624,9 +1528,7 @@ "--run", "--suite=chrome-full-dart2js-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1662,9 +1564,7 @@ "--run", "--suite=chrome-dart2wasm-html-engine" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1700,9 +1600,7 @@ "--run", "--suite=chrome-dart2wasm-html-html" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1738,9 +1636,7 @@ "--run", "--suite=chrome-dart2wasm-html-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1776,9 +1672,7 @@ "--run", "--suite=chrome-dart2wasm-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1814,9 +1708,7 @@ "--run", "--suite=chrome-dart2wasm-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1852,9 +1744,7 @@ "--run", "--suite=chrome-dart2wasm-skwasm-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1890,9 +1780,7 @@ "--run", "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] }, @@ -1928,9 +1816,7 @@ "--run", "--suite=chrome-full-dart2wasm-canvaskit-ui" ], - "scripts": [ - "flutter/lib/web_ui/dev/felt" - ] + "script": "flutter/lib/web_ui/dev/felt" } ] } diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index 42de134c452ba..e57e15cc4609c 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -61,18 +61,15 @@ Map _getArtifactBuildStep() { 'parameters': [ 'check-licenses' ], - 'scripts': [ - 'flutter/lib/web_ui/dev/felt', - ] + 'script': 'flutter/lib/web_ui/dev/felt', + }, { 'name': 'web engine analysis', 'parameters': [ 'analyze' ], - 'scripts': [ - 'flutter/lib/web_ui/dev/felt', - ] + 'script': 'flutter/lib/web_ui/dev/felt', }, { 'name': 'copy artifacts for web tests', @@ -80,9 +77,7 @@ Map _getArtifactBuildStep() { 'test', '--copy-artifacts', ], - 'scripts': [ - 'flutter/lib/web_ui/dev/felt', - ] + 'script': 'flutter/lib/web_ui/dev/felt', }, ] }, @@ -107,9 +102,7 @@ Map _getBundleBuildStep(TestBundle bundle) { '--compile', '--bundle=${bundle.name}', ], - 'scripts': [ - 'flutter/lib/web_ui/dev/felt', - ] + 'script': 'flutter/lib/web_ui/dev/felt', } ] }, @@ -176,9 +169,7 @@ Iterable _getTestStepsForPlatform( '--run', '--suite=${suite.name}' ], - 'scripts': [ - 'flutter/lib/web_ui/dev/felt', - ] + 'script': 'flutter/lib/web_ui/dev/felt', } ] } From d25ca9ead28b8cd1b3aa06bb86882eb062f9b7cc Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 18:47:24 -0700 Subject: [PATCH 39/44] Get rid of extra array layer. --- ci/builders/linux_web_engine.json | 2830 ++++++++++----------- lib/web_ui/dev/generate_builder_json.dart | 4 +- 2 files changed, 1415 insertions(+), 1419 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 8b9dd8450bba0..b6932de865337 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -327,1499 +327,1497 @@ } ], "tests": [ - [ - { - "name": "Linux run chrome-dart2js-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false - }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-engine", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "name": "Linux run chrome-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2js-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-html", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2js-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2js-skwasm-skwasm_stub suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-skwasm-skwasm_stub", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-skwasm-skwasm_stub" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2js-skwasm-skwasm_stub suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-full-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-skwasm-skwasm_stub", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-skwasm-skwasm_stub" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-full-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-full-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-full-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run firefox-dart2js-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "firefox", - "version": "version:106.0" - } - ], - "tasks": [ - { - "name": "run suite firefox-dart2js-html-engine", - "parameters": [ - "test", - "--run", - "--suite=firefox-dart2js-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run firefox-dart2js-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "firefox", - "version": "version:106.0" - } - ], - "tasks": [ - { - "name": "run suite firefox-dart2js-html-html", - "parameters": [ - "test", - "--run", - "--suite=firefox-dart2js-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run firefox-dart2js-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "firefox", - "version": "version:106.0" - } - ], - "tasks": [ - { - "name": "run suite firefox-dart2js-html-ui", - "parameters": [ - "test", - "--run", - "--suite=firefox-dart2js-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run firefox-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run firefox-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "firefox", - "version": "version:106.0" - } - ], - "tasks": [ - { - "name": "run suite firefox-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=firefox-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run firefox-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run firefox-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "firefox", - "version": "version:106.0" - } - ], - "tasks": [ - { - "name": "run suite firefox-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=firefox-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run firefox-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-engine", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "firefox", + "version": "version:106.0" + } + ], + "tasks": [ + { + "name": "run suite firefox-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=firefox-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-html", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-dart2wasm-skwasm-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-skwasm-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-skwasm-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-skwasm-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-dart2wasm-skwasm-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-full-dart2wasm-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-skwasm-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-skwasm-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-skwasm-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-full-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Linux run chrome-full-dart2wasm-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Linux" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2wasm-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2wasm-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Linux run chrome-full-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Linux" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "MacOS run safari-dart2js-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=MacOS" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "tasks": [ - { - "name": "run suite safari-dart2js-html-engine", - "parameters": [ - "test", - "--run", - "--suite=safari-dart2js-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "MacOS run safari-dart2js-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=MacOS" - ], - "gclient_variables": { - "download_android_deps": false - }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "tasks": [ - { - "name": "run suite safari-dart2js-html-html", - "parameters": [ - "test", - "--run", - "--suite=safari-dart2js-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "MacOS run safari-dart2js-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=MacOS" - ], - "gclient_variables": { - "download_android_deps": false - }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "tasks": [ - { - "name": "run suite safari-dart2js-html-ui", - "parameters": [ - "test", - "--run", - "--suite=safari-dart2js-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "MacOS run safari-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "MacOS run safari-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=MacOS" - ], - "gclient_variables": { - "download_android_deps": false - }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "tasks": [ - { - "name": "run suite safari-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=safari-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "MacOS run safari-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "MacOS run safari-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=MacOS" - ], - "gclient_variables": { - "download_android_deps": false - }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - } - ], - "tasks": [ - { - "name": "run suite safari-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=safari-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "MacOS run safari-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=MacOS" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" + } + ], + "tasks": [ + { + "name": "run suite safari-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=safari-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false + }, + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-engine", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-html", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-html-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2js-skwasm-skwasm_stub suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2js-skwasm-skwasm_stub suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-skwasm-skwasm_stub" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2js-skwasm-skwasm_stub", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2js-skwasm-skwasm_stub" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2js-skwasm-skwasm_stub", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2js-skwasm-skwasm_stub" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-full-dart2js-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-full-dart2js-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2js-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-full-dart2js-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-full-dart2js-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2js-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2js-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2js-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2js-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2js-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2js-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-engine suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-html-engine suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-engine" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-engine" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-engine", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-engine" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-engine", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-engine" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-html suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-html-html suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-html" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-html" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-html", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-html" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-html", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-html" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-html-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-html-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-html-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-html-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-html-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-html-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-html-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-html-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-dart2wasm-skwasm-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-dart2wasm-skwasm-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-skwasm-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-skwasm-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-dart2wasm-skwasm-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-dart2wasm-skwasm-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-dart2wasm-skwasm-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-dart2wasm-skwasm-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-full-dart2wasm-canvaskit-canvaskit suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-full-dart2wasm-canvaskit-canvaskit suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-canvaskit", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-canvaskit" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + }, + { + "name": "Windows run chrome-full-dart2wasm-canvaskit-ui suite", + "recipe": "engine_v2/tester_engine", + "drone_dimensions": [ + "device_type=none", + "os=Windows" + ], + "gclient_variables": { + "download_android_deps": false }, - { - "name": "Windows run chrome-full-dart2wasm-canvaskit-ui suite", - "recipe": "engine_v2/tester_engine", - "drone_dimensions": [ - "device_type=none", - "os=Windows" - ], - "gclient_variables": { - "download_android_deps": false + "dependencies": [ + "web_tests/artifacts", + "web_tests/test_bundles/dart2wasm-canvaskit-ui" + ], + "test_dependencies": [ + { + "dependency": "goldctl", + "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" }, - "dependencies": [ - "web_tests/artifacts", - "web_tests/test_bundles/dart2wasm-canvaskit-ui" - ], - "test_dependencies": [ - { - "dependency": "goldctl", - "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603" - }, - { - "dependency": "chrome_and_driver", - "version": "version:111.0" - } - ], - "tasks": [ - { - "name": "run suite chrome-full-dart2wasm-canvaskit-ui", - "parameters": [ - "test", - "--run", - "--suite=chrome-full-dart2wasm-canvaskit-ui" - ], - "script": "flutter/lib/web_ui/dev/felt" - } - ] - } - ] + { + "dependency": "chrome_and_driver", + "version": "version:111.0" + } + ], + "tasks": [ + { + "name": "run suite chrome-full-dart2wasm-canvaskit-ui", + "parameters": [ + "test", + "--run", + "--suite=chrome-full-dart2wasm-canvaskit-ui" + ], + "script": "flutter/lib/web_ui/dev/felt" + } + ] + } ] } diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index e57e15cc4609c..cd951d6829325 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -13,9 +13,7 @@ String generateBuilderJson(FeltConfig config) { for (final TestBundle bundle in config.testBundles) _getBundleBuildStep(bundle), ], - 'tests': [ - _getAllTestSteps(config.testSuites) - ] + 'tests': _getAllTestSteps(config.testSuites) }; return const JsonEncoder.withIndent(' ').convert(outputJson); } From aed3f1bcde496fadd97d1644a9d753c70a274b5b Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 18:48:45 -0700 Subject: [PATCH 40/44] No need for empty tests array in build steps --- ci/builders/linux_web_engine.json | 39 ++++++++--------------- lib/web_ui/dev/generate_builder_json.dart | 2 -- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index b6932de865337..7fa7a37b05394 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -58,8 +58,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-html-engine", @@ -80,8 +79,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-html-html", @@ -102,8 +100,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-html-ui", @@ -124,8 +121,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-canvaskit-canvaskit", @@ -146,8 +142,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-canvaskit-ui", @@ -168,8 +163,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2js-skwasm-skwasm_stub", @@ -190,8 +184,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-html-engine", @@ -212,8 +205,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-html-html", @@ -234,8 +226,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-html-ui", @@ -256,8 +247,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-canvaskit-canvaskit", @@ -278,8 +268,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-canvaskit-ui", @@ -300,8 +289,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } }, { "name": "web_tests/test_bundles/dart2wasm-skwasm-ui", @@ -322,8 +310,7 @@ "script": "flutter/lib/web_ui/dev/felt" } ] - }, - "tests": [] + } } ], "tests": [ diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index cd951d6829325..e6f351820aba3 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -79,7 +79,6 @@ Map _getArtifactBuildStep() { }, ] }, - 'tests': [], }; } @@ -104,7 +103,6 @@ Map _getBundleBuildStep(TestBundle bundle) { } ] }, - 'tests': [], }; } From 2271295185630aaf1f2d9535e0cc8b660056be77 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 19:27:50 -0700 Subject: [PATCH 41/44] It's `script` for tests, but `scripts` for generators. --- ci/builders/linux_web_engine.json | 60 +++++++++++++++++------ lib/web_ui/dev/generate_builder_json.dart | 8 +-- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 7fa7a37b05394..90170ea660000 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -40,14 +40,18 @@ "parameters": [ "check-licenses" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] }, { "name": "web engine analysis", "parameters": [ "analyze" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] }, { "name": "copy artifacts for web tests", @@ -55,7 +59,9 @@ "test", "--copy-artifacts" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -76,7 +82,9 @@ "--compile", "--bundle=dart2js-html-engine" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -97,7 +105,9 @@ "--compile", "--bundle=dart2js-html-html" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -118,7 +128,9 @@ "--compile", "--bundle=dart2js-html-ui" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -139,7 +151,9 @@ "--compile", "--bundle=dart2js-canvaskit-canvaskit" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -160,7 +174,9 @@ "--compile", "--bundle=dart2js-canvaskit-ui" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -181,7 +197,9 @@ "--compile", "--bundle=dart2js-skwasm-skwasm_stub" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -202,7 +220,9 @@ "--compile", "--bundle=dart2wasm-html-engine" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -223,7 +243,9 @@ "--compile", "--bundle=dart2wasm-html-html" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -244,7 +266,9 @@ "--compile", "--bundle=dart2wasm-html-ui" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -265,7 +289,9 @@ "--compile", "--bundle=dart2wasm-canvaskit-canvaskit" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -286,7 +312,9 @@ "--compile", "--bundle=dart2wasm-canvaskit-ui" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } @@ -307,7 +335,9 @@ "--compile", "--bundle=dart2wasm-skwasm-ui" ], - "script": "flutter/lib/web_ui/dev/felt" + "scripts": [ + "flutter/lib/web_ui/dev/felt" + ] } ] } diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index e6f351820aba3..0a125520dc7b5 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -59,7 +59,7 @@ Map _getArtifactBuildStep() { 'parameters': [ 'check-licenses' ], - 'script': 'flutter/lib/web_ui/dev/felt', + 'scripts': [ 'flutter/lib/web_ui/dev/felt' ], }, { @@ -67,7 +67,7 @@ Map _getArtifactBuildStep() { 'parameters': [ 'analyze' ], - 'script': 'flutter/lib/web_ui/dev/felt', + 'scripts': [ 'flutter/lib/web_ui/dev/felt' ], }, { 'name': 'copy artifacts for web tests', @@ -75,7 +75,7 @@ Map _getArtifactBuildStep() { 'test', '--copy-artifacts', ], - 'script': 'flutter/lib/web_ui/dev/felt', + 'scripts': [ 'flutter/lib/web_ui/dev/felt' ], }, ] }, @@ -99,7 +99,7 @@ Map _getBundleBuildStep(TestBundle bundle) { '--compile', '--bundle=${bundle.name}', ], - 'script': 'flutter/lib/web_ui/dev/felt', + 'scripts': [ 'flutter/lib/web_ui/dev/felt' ], } ] }, From d4a7f5adb05e8648fe673c0f6d6aa3b30f254c45 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Thu, 23 Mar 2023 19:42:47 -0700 Subject: [PATCH 42/44] Mac, not MacOS --- ci/builders/linux_web_engine.json | 20 ++++++++++---------- lib/web_ui/dev/generate_builder_json.dart | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ci/builders/linux_web_engine.json b/ci/builders/linux_web_engine.json index 90170ea660000..351a6777614e3 100644 --- a/ci/builders/linux_web_engine.json +++ b/ci/builders/linux_web_engine.json @@ -1101,11 +1101,11 @@ ] }, { - "name": "MacOS run safari-dart2js-html-engine suite", + "name": "Mac run safari-dart2js-html-engine suite", "recipe": "engine_v2/tester_engine", "drone_dimensions": [ "device_type=none", - "os=MacOS" + "os=Mac" ], "gclient_variables": { "download_android_deps": false @@ -1133,11 +1133,11 @@ ] }, { - "name": "MacOS run safari-dart2js-html-html suite", + "name": "Mac run safari-dart2js-html-html suite", "recipe": "engine_v2/tester_engine", "drone_dimensions": [ "device_type=none", - "os=MacOS" + "os=Mac" ], "gclient_variables": { "download_android_deps": false @@ -1165,11 +1165,11 @@ ] }, { - "name": "MacOS run safari-dart2js-html-ui suite", + "name": "Mac run safari-dart2js-html-ui suite", "recipe": "engine_v2/tester_engine", "drone_dimensions": [ "device_type=none", - "os=MacOS" + "os=Mac" ], "gclient_variables": { "download_android_deps": false @@ -1197,11 +1197,11 @@ ] }, { - "name": "MacOS run safari-dart2js-canvaskit-canvaskit suite", + "name": "Mac run safari-dart2js-canvaskit-canvaskit suite", "recipe": "engine_v2/tester_engine", "drone_dimensions": [ "device_type=none", - "os=MacOS" + "os=Mac" ], "gclient_variables": { "download_android_deps": false @@ -1229,11 +1229,11 @@ ] }, { - "name": "MacOS run safari-dart2js-canvaskit-ui suite", + "name": "Mac run safari-dart2js-canvaskit-ui suite", "recipe": "engine_v2/tester_engine", "drone_dimensions": [ "device_type=none", - "os=MacOS" + "os=Mac" ], "gclient_variables": { "download_android_deps": false diff --git a/lib/web_ui/dev/generate_builder_json.dart b/lib/web_ui/dev/generate_builder_json.dart index 0a125520dc7b5..719d088824f0f 100644 --- a/lib/web_ui/dev/generate_builder_json.dart +++ b/lib/web_ui/dev/generate_builder_json.dart @@ -112,7 +112,7 @@ Iterable _getAllTestSteps(List suites) { BrowserName.chrome, BrowserName.firefox, }), - ..._getTestStepsForPlatform(suites, 'MacOS', { + ..._getTestStepsForPlatform(suites, 'Mac', { BrowserName.safari, }), ..._getTestStepsForPlatform(suites, 'Windows', { From 4ed8d434e46ffcb36ed51022dc009699c5de85c8 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Mon, 27 Mar 2023 14:22:35 -0700 Subject: [PATCH 43/44] Yegor's comments. --- lib/web_ui/dev/felt_config.dart | 11 ++---- lib/web_ui/dev/pipeline.dart | 39 +++++++++++++------ lib/web_ui/dev/steps/compile_bundle_step.dart | 19 ++++++++- lib/web_ui/test/felt_config.yaml | 2 + 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/lib/web_ui/dev/felt_config.dart b/lib/web_ui/dev/felt_config.dart index f6e1db70ac415..e3725a4ce1d01 100644 --- a/lib/web_ui/dev/felt_config.dart +++ b/lib/web_ui/dev/felt_config.dart @@ -66,10 +66,10 @@ class ArtifactDependencies { required this.skwasm }); - ArtifactDependencies.none() - : canvasKit = false - , canvasKitChromium = false - , skwasm = false; + ArtifactDependencies.none() : + canvasKit = false, + canvasKitChromium = false, + skwasm = false; final bool canvasKit; final bool canvasKitChromium; final bool skwasm; @@ -214,19 +214,16 @@ class FeltConfig { throw AssertionError('Artifact dep $dep listed twice in suite $name.'); } canvasKit = true; - break; case 'canvaskit_chromium': if (canvasKitChromium) { throw AssertionError('Artifact dep $dep listed twice in suite $name.'); } canvasKitChromium = true; - break; case 'skwasm': if (skwasm) { throw AssertionError('Artifact dep $dep listed twice in suite $name.'); } skwasm = true; - break; default: throw AssertionError('Unrecognized artifact dependency: $dep'); } diff --git a/lib/web_ui/dev/pipeline.dart b/lib/web_ui/dev/pipeline.dart index 8a7b286acbefc..e8e8a4d2e7f7b 100644 --- a/lib/web_ui/dev/pipeline.dart +++ b/lib/web_ui/dev/pipeline.dart @@ -8,6 +8,7 @@ import 'dart:io' as io; import 'package:path/path.dart' as path; import 'package:watcher/watcher.dart'; +import 'exceptions.dart'; import 'utils.dart'; /// Describes what [Pipeline] is currently doing. @@ -87,6 +88,13 @@ abstract class ProcessStep implements PipelineStep { } } +class _PipelineStepFailure { + _PipelineStepFailure(this.step, this.error); + + final PipelineStep step; + final Object error; +} + /// Executes a sequence of asynchronous tasks, typically as part of a build/test /// process. /// @@ -112,27 +120,34 @@ class Pipeline { /// /// Returns a future that resolves after all steps have been performed. /// - /// The future resolves to an error as soon as any of the steps fails. + /// If any steps fail, the pipeline attempts to continue to subsequent steps, + /// but will fail at the end. /// /// The pipeline may be interrupted by calling [stop] before the future /// resolves. Future run() async { _status = PipelineStatus.started; - try { - for (final PipelineStep step in steps) { - if (status != PipelineStatus.started) { - break; - } - _currentStep = step; - _currentStepFuture = step.run(); + final List<_PipelineStepFailure> failures = <_PipelineStepFailure>[]; + for (final PipelineStep step in steps) { + _currentStep = step; + _currentStepFuture = step.run(); + try { await _currentStepFuture; + } catch (e) { + failures.add(_PipelineStepFailure(step, e)); + } finally { + _currentStep = null; } + } + if (failures.isEmpty) { _status = PipelineStatus.done; - } catch (_) { + } else { _status = PipelineStatus.error; - rethrow; - } finally { - _currentStep = null; + print('Pipeline experienced the following failures:'); + for (final _PipelineStepFailure failure in failures) { + print(' "${failure.step.description}": ${failure.error}'); + } + throw ToolExit('Test pipeline failed.'); } } diff --git a/lib/web_ui/dev/steps/compile_bundle_step.dart b/lib/web_ui/dev/steps/compile_bundle_step.dart index 2e62081bd5221..16ab5e2310b1f 100644 --- a/lib/web_ui/dev/steps/compile_bundle_step.dart +++ b/lib/web_ui/dev/steps/compile_bundle_step.dart @@ -131,7 +131,22 @@ class CompileBundleStep implements PipelineStep { 'results.json', )); outputResultsFile.writeAsStringSync(resultsJson); - print('\rCompleted compilation of ${bundle.name.ansiMagenta} in ${stopwatch.elapsedMilliseconds}ms.'.padRight(82)); + final List failedFiles = []; + results.forEach((String fileName, CompileResult result) { + if (result == CompileResult.compilationFailure) { + failedFiles.add(fileName); + } + }); + if (failedFiles.isEmpty) { + print('\rCompleted compilation of ${bundle.name.ansiMagenta} in ${stopwatch.elapsedMilliseconds}ms.'.padRight(82)); + } else { + print('\rThe bundle ${bundle.name.ansiMagenta} compiled with some failures in ${stopwatch.elapsedMilliseconds}ms.'); + print('Compilation failures:'); + for (final String fileName in failedFiles) { + print(' $fileName'); + } + throw ToolExit('Failed to compile ${bundle.name.ansiMagenta}.'); + } } } @@ -210,6 +225,7 @@ class Dart2JSCompiler extends TestCompiler { environment.dartExecutable, arguments, workingDirectory: inputTestSetDirectory.path, + failureIsSuccess: true, evalOutput: !isVerbose, ); final int exitCode = await process.wait(); @@ -276,6 +292,7 @@ class Dart2WasmCompiler extends TestCompiler { environment.dartAotRuntimePath, arguments, workingDirectory: inputTestSetDirectory.path, + failureIsSuccess: true, evalOutput: true, ); final int exitCode = await process.wait(); diff --git a/lib/web_ui/test/felt_config.yaml b/lib/web_ui/test/felt_config.yaml index d7ce8dfb68972..6f19e4913e9e2 100644 --- a/lib/web_ui/test/felt_config.yaml +++ b/lib/web_ui/test/felt_config.yaml @@ -1,3 +1,5 @@ +# See the `README.md` in this directory for documentation on the structure of +# this file. compile-configs: - name: dart2js-html compiler: dart2js From ba83669072b333ee987a3b88c1ff178327a3688c Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Mon, 27 Mar 2023 15:03:09 -0700 Subject: [PATCH 44/44] Add back screenshot logging under verbose flag. --- lib/web_ui/dev/test_platform.dart | 1 + web_sdk/web_test_utils/lib/image_compare.dart | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/web_ui/dev/test_platform.dart b/lib/web_ui/dev/test_platform.dart index 194e6f65b5de9..24b55c63dbecf 100644 --- a/lib/web_ui/dev/test_platform.dart +++ b/lib/web_ui/dev/test_platform.dart @@ -431,6 +431,7 @@ class BrowserPlatform extends PlatformPlugin { filename, skiaClient, isCanvaskitTest: isCanvaskitTest, + verbose: isVerbose, ); } diff --git a/web_sdk/web_test_utils/lib/image_compare.dart b/web_sdk/web_test_utils/lib/image_compare.dart index af7b5f39e03a6..4212ae642ae46 100644 --- a/web_sdk/web_test_utils/lib/image_compare.dart +++ b/web_sdk/web_test_utils/lib/image_compare.dart @@ -24,6 +24,7 @@ Future compareImage( String filename, SkiaGoldClient? skiaClient, { required bool isCanvaskitTest, + required bool verbose, }) async { if (skiaClient == null) { return 'OK'; @@ -73,7 +74,9 @@ Future compareImage( } // TODO(mdebbar): Use the Gold tool to locally diff the golden. - + if (verbose) { + print('Screenshot generated: file://$screenshotPath'); // ignore: avoid_print + } return 'OK'; }