Port shared test runner logic into separate package
The shared test runner logic was reimplementing parts of Mocha,
in particular the test logging and filtering. Moreover, it was
booting the hosted mode server and puppeteer outside of Mocha.
Mocha supports root level hooks [1]. These hooks allow us to
perform work before a test starts. Moreover, by using the
before and after hook, we can run logic before and after
all tests.
By using these hooks, we can extract the "boot the hosted mode
server and hookup puppeteer" part to these root hooks.
Additionally, we can reset the pages in the `beforeEach`, which
means that tests themselves don't have to reset the pages.
We also put the implementation code into third_party/conductor,
as we would like to reuse this logic for the Puppeteer tests.
The Puppeteer test suite now also uses Mocha and has very
similar requirements as to our DevTools tests. By extracting
from DevTools, we can look into expanding the test runner to
other usecases, but that is out of scope for now.
[1]: https://mochajs.org/#root-level-hooks
Bug: 1071369
Change-Id: Ie9f954359d9de84da564b74b6f5517dd535db008
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2150458
Commit-Queue: Tim van der Lippe <[email protected]>
Reviewed-by: Paul Lewis <[email protected]>
diff --git a/test/shared/helper.ts b/test/shared/helper.ts
index 26cc32e..e2a66f0 100644
--- a/test/shared/helper.ts
+++ b/test/shared/helper.ts
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import * as os from 'os';
import {performance} from 'perf_hooks';
import * as puppeteer from 'puppeteer';
-import * as os from 'os';
+
+import {reloadDevTools} from '../conductor/hooks.js';
+import {getBrowserAndPages} from '../conductor/puppeteer-state.js';
export let platform: string;
switch (os.platform()) {
@@ -21,24 +24,6 @@
break;
}
-interface BrowserAndPages {
- browser: puppeteer.Browser;
- target: puppeteer.Page;
- frontend: puppeteer.Page;
- screenshot?: puppeteer.Page;
-}
-
-const targetPage = Symbol('TargetPage');
-const frontEndPage = Symbol('DevToolsPage');
-const screenshotPage = Symbol('ScreenshotPage');
-const browserInstance = Symbol('BrowserInstance');
-
-interface ResetPages {
- (opts?: {enabledExperiments?: string[], selectedPanel?: {name: string, selector?: string}}): void
-}
-
-export let resetPages: ResetPages;
-
// TODO: Remove once Chromium updates its version of Node.js to 12+.
const globalThis: any = global;
@@ -50,7 +35,7 @@
* dances.
*/
const collectAllElementsFromPage = async (root?: puppeteer.JSHandle) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
await frontend.evaluate(root => {
const container = (self as any);
container.__elements = [];
@@ -100,7 +85,7 @@
export const click = async (
selector: string|puppeteer.JSHandle,
options?: {root?: puppeteer.JSHandle, clickOptions?: puppeteer.ClickOptions}) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
if (!frontend) {
throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
}
@@ -132,7 +117,7 @@
};
export const typeText = async (text: string) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
if (!frontend) {
throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
}
@@ -142,7 +127,7 @@
// Get a single element handle, across Shadow DOM boundaries.
export const $ = async (selector: string, root?: puppeteer.JSHandle) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
if (!frontend) {
throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
}
@@ -160,7 +145,7 @@
// Get multiple element handles, across Shadow DOM boundaries.
export const $$ = async (selector: string, root?: puppeteer.JSHandle) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
if (!frontend) {
throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
}
@@ -179,7 +164,7 @@
* @param root The root of the search.
*/
export const $textContent = async (textContent: string, root?: puppeteer.JSHandle) => {
- const frontend: puppeteer.Page = globalThis[frontEndPage];
+ const {frontend} = getBrowserAndPages();
if (!frontend) {
throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
}
@@ -274,35 +259,16 @@
});
};
-export const store =
- (browser: puppeteer.Browser, target: puppeteer.Page, frontend: puppeteer.Page, screenshot: puppeteer.Page | undefined,
- reset: ResetPages) => {
- globalThis[browserInstance] = browser;
- globalThis[targetPage] = target;
- globalThis[frontEndPage] = frontend;
- globalThis[screenshotPage] = screenshot;
- resetPages = reset;
- };
+export const resourcesPath = 'http://localhost:8090/test/e2e/resources';
-export const getBrowserAndPages = (): BrowserAndPages => {
- if (!globalThis[targetPage]) {
- throw new Error('Unable to locate target page. Was it stored first?');
- }
+export const enableExperiment = async (experiment: string) => {
+ const {frontend} = getBrowserAndPages();
+ await frontend.evaluate(experiment => {
+ // @ts-ignore
+ globalThis.Root.Runtime.experiments.setEnabled(experiment, true);
+ }, experiment);
- if (!globalThis[frontEndPage]) {
- throw new Error('Unable to locate DevTools frontend page. Was it stored first?');
- }
-
- if (!globalThis[browserInstance]) {
- throw new Error('Unable to locate browser instance. Was it stored first?');
- }
-
- return {
- browser: globalThis[browserInstance],
- target: globalThis[targetPage],
- frontend: globalThis[frontEndPage],
- screenshot: globalThis[screenshotPage],
- };
+ await reloadDevTools();
};
-export const resourcesPath = 'http://localhost:8090/test/e2e/resources';
+export {getBrowserAndPages, reloadDevTools};