| // 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. |
| |
| // @dart = 2.9 |
| |
| @Timeout(Duration(minutes: 5)) |
| @TestOn('vm') |
| import 'package:test/test.dart'; |
| import 'package:vm_service/vm_service.dart'; |
| import 'package:webdriver/io.dart'; |
| |
| import 'fixtures/context.dart'; |
| |
| final context = TestContext( |
| path: 'append_body/index.html', |
| ); |
| |
| Future<void> _waitForPageReady(TestContext context) async { |
| var attempt = 100; |
| while (attempt-- > 0) { |
| var content = await context.webDriver.pageSource; |
| if (content.contains('Hello World!')) return; |
| await Future.delayed(const Duration(milliseconds: 100)); |
| } |
| throw StateError('Page never initialized'); |
| } |
| |
| 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: 2)); |
| }); |
| |
| 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); |
| // TODO(grouma): switch back to `fixture.webdriver.title` when |
| // https://github.com/flutter/devtools/issues/2045 is fixed. |
| expect(await context.webDriver.pageSource, contains('Flutter')); |
| }); |
| |
| 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: 2)); |
| var windows = await context.webDriver.windows.toList(); |
| var oldAppWindow = windows[0]; |
| var newAppWindow = windows[1]; |
| var devToolsWindow = windows[2]; |
| await newAppWindow.setAsActive(); |
| |
| // Wait for the page to be ready before trying to open DevTools again. |
| await _waitForPageReady(context); |
| |
| // Try to open devtools and check for the alert. |
| await context.webDriver.driver.keyboard.sendChord([Keyboard.alt, 'd']); |
| await Future.delayed(const Duration(seconds: 2)); |
| 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: 2)); |
| windows = await context.webDriver.windows.toList(); |
| devToolsWindow = windows.firstWhere((window) => window != newAppWindow); |
| await devToolsWindow.setAsActive(); |
| // TODO(grouma): switch back to `fixture.webdriver.title` when |
| // https://github.com/flutter/devtools/issues/2045 is fixed. |
| expect(await context.webDriver.pageSource, contains('Flutter')); |
| }); |
| |
| test('destroys and recreates the isolate during a page refresh', () async { |
| // This test is the same as one in reload_test, but runs here when there |
| // is a connected client (DevTools) since it can behave differently. |
| // https://github.com/dart-lang/webdev/pull/901#issuecomment-586438132 |
| 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; |
| }); |
| }); |
| |
| 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: 2)); |
| var alert = context.webDriver.driver.switchTo.alert; |
| expect(alert, isNotNull); |
| expect(await alert.text, contains('--debug')); |
| await alert.accept(); |
| }); |
| }); |
| } |
| |
| TypeMatcher<Event> _hasKind(String kind) => |
| isA<Event>().having((e) => e.kind, 'kind', kind); |