| Index: lib/src/runner/browser/platform.dart
|
| diff --git a/lib/src/runner/browser/server.dart b/lib/src/runner/browser/platform.dart
|
| similarity index 86%
|
| rename from lib/src/runner/browser/server.dart
|
| rename to lib/src/runner/browser/platform.dart
|
| index 62085162adfb83410f4225d5f831223b7237eec1..9603212a1f428a05682e1d6c84846e539ca257f7 100644
|
| --- a/lib/src/runner/browser/server.dart
|
| +++ b/lib/src/runner/browser/platform.dart
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| @@ -14,9 +14,9 @@ import 'package:shelf/shelf.dart' as shelf;
|
| import 'package:shelf/shelf_io.dart' as shelf_io;
|
| import 'package:shelf_static/shelf_static.dart';
|
| import 'package:shelf_web_socket/shelf_web_socket.dart';
|
| +import 'package:stream_channel/stream_channel.dart';
|
|
|
| import '../../backend/metadata.dart';
|
| -import '../../backend/suite.dart';
|
| import '../../backend/test_platform.dart';
|
| import '../../util/io.dart';
|
| import '../../util/one_off_handler.dart';
|
| @@ -25,22 +25,21 @@ import '../../util/stack_trace_mapper.dart';
|
| import '../../utils.dart';
|
| import '../configuration.dart';
|
| import '../load_exception.dart';
|
| +import '../plugin/platform.dart';
|
| +import '../runner_suite.dart';
|
| import 'browser_manager.dart';
|
| import 'compiler_pool.dart';
|
| import 'polymer.dart';
|
|
|
| -/// A server that serves JS-compiled tests to browsers.
|
| -///
|
| -/// A test suite may be loaded for a given file using [loadSuite].
|
| -class BrowserServer {
|
| +class BrowserPlatform extends PlatformPlugin {
|
| /// Starts the server.
|
| ///
|
| /// [root] is the root directory that the server should serve. It defaults to
|
| /// the working directory.
|
| - static Future<BrowserServer> start(Configuration config, {String root})
|
| + static Future<BrowserPlatform> start(Configuration config, {String root})
|
| async {
|
| var server = new shelf_io.IOServer(await HttpMultiServer.loopback(0));
|
| - return new BrowserServer(server, config, root: root);
|
| + return new BrowserPlatform._(server, config, root: root);
|
| }
|
|
|
| /// The underlying server.
|
| @@ -91,9 +90,6 @@ class BrowserServer {
|
| /// Whether [close] has been called.
|
| bool get _closed => _closeMemo.hasRun;
|
|
|
| - /// The memoizer for running [close] exactly once.
|
| - final _closeMemo = new AsyncMemoizer();
|
| -
|
| /// A map from browser identifiers to futures that will complete to the
|
| /// [BrowserManager]s for those browsers, or the errors that occurred when
|
| /// trying to load those managers.
|
| @@ -109,9 +105,10 @@ class BrowserServer {
|
| /// per run, rather than once per browser per run.
|
| final _compileFutures = new Map<String, Future>();
|
|
|
| + /// Mappers for Dartifying stack traces, indexed by test path.
|
| final _mappers = new Map<String, StackTraceMapper>();
|
|
|
| - BrowserServer(this._server, Configuration config, {String root})
|
| + BrowserPlatform._(this._server, Configuration config, {String root})
|
| : _root = root == null ? p.current : root,
|
| _config = config,
|
| _compiledDir = config.pubServeUrl == null ? createTempDir() : null,
|
| @@ -161,15 +158,20 @@ class BrowserServer {
|
| var path = p.fromUri(request.url);
|
|
|
| if (path.endsWith(".browser_test.dart")) {
|
| + var testPath = p.basename(p.withoutExtension(p.withoutExtension(path)));
|
| return new shelf.Response.ok('''
|
| -import "package:test/src/runner/browser/iframe_listener.dart";
|
| + import "package:stream_channel/stream_channel.dart";
|
|
|
| -import "${p.basename(p.withoutExtension(p.withoutExtension(path)))}" as test;
|
| + import "package:test/src/runner/plugin/remote_platform_helpers.dart";
|
| + import "package:test/src/runner/browser/post_message_channel.dart";
|
|
|
| -void main() {
|
| - IframeListener.start(() => test.main);
|
| -}
|
| -''', headers: {'Content-Type': 'application/dart'});
|
| + import "$testPath" as test;
|
| +
|
| + void main() {
|
| + var channel = serializeSuite(() => test.main, hidePrints: false);
|
| + postMessageChannel().pipe(channel);
|
| + }
|
| + ''', headers: {'Content-Type': 'application/dart'});
|
| }
|
|
|
| if (path.endsWith(".html")) {
|
| @@ -184,14 +186,14 @@ void main() {
|
| : 'src="$scriptBase.js"';
|
|
|
| return new shelf.Response.ok('''
|
| -<!DOCTYPE html>
|
| -<html>
|
| -<head>
|
| - <title>${HTML_ESCAPE.convert(test)} Test</title>
|
| - <script $script></script>
|
| -</head>
|
| -</html>
|
| -''', headers: {'Content-Type': 'text/html'});
|
| + <!DOCTYPE html>
|
| + <html>
|
| + <head>
|
| + <title>${HTML_ESCAPE.convert(test)} Test</title>
|
| + <script $script></script>
|
| + </head>
|
| + </html>
|
| + ''', headers: {'Content-Type': 'text/html'});
|
| }
|
|
|
| return new shelf.Response.notFound('Not found.');
|
| @@ -201,7 +203,7 @@ void main() {
|
| ///
|
| /// This will start a browser to load the suite if one isn't already running.
|
| /// Throws an [ArgumentError] if [browser] isn't a browser platform.
|
| - Future<Suite> loadSuite(String path, TestPlatform browser,
|
| + Future<RunnerSuite> load(String path, TestPlatform browser,
|
| Metadata metadata) async {
|
| if (!browser.isBrowser) {
|
| throw new ArgumentError("$browser is not a browser.");
|
| @@ -251,12 +253,15 @@ void main() {
|
| var browserManager = await _browserManagerFor(browser);
|
| if (_closed) return null;
|
|
|
| - var suite = await browserManager.loadSuite(path, suiteUrl, metadata,
|
| + var suite = await browserManager.load(path, suiteUrl, metadata,
|
| mapper: browser.isJS ? _mappers[path] : null);
|
| if (_closed) return null;
|
| return suite;
|
| }
|
|
|
| + StreamChannel loadChannel(String path, TestPlatform platform) =>
|
| + throw new UnimplementedError();
|
| +
|
| /// Loads a test suite at [path] from the `pub serve` URL [dartUrl].
|
| ///
|
| /// This ensures that only one suite is loaded at a time, and that any errors
|
| @@ -389,7 +394,7 @@ void main() {
|
| ///
|
| /// Note that this doesn't close the server itself. Browser tests can still be
|
| /// loaded, they'll just spawn new browsers.
|
| - Future closeBrowsers() {
|
| + Future closeEphemeral() {
|
| var managers = _browserManagers.values.toList();
|
| _browserManagers.clear();
|
| return Future.wait(managers.map((manager) async {
|
| @@ -403,25 +408,24 @@ void main() {
|
| ///
|
| /// Returns a [Future] that completes once the server is closed and its
|
| /// resources have been fully released.
|
| - Future close() {
|
| - return _closeMemo.runOnce(() async {
|
| - var futures = _browserManagers.values.map((future) async {
|
| - var result = await future;
|
| - if (result.isError) return;
|
| + Future close() => _closeMemo.runOnce(() async {
|
| + var futures = _browserManagers.values.map((future) async {
|
| + var result = await future;
|
| + if (result.isError) return;
|
|
|
| - await result.asValue.value.close();
|
| - }).toList();
|
| + await result.asValue.value.close();
|
| + }).toList();
|
|
|
| - futures.add(_server.close());
|
| - futures.add(_compilers.close());
|
| + futures.add(_server.close());
|
| + futures.add(_compilers.close());
|
|
|
| - await Future.wait(futures);
|
| + await Future.wait(futures);
|
|
|
| - if (_config.pubServeUrl == null) {
|
| - new Directory(_compiledDir).deleteSync(recursive: true);
|
| - } else {
|
| - _http.close();
|
| - }
|
| - });
|
| - }
|
| + if (_config.pubServeUrl == null) {
|
| + new Directory(_compiledDir).deleteSync(recursive: true);
|
| + } else {
|
| + _http.close();
|
| + }
|
| + });
|
| + final _closeMemo = new AsyncMemoizer();
|
| }
|
|
|