diff --git a/_test/example/append_body/index.html b/_test/example/append_body/index.html
new file mode 100644
index 000000000..d93440a94
--- /dev/null
+++ b/_test/example/append_body/index.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/webdev/test/serve/injected/fixtures/web/main.dart b/_test/example/append_body/main.dart
similarity index 94%
rename from webdev/test/serve/injected/fixtures/web/main.dart
rename to _test/example/append_body/main.dart
index 31d9a6d88..34ff9b511 100644
--- a/webdev/test/serve/injected/fixtures/web/main.dart
+++ b/_test/example/append_body/main.dart
@@ -13,7 +13,7 @@ void main() {
print('Count is: ${++count}');
});
- document.body.appendText('Hello World!!');
+ document.body.appendText('Hello World!');
registerExtension('ext.flutter.disassemble', (_, __) async {
document.body.appendText('start disassemble ');
diff --git a/dwds/test/devtools_test.dart b/dwds/test/devtools_test.dart
new file mode 100644
index 000000000..b951f87b7
--- /dev/null
+++ b/dwds/test/devtools_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2019, 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.
+
+@Timeout(Duration(minutes: 5))
+import 'package:test/test.dart';
+import 'package:webdriver/io.dart';
+
+import 'fixtures/context.dart';
+
+final context = TestContext(
+ path: 'append_body/index.html',
+);
+
+void main() {
+ group('Injected client', () {
+ setUp(() async {
+ await context.setUp(serveDevTools: true);
+ await context.webDriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
+ // Wait for DevTools to actually open.
+ await Future.delayed(const Duration(seconds: 1));
+ });
+
+ tearDown(() async {
+ await context.tearDown();
+ });
+
+ test('can launch devtools', () async {
+ var windows = await context.webDriver.windows.toList();
+ await context.webDriver.driver.switchTo.window(windows.last);
+ expect(await context.webDriver.title, 'Dart DevTools');
+ });
+
+ test('can not launch devtools for the same app in multiple tabs', () async {
+ var appUrl = await context.webDriver.currentUrl;
+ // Open a new tab, select it, and navigate to the app
+ await context.webDriver.driver
+ .execute("window.open('$appUrl', '_blank');", []);
+ await Future.delayed(const Duration(seconds: 1));
+ var windows = await context.webDriver.windows.toList();
+ var oldAppWindow = windows[0];
+ var newAppWindow = windows[1];
+ var devToolsWindow = windows[2];
+ await newAppWindow.setAsActive();
+
+ // Try to open devtools and check for the alert.
+ await context.webDriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
+ await Future.delayed(const Duration(seconds: 1));
+ var alert = context.webDriver.driver.switchTo.alert;
+ expect(alert, isNotNull);
+ expect(await alert.text,
+ contains('This app is already being debugged in a different tab'));
+ await alert.accept();
+
+ // Now close the old app and try to re-open devtools.
+ await oldAppWindow.setAsActive();
+ await oldAppWindow.close();
+ await devToolsWindow.setAsActive();
+ await devToolsWindow.close();
+ await newAppWindow.setAsActive();
+ await context.webDriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
+ await Future.delayed(const Duration(seconds: 1));
+ windows = await context.webDriver.windows.toList();
+ devToolsWindow = windows.firstWhere((window) => window != newAppWindow);
+ await devToolsWindow.setAsActive();
+ expect(await context.webDriver.title, 'Dart DevTools');
+ });
+ });
+
+ group('Injected client without DevTools', () {
+ setUp(() async {
+ await context.setUp(serveDevTools: false);
+ });
+
+ tearDown(() async {
+ await context.tearDown();
+ });
+
+ test('gives a good error if devtools is not served', () async {
+ // Try to open devtools and check for the alert.
+ await context.webDriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
+ await Future.delayed(const Duration(seconds: 1));
+ var alert = context.webDriver.driver.switchTo.alert;
+ expect(alert, isNotNull);
+ expect(await alert.text, contains('--debug'));
+ await alert.accept();
+ });
+ });
+}
diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart
index 21761cfb3..65f405958 100644
--- a/dwds/test/fixtures/context.dart
+++ b/dwds/test/fixtures/context.dart
@@ -31,6 +31,8 @@ class TestContext {
DebugConnection debugConnection;
ChromeProxyService chromeProxyService;
int port;
+ File _entryFile;
+ String _entryContents;
/// Top level directory in which we run the test server..
String workingDirectory;
@@ -47,9 +49,15 @@ class TestContext {
this.pathToServe = 'example'}) {
workingDirectory = p.normalize(
p.absolute(directory ?? p.relative('../_test', from: p.current)));
+ _entryFile = File(p.absolute(p.join(p.relative('../_test', from: p.current),
+ 'example', 'append_body', 'main.dart')));
+ _entryContents = _entryFile.readAsStringSync();
}
- Future setUp() async {
+ Future setUp(
+ {ReloadConfiguration reloadConfiguration, bool serveDevTools}) async {
+ reloadConfiguration ??= ReloadConfiguration.none;
+ serveDevTools ??= false;
port = await findUnusedPort();
try {
chromeDriver = await Process.start(
@@ -70,7 +78,7 @@ class TestContext {
await daemonClient.buildResults
.firstWhere((results) => results.results
.any((result) => result.status == BuildStatus.succeeded))
- .timeout(Duration(seconds: 60));
+ .timeout(const Duration(seconds: 60));
var debugPort = await findUnusedPort();
var capabilities = Capabilities.chrome
@@ -89,6 +97,8 @@ class TestContext {
pathToServe,
daemonClient.buildResults,
() async => connection,
+ reloadConfiguration,
+ serveDevTools,
);
appUrl = 'http://localhost:$port/$path';
@@ -110,9 +120,22 @@ class TestContext {
}
Future tearDown() async {
+ _entryFile.writeAsStringSync(_entryContents);
await daemonClient.close();
await testServer.stop();
await webDriver?.quit();
chromeDriver.kill();
}
+
+ Future changeInput() async {
+ _entryFile.writeAsStringSync(
+ _entryContents.replaceAll('Hello World!', 'Gary is awesome!'));
+
+ // Wait for the build.
+ await daemonClient.buildResults.firstWhere((results) => results.results
+ .any((result) => result.status == BuildStatus.succeeded));
+
+ // Allow change to propagate to the browser.
+ await Future.delayed(const Duration(seconds: 2));
+ }
}
diff --git a/dwds/test/fixtures/server.dart b/dwds/test/fixtures/server.dart
index 2e35df2c3..c793d44a0 100644
--- a/dwds/test/fixtures/server.dart
+++ b/dwds/test/fixtures/server.dart
@@ -46,6 +46,8 @@ class TestServer {
String target,
Stream buildResults,
Future Function() chromeConnection,
+ ReloadConfiguration reloadConfiguration,
+ bool serveDevTools,
) async {
var pipeline = const Pipeline();
@@ -59,6 +61,8 @@ class TestServer {
buildResults: filteredBuildResults,
chromeConnection: chromeConnection,
logWriter: (level, message) => printOnFailure(message),
+ reloadConfiguration: reloadConfiguration,
+ serveDevTools: serveDevTools,
verbose: true,
);
diff --git a/dwds/test/reload_test.dart b/dwds/test/reload_test.dart
new file mode 100644
index 000000000..7cd4f8b9b
--- /dev/null
+++ b/dwds/test/reload_test.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 2019, 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.
+
+@Timeout(Duration(minutes: 5))
+import 'dart:io';
+
+import 'package:dwds/dwds.dart';
+import 'package:test/test.dart';
+import 'package:vm_service_lib/vm_service_lib.dart';
+
+import 'fixtures/context.dart';
+
+final context = TestContext(
+ path: 'append_body/index.html',
+);
+
+void main() {
+ group('Injected client with live reload', () {
+ setUp(() async {
+ await context.setUp(reloadConfiguration: ReloadConfiguration.liveReload);
+ });
+
+ tearDown(() async {
+ await context.tearDown();
+ });
+
+ test('can live reload changes ', () async {
+ await context.changeInput();
+
+ var source = await context.webDriver.pageSource;
+
+ // A full reload should clear the state.
+ expect(source.contains('Hello World!'), isFalse);
+ expect(source.contains('Gary is awesome!'), isTrue);
+ });
+ });
+
+ group('Injected client', () {
+ setUp(() async {
+ await context.setUp();
+ });
+
+ tearDown(() async {
+ await context.tearDown();
+ });
+
+ test('destroys and recreates the isolate during a hot restart', () async {
+ var client = context.debugConnection.vmService;
+ await client.streamListen('Isolate');
+ await context.changeInput();
+
+ var eventsDone = expectLater(
+ client.onIsolateEvent,
+ emitsThrough(emitsInOrder([
+ _hasKind(EventKind.kIsolateExit),
+ _hasKind(EventKind.kIsolateStart),
+ _hasKind(EventKind.kIsolateRunnable),
+ ])));
+
+ expect(await client.callServiceExtension('hotRestart'),
+ const TypeMatcher());
+
+ await eventsDone;
+ });
+
+ test('destroys and recreates the isolate during a page refresh', () async {
+ var client = context.debugConnection.vmService;
+ await client.streamListen('Isolate');
+ await context.changeInput();
+
+ var eventsDone = expectLater(
+ client.onIsolateEvent,
+ emitsThrough(emitsInOrder([
+ _hasKind(EventKind.kIsolateExit),
+ _hasKind(EventKind.kIsolateStart),
+ _hasKind(EventKind.kIsolateRunnable),
+ ])));
+
+ await context.webDriver.driver.refresh();
+
+ await eventsDone;
+ });
+
+ test('can hot restart via the service extension', () async {
+ var client = context.debugConnection.vmService;
+ await context.changeInput();
+
+ expect(await client.callServiceExtension('hotRestart'),
+ const TypeMatcher());
+ await Future.delayed(const Duration(seconds: 2));
+
+ var source = await context.webDriver.pageSource;
+ // Main is re-invoked which shouldn't clear the state.
+ expect(source, contains('Hello World!'));
+ expect(source, contains('Gary is awesome!'));
+ });
+
+ test('can refresh the page via the fullReload service extension', () async {
+ var client = context.debugConnection.vmService;
+ await context.changeInput();
+
+ expect(await client.callServiceExtension('fullReload'), isA());
+ await Future.delayed(const Duration(seconds: 2));
+
+ var source = await context.webDriver.pageSource;
+ // Should see only the new text
+ expect(source, isNot(contains('Hello World!')));
+ expect(source, contains('Gary is awesome!'));
+ });
+
+ test('can hot restart while paused', () async {
+ var client = context.debugConnection.vmService;
+ var vm = await client.getVM();
+ var isolateId = vm.isolates.first.id;
+ await client.streamListen('Debug');
+ var stream = client.onEvent('Debug');
+ var scriptList = await client.getScripts(isolateId);
+ var main = scriptList.scripts
+ .firstWhere((script) => script.uri.contains('main.dart'));
+ await client.addBreakpoint(isolateId, main.id, 13);
+ await stream
+ .firstWhere((event) => event.kind == EventKind.kPauseBreakpoint);
+
+ await context.changeInput();
+ await client.streamListen('Isolate');
+ stream = client.onEvent('Isolate');
+ await client.callServiceExtension('hotRestart');
+ await stream.firstWhere((event) => event.kind == EventKind.kIsolateStart);
+ var source = await context.webDriver.pageSource;
+
+ // Main is re-invoked which shouldn't clear the state.
+ expect(source.contains('Hello World!'), isTrue);
+ expect(source.contains('Gary is awesome!'), isTrue);
+
+ // Should not be paused.
+ vm = await client.getVM();
+ isolateId = vm.isolates.first.id;
+ var isolate = await client.getIsolate(isolateId) as Isolate;
+ expect(isolate.pauseEvent.kind, EventKind.kResume);
+ expect(isolate.breakpoints.isEmpty, isTrue);
+
+ // TODO(sdk/issues/37364) - Remove once corresponding SDK issue is fixed.
+ }, skip: Platform.isWindows);
+ });
+
+ group('Injected client with hot restart', () {
+ setUp(() async {
+ await context.setUp(reloadConfiguration: ReloadConfiguration.hotRestart);
+ });
+
+ tearDown(() async {
+ await context.tearDown();
+ });
+
+ test('can hot restart changes ', () async {
+ await context.changeInput();
+
+ var source = await context.webDriver.pageSource;
+
+ // Main is re-invoked which shouldn't clear the state.
+ expect(source.contains('Hello World!'), isTrue);
+ expect(source.contains('Gary is awesome!'), isTrue);
+ // The ext.flutter.disassemble callback is invoked and waited for.
+ expect(source,
+ contains('start disassemble end disassemble Gary is awesome'));
+ });
+
+ test('fires isolate create/destroy events during hot restart', () async {
+ var client = context.debugConnection.vmService;
+ await client.streamListen('Isolate');
+
+ var eventsDone = expectLater(
+ client.onIsolateEvent,
+ emitsThrough(emitsInOrder([
+ _hasKind(EventKind.kIsolateExit),
+ _hasKind(EventKind.kIsolateStart),
+ _hasKind(EventKind.kIsolateRunnable),
+ ])));
+
+ await context.changeInput();
+
+ await eventsDone;
+ });
+ });
+}
+
+TypeMatcher _hasKind(String kind) =>
+ isA().having((e) => e.kind, 'kind', kind);
diff --git a/webdev/test/serve/chrome_test.dart b/webdev/test/chrome_test.dart
similarity index 100%
rename from webdev/test/serve/chrome_test.dart
rename to webdev/test/chrome_test.dart
diff --git a/webdev/test/serve/injected/devtools_test.dart b/webdev/test/serve/injected/devtools_test.dart
deleted file mode 100644
index 24c2e124e..000000000
--- a/webdev/test/serve/injected/devtools_test.dart
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2019, 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.
-
-@Timeout(Duration(minutes: 5))
-import 'dart:async';
-import 'dart:io';
-
-import 'package:test/test.dart';
-import 'package:vm_service_lib/vm_service_lib.dart';
-import 'package:vm_service_lib/vm_service_lib_io.dart';
-import 'package:webdriver/io.dart';
-
-import 'injected_fixture.dart';
-
-void main() {
- InjectedFixture fixture;
- Process chromeDriver;
- String debugUri;
-
- setUpAll(() async {
- try {
- chromeDriver = await Process.start(
- 'chromedriver', ['--port=4444', '--url-base=wd/hub']);
- } catch (e) {
- throw StateError(
- 'Could not start ChromeDriver. Is it installed?\nError: $e');
- }
- });
-
- tearDownAll(() {
- chromeDriver.kill();
- });
-
- group('Injected client', () {
- setUp(() async {
- fixture = await InjectedFixture.create();
- await fixture.buildAndLoad(['--debug']);
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- var debugServiceLine = '';
- while (!debugServiceLine.contains('Debug service listening')) {
- debugServiceLine = await fixture.webdev.stdout.next;
- }
- debugUri =
- debugServiceLine.substring(debugServiceLine.indexOf('ws://')).trim();
-
- // Let DevTools open.
- await Future.delayed(const Duration(seconds: 2));
- });
-
- tearDown(() async {
- await fixture.tearDown();
- fixture = null;
- });
-
- test('can launch devtools', () async {
- var windows = await fixture.webdriver.windows.toList();
-
- await fixture.webdriver.driver.switchTo.window(windows.last);
-
- expect(await fixture.webdriver.title, 'Dart DevTools');
- await fixture.webdev.kill();
- });
-
- test('can not launch devtools for the same app in multiple tabs', () async {
- var appUrl = await fixture.webdriver.currentUrl;
- // Open a new tab, select it, and navigate to the app
- await fixture.webdriver.driver
- .execute("window.open('$appUrl', '_blank');", []);
- await Future.delayed(const Duration(seconds: 1));
- var windows = await fixture.webdriver.windows.toList();
- var oldAppWindow = windows[0];
- var newAppWindow = windows[1];
- var devToolsWindow = windows[2];
- await newAppWindow.setAsActive();
-
- // Try to open devtools and check for the alert.
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- await Future.delayed(const Duration(seconds: 1));
- var alert = fixture.webdriver.driver.switchTo.alert;
- expect(alert, isNotNull);
- expect(await alert.text,
- contains('This app is already being debugged in a different tab'));
- await alert.accept();
-
- // Now close the old app and try to re-open devtools.
- await oldAppWindow.setAsActive();
- await oldAppWindow.close();
- await devToolsWindow.setAsActive();
- await devToolsWindow.close();
- await newAppWindow.setAsActive();
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- await Future.delayed(const Duration(seconds: 1));
- windows = await fixture.webdriver.windows.toList();
- devToolsWindow = windows.firstWhere((window) => window != newAppWindow);
- await devToolsWindow.setAsActive();
- expect(await fixture.webdriver.title, 'Dart DevTools');
-
- await fixture.webdev.kill();
- });
-
- test('can hot restart via the service extension', () async {
- var client = await vmServiceConnectUri(debugUri);
- await fixture.changeInput();
-
- expect(await client.callServiceExtension('hotRestart'),
- const TypeMatcher());
- await Future.delayed(const Duration(seconds: 2));
-
- var source = await fixture.webdriver.pageSource;
- // Main is re-invoked which shouldn't clear the state.
- expect(source, contains('Hello World!'));
- expect(source, contains('Gary is awesome!'));
- await fixture.webdev.kill();
- });
-
- test('destroys and recreates the isolate during a hot restart', () async {
- var client = await vmServiceConnectUri(debugUri);
- await client.streamListen('Isolate');
- await fixture.changeInput();
-
- var eventsDone = expectLater(
- client.onIsolateEvent,
- emitsThrough(emitsInOrder([
- _hasKind(EventKind.kIsolateExit),
- _hasKind(EventKind.kIsolateStart),
- _hasKind(EventKind.kIsolateRunnable),
- ])));
-
- expect(await client.callServiceExtension('hotRestart'),
- const TypeMatcher());
-
- await eventsDone;
- await fixture.webdev.kill();
- });
-
- test('destroys and recreates the isolate during a page refresh', () async {
- var client = await vmServiceConnectUri(debugUri);
- await client.streamListen('Isolate');
- await fixture.changeInput();
-
- var eventsDone = expectLater(
- client.onIsolateEvent,
- emitsThrough(emitsInOrder([
- _hasKind(EventKind.kIsolateExit),
- _hasKind(EventKind.kIsolateStart),
- _hasKind(EventKind.kIsolateRunnable),
- ])));
-
- await fixture.webdriver.driver.refresh();
-
- await eventsDone;
- await fixture.webdev.kill();
- });
-
- test('can refresh the page via the fullReload service extension', () async {
- var client = await vmServiceConnectUri(debugUri);
- await fixture.changeInput();
-
- expect(await client.callServiceExtension('fullReload'), isA());
- await Future.delayed(const Duration(seconds: 2));
-
- var source = await fixture.webdriver.pageSource;
- // Should see only the new text
- expect(source, isNot(contains('Hello World!')));
- expect(source, contains('Gary is awesome!'));
- await fixture.webdev.kill();
- });
- });
-
- group('Injected client with --auto restart', () {
- setUp(() async {
- fixture = await InjectedFixture.create();
- await fixture.buildAndLoad(['--debug', '--auto', 'restart']);
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- var debugServiceLine = '';
- while (!debugServiceLine.contains('Debug service listening')) {
- debugServiceLine = await fixture.webdev.stdout.next;
- }
- debugUri =
- debugServiceLine.substring(debugServiceLine.indexOf('ws://')).trim();
-
- // Let DevTools open.
- await Future.delayed(const Duration(seconds: 2));
- });
-
- tearDown(() async {
- await fixture.tearDown();
- fixture = null;
- });
-
- test('fires isolate create/destroy events during hot restart', () async {
- var client = await vmServiceConnectUri(debugUri);
- await client.streamListen('Isolate');
- await fixture.changeInput();
-
- var eventsDone = expectLater(
- client.onIsolateEvent,
- emitsThrough(emitsInOrder([
- _hasKind(EventKind.kIsolateExit),
- _hasKind(EventKind.kIsolateStart),
- _hasKind(EventKind.kIsolateRunnable),
- ])));
-
- await fixture.changeInput();
-
- await eventsDone;
- await fixture.webdev.kill();
- });
- });
-
- test('gives a good error if --debug was not passed', () async {
- var fixture = await InjectedFixture.create();
- addTearDown(() => fixture.tearDown());
- await fixture.buildAndLoad([]);
-
- // Try to open devtools and check for the alert.
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- await Future.delayed(const Duration(seconds: 1));
- var alert = fixture.webdriver.driver.switchTo.alert;
- expect(alert, isNotNull);
- expect(await alert.text, contains('--debug'));
- await alert.accept();
-
- await fixture.webdev.kill();
- });
-}
-
-TypeMatcher _hasKind(String kind) =>
- isA().having((e) => e.kind, 'kind', kind);
diff --git a/webdev/test/serve/injected/fixtures/pubspec.yaml b/webdev/test/serve/injected/fixtures/pubspec.yaml
deleted file mode 100644
index aa1304245..000000000
--- a/webdev/test/serve/injected/fixtures/pubspec.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: fixture
-description: Dummy app for tests.
-
-environment:
- sdk: ">=2.0.0 <3.0.0"
-
-dev_dependencies:
- build_runner: '>=0.10.0 <2.0.0'
- build_web_compilers: ^2.0.0
diff --git a/webdev/test/serve/injected/fixtures/web/index.html b/webdev/test/serve/injected/fixtures/web/index.html
deleted file mode 100644
index fb4042d7b..000000000
--- a/webdev/test/serve/injected/fixtures/web/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- Test App
-
-
-
-
-
-
-
diff --git a/webdev/test/serve/injected/injected_fixture.dart b/webdev/test/serve/injected/injected_fixture.dart
deleted file mode 100644
index 052e27a02..000000000
--- a/webdev/test/serve/injected/injected_fixture.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2019, 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.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:path/path.dart' as p;
-import 'package:test/test.dart';
-import 'package:test_descriptor/test_descriptor.dart' as d;
-import 'package:test_process/test_process.dart';
-import 'package:webdev/src/serve/utils.dart';
-import 'package:webdev/src/util.dart';
-import 'package:webdriver/io.dart';
-
-import '../../test_utils.dart';
-
-class InjectedFixture {
- final File _entryFile;
- final String _entryContents;
- final String _exampleDirectory;
- final bool _headless;
- WebDriver webdriver;
- TestProcess webdev;
-
- InjectedFixture._(this._entryFile, this._entryContents,
- this._exampleDirectory, this._headless);
-
- Future buildAndLoad(List arg) async {
- var success = false;
- int debugPort;
- for (var attempt = 1; attempt <= 10; attempt++) {
- try {
- debugPort = await findUnusedPort();
- var capabilities = Capabilities.chrome
- ..addAll({
- Capabilities.chromeOptions: {
- 'args': [
- 'remote-debugging-port=$debugPort',
- if (_headless) '--headless',
- ]
- }
- });
- webdriver = await createDriver(
- spec: WebDriverSpec.JsonWire, desired: capabilities);
- success = true;
- break;
- } on SocketException {
- // AppVeyor can be flaky to start webdriver.
- }
- }
- if (!success) throw Exception('Unable to start webdriver.');
-
- var openPort = await findUnusedPort();
- var args = ['serve', 'web:$openPort', '--chrome-debug-port=$debugPort']
- ..addAll(arg);
-
- // This keeps the test open so kill it at the end :/
- webdev = await runWebDev(args, workingDirectory: _exampleDirectory);
-
- var hostUrl = 'http://localhost:$openPort';
-
- // Wait for the initial build to finish.
- await expectLater(webdev.stdout, emitsThrough(contains('Succeeded')));
-
- await webdriver.get(hostUrl);
-
- // Wait for the page to fully load.
- await Future.delayed(Platform.isWindows
- // AppVeyor is a little slower than Travis.
- ? const Duration(seconds: 5)
- : const Duration(seconds: 2));
-
- var source = await webdriver.pageSource;
-
- expect(source.contains('Hello World!'), isTrue);
- }
-
- Future changeInput() async {
- _entryFile.writeAsStringSync(
- _entryContents.replaceAll('Hello World!', 'Gary is awesome!'));
-
- // Wait for the build.
- await expectLater(webdev.stdout, emitsThrough(contains('Succeeded')));
-
- // Allow change to propagate to the browser.
- await Future.delayed(const Duration(seconds: 2));
- }
-
- Future tearDown() async {
- if (_entryContents != null) {
- _entryFile?.writeAsStringSync(_entryContents);
- }
- await webdriver?.quit();
- webdriver = null;
- await webdev?.kill();
- webdev = null;
- }
-
- static Future create({bool headless}) async {
- headless ??= true;
- var exampleDirectory =
- p.absolute(p.join(p.current, 'test', 'serve', 'injected', 'fixtures'));
- var entryFile = File(p.absolute(p.join(p.current, 'test', 'serve',
- 'injected', 'fixtures', 'web', 'main.dart')));
-
- var entryContents = entryFile.readAsStringSync();
-
- var process = await TestProcess.start(pubPath, ['upgrade'],
- workingDirectory: exampleDirectory, environment: getPubEnvironment());
-
- await process.shouldExit(0);
-
- await d.file('.packages', isNotEmpty).validate(exampleDirectory);
- await d.file('pubspec.lock', isNotEmpty).validate(exampleDirectory);
-
- return InjectedFixture._(
- entryFile, entryContents, exampleDirectory, headless);
- }
-}
diff --git a/webdev/test/serve/injected/reload_test.dart b/webdev/test/serve/injected/reload_test.dart
deleted file mode 100644
index d8d1e84ee..000000000
--- a/webdev/test/serve/injected/reload_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2019, 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.
-
-@Timeout(Duration(minutes: 5))
-import 'dart:io';
-
-import 'package:test/test.dart';
-import 'package:vm_service_lib/vm_service_lib.dart';
-import 'package:vm_service_lib/vm_service_lib_io.dart';
-import 'package:webdriver/io.dart';
-
-import 'injected_fixture.dart';
-
-void main() {
- InjectedFixture fixture;
- Process chromeDriver;
-
- setUpAll(() async {
- try {
- chromeDriver = await Process.start(
- 'chromedriver', ['--port=4444', '--url-base=wd/hub']);
- } catch (e) {
- throw StateError(
- 'Could not start ChromeDriver. Is it installed?\nError: $e');
- }
- });
-
- tearDownAll(() {
- chromeDriver.kill();
- });
-
- group('Injected client', () {
- setUp(() async {
- fixture = await InjectedFixture.create();
- });
-
- tearDown(() async {
- await fixture?.tearDown();
- fixture = null;
- });
-
- test('can hot restart changes ', () async {
- await fixture.buildAndLoad(['--auto=restart']);
- await fixture.changeInput();
-
- var source = await fixture.webdriver.pageSource;
-
- // Main is re-invoked which shouldn't clear the state.
- expect(source.contains('Hello World!'), isTrue);
- expect(source.contains('Gary is awesome!'), isTrue);
- // The ext.flutter.disassemble callback is invoked and waited for.
- expect(source,
- contains('start disassemble end disassemble Gary is awesome'));
-
- await fixture.webdev.kill();
- });
-
- test('can hot restart while paused', () async {
- await fixture.buildAndLoad(['--debug']);
-
- await fixture.webdriver.driver.keyboard.sendChord([Keyboard.alt, 'd']);
- var debugServiceLine = '';
- while (!debugServiceLine.contains('Debug service listening')) {
- debugServiceLine = await fixture.webdev.stdout.next;
- }
- var debugUri =
- debugServiceLine.substring(debugServiceLine.indexOf('ws://')).trim();
- var client = await vmServiceConnectUri(debugUri);
- var windows = await fixture.webdriver.windows.toList();
- await fixture.webdriver.driver.switchTo.window(windows.first);
- var vm = await client.getVM();
- var isolateId = vm.isolates.first.id;
- await client.streamListen('Debug');
- var stream = client.onEvent('Debug');
- var scriptList = await client.getScripts(isolateId);
- var main = scriptList.scripts
- .firstWhere((script) => script.uri.contains('main.dart'));
- await client.addBreakpoint(isolateId, main.id, 13);
- await stream
- .firstWhere((event) => event.kind == EventKind.kPauseBreakpoint);
-
- await fixture.changeInput();
- await client.streamListen('Isolate');
- stream = client.onEvent('Isolate');
- await client.callServiceExtension('hotRestart');
- await stream.firstWhere((event) => event.kind == EventKind.kIsolateStart);
- var source = await fixture.webdriver.pageSource;
-
- // Main is re-invoked which shouldn't clear the state.
- expect(source.contains('Hello World!'), isTrue);
- expect(source.contains('Gary is awesome!'), isTrue);
-
- // Should not be paused.
- vm = await client.getVM();
- isolateId = vm.isolates.first.id;
- var isolate = await client.getIsolate(isolateId) as Isolate;
- expect(isolate.pauseEvent.kind, EventKind.kResume);
- expect(isolate.breakpoints.isEmpty, isTrue);
-
- await fixture.webdev.kill();
- // TODO(sdk/issues/37364) - Remove once corresponding SDK issue is fixed.
- }, skip: Platform.isWindows);
-
- test('can live reload changes ', () async {
- await fixture.buildAndLoad(['--auto=refresh']);
- await fixture.changeInput();
-
- var source = await fixture.webdriver.pageSource;
-
- // A full reload should clear the state.
- expect(source.contains('Hello World!'), isFalse);
- expect(source.contains('Gary is awesome!'), isTrue);
-
- await fixture.webdev.kill();
- });
- });
-}