diff --git a/script/tool/lib/src/common/core.dart b/script/tool/lib/src/common/core.dart index c75432f98c25..520685f31fc9 100644 --- a/script/tool/lib/src/common/core.dart +++ b/script/tool/lib/src/common/core.dart @@ -37,6 +37,9 @@ const String kEnableExperiment = 'enable-experiment'; /// land (e.g., dependency overrides in federated plugin combination PRs). const String kDoNotLandWarning = 'DO NOT MERGE'; +/// Key for enabling web WASM compilation +const String kWebWasmFlag = 'wasm'; + /// Target platforms supported by Flutter. // ignore: public_member_api_docs enum FlutterPlatform { android, ios, linux, macos, web, windows } diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 984bff7c8bf7..a5ddd3bd4a9d 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -13,7 +13,7 @@ import 'common/package_looping_command.dart'; import 'common/plugin_utils.dart'; import 'common/repository_package.dart'; -const int _exitNoPlatformFlags = 2; +const int _exitInvalidArgs = 2; const int _exitNoAvailableDevice = 3; // From https://flutter.dev/to/integration-test-on-web @@ -40,6 +40,8 @@ class DriveExamplesCommand extends PackageLoopingCommand { help: 'Runs the web implementation of the examples'); argParser.addFlag(platformWindows, help: 'Runs the Windows implementation of the examples'); + argParser.addFlag(kWebWasmFlag, + help: 'Compile to WebAssembly rather than JavaScript'); argParser.addOption( kEnableExperiment, defaultsTo: '', @@ -84,7 +86,7 @@ class DriveExamplesCommand extends PackageLoopingCommand { printError( 'Exactly one of ${platformSwitches.map((String platform) => '--$platform').join(', ')} ' 'must be specified.'); - throw ToolExit(_exitNoPlatformFlags); + throw ToolExit(_exitInvalidArgs); } String? androidDevice; @@ -107,22 +109,31 @@ class DriveExamplesCommand extends PackageLoopingCommand { iOSDevice = devices.first; } + final bool useWasm = getBoolArg(kWebWasmFlag); + final bool hasPlatformWeb = getBoolArg(platformWeb); + if (useWasm && !hasPlatformWeb) { + printError('--wasm is only supported on the web platform'); + throw ToolExit(_exitInvalidArgs); + } + _targetDeviceFlags = >{ if (getBoolArg(platformAndroid)) platformAndroid: ['-d', androidDevice!], if (getBoolArg(platformIOS)) platformIOS: ['-d', iOSDevice!], if (getBoolArg(platformLinux)) platformLinux: ['-d', 'linux'], if (getBoolArg(platformMacOS)) platformMacOS: ['-d', 'macos'], - if (getBoolArg(platformWeb)) + if (hasPlatformWeb) platformWeb: [ '-d', 'web-server', '--web-port=7357', '--browser-name=chrome', + if (useWasm) + '--wasm' // TODO(dit): Clean this up, https://github.com/flutter/flutter/issues/151869 - if (platform.environment['CHANNEL']?.toLowerCase() == 'master') - '--web-renderer=canvaskit', - if (platform.environment['CHANNEL']?.toLowerCase() != 'master') + else if (platform.environment['CHANNEL']?.toLowerCase() == 'master') + '--web-renderer=canvaskit' + else '--web-renderer=html', if (platform.environment.containsKey('CHROME_EXECUTABLE')) '--chrome-binary=${platform.environment['CHROME_EXECUTABLE']}', diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 4484b7099ae9..6bbd5e301ad5 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -89,6 +89,24 @@ void main() { ); }); + test('fails if wasm flag is present but not web platform', () async { + setMockFlutterDevicesOutput(); + Error? commandError; + final List output = await runCapturingPrint( + runner, ['drive-examples', '--android', '--wasm'], + errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('--wasm is only supported on the web platform'), + ]), + ); + }); + test('fails if multiple platforms are provided', () async { setMockFlutterDevicesOutput(); Error? commandError; @@ -691,6 +709,57 @@ void main() { ])); }); + test('drives a web plugin compiled to WASM', () async { + final RepositoryPackage plugin = createFakePlugin( + 'plugin', + packagesDir, + extraFiles: [ + 'example/integration_test/plugin_test.dart', + 'example/test_driver/integration_test.dart', + 'example/web/index.html', + ], + platformSupport: { + platformWeb: const PlatformDetails(PlatformSupport.inline), + }, + ); + + final Directory pluginExampleDirectory = getExampleDir(plugin); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--web', + '--wasm', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running for plugin'), + contains('No issues found!'), + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + const [ + 'drive', + '-d', + 'web-server', + '--web-port=7357', + '--browser-name=chrome', + '--wasm', + '--driver', + 'test_driver/integration_test.dart', + '--target', + 'integration_test/plugin_test.dart', + ], + pluginExampleDirectory.path), + ])); + }); + // TODO(dit): Clean this up, https://github.com/flutter/flutter/issues/151869 test('drives a web plugin (html renderer in stable)', () async { // Override the platform to simulate CHANNEL: stable