Skip to content

Commit 5aa3195

Browse files
authored
Add tests for interacting with the extension panels added to Chrome Devtools (#1836)
1 parent 82ac652 commit 5aa3195

File tree

9 files changed

+124
-34
lines changed

9 files changed

+124
-34
lines changed

dwds/debug_extension_mv3/web/static_assets/debugger_panel.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<link rel="stylesheet" href="styles.css" type="text/css">
88
</head>
99

10-
<body class="dark-theme">
10+
<body id="panelBody" data-panel="debugger" class="dark-theme">
1111

1212
<div class="mdl-layout mdl-js-layout">
1313

dwds/debug_extension_mv3/web/static_assets/inspector_panel.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<link rel="stylesheet" href="styles.css" type="text/css">
88
</head>
99

10-
<body class="dark-theme">
10+
<body id="panelBody" data-panel="inspector" class="dark-theme">
1111

1212
<div class="mdl-layout mdl-js-layout">
1313

dwds/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ dev_dependencies:
5252
js: ^0.6.4
5353
lints: ^2.0.0
5454
pubspec_parse: ^1.2.0
55-
puppeteer: ^2.18.0
55+
puppeteer: ^2.19.0
5656
stream_channel: ^2.1.0
5757
test: ^1.21.1
5858
webdriver: ^3.0.0

dwds/test/puppeteer/extension_test.dart

Lines changed: 118 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
// TODO(elliette): Enable on Linux.
99
'linux': Skip('https://github.com/dart-lang/webdev/issues/1787'),
1010
})
11-
@Timeout(Duration(seconds: 60))
11+
@Timeout(Duration(minutes: 2))
12+
import 'dart:io';
1213
import 'dart:async';
1314
import 'dart:convert';
1415

16+
import 'package:collection/collection.dart';
1517
import 'package:dwds/data/debug_info.dart';
18+
import 'package:path/path.dart' as p;
1619
import 'package:puppeteer/puppeteer.dart';
1720
import 'package:test/test.dart';
1821

@@ -23,6 +26,8 @@ import 'test_utils.dart';
2326

2427
final context = TestContext();
2528

29+
enum Panel { debugger, inspector }
30+
2631
void main() async {
2732
group('MV3 Debug Extension', () {
2833
late String extensionPath;
@@ -54,6 +59,7 @@ void main() async {
5459
tearDown(() async {
5560
await workerEvalDelay();
5661
await worker.evaluate(_clearStorageJs());
62+
await workerEvalDelay();
5763
});
5864

5965
tearDownAll(() async {
@@ -91,14 +97,14 @@ void main() async {
9197
final extensionOrigin = getExtensionOrigin(browser);
9298
final settingsTab = await navigateToPage(
9399
browser,
94-
url: '$extensionOrigin/settings.html',
100+
url: '$extensionOrigin/static_assets/settings.html',
95101
isNew: true,
96102
);
97103
// Set the settings to open DevTools in a new window:
98104
await settingsTab.tap('#windowOpt');
99105
await settingsTab.tap('#saveButton');
100106
// Wait for the saved message to verify settings have been saved:
101-
await settingsTab.waitForSelector('#savedMsg');
107+
await settingsTab.waitForSelector('.show');
102108
// Close the settings tab:
103109
await settingsTab.close();
104110
// Check that is has been saved in local storage:
@@ -133,19 +139,20 @@ void main() async {
133139
var appWindowId = await _getWindowId(appUrl, worker: worker);
134140
expect(devToolsWindowId == appWindowId, isTrue);
135141
// Close the DevTools tab:
142+
devToolsTab = await devToolsTabTarget.page;
136143
await devToolsTab.close();
137144
// Navigate to the extension settings page:
138145
final extensionOrigin = getExtensionOrigin(browser);
139146
final settingsTab = await navigateToPage(
140147
browser,
141-
url: '$extensionOrigin/settings.html',
148+
url: '$extensionOrigin/static_assets/settings.html',
142149
isNew: true,
143150
);
144151
// Set the settings to open DevTools in a new window:
145152
await settingsTab.tap('#windowOpt');
146153
await settingsTab.tap('#saveButton');
147154
// Wait for the saved message to verify settings have been saved:
148-
await settingsTab.waitForSelector('#savedMsg');
155+
await settingsTab.waitForSelector('.show');
149156
// Close the settings tab:
150157
await settingsTab.close();
151158
// Navigate to the Dart app:
@@ -156,7 +163,6 @@ void main() async {
156163
devToolsTabTarget = await browser.waitForTarget(
157164
(target) => target.url.contains(devToolsUrlFragment));
158165
devToolsTab = await devToolsTabTarget.page;
159-
await devToolsTab.bringToFront();
160166
devToolsWindowId = await _getWindowId(
161167
devToolsTab.url!,
162168
worker: worker,
@@ -228,7 +234,9 @@ void main() async {
228234
serveDevTools: true,
229235
isInternalBuild: false,
230236
isFlutterApp: isFlutterApp,
237+
openChromeDevTools: true,
231238
);
239+
232240
worker = await getServiceWorker(browser);
233241
});
234242

@@ -262,10 +270,27 @@ void main() async {
262270
});
263271

264272
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+
});
269294
});
270295
}
271296
});
@@ -283,13 +308,16 @@ void main() async {
283308
serveDevTools: true,
284309
isInternalBuild: true,
285310
isFlutterApp: isFlutterApp,
311+
openChromeDevTools: true,
286312
);
313+
287314
worker = await getServiceWorker(browser);
288315
});
289316

290317
tearDown(() async {
291318
await workerEvalDelay();
292319
await worker.evaluate(_clearStorageJs());
320+
await workerEvalDelay();
293321
});
294322

295323
tearDownAll(() async {
@@ -316,26 +344,74 @@ void main() async {
316344
await appTab.close();
317345
});
318346

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+
});
333383
});
334384
}
335385
});
336386
});
337387
}
338388

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+
339415
Future<int> _getTabId(
340416
String url, {
341417
required Worker worker,
@@ -414,3 +490,21 @@ String _clearStorageJs() {
414490
}
415491
''';
416492
}
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+
}
53.4 KB
Loading
66.8 KB
Loading
66.8 KB
Loading
70.9 KB
Loading

dwds/test/puppeteer/test_utils.dart

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,17 @@ import 'package:path/path.dart' as p;
99
import 'package:puppeteer/puppeteer.dart';
1010

1111
import '../fixtures/context.dart';
12+
import '../fixtures/utilities.dart';
1213

1314
Future<String> buildDebugExtension() async {
14-
final currentDir = Directory.current.path;
15-
if (!currentDir.endsWith('dwds')) {
16-
throw StateError(
17-
'Expected to be in /dwds directory, instead path was $currentDir.');
18-
}
19-
final extensionDir = p.join(currentDir, 'debug_extension_mv3');
15+
final extensionDir = absolutePath(pathFromDwds: 'debug_extension_mv3');
2016
// TODO(elliette): This doesn't work on Windows, see https://github.com/dart-lang/webdev/issues/1724.
2117
await Process.run(
2218
p.join('tool', 'build_extension.sh'),
2319
[],
2420
workingDirectory: extensionDir,
2521
);
26-
return '$extensionDir/compiled';
22+
return p.join(extensionDir, 'compiled');
2723
}
2824

2925
Future<Browser> setUpExtensionTest(

0 commit comments

Comments
 (0)