Skip to content

Commit

Permalink
feat(test-utils): add onStart/onFinish callbacks to BrowserTestDriver (
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress authored Feb 19, 2024
1 parent 2fca0c1 commit 8c1e1c2
Show file tree
Hide file tree
Showing 11 changed files with 1,436 additions and 726 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
dist/
node_modules/
coverage/
.nyc_output/
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ dist/
node_modules/
modules/stats/src/lib/stats.ts
modules/seer/src/api.ts
coverage/
.nyc_output/
4 changes: 2 additions & 2 deletions docs/modules/test-utils/browser-driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ browserDriver.startBrowser().openPage({url: 'http://localhost'});

Parameters:

* `url` (String) - The url to load in the page. Default `http://localhost`.
* `url` (String) - If provided, the url to load in the page.
* `exposeFunctions` (Object) - keys are function names to be added to the page's `window` object, and the values are callback functions to execute in Node.js. See [exposeFunction](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageexposefunctionname-puppeteerfunction) for details.
* `onLoad` (Function) - callback when the page is loaded
* `onConsole` (Function) - callback when the page logs to console
* `onError` (Function) - callback if the puppeteer page crashes

Returns a `Promise` that resolves when the page is open.
Returns a `Promise` that resolves to the page that is open.


### stopBrowser()
Expand Down
5 changes: 5 additions & 0 deletions docs/modules/test-utils/browser-test-driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ Parameters:
* `exposeFunctions` (Object) - keys are function names to be added to the page's `window` object, and the values are callback functions to execute in Node.js. See [exposeFunction](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageexposefunctionname-puppeteerfunction) for details.
* `url` (String) - if supplied, will be used instead of the URL returned by the dev server.
* `maxConsoleMessageLength` (Number) - used in `headless: true` mode to crop log messages that are piped to the console. Default `500`.
* `onStart` (Function) - callback when the page is ready and before the test starts running. Receives the following arguments:
- `page` ([Puppeteer.Page](https://pptr.dev/api/puppeteer.page)) - the browser page instance
* `onFinish` (Function) - callback when the test finishes running and the browser is about to close. Receives the following arguments:
- `page` ([Puppeteer.Page](https://pptr.dev/api/puppeteer.page)) - the browser page instance
- `isSuccessful` (Boolean) - if all tests passed.

## Built-in Exposed Globals

Expand Down
7 changes: 7 additions & 0 deletions examples/browser-test-vite/.nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"all": "true",
"include": [
"test/**/*.*"
],
"exclude": []
}
9 changes: 7 additions & 2 deletions examples/browser-test-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
"scripts": {
"start": "npm run test-browser",
"test": "node test/start.js headless",
"test-browser": "node test/start.js"
"test-browser": "node test/start.js",
"coverage": "VITE_COVERAGE=true npm run test && nyc report --reporter=text"
},
"dependencies": {
"@probe.gl/test-utils": "4.0.5",
"tape": "^4.5.1"
},
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"nyc": "^15.1.0",
"typescript": "^5.3.0",
"vite": "^4.0.0"
"vite": "^5.0.0",
"vite-plugin-istanbul": "^5.0.0"
}
}
13 changes: 12 additions & 1 deletion examples/browser-test-vite/test/start.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {BrowserTestDriver} from '@probe.gl/test-utils';
import {createServer} from 'vite';
import fs from 'fs/promises';

const mode = process.argv[2];
const CoverageOutputDir = './.nyc_output';

async function startViteServer(opts) {
const server = await createServer({
Expand All @@ -27,5 +29,14 @@ new BrowserTestDriver().run({
port: 'auto',
start: startViteServer
},
headless: mode === 'headless'
headless: mode === 'headless',
onFinish: async ({page, isSuccessful}) => {
if (!isSuccessful) return;
const coverage = await page.evaluate('window.__coverage__');
if (coverage) {
await fs.rm(CoverageOutputDir, {force: true, recursive: true});
await fs.mkdir(CoverageOutputDir);
await fs.writeFile(`${CoverageOutputDir}/out.json`, JSON.stringify(coverage), 'utf8');
}
}
});
12 changes: 11 additions & 1 deletion examples/browser-test-vite/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {NodeGlobalsPolyfillPlugin} from '@esbuild-plugins/node-globals-polyfill';
import {NodeModulesPolyfillPlugin} from '@esbuild-plugins/node-modules-polyfill';
import istanbul from 'vite-plugin-istanbul';

export default {
optimizeDeps: {
Expand All @@ -16,5 +17,14 @@ export default {
NodeModulesPolyfillPlugin()
]
}
}
},
plugins: [
istanbul({
include: 'test/*',
exclude: ['node_modules'],
extension: ['.js', '.ts', '.cjs', '.mjs', '.jsx', '.tsx'],
// require the env var VITE_COVERAGE to equal true in order to instrument the code
requireEnv: true
})
]
};
10 changes: 7 additions & 3 deletions modules/test-utils/src/browser-automation/browser-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export default class BrowserDriver {
onLoad?: () => void;
onConsole?: (e: ConsoleMessage) => void;
onError?: (e: Error) => void;
}): Promise<void> {
}): Promise<Page> {
const {
url = 'http://localhost',
url,
exposeFunctions = {},
onLoad = noop,
onConsole = noop,
Expand Down Expand Up @@ -96,7 +96,11 @@ export default class BrowserDriver {
}
await Promise.all(promises);

await this.page.goto(url);
if (url) {
await this.page.goto(url);
}

return this.page;
}

async stopBrowser(): Promise<void> {
Expand Down
20 changes: 16 additions & 4 deletions modules/test-utils/src/browser-automation/browser-test-driver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// probe.gl, MIT license
/* eslint-disable camelcase */

import {ScreenshotOptions} from 'puppeteer';
import {ScreenshotOptions, Page} from 'puppeteer';
import fs from 'fs';
import {COLOR, addColor} from '@probe.gl/log';
import diffImages, {DiffImagesOptions} from '../utils/diff-images';
Expand All @@ -25,6 +25,8 @@ type BrowserTestDriverProps = {
browser?: object;
exposeFunctions?: any;
url?: string;
onStart?: (params: {page: Page}) => void | Promise<void>;
onFinish?: (params: {page: Page; isSuccessful: boolean}) => void | Promise<void>;
};

export type DiffImagesOpts = DiffImagesOptions & {
Expand Down Expand Up @@ -80,6 +82,13 @@ export default class BrowserTestDriver extends BrowserDriver {
}

const result = await this._openPage(url, config);

await config.onFinish?.({
// @ts-ignore this.page is always populated after _openPage
page: this.page,
isSuccessful: this.failures === 0
});

this._onFinish(result);
} catch (error: unknown) {
this._fail((error as Error).message || 'puppeteer run failes');
Expand All @@ -91,7 +100,7 @@ export default class BrowserTestDriver extends BrowserDriver {

return this.startBrowser(browserConfig).then(
_ =>
new Promise<string>((resolve, reject) => {
new Promise<string>(async (resolve, reject) => {

Check warning on line 103 in modules/test-utils/src/browser-automation/browser-test-driver.ts

View workflow job for this annotation

GitHub Actions / test (18)

Promise returned in function argument where a void return was expected

Check warning on line 103 in modules/test-utils/src/browser-automation/browser-test-driver.ts

View workflow job for this annotation

GitHub Actions / test (20)

Promise returned in function argument where a void return was expected
const exposeFunctions = {
...config.exposeFunctions,
browserTestDriver_fail: () => this.failures++,
Expand Down Expand Up @@ -120,12 +129,15 @@ export default class BrowserTestDriver extends BrowserDriver {
: url;

// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.openPage({
url: pageUrl,
const page = await this.openPage({
exposeFunctions,
onConsole: event => this._onConsole(event),
onError: reject
});

await config.onStart?.({page});

await page.goto(pageUrl);
})
);
}
Expand Down
Loading

0 comments on commit 8c1e1c2

Please sign in to comment.