Support flutter run --wasm
and flutter drive --wasm
. (#146231)
This adds support for adding the `--wasm` flag to `flutter run` and `flutter drive` * Emits errors if you attempt to use the skwasm renderer without the `--wasm` flag * Emits errors if you try to use `--wasm` when not using a web device * Uses the skwasm renderer by default if you pass `--wasm` and no `--web-renderer`
This commit is contained in:
parent
e2c812155c
commit
9973673752
@ -32,6 +32,7 @@ Future<void> webLongRunningTestsRunner(String flutterRoot) async {
|
|||||||
target: path.join('test_driver', 'failure.dart'),
|
target: path.join('test_driver', 'failure.dart'),
|
||||||
buildMode: buildMode,
|
buildMode: buildMode,
|
||||||
renderer: 'canvaskit',
|
renderer: 'canvaskit',
|
||||||
|
wasm: false,
|
||||||
// This test intentionally fails and prints stack traces in the browser
|
// This test intentionally fails and prints stack traces in the browser
|
||||||
// logs. To avoid confusion, silence browser output.
|
// logs. To avoid confusion, silence browser output.
|
||||||
silenceBrowserOutput: true,
|
silenceBrowserOutput: true,
|
||||||
@ -42,6 +43,17 @@ Future<void> webLongRunningTestsRunner(String flutterRoot) async {
|
|||||||
driver: path.join('test_driver', 'integration_test.dart'),
|
driver: path.join('test_driver', 'integration_test.dart'),
|
||||||
buildMode: buildMode,
|
buildMode: buildMode,
|
||||||
renderer: 'canvaskit',
|
renderer: 'canvaskit',
|
||||||
|
wasm: false,
|
||||||
|
expectWriteResponseFile: true,
|
||||||
|
expectResponseFileContent: 'null',
|
||||||
|
),
|
||||||
|
() => _runFlutterDriverWebTest(
|
||||||
|
testAppDirectory: path.join('packages', 'integration_test', 'example'),
|
||||||
|
target: path.join('integration_test', 'example_test.dart'),
|
||||||
|
driver: path.join('test_driver', 'integration_test.dart'),
|
||||||
|
buildMode: buildMode,
|
||||||
|
renderer: 'skwasm',
|
||||||
|
wasm: true,
|
||||||
expectWriteResponseFile: true,
|
expectWriteResponseFile: true,
|
||||||
expectResponseFileContent: 'null',
|
expectResponseFileContent: 'null',
|
||||||
),
|
),
|
||||||
@ -51,6 +63,7 @@ Future<void> webLongRunningTestsRunner(String flutterRoot) async {
|
|||||||
driver: path.join('test_driver', 'extended_integration_test.dart'),
|
driver: path.join('test_driver', 'extended_integration_test.dart'),
|
||||||
buildMode: buildMode,
|
buildMode: buildMode,
|
||||||
renderer: 'canvaskit',
|
renderer: 'canvaskit',
|
||||||
|
wasm: false,
|
||||||
expectWriteResponseFile: true,
|
expectWriteResponseFile: true,
|
||||||
expectResponseFileContent: '''
|
expectResponseFileContent: '''
|
||||||
{
|
{
|
||||||
@ -97,6 +110,7 @@ Future<void> webLongRunningTestsRunner(String flutterRoot) async {
|
|||||||
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'debug', renderer: 'auto'),
|
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'debug', renderer: 'auto'),
|
||||||
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'profile', renderer: 'canvaskit'),
|
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'profile', renderer: 'canvaskit'),
|
||||||
() => _runWebE2eTest('capabilities_integration_html', buildMode: 'release', renderer: 'html'),
|
() => _runWebE2eTest('capabilities_integration_html', buildMode: 'release', renderer: 'html'),
|
||||||
|
() => _runWebE2eTest('capabilities_integration_skwasm', buildMode: 'release', renderer: 'skwasm', wasm: true),
|
||||||
|
|
||||||
// This test doesn't do anything interesting w.r.t. rendering, so we don't run the full build mode x renderer matrix.
|
// This test doesn't do anything interesting w.r.t. rendering, so we don't run the full build mode x renderer matrix.
|
||||||
// CacheWidth and CacheHeight are only currently supported in CanvasKit mode, so we don't run the test in HTML mode.
|
// CacheWidth and CacheHeight are only currently supported in CanvasKit mode, so we don't run the test in HTML mode.
|
||||||
@ -110,6 +124,7 @@ Future<void> webLongRunningTestsRunner(String flutterRoot) async {
|
|||||||
target: 'test_driver/smoke_web_engine.dart',
|
target: 'test_driver/smoke_web_engine.dart',
|
||||||
buildMode: 'profile',
|
buildMode: 'profile',
|
||||||
renderer: 'auto',
|
renderer: 'auto',
|
||||||
|
wasm: false,
|
||||||
),
|
),
|
||||||
() => _runGalleryE2eWebTest('debug'),
|
() => _runGalleryE2eWebTest('debug'),
|
||||||
() => _runGalleryE2eWebTest('debug', canvasKit: true),
|
() => _runGalleryE2eWebTest('debug', canvasKit: true),
|
||||||
@ -192,12 +207,14 @@ Future<void> _runWebE2eTest(
|
|||||||
String name, {
|
String name, {
|
||||||
required String buildMode,
|
required String buildMode,
|
||||||
required String renderer,
|
required String renderer,
|
||||||
|
bool wasm = false,
|
||||||
}) async {
|
}) async {
|
||||||
await _runFlutterDriverWebTest(
|
await _runFlutterDriverWebTest(
|
||||||
target: path.join('test_driver', '$name.dart'),
|
target: path.join('test_driver', '$name.dart'),
|
||||||
buildMode: buildMode,
|
buildMode: buildMode,
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
testAppDirectory: path.join(flutterRoot, 'dev', 'integration_tests', 'web_e2e_tests'),
|
testAppDirectory: path.join(flutterRoot, 'dev', 'integration_tests', 'web_e2e_tests'),
|
||||||
|
wasm: wasm,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +223,7 @@ Future<void> _runFlutterDriverWebTest({
|
|||||||
required String buildMode,
|
required String buildMode,
|
||||||
required String renderer,
|
required String renderer,
|
||||||
required String testAppDirectory,
|
required String testAppDirectory,
|
||||||
|
required bool wasm,
|
||||||
String? driver,
|
String? driver,
|
||||||
bool expectFailure = false,
|
bool expectFailure = false,
|
||||||
bool silenceBrowserOutput = false,
|
bool silenceBrowserOutput = false,
|
||||||
@ -235,6 +253,7 @@ Future<void> _runFlutterDriverWebTest({
|
|||||||
'web-server',
|
'web-server',
|
||||||
'--$buildMode',
|
'--$buildMode',
|
||||||
'--web-renderer=$renderer',
|
'--web-renderer=$renderer',
|
||||||
|
if (wasm) '--wasm',
|
||||||
],
|
],
|
||||||
expectNonZeroExit: expectFailure,
|
expectNonZeroExit: expectFailure,
|
||||||
workingDirectory: testAppDirectory,
|
workingDirectory: testAppDirectory,
|
||||||
|
12
dev/integration_tests/non_nullable/web/flutter_bootstrap.js
Normal file
12
dev/integration_tests/non_nullable/web/flutter_bootstrap.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
{{flutter_js}}
|
||||||
|
{{flutter_build_config}}
|
||||||
|
_flutter.loader.load({
|
||||||
|
config: {
|
||||||
|
// Use the local CanvasKit bundle instead of the CDN to reduce test flakiness.
|
||||||
|
canvasKitBaseUrl: "/canvaskit/",
|
||||||
|
},
|
||||||
|
});
|
@ -22,16 +22,6 @@ found in the LICENSE file. -->
|
|||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
application. For more information, see:
|
|
||||||
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
|
||||||
<script>
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
window.addEventListener('load', function () {
|
|
||||||
navigator.serviceWorker.register('flutter_service_worker.js');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="main.dart.js" type="application/javascript"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
{{flutter_js}}
|
||||||
|
{{flutter_build_config}}
|
||||||
|
_flutter.loader.load({
|
||||||
|
config: {
|
||||||
|
// Use the local CanvasKit bundle instead of the CDN to reduce test flakiness.
|
||||||
|
canvasKitBaseUrl: "/canvaskit/",
|
||||||
|
},
|
||||||
|
});
|
@ -7,6 +7,6 @@ found in the LICENSE file. -->
|
|||||||
<title>Hello, World</title>
|
<title>Hello, World</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="main.dart.js"></script>
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -12,5 +12,7 @@ void main() {
|
|||||||
testWidgets('isCanvasKit returns true in CanvasKit mode', (WidgetTester tester) async {
|
testWidgets('isCanvasKit returns true in CanvasKit mode', (WidgetTester tester) async {
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(isCanvasKit, true);
|
expect(isCanvasKit, true);
|
||||||
|
expect(isSkwasm, false);
|
||||||
|
expect(isSkiaWeb, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import 'package:integration_test/integration_test.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('isCanvasKit returns false in HTML mode', (WidgetTester tester) async {
|
testWidgets('capabilities are set properly in HTML mode', (WidgetTester tester) async {
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(isCanvasKit, false);
|
expect(isCanvasKit, false);
|
||||||
|
expect(isSkwasm, false);
|
||||||
|
expect(isSkiaWeb, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2014 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 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
testWidgets('capabilities are set properly in Skwasm mode', (WidgetTester tester) async {
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(isCanvasKit, false);
|
||||||
|
expect(isSkwasm, true);
|
||||||
|
expect(isSkiaWeb, true);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2014 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 'package:integration_test/integration_test_driver.dart' as test;
|
||||||
|
|
||||||
|
Future<void> main() async => test.integrationDriver();
|
12
examples/hello_world/web/flutter_bootstrap.js
Normal file
12
examples/hello_world/web/flutter_bootstrap.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
{{flutter_js}}
|
||||||
|
{{flutter_build_config}}
|
||||||
|
_flutter.loader.load({
|
||||||
|
config: {
|
||||||
|
// Use the local CanvasKit bundle instead of the CDN to reduce test flakiness.
|
||||||
|
canvasKitBaseUrl: "/canvaskit/",
|
||||||
|
},
|
||||||
|
});
|
@ -7,6 +7,6 @@ found in the LICENSE file. -->
|
|||||||
<title>Hello, World</title>
|
<title>Hello, World</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="main.dart.js"></script>
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -64,7 +64,7 @@ class BuildWebCommand extends BuildSubCommand {
|
|||||||
help:
|
help:
|
||||||
'Sets the optimization level used for Dart compilation to JavaScript/Wasm.',
|
'Sets the optimization level used for Dart compilation to JavaScript/Wasm.',
|
||||||
defaultsTo: '${WebCompilerConfig.kDefaultOptimizationLevel}',
|
defaultsTo: '${WebCompilerConfig.kDefaultOptimizationLevel}',
|
||||||
allowed: const <String>['1', '2', '3', '4'],
|
allowed: const <String>['0', '1', '2', '3', '4'],
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -30,6 +30,7 @@ import '../runner/flutter_command_runner.dart';
|
|||||||
import '../tracing.dart';
|
import '../tracing.dart';
|
||||||
import '../vmservice.dart';
|
import '../vmservice.dart';
|
||||||
import '../web/compile.dart';
|
import '../web/compile.dart';
|
||||||
|
import '../web/web_constants.dart';
|
||||||
import '../web/web_runner.dart';
|
import '../web/web_runner.dart';
|
||||||
import 'daemon.dart';
|
import 'daemon.dart';
|
||||||
|
|
||||||
@ -179,6 +180,11 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
hide: !verboseHelp,
|
hide: !verboseHelp,
|
||||||
help: 'Uninstall previous versions of the app on the device '
|
help: 'Uninstall previous versions of the app on the device '
|
||||||
'before reinstalling. Currently only supported on iOS.',
|
'before reinstalling. Currently only supported on iOS.',
|
||||||
|
)
|
||||||
|
..addFlag(
|
||||||
|
FlutterOptions.kWebWasmFlag,
|
||||||
|
help: 'Compile to WebAssembly rather than JavaScript.\n$kWasmMoreInfo',
|
||||||
|
negatable: false,
|
||||||
);
|
);
|
||||||
usesWebOptions(verboseHelp: verboseHelp);
|
usesWebOptions(verboseHelp: verboseHelp);
|
||||||
usesTargetOption();
|
usesTargetOption();
|
||||||
@ -227,6 +233,13 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
|
|
||||||
String? get traceAllowlist => stringArg('trace-allowlist');
|
String? get traceAllowlist => stringArg('trace-allowlist');
|
||||||
|
|
||||||
|
bool get useWasm => boolArg(FlutterOptions.kWebWasmFlag);
|
||||||
|
|
||||||
|
WebRendererMode get webRenderer => WebRendererMode.fromCliOption(
|
||||||
|
stringArg(FlutterOptions.kWebRendererFlag),
|
||||||
|
useWasm: useWasm
|
||||||
|
);
|
||||||
|
|
||||||
/// Create a debugging options instance for the current `run` or `drive` invocation.
|
/// Create a debugging options instance for the current `run` or `drive` invocation.
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
@protected
|
@protected
|
||||||
@ -242,10 +255,6 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
final Map<String, String> webHeaders = featureFlags.isWebEnabled
|
final Map<String, String> webHeaders = featureFlags.isWebEnabled
|
||||||
? extractWebHeaders()
|
? extractWebHeaders()
|
||||||
: const <String, String>{};
|
: const <String, String>{};
|
||||||
final String? webRendererString = stringArg('web-renderer');
|
|
||||||
final WebRendererMode webRenderer = (webRendererString != null)
|
|
||||||
? WebRendererMode.values.byName(webRendererString)
|
|
||||||
: WebRendererMode.auto;
|
|
||||||
|
|
||||||
if (buildInfo.mode.isRelease) {
|
if (buildInfo.mode.isRelease) {
|
||||||
return DebuggingOptions.disabled(
|
return DebuggingOptions.disabled(
|
||||||
@ -264,6 +273,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
webBrowserFlags: webBrowserFlags,
|
webBrowserFlags: webBrowserFlags,
|
||||||
webHeaders: webHeaders,
|
webHeaders: webHeaders,
|
||||||
webRenderer: webRenderer,
|
webRenderer: webRenderer,
|
||||||
|
webUseWasm: useWasm,
|
||||||
enableImpeller: enableImpeller,
|
enableImpeller: enableImpeller,
|
||||||
enableVulkanValidation: enableVulkanValidation,
|
enableVulkanValidation: enableVulkanValidation,
|
||||||
uninstallFirst: uninstallFirst,
|
uninstallFirst: uninstallFirst,
|
||||||
@ -314,6 +324,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
webLaunchUrl: featureFlags.isWebEnabled ? stringArg('web-launch-url') : null,
|
webLaunchUrl: featureFlags.isWebEnabled ? stringArg('web-launch-url') : null,
|
||||||
webHeaders: webHeaders,
|
webHeaders: webHeaders,
|
||||||
webRenderer: webRenderer,
|
webRenderer: webRenderer,
|
||||||
|
webUseWasm: useWasm,
|
||||||
vmserviceOutFile: stringArg('vmservice-out-file'),
|
vmserviceOutFile: stringArg('vmservice-out-file'),
|
||||||
fastStart: argParser.options.containsKey('fast-start')
|
fastStart: argParser.options.containsKey('fast-start')
|
||||||
&& boolArg('fast-start')
|
&& boolArg('fast-start')
|
||||||
@ -630,12 +641,21 @@ class RunCommand extends RunCommandBase {
|
|||||||
if (devices!.any((Device device) => device is AndroidDevice)) {
|
if (devices!.any((Device device) => device is AndroidDevice)) {
|
||||||
_deviceDeprecationBehavior = DeprecationBehavior.exit;
|
_deviceDeprecationBehavior = DeprecationBehavior.exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only support "web mode" with a single web device due to resident runner
|
// Only support "web mode" with a single web device due to resident runner
|
||||||
// refactoring required otherwise.
|
// refactoring required otherwise.
|
||||||
webMode = featureFlags.isWebEnabled &&
|
webMode = featureFlags.isWebEnabled &&
|
||||||
devices!.length == 1 &&
|
devices!.length == 1 &&
|
||||||
await devices!.single.targetPlatform == TargetPlatform.web_javascript;
|
await devices!.single.targetPlatform == TargetPlatform.web_javascript;
|
||||||
|
|
||||||
|
if (useWasm && !webMode) {
|
||||||
|
throwToolExit('--wasm is only supported on the web platform');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webRenderer == WebRendererMode.skwasm && !useWasm) {
|
||||||
|
throwToolExit('Skwasm renderer requires --wasm');
|
||||||
|
}
|
||||||
|
|
||||||
final String? flavor = stringArg('flavor');
|
final String? flavor = stringArg('flavor');
|
||||||
final bool flavorsSupportedOnEveryDevice = devices!
|
final bool flavorsSupportedOnEveryDevice = devices!
|
||||||
.every((Device device) => device.supportsFlavors);
|
.every((Device device) => device.supportsFlavors);
|
||||||
|
@ -330,6 +330,11 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
|
|||||||
return super.verifyThenRunCommand(commandPath);
|
return super.verifyThenRunCommand(commandPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRendererMode get webRenderer => WebRendererMode.fromCliOption(
|
||||||
|
stringArg(FlutterOptions.kWebRendererFlag),
|
||||||
|
useWasm: useWasm
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<FlutterCommandResult> runCommand() async {
|
Future<FlutterCommandResult> runCommand() async {
|
||||||
if (!globals.fs.isFileSync('pubspec.yaml')) {
|
if (!globals.fs.isFileSync('pubspec.yaml')) {
|
||||||
@ -388,10 +393,6 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String? webRendererString = stringArg('web-renderer');
|
|
||||||
final WebRendererMode webRenderer = (webRendererString != null)
|
|
||||||
? WebRendererMode.values.byName(webRendererString)
|
|
||||||
: WebRendererMode.auto;
|
|
||||||
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(
|
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(
|
||||||
buildInfo,
|
buildInfo,
|
||||||
startPaused: startPaused,
|
startPaused: startPaused,
|
||||||
@ -405,6 +406,7 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
|
|||||||
enableImpeller: ImpellerStatus.fromBool(argResults!['enable-impeller'] as bool?),
|
enableImpeller: ImpellerStatus.fromBool(argResults!['enable-impeller'] as bool?),
|
||||||
debugLogsDirectoryPath: debugLogsDirectoryPath,
|
debugLogsDirectoryPath: debugLogsDirectoryPath,
|
||||||
webRenderer: webRenderer,
|
webRenderer: webRenderer,
|
||||||
|
webUseWasm: useWasm,
|
||||||
);
|
);
|
||||||
|
|
||||||
String? testAssetDirectory;
|
String? testAssetDirectory;
|
||||||
@ -511,6 +513,10 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
|
|||||||
throwToolExit('--wasm is only supported on the web platform');
|
throwToolExit('--wasm is only supported on the web platform');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webRenderer == WebRendererMode.skwasm && !useWasm) {
|
||||||
|
throwToolExit('Skwasm renderer requires --wasm');
|
||||||
|
}
|
||||||
|
|
||||||
Device? integrationTestDevice;
|
Device? integrationTestDevice;
|
||||||
if (_isIntegrationTest) {
|
if (_isIntegrationTest) {
|
||||||
integrationTestDevice = await findTargetDevice();
|
integrationTestDevice = await findTargetDevice();
|
||||||
@ -589,7 +595,6 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
|
|||||||
testAssetDirectory: testAssetDirectory,
|
testAssetDirectory: testAssetDirectory,
|
||||||
flutterProject: flutterProject,
|
flutterProject: flutterProject,
|
||||||
web: isWeb,
|
web: isWeb,
|
||||||
useWasm: useWasm,
|
|
||||||
randomSeed: stringArg('test-randomize-ordering-seed'),
|
randomSeed: stringArg('test-randomize-ordering-seed'),
|
||||||
reporter: stringArg('reporter'),
|
reporter: stringArg('reporter'),
|
||||||
fileReporter: stringArg('file-reporter'),
|
fileReporter: stringArg('file-reporter'),
|
||||||
|
@ -994,6 +994,7 @@ class DebuggingOptions {
|
|||||||
this.webHeaders = const <String, String>{},
|
this.webHeaders = const <String, String>{},
|
||||||
this.webLaunchUrl,
|
this.webLaunchUrl,
|
||||||
this.webRenderer = WebRendererMode.auto,
|
this.webRenderer = WebRendererMode.auto,
|
||||||
|
this.webUseWasm = false,
|
||||||
this.vmserviceOutFile,
|
this.vmserviceOutFile,
|
||||||
this.fastStart = false,
|
this.fastStart = false,
|
||||||
this.nullAssertions = false,
|
this.nullAssertions = false,
|
||||||
@ -1024,6 +1025,7 @@ class DebuggingOptions {
|
|||||||
this.webLaunchUrl,
|
this.webLaunchUrl,
|
||||||
this.webHeaders = const <String, String>{},
|
this.webHeaders = const <String, String>{},
|
||||||
this.webRenderer = WebRendererMode.auto,
|
this.webRenderer = WebRendererMode.auto,
|
||||||
|
this.webUseWasm = false,
|
||||||
this.cacheSkSL = false,
|
this.cacheSkSL = false,
|
||||||
this.traceAllowlist,
|
this.traceAllowlist,
|
||||||
this.enableImpeller = ImpellerStatus.platformDefault,
|
this.enableImpeller = ImpellerStatus.platformDefault,
|
||||||
@ -1104,6 +1106,7 @@ class DebuggingOptions {
|
|||||||
required this.webHeaders,
|
required this.webHeaders,
|
||||||
required this.webLaunchUrl,
|
required this.webLaunchUrl,
|
||||||
required this.webRenderer,
|
required this.webRenderer,
|
||||||
|
required this.webUseWasm,
|
||||||
required this.vmserviceOutFile,
|
required this.vmserviceOutFile,
|
||||||
required this.fastStart,
|
required this.fastStart,
|
||||||
required this.nullAssertions,
|
required this.nullAssertions,
|
||||||
@ -1191,6 +1194,9 @@ class DebuggingOptions {
|
|||||||
/// Which web renderer to use for the debugging session
|
/// Which web renderer to use for the debugging session
|
||||||
final WebRendererMode webRenderer;
|
final WebRendererMode webRenderer;
|
||||||
|
|
||||||
|
/// Whether to compile to webassembly
|
||||||
|
final bool webUseWasm;
|
||||||
|
|
||||||
/// A file where the VM Service URL should be written after the application is started.
|
/// A file where the VM Service URL should be written after the application is started.
|
||||||
final String? vmserviceOutFile;
|
final String? vmserviceOutFile;
|
||||||
final bool fastStart;
|
final bool fastStart;
|
||||||
@ -1300,6 +1306,7 @@ class DebuggingOptions {
|
|||||||
'webLaunchUrl': webLaunchUrl,
|
'webLaunchUrl': webLaunchUrl,
|
||||||
'webHeaders': webHeaders,
|
'webHeaders': webHeaders,
|
||||||
'webRenderer': webRenderer.name,
|
'webRenderer': webRenderer.name,
|
||||||
|
'webUseWasm': webUseWasm,
|
||||||
'vmserviceOutFile': vmserviceOutFile,
|
'vmserviceOutFile': vmserviceOutFile,
|
||||||
'fastStart': fastStart,
|
'fastStart': fastStart,
|
||||||
'nullAssertions': nullAssertions,
|
'nullAssertions': nullAssertions,
|
||||||
@ -1356,6 +1363,7 @@ class DebuggingOptions {
|
|||||||
webHeaders: (json['webHeaders']! as Map<dynamic, dynamic>).cast<String, String>(),
|
webHeaders: (json['webHeaders']! as Map<dynamic, dynamic>).cast<String, String>(),
|
||||||
webLaunchUrl: json['webLaunchUrl'] as String?,
|
webLaunchUrl: json['webLaunchUrl'] as String?,
|
||||||
webRenderer: WebRendererMode.values.byName(json['webRenderer']! as String),
|
webRenderer: WebRendererMode.values.byName(json['webRenderer']! as String),
|
||||||
|
webUseWasm: json['webUseWasm']! as bool,
|
||||||
vmserviceOutFile: json['vmserviceOutFile'] as String?,
|
vmserviceOutFile: json['vmserviceOutFile'] as String?,
|
||||||
fastStart: json['fastStart']! as bool,
|
fastStart: json['fastStart']! as bool,
|
||||||
nullAssertions: json['nullAssertions']! as bool,
|
nullAssertions: json['nullAssertions']! as bool,
|
||||||
|
@ -79,6 +79,7 @@ class WebDriverService extends DriverService {
|
|||||||
port: debuggingOptions.port,
|
port: debuggingOptions.port,
|
||||||
hostname: debuggingOptions.hostname,
|
hostname: debuggingOptions.hostname,
|
||||||
webRenderer: debuggingOptions.webRenderer,
|
webRenderer: debuggingOptions.webRenderer,
|
||||||
|
webUseWasm: debuggingOptions.webUseWasm
|
||||||
)
|
)
|
||||||
: DebuggingOptions.enabled(
|
: DebuggingOptions.enabled(
|
||||||
buildInfo,
|
buildInfo,
|
||||||
@ -86,6 +87,7 @@ class WebDriverService extends DriverService {
|
|||||||
hostname: debuggingOptions.hostname,
|
hostname: debuggingOptions.hostname,
|
||||||
disablePortPublication: debuggingOptions.disablePortPublication,
|
disablePortPublication: debuggingOptions.disablePortPublication,
|
||||||
webRenderer: debuggingOptions.webRenderer,
|
webRenderer: debuggingOptions.webRenderer,
|
||||||
|
webUseWasm: debuggingOptions.webUseWasm,
|
||||||
),
|
),
|
||||||
stayResident: true,
|
stayResident: true,
|
||||||
flutterProject: FlutterProject.current(),
|
flutterProject: FlutterProject.current(),
|
||||||
|
@ -180,6 +180,7 @@ class WebAssetServer implements AssetReader {
|
|||||||
Map<String, String> extraHeaders,
|
Map<String, String> extraHeaders,
|
||||||
NullSafetyMode nullSafetyMode, {
|
NullSafetyMode nullSafetyMode, {
|
||||||
required WebRendererMode webRenderer,
|
required WebRendererMode webRenderer,
|
||||||
|
required bool isWasm,
|
||||||
bool testMode = false,
|
bool testMode = false,
|
||||||
DwdsLauncher dwdsLauncher = Dwds.start,
|
DwdsLauncher dwdsLauncher = Dwds.start,
|
||||||
// TODO(markzipan): Make sure this default value aligns with that in the debugger options.
|
// TODO(markzipan): Make sure this default value aligns with that in the debugger options.
|
||||||
@ -237,8 +238,8 @@ class WebAssetServer implements AssetReader {
|
|||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In release builds deploy a simpler proxy server.
|
// In release builds (or wasm builds) deploy a simpler proxy server.
|
||||||
if (buildInfo.mode != BuildMode.debug) {
|
if (buildInfo.mode != BuildMode.debug || isWasm) {
|
||||||
final ReleaseAssetServer releaseAssetServer = ReleaseAssetServer(
|
final ReleaseAssetServer releaseAssetServer = ReleaseAssetServer(
|
||||||
entrypoint,
|
entrypoint,
|
||||||
fileSystem: globals.fs,
|
fileSystem: globals.fs,
|
||||||
@ -246,6 +247,7 @@ class WebAssetServer implements AssetReader {
|
|||||||
flutterRoot: Cache.flutterRoot,
|
flutterRoot: Cache.flutterRoot,
|
||||||
webBuildDirectory: getWebBuildDirectory(),
|
webBuildDirectory: getWebBuildDirectory(),
|
||||||
basePath: server.basePath,
|
basePath: server.basePath,
|
||||||
|
needsCoopCoep: webRenderer == WebRendererMode.skwasm,
|
||||||
);
|
);
|
||||||
runZonedGuarded(() {
|
runZonedGuarded(() {
|
||||||
shelf.serveRequests(httpServer!, releaseAssetServer.handle);
|
shelf.serveRequests(httpServer!, releaseAssetServer.handle);
|
||||||
@ -737,6 +739,7 @@ class WebDevFS implements DevFS {
|
|||||||
required this.nullSafetyMode,
|
required this.nullSafetyMode,
|
||||||
required this.ddcModuleSystem,
|
required this.ddcModuleSystem,
|
||||||
required this.webRenderer,
|
required this.webRenderer,
|
||||||
|
required this.isWasm,
|
||||||
required this.rootDirectory,
|
required this.rootDirectory,
|
||||||
this.testMode = false,
|
this.testMode = false,
|
||||||
}) : _port = port;
|
}) : _port = port;
|
||||||
@ -763,6 +766,7 @@ class WebDevFS implements DevFS {
|
|||||||
final String? tlsCertPath;
|
final String? tlsCertPath;
|
||||||
final String? tlsCertKeyPath;
|
final String? tlsCertKeyPath;
|
||||||
final WebRendererMode webRenderer;
|
final WebRendererMode webRenderer;
|
||||||
|
final bool isWasm;
|
||||||
|
|
||||||
late WebAssetServer webAssetServer;
|
late WebAssetServer webAssetServer;
|
||||||
|
|
||||||
@ -863,6 +867,7 @@ class WebDevFS implements DevFS {
|
|||||||
extraHeaders,
|
extraHeaders,
|
||||||
nullSafetyMode,
|
nullSafetyMode,
|
||||||
webRenderer: webRenderer,
|
webRenderer: webRenderer,
|
||||||
|
isWasm: isWasm,
|
||||||
testMode: testMode,
|
testMode: testMode,
|
||||||
ddcModuleSystem: ddcModuleSystem,
|
ddcModuleSystem: ddcModuleSystem,
|
||||||
);
|
);
|
||||||
@ -1108,11 +1113,13 @@ class ReleaseAssetServer {
|
|||||||
required String? webBuildDirectory,
|
required String? webBuildDirectory,
|
||||||
required String? flutterRoot,
|
required String? flutterRoot,
|
||||||
required Platform platform,
|
required Platform platform,
|
||||||
|
required bool needsCoopCoep,
|
||||||
this.basePath = '',
|
this.basePath = '',
|
||||||
}) : _fileSystem = fileSystem,
|
}) : _fileSystem = fileSystem,
|
||||||
_platform = platform,
|
_platform = platform,
|
||||||
_flutterRoot = flutterRoot,
|
_flutterRoot = flutterRoot,
|
||||||
_webBuildDirectory = webBuildDirectory,
|
_webBuildDirectory = webBuildDirectory,
|
||||||
|
_needsCoopCoep = needsCoopCoep,
|
||||||
_fileSystemUtils =
|
_fileSystemUtils =
|
||||||
FileSystemUtils(fileSystem: fileSystem, platform: platform);
|
FileSystemUtils(fileSystem: fileSystem, platform: platform);
|
||||||
|
|
||||||
@ -1122,6 +1129,7 @@ class ReleaseAssetServer {
|
|||||||
final FileSystem _fileSystem;
|
final FileSystem _fileSystem;
|
||||||
final FileSystemUtils _fileSystemUtils;
|
final FileSystemUtils _fileSystemUtils;
|
||||||
final Platform _platform;
|
final Platform _platform;
|
||||||
|
final bool _needsCoopCoep;
|
||||||
|
|
||||||
/// The base path to serve from.
|
/// The base path to serve from.
|
||||||
///
|
///
|
||||||
@ -1174,13 +1182,22 @@ class ReleaseAssetServer {
|
|||||||
'application/octet-stream';
|
'application/octet-stream';
|
||||||
return shelf.Response.ok(bytes, headers: <String, String>{
|
return shelf.Response.ok(bytes, headers: <String, String>{
|
||||||
'Content-Type': mimeType,
|
'Content-Type': mimeType,
|
||||||
|
if (_needsCoopCoep && file.basename == 'index.html') ...<String, String>{
|
||||||
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||||
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final File file = _fileSystem
|
final File file = _fileSystem
|
||||||
.file(_fileSystem.path.join(_webBuildDirectory!, 'index.html'));
|
.file(_fileSystem.path.join(_webBuildDirectory!, 'index.html'));
|
||||||
return shelf.Response.ok(file.readAsBytesSync(), headers: <String, String>{
|
return shelf.Response.ok(file.readAsBytesSync(),
|
||||||
|
headers: <String, String>{
|
||||||
'Content-Type': 'text/html',
|
'Content-Type': 'text/html',
|
||||||
|
if (_needsCoopCoep) ...<String, String>{
|
||||||
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||||
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,9 +134,9 @@ class ResidentWebRunner extends ResidentRunner {
|
|||||||
// and platform initialization.
|
// and platform initialization.
|
||||||
Directory? _generatedEntrypointDirectory;
|
Directory? _generatedEntrypointDirectory;
|
||||||
|
|
||||||
// Only the debug builds of the web support the service protocol.
|
// Only non-wasm debug builds of the web support the service protocol.
|
||||||
@override
|
@override
|
||||||
bool get supportsServiceProtocol => isRunningDebug && deviceIsDebuggable;
|
bool get supportsServiceProtocol => !debuggingOptions.webUseWasm && isRunningDebug && deviceIsDebuggable;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get debuggingEnabled => isRunningDebug && deviceIsDebuggable;
|
bool get debuggingEnabled => isRunningDebug && deviceIsDebuggable;
|
||||||
@ -311,13 +311,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
nativeNullAssertions: debuggingOptions.nativeNullAssertions,
|
nativeNullAssertions: debuggingOptions.nativeNullAssertions,
|
||||||
ddcModuleSystem: debuggingOptions.buildInfo.ddcModuleFormat == DdcModuleFormat.ddc,
|
ddcModuleSystem: debuggingOptions.buildInfo.ddcModuleFormat == DdcModuleFormat.ddc,
|
||||||
webRenderer: debuggingOptions.webRenderer,
|
webRenderer: debuggingOptions.webRenderer,
|
||||||
|
isWasm: debuggingOptions.webUseWasm,
|
||||||
rootDirectory: fileSystem.directory(projectRootPath),
|
rootDirectory: fileSystem.directory(projectRootPath),
|
||||||
);
|
);
|
||||||
Uri url = await device!.devFS!.create();
|
Uri url = await device!.devFS!.create();
|
||||||
if (debuggingOptions.tlsCertKeyPath != null && debuggingOptions.tlsCertPath != null) {
|
if (debuggingOptions.tlsCertKeyPath != null && debuggingOptions.tlsCertPath != null) {
|
||||||
url = url.replace(scheme: 'https');
|
url = url.replace(scheme: 'https');
|
||||||
}
|
}
|
||||||
if (debuggingOptions.buildInfo.isDebug) {
|
if (debuggingOptions.buildInfo.isDebug && !debuggingOptions.webUseWasm) {
|
||||||
await runSourceGenerators();
|
await runSourceGenerators();
|
||||||
final UpdateFSReport report = await _updateDevFS(fullRestart: true);
|
final UpdateFSReport report = await _updateDevFS(fullRestart: true);
|
||||||
if (!report.success) {
|
if (!report.success) {
|
||||||
@ -342,12 +343,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
target,
|
target,
|
||||||
debuggingOptions.buildInfo,
|
debuggingOptions.buildInfo,
|
||||||
ServiceWorkerStrategy.none,
|
ServiceWorkerStrategy.none,
|
||||||
compilerConfigs: <WebCompilerConfig>[
|
compilerConfigs: <WebCompilerConfig>[_compilerConfig],
|
||||||
JsCompilerConfig.run(
|
|
||||||
nativeNullAssertions: debuggingOptions.nativeNullAssertions,
|
|
||||||
renderer: debuggingOptions.webRenderer,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await device!.device!.startApp(
|
await device!.device!.startApp(
|
||||||
@ -386,6 +382,17 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebCompilerConfig get _compilerConfig => (debuggingOptions.webUseWasm)
|
||||||
|
? WasmCompilerConfig(
|
||||||
|
optimizationLevel: 0,
|
||||||
|
stripWasm: false,
|
||||||
|
renderer: debuggingOptions.webRenderer
|
||||||
|
)
|
||||||
|
: JsCompilerConfig.run(
|
||||||
|
nativeNullAssertions: debuggingOptions.nativeNullAssertions,
|
||||||
|
renderer: debuggingOptions.webRenderer,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<OperationResult> restart({
|
Future<OperationResult> restart({
|
||||||
bool fullRestart = false,
|
bool fullRestart = false,
|
||||||
@ -399,7 +406,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
progressId: 'hot.restart',
|
progressId: 'hot.restart',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (debuggingOptions.buildInfo.isDebug) {
|
if (debuggingOptions.buildInfo.isDebug && !debuggingOptions.webUseWasm) {
|
||||||
await runSourceGenerators();
|
await runSourceGenerators();
|
||||||
// Full restart is always false for web, since the extra recompile is wasteful.
|
// Full restart is always false for web, since the extra recompile is wasteful.
|
||||||
final UpdateFSReport report = await _updateDevFS();
|
final UpdateFSReport report = await _updateDevFS();
|
||||||
@ -426,12 +433,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
target,
|
target,
|
||||||
debuggingOptions.buildInfo,
|
debuggingOptions.buildInfo,
|
||||||
ServiceWorkerStrategy.none,
|
ServiceWorkerStrategy.none,
|
||||||
compilerConfigs: <WebCompilerConfig>[
|
compilerConfigs: <WebCompilerConfig>[_compilerConfig],
|
||||||
JsCompilerConfig.run(
|
|
||||||
nativeNullAssertions: debuggingOptions.nativeNullAssertions,
|
|
||||||
renderer: debuggingOptions.webRenderer,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
} on ToolExit {
|
} on ToolExit {
|
||||||
return OperationResult(1, 'Failed to recompile application.');
|
return OperationResult(1, 'Failed to recompile application.');
|
||||||
|
@ -1181,10 +1181,10 @@ abstract class ResidentRunner extends ResidentHandlers {
|
|||||||
bool get debuggingEnabled => debuggingOptions.debuggingEnabled;
|
bool get debuggingEnabled => debuggingOptions.debuggingEnabled;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get isRunningDebug => debuggingOptions.buildInfo.isDebug;
|
bool get isRunningDebug => !debuggingOptions.webUseWasm && debuggingOptions.buildInfo.isDebug;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get isRunningProfile => debuggingOptions.buildInfo.isProfile;
|
bool get isRunningProfile => !debuggingOptions.webUseWasm && debuggingOptions.buildInfo.isProfile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get isRunningRelease => debuggingOptions.buildInfo.isRelease;
|
bool get isRunningRelease => debuggingOptions.buildInfo.isRelease;
|
||||||
|
@ -52,7 +52,6 @@ abstract class FlutterTestRunner {
|
|||||||
String? icudtlPath,
|
String? icudtlPath,
|
||||||
Directory? coverageDirectory,
|
Directory? coverageDirectory,
|
||||||
bool web = false,
|
bool web = false,
|
||||||
bool useWasm = false,
|
|
||||||
String? randomSeed,
|
String? randomSeed,
|
||||||
String? reporter,
|
String? reporter,
|
||||||
String? fileReporter,
|
String? fileReporter,
|
||||||
@ -118,7 +117,6 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
|
|||||||
String? icudtlPath,
|
String? icudtlPath,
|
||||||
Directory? coverageDirectory,
|
Directory? coverageDirectory,
|
||||||
bool web = false,
|
bool web = false,
|
||||||
bool useWasm = false,
|
|
||||||
String? randomSeed,
|
String? randomSeed,
|
||||||
String? reporter,
|
String? reporter,
|
||||||
String? fileReporter,
|
String? fileReporter,
|
||||||
@ -188,7 +186,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
|
|||||||
testFiles: testFiles.map((Uri uri) => uri.toFilePath()).toList(),
|
testFiles: testFiles.map((Uri uri) => uri.toFilePath()).toList(),
|
||||||
buildInfo: debuggingOptions.buildInfo,
|
buildInfo: debuggingOptions.buildInfo,
|
||||||
webRenderer: debuggingOptions.webRenderer,
|
webRenderer: debuggingOptions.webRenderer,
|
||||||
useWasm: useWasm,
|
useWasm: debuggingOptions.webUseWasm,
|
||||||
);
|
);
|
||||||
testArgs
|
testArgs
|
||||||
..add('--platform=chrome')
|
..add('--platform=chrome')
|
||||||
@ -221,7 +219,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
|
|||||||
),
|
),
|
||||||
testTimeRecorder: testTimeRecorder,
|
testTimeRecorder: testTimeRecorder,
|
||||||
webRenderer: debuggingOptions.webRenderer,
|
webRenderer: debuggingOptions.webRenderer,
|
||||||
useWasm: useWasm,
|
useWasm: debuggingOptions.webUseWasm,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -184,6 +184,17 @@ enum WebRendererMode implements CliEnum {
|
|||||||
/// Always use skwasm.
|
/// Always use skwasm.
|
||||||
skwasm;
|
skwasm;
|
||||||
|
|
||||||
|
factory WebRendererMode.fromCliOption(String? webRendererString, {required bool useWasm}) {
|
||||||
|
final WebRendererMode mode = webRendererString != null
|
||||||
|
? WebRendererMode.values.byName(webRendererString)
|
||||||
|
: WebRendererMode.auto;
|
||||||
|
if (mode == WebRendererMode.auto && useWasm) {
|
||||||
|
// Wasm defaults to skwasm
|
||||||
|
return WebRendererMode.skwasm;
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get cliName => snakeCase(name, '-');
|
String get cliName => snakeCase(name, '-');
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ sealed class WebCompilerConfig {
|
|||||||
|
|
||||||
/// The compiler optimization level.
|
/// The compiler optimization level.
|
||||||
///
|
///
|
||||||
/// Valid values are O1 (lowest, profile default) to O4 (highest, release default).
|
/// Valid values are O0 (lowest, debug default) to O4 (highest, release default).
|
||||||
final int optimizationLevel;
|
final int optimizationLevel;
|
||||||
|
|
||||||
/// Returns which target this compiler outputs (js or wasm)
|
/// Returns which target this compiler outputs (js or wasm)
|
||||||
|
@ -29,6 +29,7 @@ import 'package:flutter_tools/src/resident_runner.dart';
|
|||||||
import 'package:flutter_tools/src/run_hot.dart';
|
import 'package:flutter_tools/src/run_hot.dart';
|
||||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||||
import 'package:flutter_tools/src/vmservice.dart';
|
import 'package:flutter_tools/src/vmservice.dart';
|
||||||
|
import 'package:flutter_tools/src/web/compile.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
import 'package:unified_analytics/unified_analytics.dart' as analytics;
|
import 'package:unified_analytics/unified_analytics.dart' as analytics;
|
||||||
import 'package:vm_service/vm_service.dart';
|
import 'package:vm_service/vm_service.dart';
|
||||||
@ -986,6 +987,36 @@ void main() {
|
|||||||
DeviceManager: () => testDeviceManager,
|
DeviceManager: () => testDeviceManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('throws a ToolExit when using --wasm on a non-web platform', () async {
|
||||||
|
final RunCommand command = RunCommand();
|
||||||
|
await expectLater(
|
||||||
|
() => createTestCommandRunner(command).run(<String>[
|
||||||
|
'run',
|
||||||
|
'--no-pub',
|
||||||
|
'--wasm',
|
||||||
|
]), throwsToolExit(message: '--wasm is only supported on the web platform'));
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Logger: () => logger,
|
||||||
|
DeviceManager: () => testDeviceManager,
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('throws a ToolExit when using the skwasm renderer without --wasm', () async {
|
||||||
|
final RunCommand command = RunCommand();
|
||||||
|
await expectLater(
|
||||||
|
() => createTestCommandRunner(command).run(<String>[
|
||||||
|
'run',
|
||||||
|
'--no-pub',
|
||||||
|
'--web-renderer=skwasm',
|
||||||
|
]), throwsToolExit(message: 'Skwasm renderer requires --wasm'));
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Logger: () => logger,
|
||||||
|
DeviceManager: () => testDeviceManager,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('accepts headers with commas in them', () async {
|
testUsingContext('accepts headers with commas in them', () async {
|
||||||
final RunCommand command = RunCommand();
|
final RunCommand command = RunCommand();
|
||||||
await expectLater(
|
await expectLater(
|
||||||
@ -1170,6 +1201,24 @@ void main() {
|
|||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('wasm mode selects skwasm renderer by default', () async {
|
||||||
|
final RunCommand command = RunCommand();
|
||||||
|
await expectLater(() => createTestCommandRunner(command).run(<String>[
|
||||||
|
'run',
|
||||||
|
'-d chrome',
|
||||||
|
'--wasm',
|
||||||
|
]), throwsToolExit());
|
||||||
|
|
||||||
|
final DebuggingOptions options = await command.createDebuggingOptions(false);
|
||||||
|
|
||||||
|
expect(options.webUseWasm, true);
|
||||||
|
expect(options.webRenderer, WebRendererMode.skwasm);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
|
||||||
|
FileSystem: () => MemoryFileSystem.test(),
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('fails when "--web-launch-url" is not supported', () async {
|
testUsingContext('fails when "--web-launch-url" is not supported', () async {
|
||||||
final RunCommand command = RunCommand();
|
final RunCommand command = RunCommand();
|
||||||
await expectLater(
|
await expectLater(
|
||||||
|
@ -1348,6 +1348,24 @@ dev_dependencies:
|
|||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('Web renderer defaults to Skwasm when using wasm', () async {
|
||||||
|
final FakeFlutterTestRunner testRunner = FakeFlutterTestRunner(0);
|
||||||
|
|
||||||
|
final TestCommand testCommand = TestCommand(testRunner: testRunner);
|
||||||
|
final CommandRunner<void> commandRunner = createTestCommandRunner(testCommand);
|
||||||
|
|
||||||
|
await commandRunner.run(const <String>[
|
||||||
|
'test',
|
||||||
|
'--no-pub',
|
||||||
|
'--platform=chrome',
|
||||||
|
'--wasm',
|
||||||
|
]);
|
||||||
|
expect(testRunner.lastDebuggingOptionsValue.webRenderer, WebRendererMode.skwasm);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@ void main() {
|
|||||||
flutterRoot: null, // ignore: avoid_redundant_argument_values
|
flutterRoot: null, // ignore: avoid_redundant_argument_values
|
||||||
platform: FakePlatform(),
|
platform: FakePlatform(),
|
||||||
webBuildDirectory: null, // ignore: avoid_redundant_argument_values
|
webBuildDirectory: null, // ignore: avoid_redundant_argument_values
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
overrides: <Type, Generator>{
|
overrides: <Type, Generator>{
|
||||||
@ -927,6 +928,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.html,
|
webRenderer: WebRendererMode.html,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1063,6 +1065,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.html,
|
webRenderer: WebRendererMode.html,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1199,6 +1202,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1272,6 +1276,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1321,6 +1326,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1372,6 +1378,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.auto,
|
webRenderer: WebRendererMode.auto,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1425,6 +1432,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
@ -1463,6 +1471,7 @@ void main() {
|
|||||||
const <String, String>{},
|
const <String, String>{},
|
||||||
NullSafetyMode.unsound,
|
NullSafetyMode.unsound,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
testMode: true);
|
testMode: true);
|
||||||
|
|
||||||
expect(webAssetServer.defaultResponseHeaders['x-frame-options'], null);
|
expect(webAssetServer.defaultResponseHeaders['x-frame-options'], null);
|
||||||
@ -1496,6 +1505,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
NullSafetyMode.unsound,
|
NullSafetyMode.unsound,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
testMode: true);
|
testMode: true);
|
||||||
|
|
||||||
expect(webAssetServer.defaultResponseHeaders[extraHeaderKey],
|
expect(webAssetServer.defaultResponseHeaders[extraHeaderKey],
|
||||||
@ -1596,6 +1606,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
webDevFS.ddcModuleLoaderJS.createSync(recursive: true);
|
||||||
|
@ -76,6 +76,7 @@ void main() {
|
|||||||
flutterRoot: null,
|
flutterRoot: null,
|
||||||
platform: FakePlatform(),
|
platform: FakePlatform(),
|
||||||
webBuildDirectory: null,
|
webBuildDirectory: null,
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Logger: () => logger,
|
Logger: () => logger,
|
||||||
@ -715,6 +716,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.html,
|
webRenderer: WebRendererMode.html,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -827,6 +829,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.html,
|
webRenderer: WebRendererMode.html,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -945,6 +948,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -1009,6 +1013,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -1057,6 +1062,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -1106,6 +1112,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.sound,
|
nullSafetyMode: NullSafetyMode.sound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.auto,
|
webRenderer: WebRendererMode.auto,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -1156,6 +1163,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
@ -1194,6 +1202,7 @@ void main() {
|
|||||||
const <String, String>{},
|
const <String, String>{},
|
||||||
NullSafetyMode.unsound,
|
NullSafetyMode.unsound,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
testMode: true
|
testMode: true
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1228,6 +1237,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
NullSafetyMode.unsound,
|
NullSafetyMode.unsound,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
testMode: true
|
testMode: true
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1310,6 +1320,7 @@ void main() {
|
|||||||
nullSafetyMode: NullSafetyMode.unsound,
|
nullSafetyMode: NullSafetyMode.unsound,
|
||||||
ddcModuleSystem: usesDdcModuleSystem,
|
ddcModuleSystem: usesDdcModuleSystem,
|
||||||
webRenderer: WebRendererMode.canvaskit,
|
webRenderer: WebRendererMode.canvaskit,
|
||||||
|
isWasm: false,
|
||||||
rootDirectory: globals.fs.currentDirectory,
|
rootDirectory: globals.fs.currentDirectory,
|
||||||
);
|
);
|
||||||
webDevFS.requireJS.createSync(recursive: true);
|
webDevFS.requireJS.createSync(recursive: true);
|
||||||
|
@ -49,6 +49,7 @@ void main() {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
flutterRoot: '/flutter',
|
flutterRoot: '/flutter',
|
||||||
webBuildDirectory: 'build/web',
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
fileSystem.file('build/web/assets/foo.png')
|
fileSystem.file('build/web/assets/foo.png')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -68,6 +69,7 @@ void main() {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
flutterRoot: '/flutter',
|
flutterRoot: '/flutter',
|
||||||
webBuildDirectory: 'build/web',
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
fileSystem.file('build/web/assets/foo.js')
|
fileSystem.file('build/web/assets/foo.js')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -87,6 +89,7 @@ void main() {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
flutterRoot: '/flutter',
|
flutterRoot: '/flutter',
|
||||||
webBuildDirectory: 'build/web',
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
fileSystem.file('build/web/assets/foo.html')
|
fileSystem.file('build/web/assets/foo.html')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -106,6 +109,7 @@ void main() {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
flutterRoot: '/flutter',
|
flutterRoot: '/flutter',
|
||||||
webBuildDirectory: 'build/web',
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
fileSystem.file('flutter/bar.dart')
|
fileSystem.file('flutter/bar.dart')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -122,6 +126,7 @@ void main() {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
flutterRoot: '/flutter',
|
flutterRoot: '/flutter',
|
||||||
webBuildDirectory: 'build/web',
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
);
|
);
|
||||||
fileSystem.file('bar.dart')
|
fileSystem.file('bar.dart')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -131,4 +136,44 @@ void main() {
|
|||||||
|
|
||||||
expect(response.statusCode, HttpStatus.ok);
|
expect(response.statusCode, HttpStatus.ok);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWithoutContext('release asset server serves html content with COOP/COEP headers when specified', () async {
|
||||||
|
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: platform,
|
||||||
|
flutterRoot: '/flutter',
|
||||||
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: true,
|
||||||
|
);
|
||||||
|
fileSystem.file('build/web/index.html')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync('<html></html>');
|
||||||
|
final Response response = await assetServer
|
||||||
|
.handle(Request('GET', Uri.parse('http://localhost:8080/index.html')));
|
||||||
|
|
||||||
|
expect(response.statusCode, HttpStatus.ok);
|
||||||
|
final Map<String, String> headers = response.headers;
|
||||||
|
expect(headers['Cross-Origin-Opener-Policy'], 'same-origin');
|
||||||
|
expect(headers['Cross-Origin-Embedder-Policy'], 'require-corp');
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('release asset server serves html content without COOP/COEP headers when specified', () async {
|
||||||
|
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: platform,
|
||||||
|
flutterRoot: '/flutter',
|
||||||
|
webBuildDirectory: 'build/web',
|
||||||
|
needsCoopCoep: false,
|
||||||
|
);
|
||||||
|
fileSystem.file('build/web/index.html')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync('<html></html>');
|
||||||
|
final Response response = await assetServer
|
||||||
|
.handle(Request('GET', Uri.parse('http://localhost:8080/index.html')));
|
||||||
|
|
||||||
|
expect(response.statusCode, HttpStatus.ok);
|
||||||
|
final Map<String, String> headers = response.headers;
|
||||||
|
expect(headers.containsKey('Cross-Origin-Opener-Policy'), false);
|
||||||
|
expect(headers.containsKey('Cross-Origin-Embedder-Policy'), false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
12
packages/integration_test/example/web/flutter_bootstrap.js
Normal file
12
packages/integration_test/example/web/flutter_bootstrap.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
{{flutter_js}}
|
||||||
|
{{flutter_build_config}}
|
||||||
|
_flutter.loader.load({
|
||||||
|
config: {
|
||||||
|
// Use the local CanvasKit bundle instead of the CDN to reduce test flakiness.
|
||||||
|
canvasKitBaseUrl: "/canvaskit/",
|
||||||
|
},
|
||||||
|
});
|
@ -21,16 +21,6 @@ found in the LICENSE file. -->
|
|||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
application. For more information, see:
|
|
||||||
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
|
||||||
<script>
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
window.addEventListener('load', function () {
|
|
||||||
navigator.serviceWorker.register('/flutter_service_worker.js');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="main.dart.js" type="application/javascript"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user