Skip to content

Commit

Permalink
[web] provide serviceWorkerVersion to the getNewServiceWorker functio…
Browse files Browse the repository at this point in the history
…n (#131240)

Fixes flutter/flutter#130212

Fix `Unresolved variable or type 'serviceWorkerVersion'` in the `_getNewServiceWorker` function.  

Supersedes flutter/flutter#130206
  • Loading branch information
p-mazhnik authored Sep 14, 2023
1 parent 98bee67 commit 783f2f4
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 2 deletions.
139 changes: 139 additions & 0 deletions dev/bots/service_worker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ enum ServiceWorkerTestType {
withFlutterJsEntrypointLoadedEvent,
// Same as withFlutterJsEntrypointLoadedEvent, but with TrustedTypes enabled.
withFlutterJsTrustedTypesOn,
// Uses custom serviceWorkerVersion.
withFlutterJsCustomServiceWorkerVersion,
// Entrypoint generated by `flutter create`.
generatedEntrypoint,
}
Expand All @@ -58,6 +60,7 @@ Future<void> main() async {
await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withFlutterJsTrustedTypesOn);
await runWebServiceWorkerTestWithGeneratedEntrypoint(headless: false);
await runWebServiceWorkerTestWithBlockedServiceWorkers(headless: false);
await runWebServiceWorkerTestWithCustomServiceWorkerVersion(headless: false);

if (hasError) {
reportErrorsAndExit('${bold}One or more tests failed.$reset');
Expand Down Expand Up @@ -117,6 +120,8 @@ String _testTypeToIndexFile(ServiceWorkerTestType type) {
indexFile = 'index_with_flutterjs_entrypoint_loaded.html';
case ServiceWorkerTestType.withFlutterJsTrustedTypesOn:
indexFile = 'index_with_flutterjs_el_tt_on.html';
case ServiceWorkerTestType.withFlutterJsCustomServiceWorkerVersion:
indexFile = 'index_with_flutterjs_custom_sw_version.html';
case ServiceWorkerTestType.generatedEntrypoint:
indexFile = 'generated_entrypoint.html';
}
Expand Down Expand Up @@ -703,3 +708,137 @@ Future<void> runWebServiceWorkerTestWithBlockedServiceWorkers({
}
print('END runWebServiceWorkerTestWithBlockedServiceWorkers(headless: $headless)');
}

/// Regression test for https://github.com/flutter/flutter/issues/130212.
Future<void> runWebServiceWorkerTestWithCustomServiceWorkerVersion({
required bool headless,
}) async {
final Map<String, int> requestedPathCounts = <String, int>{};
void expectRequestCounts(Map<String, int> expectedCounts) =>
_expectRequestCounts(expectedCounts, requestedPathCounts);

AppServer? server;
Future<void> waitForAppToLoad(Map<String, int> waitForCounts) async =>
_waitForAppToLoad(waitForCounts, requestedPathCounts, server);

Future<void> startAppServer({
required String cacheControl,
}) async {
final int serverPort = await findAvailablePortAndPossiblyCauseFlakyTests();
final int browserDebugPort = await findAvailablePortAndPossiblyCauseFlakyTests();
server = await AppServer.start(
headless: headless,
cacheControl: cacheControl,
// TODO(yjbanov): use a better port disambiguation strategy than trying
// to guess what ports other tests use.
appUrl: 'http://localhost:$serverPort/index.html',
serverPort: serverPort,
browserDebugPort: browserDebugPort,
appDirectory: _appBuildDirectory,
additionalRequestHandlers: <Handler>[
(Request request) {
final String requestedPath = request.url.path;
requestedPathCounts.putIfAbsent(requestedPath, () => 0);
requestedPathCounts[requestedPath] = requestedPathCounts[requestedPath]! + 1;
if (requestedPath == 'CLOSE') {
return Response.ok('OK');
}
return Response.notFound('');
},
],
);
}

// Preserve old index.html as index_og.html so we can restore it later for other tests
await runCommand(
'mv',
<String>[
'index.html',
'index_og.html',
],
workingDirectory: _testAppWebDirectory,
);

print('BEGIN runWebServiceWorkerTestWithCustomServiceWorkerVersion(headless: $headless)');
try {
await _rebuildApp(version: 1, testType: ServiceWorkerTestType.withFlutterJsCustomServiceWorkerVersion, target: _target);

print('Test page load');
await startAppServer(cacheControl: 'max-age=0');
await waitForAppToLoad(<String, int>{
'CLOSE': 1,
'flutter_service_worker.js': 1,
'assets/fonts/MaterialIcons-Regular.otf': 1,
});
expectRequestCounts(<String, int>{
'index.html': 2,
'flutter.js': 1,
'main.dart.js': 1,
'CLOSE': 1,
'flutter_service_worker.js': 1,
'assets/FontManifest.json': 1,
'assets/AssetManifest.json': 1,
'assets/fonts/MaterialIcons-Regular.otf': 1,
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
if (!headless)
...<String, int>{
'manifest.json': 1,
'favicon.ico': 1,
},
});

print('Test page reload, ensure service worker is not reloaded');
await server!.chrome.reloadPage(ignoreCache: true);
await waitForAppToLoad(<String, int>{
'CLOSE': 1,
'flutter.js': 1,
});
expectRequestCounts(<String, int>{
'index.html': 1,
'flutter.js': 1,
'main.dart.js': 1,
'assets/FontManifest.json': 1,
'assets/fonts/MaterialIcons-Regular.otf': 1,
'CLOSE': 1,
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
if (!headless)
...<String, int>{
'manifest.json': 1,
'favicon.ico': 1,
},
});

print('Test page reload after rebuild, ensure service worker is not reloaded');
await _rebuildApp(version: 1, testType: ServiceWorkerTestType.withFlutterJsCustomServiceWorkerVersion, target: _target);
await server!.chrome.reloadPage(ignoreCache: true);
await waitForAppToLoad(<String, int>{
'CLOSE': 1,
'flutter.js': 1,
});
expectRequestCounts(<String, int>{
'index.html': 1,
'flutter.js': 1,
'main.dart.js': 1,
'assets/FontManifest.json': 1,
'assets/fonts/MaterialIcons-Regular.otf': 1,
'CLOSE': 1,
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
if (!headless)
...<String, int>{
'manifest.json': 1,
'favicon.ico': 1,
},
});
} finally {
await runCommand(
'mv',
<String>[
'index_og.html',
'index.html',
],
workingDirectory: _testAppWebDirectory,
);
await server?.stop();
}
print('END runWebServiceWorkerTestWithCustomServiceWorkerVersion(headless: $headless)');
}
1 change: 1 addition & 0 deletions dev/bots/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,7 @@ Future<void> _runWebLongRunningTests() async {
() => runWebServiceWorkerTestWithCachingResources(headless: true, testType: ServiceWorkerTestType.withFlutterJsTrustedTypesOn),
() => runWebServiceWorkerTestWithGeneratedEntrypoint(headless: true),
() => runWebServiceWorkerTestWithBlockedServiceWorkers(headless: true),
() => runWebServiceWorkerTestWithCustomServiceWorkerVersion(headless: true),
() => _runWebStackTraceTest('profile', 'lib/stack_trace.dart'),
() => _runWebStackTraceTest('release', 'lib/stack_trace.dart'),
() => _runWebStackTraceTest('profile', 'lib/framework_stack_trace.dart'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<!-- 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. -->
<html>
<head>
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">

<title>Integration test. App load with flutter.js. Custom serviceWorkerVersion provided.</title>

<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Web Test">
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
var serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: '123',
},
onEntrypointLoaded: function(engineInitializer) {
return engineInitializer.autoStart();
}
});
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ _flutter.loader = null;

const serviceWorkerActivation = navigator.serviceWorker
.register(url)
.then(this._getNewServiceWorker)
.then((serviceWorkerRegistration) => this._getNewServiceWorker(serviceWorkerRegistration, serviceWorkerVersion))
.then(this._waitForServiceWorkerActivation);

// Timeout race promise
Expand All @@ -162,9 +162,10 @@ _flutter.loader = null;
* awaiting to be installed/updated.
*
* @param {ServiceWorkerRegistration} serviceWorkerRegistration
* @param {String} serviceWorkerVersion
* @returns {Promise<ServiceWorker>}
*/
async _getNewServiceWorker(serviceWorkerRegistration) {
async _getNewServiceWorker(serviceWorkerRegistration, serviceWorkerVersion) {
if (!serviceWorkerRegistration.active && (serviceWorkerRegistration.installing || serviceWorkerRegistration.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
Expand Down

0 comments on commit 783f2f4

Please sign in to comment.