Skip to content

[MV3 Debug Extension] Print console messages on test failure #1961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 14, 2023
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/debug_extension_mv3/web/chrome_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class MessageSender {
@JS()
@anonymous
class Scripting {
external executeScript(InjectDetails details, Function? callback);
external Object executeScript(InjectDetails details);
}

@JS()
Expand Down
16 changes: 6 additions & 10 deletions dwds/debug_extension_mv3/web/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,12 @@ Future<bool> removeTab(int tabId) {
return completer.future;
}

Future<bool> injectScript(String scriptName, {required int tabId}) {
final completer = Completer<bool>();
chrome.scripting.executeScript(
InjectDetails(
target: Target(tabId: tabId),
files: [scriptName],
), allowInterop(() {
completer.complete(true);
}));
return completer.future;
Future<bool> injectScript(String scriptName, {required int tabId}) async {
await promiseToFuture(chrome.scripting.executeScript(InjectDetails(
target: Target(tabId: tabId),
files: [scriptName],
)));
return true;
}

void onExtensionIconClicked(void Function(Tab) callback) {
Expand Down
41 changes: 8 additions & 33 deletions dwds/test/puppeteer/extension_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ void main() async {
});

tearDown(() async {
await workerEvalDelay();
await worker.evaluate(_clearStorageJs());
await workerEvalDelay();
await tearDownHelper(worker: worker);
});

tearDownAll(() async {
Expand Down Expand Up @@ -205,7 +203,6 @@ void main() async {
// Click on the Dart Debug Extension icon:
await workerEvalDelay();
await clickOnExtensionIcon(worker);
print('clicked, waiting for devtools');
// Wait for DevTools to open:
final devToolsTabTarget = await browser.waitForTarget(
(target) => target.url.contains(devToolsUrlFragment));
Expand Down Expand Up @@ -344,8 +341,7 @@ void main() async {
});

tearDown(() async {
await workerEvalDelay();
await worker.evaluate(_clearStorageJs());
await tearDownHelper(worker: worker);
});

tearDownAll(() async {
Expand Down Expand Up @@ -424,7 +420,7 @@ void main() async {

setUp(() async {
for (final page in await browser.pages) {
await page.close();
await page.close().catchError((_) {});
}
appTab = await navigateToPage(
browser,
Expand All @@ -434,9 +430,7 @@ void main() async {
});

tearDown(() async {
await workerEvalDelay();
await worker.evaluate(_clearStorageJs());
await workerEvalDelay();
await tearDownHelper(worker: worker);
});

tearDownAll(() async {
Expand All @@ -461,7 +455,7 @@ void main() async {

test('the correct extension panels are added to Chrome DevTools',
() async {
final chromeDevToolsPage = await _getChromeDevToolsPage(browser);
final chromeDevToolsPage = await getChromeDevToolsPage(browser);
// There are no hooks for when a panel is added to Chrome DevTools,
// therefore we rely on a slight delay:
await Future.delayed(Duration(seconds: 1));
Expand Down Expand Up @@ -494,7 +488,7 @@ void main() async {

test('Dart DevTools is embedded for debug session lifetime',
() async {
final chromeDevToolsPage = await _getChromeDevToolsPage(browser);
final chromeDevToolsPage = await getChromeDevToolsPage(browser);
// There are no hooks for when a panel is added to Chrome DevTools,
// therefore we rely on a slight delay:
await Future.delayed(Duration(seconds: 1));
Expand Down Expand Up @@ -541,7 +535,7 @@ void main() async {

test('The Dart DevTools IFRAME has the correct query parameters',
() async {
final chromeDevToolsPage = await _getChromeDevToolsPage(browser);
final chromeDevToolsPage = await getChromeDevToolsPage(browser);
// There are no hooks for when a panel is added to Chrome DevTools,
// therefore we rely on a slight delay:
await Future.delayed(Duration(seconds: 1));
Expand Down Expand Up @@ -618,9 +612,7 @@ void main() async {
});

tearDown(() async {
await workerEvalDelay();
await worker.evaluate(_clearStorageJs());
await workerEvalDelay();
await tearDownHelper(worker: worker);
});

tearDownAll(() async {
Expand Down Expand Up @@ -672,13 +664,6 @@ Future<bool> _clickLaunchButton(
}
}

Future<Page> _getChromeDevToolsPage(Browser browser) async {
final chromeDevToolsTarget = browser.targets
.firstWhere((target) => target.url.startsWith('devtools://devtools'));
chromeDevToolsTarget.type = 'page';
return await chromeDevToolsTarget.page;
}

Future<Page> _getPanelPage(
Browser browser, {
required Panel panel,
Expand Down Expand Up @@ -787,16 +772,6 @@ String _fetchStorageObjJs(
''';
}

String _clearStorageJs() {
return '''
async () => {
await chrome.storage.local.clear();
await chrome.storage.session.clear();
return true;
}
''';
}

String _getNotifications() {
return '''
async () => {
Expand Down
79 changes: 78 additions & 1 deletion dwds/test/puppeteer/test_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:puppeteer/puppeteer.dart';
import 'package:test/test.dart';

import '../fixtures/context.dart';
import '../fixtures/utilities.dart';

enum ConsoleSource {
worker,
devTools,
}

final _workerLogs = [];
final _devToolsLogs = [];

Future<String> buildDebugExtension() async {
final extensionDir = absolutePath(pathFromDwds: 'debug_extension_mv3');
await Process.run(
Expand Down Expand Up @@ -52,10 +61,61 @@ Future<Browser> setUpExtensionTest(
);
}

Future<void> tearDownHelper({required Worker worker}) async {
_logConsoleMsgsOnFailure();
_workerLogs.clear();
_devToolsLogs.clear();
await worker.evaluate(_clearStorageJs).catchError((_) {});
}

Future<Worker> getServiceWorker(Browser browser) async {
final serviceWorkerTarget =
await browser.waitForTarget((target) => target.type == 'service_worker');
return (await serviceWorkerTarget.worker)!;
final worker = (await serviceWorkerTarget.worker)!;
return Worker(
worker.client,
worker.url,
onConsoleApiCalled: (type, jsHandles, _) {
for (var handle in jsHandles) {
saveConsoleMsg(
source: ConsoleSource.worker, type: '$type', msg: '$handle');
}
},
onExceptionThrown: null,
);
}

Future<Page> getChromeDevToolsPage(Browser browser) async {
final chromeDevToolsTarget = browser.targets
.firstWhere((target) => target.url.startsWith('devtools://devtools'));
chromeDevToolsTarget.type = 'page';
final chromeDevToolsPage = await chromeDevToolsTarget.page;
chromeDevToolsPage.onConsole.listen((msg) {
saveConsoleMsg(
source: ConsoleSource.devTools,
type: '${msg.type}',
msg: msg.text ?? '',
);
});
return chromeDevToolsPage;
}

void saveConsoleMsg({
required ConsoleSource source,
required String type,
required String msg,
}) {
if (msg.isEmpty) return;
final consiseMsg = msg.startsWith('JSHandle:') ? msg.substring(9) : msg;
final formatted = 'console.$type: $consiseMsg';
switch (source) {
case ConsoleSource.worker:
_workerLogs.add(formatted);
break;
case ConsoleSource.devTools:
_devToolsLogs.add(formatted);
break;
}
}

Future<void> clickOnExtensionIcon(Worker worker) async {
Expand Down Expand Up @@ -96,6 +156,15 @@ String getExtensionOrigin(Browser browser) {
return '$chromeExtension//$extensionId';
}

void _logConsoleMsgsOnFailure() {
if (_workerLogs.isNotEmpty) {
printOnFailure(['Service Worker logs:', ..._workerLogs].join('\n'));
}
if (_devToolsLogs.isNotEmpty) {
printOnFailure(['Chrome DevTools logs:', ..._devToolsLogs].join('\n'));
}
}

Iterable<String> _getUrlsInBrowser(Browser browser) {
return browser.targets.map((target) => target.url);
}
Expand All @@ -112,3 +181,11 @@ final _clickIconJs = '''
chrome.action.onClicked.dispatch(tab);
}
''';

final _clearStorageJs = '''
async () => {
await chrome.storage.local.clear();
await chrome.storage.session.clear();
return true;
}
''';