Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dwds/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ dev_dependencies:
js: ^0.6.4
lints: ^2.0.0
pubspec_parse: ^1.2.0
puppeteer: ^2.17.0
puppeteer: ^2.18.0
stream_channel: ^2.1.0
test: ^1.21.1
webdriver: ^3.0.0
93 changes: 58 additions & 35 deletions dwds/test/puppeteer/extension_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,8 @@ import 'test_utils.dart';

final context = TestContext();

// Note: The following delay is required to reduce flakiness. It makes
// sure the service worker execution context is ready.
const executionContextDelay = 1;

void main() async {
late Target serviceWorkerTarget;
late Worker worker;
late Browser browser;
late String extensionPath;

Expand Down Expand Up @@ -58,13 +54,13 @@ void main() async {
],
);

serviceWorkerTarget = await browser
final serviceWorkerTarget = await browser
.waitForTarget((target) => target.type == 'service_worker');
worker = (await serviceWorkerTarget.worker)!;
});

tearDown(() async {
final worker = (await serviceWorkerTarget.worker)!;
await Future.delayed(Duration(seconds: executionContextDelay));
await workerEvalDelay();
await worker.evaluate(_clearStorageJs());
});

Expand All @@ -78,17 +74,15 @@ void main() async {
// Navigate to the Dart app:
final appTab =
await navigateToPage(browser, url: appUrl, isNew: true);
final worker = (await serviceWorkerTarget.worker)!;
await Future.delayed(Duration(seconds: executionContextDelay));
// Verify that we have debug info for the Dart app:
final tabIdForAppJs = _tabIdForTabJs(appUrl);
final appTabId = (await worker.evaluate(tabIdForAppJs)) as int;
await workerEvalDelay();
final appTabId = await _getTabId(appUrl, worker: worker);
final debugInfoKey = '$appTabId-debugInfo';
final storageObj = await worker.evaluate(
_fetchStorageObjJs(debugInfoKey, storageArea: 'session'));
final json = storageObj[debugInfoKey];
final debugInfo =
serializers.deserialize(jsonDecode(json)) as DebugInfo;
final debugInfo = await _fetchStorageObj<DebugInfo>(
debugInfoKey,
storageArea: 'session',
worker: worker,
);
expect(debugInfo.appId, isNotNull);
expect(debugInfo.appEntrypointPath, isNotNull);
expect(debugInfo.appInstanceId, isNotNull);
Expand Down Expand Up @@ -116,12 +110,11 @@ void main() async {
// Close the settings tab:
await settingsTab.close();
// Check that is has been saved in local storage:
final worker = (await serviceWorkerTarget.worker)!;
final storageObj = await worker.evaluate(
_fetchStorageObjJs('devToolsOpener', storageArea: 'local'));
final json = storageObj['devToolsOpener'];
final devToolsOpener =
serializers.deserialize(jsonDecode(json)) as DevToolsOpener;
final devToolsOpener = await _fetchStorageObj<DevToolsOpener>(
'devToolsOpener',
storageArea: 'local',
worker: worker,
);
expect(devToolsOpener.newWindow, isTrue);
});

Expand All @@ -131,22 +124,21 @@ void main() async {
final appUrl = context.appUrl;
final devToolsUrlFragment =
useSse ? 'debugger?uri=sse' : 'debugger?uri=ws';
final windowIdForAppJs = _windowIdForTabJs(appUrl);
// Navigate to the Dart app:
final appTab =
await navigateToPage(browser, url: appUrl, isNew: true);
// Click on the Dart Debug Extension icon:
final worker = (await serviceWorkerTarget.worker)!;
await Future.delayed(Duration(seconds: executionContextDelay));
await worker.evaluate(clickIconJs);
await workerEvalDelay();
await clickOnExtensionIcon(worker);
// Verify the extension opened the Dart docs in the same window:
var devToolsTabTarget = await browser.waitForTarget(
(target) => target.url.contains(devToolsUrlFragment));
final devToolsPage = await devToolsTabTarget.page;
final windowIdForDevToolsJs = _windowIdForTabJs(devToolsPage.url!);
var devToolsWindowId =
(await worker.evaluate(windowIdForDevToolsJs)) as int?;
var appWindowId = (await worker.evaluate(windowIdForAppJs)) as int?;
var devToolsWindowId = await _getWindowId(
devToolsPage.url!,
worker: worker,
);
var appWindowId = await _getWindowId(appUrl, worker: worker);
expect(devToolsWindowId == appWindowId, isTrue);
// Close the DevTools tab:
var devToolsTab = await devToolsTabTarget.page;
Expand All @@ -168,13 +160,15 @@ void main() async {
// Navigate to the Dart app:
await navigateToPage(browser, url: appUrl);
// Click on the Dart Debug Extension icon:
await worker.evaluate(clickIconJs);
await clickOnExtensionIcon(worker);
// Verify the extension opened DevTools in a different window:
devToolsTabTarget = await browser.waitForTarget(
(target) => target.url.contains(devToolsUrlFragment));
devToolsWindowId =
(await worker.evaluate(windowIdForDevToolsJs)) as int?;
appWindowId = (await worker.evaluate(windowIdForAppJs)) as int?;
devToolsWindowId = await _getWindowId(
devToolsPage.url!,
worker: worker,
);
appWindowId = await _getWindowId(appUrl, worker: worker);
expect(devToolsWindowId == appWindowId, isFalse);
// Close the DevTools tab:
devToolsTab = await devToolsTabTarget.page;
Expand All @@ -186,6 +180,35 @@ void main() async {
});
}

