mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
144 lines
4.5 KiB
Dart
144 lines
4.5 KiB
Dart
// 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 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:flutter_devicelab/framework/browser.dart';
|
|
import 'package:meta/meta.dart';
|
|
import 'package:shelf/shelf.dart';
|
|
import 'package:shelf_static/shelf_static.dart';
|
|
import 'package:shelf/shelf_io.dart' as shelf_io;
|
|
|
|
final String bat = Platform.isWindows ? '.bat' : '';
|
|
final String flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
|
|
final String flutter = path.join(flutterRoot, 'bin', 'flutter$bat');
|
|
|
|
|
|
// Run a web service worker test. The expectations are currently stored here
|
|
// instead of in the application. This is not run on CI due to the requirement
|
|
// of having a headful chrome instance.
|
|
Future<void> main() async {
|
|
await _runWebServiceWorkerTest('lib/service_worker_test.dart');
|
|
}
|
|
|
|
Future<void> _runWebServiceWorkerTest(String target, {
|
|
List<String> additionalArguments = const<String>[],
|
|
}) async {
|
|
final String testAppDirectory = path.join(flutterRoot, 'dev', 'integration_tests', 'web');
|
|
final String appBuildDirectory = path.join(testAppDirectory, 'build', 'web');
|
|
|
|
// Build the app.
|
|
await Process.run(
|
|
flutter,
|
|
<String>[ 'clean' ],
|
|
workingDirectory: testAppDirectory,
|
|
);
|
|
await Process.run(
|
|
flutter,
|
|
<String>[
|
|
'build',
|
|
'web',
|
|
'--release',
|
|
...additionalArguments,
|
|
'-t',
|
|
target,
|
|
],
|
|
workingDirectory: testAppDirectory,
|
|
environment: <String, String>{
|
|
'FLUTTER_WEB': 'true',
|
|
},
|
|
);
|
|
final List<Uri> requests = <Uri>[];
|
|
final List<Map<String, String>> headers = <Map<String, String>>[];
|
|
await runRecordingServer(
|
|
appUrl: 'http://localhost:8080/',
|
|
appDirectory: appBuildDirectory,
|
|
requests: requests,
|
|
headers: headers,
|
|
browserDebugPort: null,
|
|
);
|
|
|
|
final List<String> requestedPaths = requests.map((Uri uri) => uri.toString()).toList();
|
|
final List<String> expectedPaths = <String>[
|
|
// Initial page load
|
|
'',
|
|
'main.dart.js',
|
|
'assets/FontManifest.json',
|
|
'flutter_service_worker.js',
|
|
'manifest.json',
|
|
'favicon.ico',
|
|
// Service worker install.
|
|
'main.dart.js',
|
|
'index.html',
|
|
'assets/LICENSE',
|
|
'assets/AssetManifest.json',
|
|
'assets/FontManifest.json',
|
|
'',
|
|
// Second page load all cached.
|
|
];
|
|
print('requests: $requestedPaths');
|
|
// The exact order isn't important or deterministic.
|
|
for (final String path in requestedPaths) {
|
|
if (!expectedPaths.remove(path)) {
|
|
print('unexpected service worker request: $path');
|
|
exit(1);
|
|
}
|
|
}
|
|
if (expectedPaths.isNotEmpty) {
|
|
print('Missing service worker requests from expected paths: $expectedPaths');
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/// This server runs a release web application and verifies that the service worker
|
|
/// caches files correctly, by checking the request resources over HTTP.
|
|
///
|
|
/// When it receives a request for `CLOSE` the server will be torn down.
|
|
///
|
|
/// Expects a path to the `build/web` directory produced from `flutter build web`.
|
|
Future<void> runRecordingServer({
|
|
@required String appUrl,
|
|
@required String appDirectory,
|
|
@required List<Uri> requests,
|
|
@required List<Map<String, String>> headers,
|
|
int serverPort = 8080,
|
|
int browserDebugPort = 8081,
|
|
}) async {
|
|
Chrome chrome;
|
|
HttpServer server;
|
|
final Completer<void> completer = Completer<void>();
|
|
Directory userDataDirectory;
|
|
try {
|
|
server = await HttpServer.bind('localhost', serverPort);
|
|
final Cascade cascade = Cascade()
|
|
.add((Request request) async {
|
|
if (request.url.toString().contains('CLOSE')) {
|
|
completer.complete();
|
|
return Response.notFound('');
|
|
}
|
|
requests.add(request.url);
|
|
headers.add(request.headers);
|
|
return Response.notFound('');
|
|
})
|
|
.add(createStaticHandler(appDirectory, defaultDocument: 'index.html'));
|
|
shelf_io.serveRequests(server, cascade.handler);
|
|
userDataDirectory = Directory.systemTemp.createTempSync('chrome_user_data_');
|
|
chrome = await Chrome.launch(ChromeOptions(
|
|
headless: false,
|
|
debugPort: browserDebugPort,
|
|
url: appUrl,
|
|
userDataDirectory: userDataDirectory.path,
|
|
windowHeight: 500,
|
|
windowWidth: 500,
|
|
), onError: completer.completeError);
|
|
await completer.future;
|
|
} finally {
|
|
chrome?.stop();
|
|
await server?.close();
|
|
userDataDirectory.deleteSync(recursive: true);
|
|
}
|
|
}
|