Skip to content

Commit a761125

Browse files
authored
[MV3 Debug Extension] Print console messages on test failure (#1961)
1 parent 41e92be commit a761125

File tree

4 files changed

+93
-45
lines changed

4 files changed

+93
-45
lines changed

dwds/debug_extension_mv3/web/chrome_api.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class MessageSender {
230230
@JS()
231231
@anonymous
232232
class Scripting {
233-
external executeScript(InjectDetails details, Function? callback);
233+
external Object executeScript(InjectDetails details);
234234
}
235235

236236
@JS()

dwds/debug_extension_mv3/web/utils.dart

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,12 @@ Future<bool> removeTab(int tabId) {
6868
return completer.future;
6969
}
7070

71-
Future<bool> injectScript(String scriptName, {required int tabId}) {
72-
final completer = Completer<bool>();
73-
chrome.scripting.executeScript(
74-
InjectDetails(
75-
target: Target(tabId: tabId),
76-
files: [scriptName],
77-
), allowInterop(() {
78-
completer.complete(true);
79-
}));
80-
return completer.future;
71+
Future<bool> injectScript(String scriptName, {required int tabId}) async {
72+
await promiseToFuture(chrome.scripting.executeScript(InjectDetails(
73+
target: Target(tabId: tabId),
74+
files: [scriptName],
75+
)));
76+
return true;
8177
}
8278

8379
void onExtensionIconClicked(void Function(Tab) callback) {

dwds/test/puppeteer/extension_test.dart

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ void main() async {
5858
});
5959

6060
tearDown(() async {
61-
await workerEvalDelay();
62-
await worker.evaluate(_clearStorageJs());
63-
await workerEvalDelay();
61+
await tearDownHelper(worker: worker);
6462
});
6563

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

346343
tearDown(() async {
347-
await workerEvalDelay();
348-
await worker.evaluate(_clearStorageJs());
344+
await tearDownHelper(worker: worker);
349345
});
350346

351347
tearDownAll(() async {
@@ -424,7 +420,7 @@ void main() async {
424420

425421
setUp(() async {
426422
for (final page in await browser.pages) {
427-
await page.close();
423+
await page.close().catchError((_) {});
428424
}
429425
appTab = await navigateToPage(
430426
browser,
@@ -434,9 +430,7 @@ void main() async {
434430
});
435431

436432
tearDown(() async {
437-
await workerEvalDelay();
438-
await worker.evaluate(_clearStorageJs());
439-
await workerEvalDelay();
433+
await tearDownHelper(worker: worker);
440434
});
441435

442436
tearDownAll(() async {
@@ -461,7 +455,7 @@ void main() async {
461455

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

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

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

620614
tearDown(() async {
621-
await workerEvalDelay();
622-
await worker.evaluate(_clearStorageJs());
623-
await workerEvalDelay();
615+
await tearDownHelper(worker: worker);
624616
});
625617

626618
tearDownAll(() async {
@@ -672,13 +664,6 @@ Future<bool> _clickLaunchButton(
672664
}
673665
}
674666

675-
Future<Page> _getChromeDevToolsPage(Browser browser) async {
676-
final chromeDevToolsTarget = browser.targets
677-
.firstWhere((target) => target.url.startsWith('devtools://devtools'));
678-
chromeDevToolsTarget.type = 'page';
679-
return await chromeDevToolsTarget.page;
680-
}
681-
682667
Future<Page> _getPanelPage(
683668
Browser browser, {
684669
required Panel panel,
@@ -787,16 +772,6 @@ String _fetchStorageObjJs(
787772
''';
788773
}
789774

790-
String _clearStorageJs() {
791-
return '''
792-
async () => {
793-
await chrome.storage.local.clear();
794-
await chrome.storage.session.clear();
795-
return true;
796-
}
797-
''';
798-
}
799-
800775
String _getNotifications() {
801776
return '''
802777
async () => {

dwds/test/puppeteer/test_utils.dart

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@ import 'dart:io';
77

88
import 'package:path/path.dart' as p;
99
import 'package:puppeteer/puppeteer.dart';
10+
import 'package:test/test.dart';
1011

1112
import '../fixtures/context.dart';
1213
import '../fixtures/utilities.dart';
1314

15+
enum ConsoleSource {
16+
worker,
17+
devTools,
18+
}
19+
20+
final _workerLogs = [];
21+
final _devToolsLogs = [];
22+
1423
Future<String> buildDebugExtension() async {
1524
final extensionDir = absolutePath(pathFromDwds: 'debug_extension_mv3');
1625
await Process.run(
@@ -52,10 +61,61 @@ Future<Browser> setUpExtensionTest(
5261
);
5362
}
5463

64+
Future<void> tearDownHelper({required Worker worker}) async {
65+
_logConsoleMsgsOnFailure();
66+
_workerLogs.clear();
67+
_devToolsLogs.clear();
68+
await worker.evaluate(_clearStorageJs).catchError((_) {});
69+
}
70+
5571
Future<Worker> getServiceWorker(Browser browser) async {
5672
final serviceWorkerTarget =
5773
await browser.waitForTarget((target) => target.type == 'service_worker');
58-
return (await serviceWorkerTarget.worker)!;
74+
final worker = (await serviceWorkerTarget.worker)!;
75+
return Worker(
76+
worker.client,
77+
worker.url,
78+
onConsoleApiCalled: (type, jsHandles, _) {
79+
for (var handle in jsHandles) {
80+
saveConsoleMsg(
81+
source: ConsoleSource.worker, type: '$type', msg: '$handle');
82+
}
83+
},
84+
onExceptionThrown: null,
85+
);
86+
}
87+
88+
Future<Page> getChromeDevToolsPage(Browser browser) async {
89+
final chromeDevToolsTarget = browser.targets
90+
.firstWhere((target) => target.url.startsWith('devtools://devtools'));
91+
chromeDevToolsTarget.type = 'page';
92+
final chromeDevToolsPage = await chromeDevToolsTarget.page;
93+
chromeDevToolsPage.onConsole.listen((msg) {
94+
saveConsoleMsg(
95+
source: ConsoleSource.devTools,
96+
type: '${msg.type}',
97+
msg: msg.text ?? '',
98+
);
99+
});
100+
return chromeDevToolsPage;
101+
}
102+
103+
void saveConsoleMsg({
104+
required ConsoleSource source,
105+
required String type,
106+
required String msg,
107+
}) {
108+
if (msg.isEmpty) return;
109+
final consiseMsg = msg.startsWith('JSHandle:') ? msg.substring(9) : msg;
110+
final formatted = 'console.$type: $consiseMsg';
111+
switch (source) {
112+
case ConsoleSource.worker:
113+
_workerLogs.add(formatted);
114+
break;
115+
case ConsoleSource.devTools:
116+
_devToolsLogs.add(formatted);
117+
break;
118+
}
59119
}
60120

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

159+
void _logConsoleMsgsOnFailure() {
160+
if (_workerLogs.isNotEmpty) {
161+
printOnFailure(['Service Worker logs:', ..._workerLogs].join('\n'));
162+
}
163+
if (_devToolsLogs.isNotEmpty) {
164+
printOnFailure(['Chrome DevTools logs:', ..._devToolsLogs].join('\n'));
165+
}
166+
}
167+
99168
Iterable<String> _getUrlsInBrowser(Browser browser) {
100169
return browser.targets.map((target) => target.url);
101170
}
@@ -112,3 +181,11 @@ final _clickIconJs = '''
112181
chrome.action.onClicked.dispatch(tab);
113182
}
114183
''';
184+
185+
final _clearStorageJs = '''
186+
async () => {
187+
await chrome.storage.local.clear();
188+
await chrome.storage.session.clear();
189+
return true;
190+
}
191+
''';

0 commit comments

Comments
 (0)