Future<int> _getTabId(
String url, {
required Worker worker,
}) async {
final jsExpression = _tabIdForTabJs(url);
return (await worker.evaluate(jsExpression)) as int;
}

Future<int?> _getWindowId(
String url, {
required Worker worker,
}) async {
final jsExpression = _windowIdForTabJs(url);
return (await worker.evaluate(jsExpression)) as int?;
}

Future<T> _fetchStorageObj<T>(
String storageKey, {
required String storageArea,
required Worker worker,
}) async {
final storageObj = await worker.evaluate(_fetchStorageObjJs(
storageKey,
storageArea: storageArea,
));
final json = storageObj[storageKey];
return serializers.deserialize(jsonDecode(json)) as T;
}

String _tabIdForTabJs(String tabUrl) {
return '''
async () => {
Expand Down
30 changes: 18 additions & 12 deletions dwds/test/puppeteer/lifeline_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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: 10))
@Timeout(Duration(minutes: 12))
@Skip('https://github.com/dart-lang/webdev/issues/1788')
import 'dart:async';

Expand All @@ -15,7 +15,7 @@ import 'test_utils.dart';
final context = TestContext();

void main() async {
late Target serviceWorkerTarget;
late Worker worker;
late Browser browser;
late String extensionPath;

Expand All @@ -38,8 +38,9 @@ void main() async {
],
);

serviceWorkerTarget = await browser
final serviceWorkerTarget = await browser
.waitForTarget((target) => target.type == 'service_worker');
worker = (await serviceWorkerTarget.worker)!;
});

tearDownAll(() async {
Expand All @@ -50,14 +51,10 @@ void main() async {
// Navigate to the Dart app:
final appTab =
await navigateToPage(browser, url: context.appUrl, isNew: true);
// Click on the Dart Debug Extension icon:
final worker = (await serviceWorkerTarget.worker)!;
// Note: The following delay is required to reduce flakiness (it makes
// sure the execution context is ready):
await Future.delayed(Duration(seconds: 1));
await workerEvalDelay();
// Initiate listeners for the port connection event and the subsequent
// reconnection logs:
final portConnectionPromise = worker.evaluate<bool>(_portConnectionJs);
final portConnectionFuture = _connectToPort(worker);
appTab.onConsole.listen((ConsoleMessage message) {
final messageText = message.text ?? '';
if (messageText
Expand All @@ -66,19 +63,28 @@ void main() async {
}
});
// Click on the Dart Debug Extension icon to intiate a debug session:
await worker.evaluate(clickIconJs);
final connectedToPort = await portConnectionPromise;
await clickOnExtensionIcon(worker);
final connectedToPort = await portConnectionFuture;
// Verify that we have connected to the port:
expect(connectedToPort, isTrue);
expect(connectionCount, equals(1));
// Wait for a little over 5 minutes, and verify that we have reconnected
// to the port again:
await Future.delayed(Duration(minutes: 5) + Duration(seconds: 15));
await _reconnectToPortDelay();
expect(connectionCount, equals(2));
});
});
}

Future<void> _reconnectToPortDelay() async {
await Future.delayed(Duration(minutes: 5) + Duration(seconds: 15));
return;
}

Future<bool?> _connectToPort(Worker worker) async {
return worker.evaluate<bool>(_portConnectionJs);
}

final _portConnectionJs = '''
async () => {
return new Promise((resolve, reject) => {
Expand Down
13 changes: 12 additions & 1 deletion dwds/test/puppeteer/test_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ Future<String> buildDebugExtension() async {
return '$extensionDir/compiled';
}

Future<void> clickOnExtensionIcon(Worker worker) async {
return worker.evaluate(_clickIconJs);
}

// Note: The following delay is required to reduce flakiness. It makes
// sure the service worker execution context is ready.
Future<void> workerEvalDelay() async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question - is there a way to detect when the extension is ready, so we can avoid potentially waiting too little?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not! Same answer as #1791 (comment), I haven't found a way to determine whether or not this will flake. We could add retry logic and add the delay before the retry

await Future.delayed(Duration(seconds: 1));
return;
}

Future<Page> navigateToPage(
Browser browser, {
required String url,
Expand Down Expand Up @@ -60,7 +71,7 @@ Future<Page> _getPageForUrl(Browser browser, {required String url}) {
return pageTarget.page;
}

final clickIconJs = '''
final _clickIconJs = '''
async () => {
const activeTabs = await chrome.tabs.query({ active: true });
const tab = activeTabs[0];
Expand Down