8
8
// TODO(elliette): Enable on Linux.
9
9
'linux' : Skip ('https://github.com/dart-lang/webdev/issues/1787' ),
10
10
})
11
- @Timeout (Duration (seconds: 60 ))
11
+ @Timeout (Duration (minutes: 2 ))
12
+ import 'dart:io' ;
12
13
import 'dart:async' ;
13
14
import 'dart:convert' ;
14
15
16
+ import 'package:collection/collection.dart' ;
15
17
import 'package:dwds/data/debug_info.dart' ;
18
+ import 'package:path/path.dart' as p;
16
19
import 'package:puppeteer/puppeteer.dart' ;
17
20
import 'package:test/test.dart' ;
18
21
@@ -23,6 +26,8 @@ import 'test_utils.dart';
23
26
24
27
final context = TestContext ();
25
28
29
+ enum Panel { debugger, inspector }
30
+
26
31
void main () async {
27
32
group ('MV3 Debug Extension' , () {
28
33
late String extensionPath;
@@ -54,6 +59,7 @@ void main() async {
54
59
tearDown (() async {
55
60
await workerEvalDelay ();
56
61
await worker.evaluate (_clearStorageJs ());
62
+ await workerEvalDelay ();
57
63
});
58
64
59
65
tearDownAll (() async {
@@ -91,14 +97,14 @@ void main() async {
91
97
final extensionOrigin = getExtensionOrigin (browser);
92
98
final settingsTab = await navigateToPage (
93
99
browser,
94
- url: '$extensionOrigin /settings.html' ,
100
+ url: '$extensionOrigin /static_assets/ settings.html' ,
95
101
isNew: true ,
96
102
);
97
103
// Set the settings to open DevTools in a new window:
98
104
await settingsTab.tap ('#windowOpt' );
99
105
await settingsTab.tap ('#saveButton' );
100
106
// Wait for the saved message to verify settings have been saved:
101
- await settingsTab.waitForSelector ('#savedMsg ' );
107
+ await settingsTab.waitForSelector ('.show ' );
102
108
// Close the settings tab:
103
109
await settingsTab.close ();
104
110
// Check that is has been saved in local storage:
@@ -133,19 +139,20 @@ void main() async {
133
139
var appWindowId = await _getWindowId (appUrl, worker: worker);
134
140
expect (devToolsWindowId == appWindowId, isTrue);
135
141
// Close the DevTools tab:
142
+ devToolsTab = await devToolsTabTarget.page;
136
143
await devToolsTab.close ();
137
144
// Navigate to the extension settings page:
138
145
final extensionOrigin = getExtensionOrigin (browser);
139
146
final settingsTab = await navigateToPage (
140
147
browser,
141
- url: '$extensionOrigin /settings.html' ,
148
+ url: '$extensionOrigin /static_assets/ settings.html' ,
142
149
isNew: true ,
143
150
);
144
151
// Set the settings to open DevTools in a new window:
145
152
await settingsTab.tap ('#windowOpt' );
146
153
await settingsTab.tap ('#saveButton' );
147
154
// Wait for the saved message to verify settings have been saved:
148
- await settingsTab.waitForSelector ('#savedMsg ' );
155
+ await settingsTab.waitForSelector ('.show ' );
149
156
// Close the settings tab:
150
157
await settingsTab.close ();
151
158
// Navigate to the Dart app:
@@ -156,7 +163,6 @@ void main() async {
156
163
devToolsTabTarget = await browser.waitForTarget (
157
164
(target) => target.url.contains (devToolsUrlFragment));
158
165
devToolsTab = await devToolsTabTarget.page;
159
- await devToolsTab.bringToFront ();
160
166
devToolsWindowId = await _getWindowId (
161
167
devToolsTab.url! ,
162
168
worker: worker,
@@ -228,7 +234,9 @@ void main() async {
228
234
serveDevTools: true ,
229
235
isInternalBuild: false ,
230
236
isFlutterApp: isFlutterApp,
237
+ openChromeDevTools: true ,
231
238
);
239
+
232
240
worker = await getServiceWorker (browser);
233
241
});
234
242
@@ -262,10 +270,27 @@ void main() async {
262
270
});
263
271
264
272
test ('no additional panels are added in Chrome DevTools' , () async {
265
- // TODO(elliette): Requires either of the following to be resolved:
266
- // - https://github.com/puppeteer/puppeteer/issues/9371
267
- // - https://github.com/xvrh/puppeteer-dart/issues/201
268
- }, skip: true );
273
+ final appUrl = context.appUrl;
274
+ // This is the blank page automatically opened by Chrome:
275
+ final blankTab = await navigateToPage (browser, url: 'about:blank' );
276
+ // Navigate to the Dart app:
277
+ await blankTab.goto (appUrl, wait: Until .domContentLoaded);
278
+ final appTab = blankTab;
279
+ await appTab.bringToFront ();
280
+ final chromeDevToolsTarget = browser.targets.firstWhere (
281
+ (target) => target.url.startsWith ('devtools://devtools' ));
282
+ chromeDevToolsTarget.type = 'page' ;
283
+ final chromeDevToolsPage = await chromeDevToolsTarget.page;
284
+ _tabLeft (chromeDevToolsPage);
285
+ await _takeScreenshot (chromeDevToolsPage,
286
+ screenshotName: 'chromeDevTools_externalBuild' );
287
+ final inspectorPanelTarget = browser.targets
288
+ .firstWhereOrNull ((target) => target.url == 'inspector_panel' );
289
+ expect (inspectorPanelTarget, isNull);
290
+ final debuggerPanelTarget = browser.targets
291
+ .firstWhereOrNull ((target) => target.url == 'debugger_panel' );
292
+ expect (debuggerPanelTarget, isNull);
293
+ });
269
294
});
270
295
}
271
296
});
@@ -283,13 +308,16 @@ void main() async {
283
308
serveDevTools: true ,
284
309
isInternalBuild: true ,
285
310
isFlutterApp: isFlutterApp,
311
+ openChromeDevTools: true ,
286
312
);
313
+
287
314
worker = await getServiceWorker (browser);
288
315
});
289
316
290
317
tearDown (() async {
291
318
await workerEvalDelay ();
292
319
await worker.evaluate (_clearStorageJs ());
320
+ await workerEvalDelay ();
293
321
});
294
322
295
323
tearDownAll (() async {
@@ -316,26 +344,74 @@ void main() async {
316
344
await appTab.close ();
317
345
});
318
346
319
- test ('the Dart Debugger panel is added to Chrome DevTools' , () async {
320
- // TODO(elliette): Requires either of the following to be resolved:
321
- // - https://github.com/puppeteer/puppeteer/issues/9371
322
- // - https://github.com/xvrh/puppeteer-dart/issues/201
323
- }, skip: true );
324
-
325
- if (isFlutterApp) {
326
- test ('the Flutter Inspector panel is added to Chrome DevTools' ,
327
- () async {
328
- // TODO(elliette): Requires either of the following to be resolved:
329
- // - https://github.com/puppeteer/puppeteer/issues/9371
330
- // - https://github.com/xvrh/puppeteer-dart/issues/201
331
- }, skip: true );
332
- }
347
+ test ('the correct extension panels are added to Chrome DevTools' ,
348
+ () async {
349
+ final appUrl = context.appUrl;
350
+ // This is the blank page automatically opened by Chrome:
351
+ final blankTab = await navigateToPage (browser, url: 'about:blank' );
352
+ // Navigate to the Dart app:
353
+ await blankTab.goto (appUrl, wait: Until .domContentLoaded);
354
+ final appTab = blankTab;
355
+ await appTab.bringToFront ();
356
+ final chromeDevToolsTarget = browser.targets.firstWhere (
357
+ (target) => target.url.startsWith ('devtools://devtools' ));
358
+ chromeDevToolsTarget.type = 'page' ;
359
+ final chromeDevToolsPage = await chromeDevToolsTarget.page;
360
+ // There are no hooks for when a panel is added to Chrome DevTools,
361
+ // therefore we rely on a slight delay:
362
+ await Future .delayed (Duration (seconds: 1 ));
363
+ if (isFlutterApp) {
364
+ _tabLeft (chromeDevToolsPage);
365
+ final inspectorPanelElement =
366
+ await _getPanelElement (browser, panel: Panel .inspector);
367
+ expect (inspectorPanelElement, isNotNull);
368
+ await _takeScreenshot (
369
+ chromeDevToolsPage,
370
+ screenshotName: 'inspectorPanelLandingPage_flutterApp' ,
371
+ );
372
+ }
373
+ _tabLeft (chromeDevToolsPage);
374
+ final debuggerPanelElement =
375
+ await _getPanelElement (browser, panel: Panel .debugger);
376
+ expect (debuggerPanelElement, isNotNull);
377
+ await _takeScreenshot (
378
+ chromeDevToolsPage,
379
+ screenshotName:
380
+ 'debuggerPanelLandingPage_${isFlutterApp ? 'flutterApp' : 'dartApp' }' ,
381
+ );
382
+ });
333
383
});
334
384
}
335
385
});
336
386
});
337
387
}
338
388
389
+ Future <ElementHandle ?> _getPanelElement (
390
+ Browser browser, {
391
+ required Panel panel,
392
+ }) async {
393
+ final panelName =
394
+ panel == Panel .inspector ? 'inspector_panel' : 'debugger_panel' ;
395
+ final panelTarget =
396
+ await browser.waitForTarget ((target) => target.url.contains (panelName));
397
+ panelTarget.type = 'page' ;
398
+ final panelPage = await panelTarget.page;
399
+ final frames = panelPage.frames;
400
+ final mainFrame = frames[0 ];
401
+ final panelElement = await mainFrame.$OrNull ('#panelBody' );
402
+ return panelElement;
403
+ }
404
+
405
+ void _tabLeft (Page chromeDevToolsPage) async {
406
+ // TODO(elliette): Detect which enviroment we are OS we are running
407
+ // in and update modifier key accordingly. Meta key for MacOs and
408
+ // Ctrl key for Linux/Windows.
409
+ final modifierKey = Key .meta;
410
+ await chromeDevToolsPage.keyboard.down (modifierKey);
411
+ await chromeDevToolsPage.keyboard.press (Key .bracketLeft);
412
+ await chromeDevToolsPage.keyboard.up (modifierKey);
413
+ }
414
+
339
415
Future <int > _getTabId (
340
416
String url, {
341
417
required Worker worker,
@@ -414,3 +490,21 @@ String _clearStorageJs() {
414
490
}
415
491
''' ;
416
492
}
493
+
494
+ // TODO(https://github.com/dart-lang/webdev/issues/1787): Compare to golden
495
+ // images. Currently golden comparison is not set up, since this is only run
496
+ // locally, not as part of our CI test suite.
497
+ Future <void > _takeScreenshot (
498
+ Page page, {
499
+ required String screenshotName,
500
+ }) async {
501
+ // Since the DevTools panels are not real "pages" but merely targets we have
502
+ // coerced into having a "page" type, there doesn't seem to be a way to verify
503
+ // that the DOM has been loaded. Therefore we use a slight delay before taking
504
+ // a screenshot. See https://github.com/puppeteer/puppeteer/issues/9371.
505
+ await Future .delayed (Duration (seconds: 1 ));
506
+ final screenshot = await page.screenshot ();
507
+ final screenshotPath =
508
+ p.join ('test' , 'puppeteer' , 'test_images' , '$screenshotName .png' );
509
+ await File (screenshotPath).writeAsBytes (screenshot);
510
+ }
0 commit comments