chore: readd browser setup hook (#10478)

This commit is contained in:
Nikolay Vitkov 2023-07-03 14:01:29 +02:00 committed by GitHub
parent 87aaed4807
commit d0d738d2fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 320 additions and 177 deletions

View File

@ -17,10 +17,12 @@
import expect from 'expect'; import expect from 'expect';
import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js'; import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
describe('Target.createCDPSession', function () { describe('Target.createCDPSession', function () {
setupTestBrowserHooks();
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -22,7 +22,7 @@ import {attachFrame} from './utils.js';
describe('TargetManager', () => { describe('TargetManager', () => {
/* We use a special browser for this test as we need the --site-per-process flag */ /* We use a special browser for this test as we need the --site-per-process flag */
let testState: Awaited<ReturnType<typeof launch>> & { let state: Awaited<ReturnType<typeof launch>> & {
browser: CDPBrowser; browser: CDPBrowser;
}; };
@ -30,7 +30,7 @@ describe('TargetManager', () => {
const {defaultBrowserOptions} = await getTestState({ const {defaultBrowserOptions} = await getTestState({
skipLaunch: true, skipLaunch: true,
}); });
testState = (await launch( state = (await launch(
Object.assign({}, defaultBrowserOptions, { Object.assign({}, defaultBrowserOptions, {
args: (defaultBrowserOptions.args || []).concat([ args: (defaultBrowserOptions.args || []).concat([
'--site-per-process', '--site-per-process',
@ -45,11 +45,11 @@ describe('TargetManager', () => {
}); });
afterEach(async () => { afterEach(async () => {
await testState.close(); await state.close();
}); });
it('should handle targets', async () => { it('should handle targets', async () => {
const {server, context, browser} = testState; const {server, context, browser} = state;
const targetManager = browser._targetManager(); const targetManager = browser._targetManager();
expect(targetManager.getAvailableTargets().size).toBe(2); expect(targetManager.getAvailableTargets().size).toBe(2);

View File

@ -19,9 +19,11 @@ import assert from 'assert';
import expect from 'expect'; import expect from 'expect';
import {SerializedAXNode} from 'puppeteer-core/internal/common/Accessibility.js'; import {SerializedAXNode} from 'puppeteer-core/internal/common/Accessibility.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Accessibility', function () { describe('Accessibility', function () {
setupTestBrowserHooks();
it('should work', async () => { it('should work', async () => {
const {page, isFirefox} = await getTestState(); const {page, isFirefox} = await getTestState();

View File

@ -20,10 +20,12 @@ import expect from 'expect';
import {TimeoutError} from 'puppeteer'; import {TimeoutError} from 'puppeteer';
import type {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js'; import type {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame, detachFrame} from './utils.js'; import {attachFrame, detachFrame} from './utils.js';
describe('AriaQueryHandler', () => { describe('AriaQueryHandler', () => {
setupTestBrowserHooks();
describe('parseAriaSelector', () => { describe('parseAriaSelector', () => {
it('should find button', async () => { it('should find button', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Browser specs', function () { describe('Browser specs', function () {
setupTestBrowserHooks();
describe('Browser.version', function () { describe('Browser.version', function () {
it('should return version', async () => { it('should return version', async () => {
const {browser} = await getTestState(); const {browser} = await getTestState();

View File

@ -17,10 +17,12 @@
import expect from 'expect'; import expect from 'expect';
import {TimeoutError} from 'puppeteer'; import {TimeoutError} from 'puppeteer';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
describe('BrowserContext', function () { describe('BrowserContext', function () {
setupTestBrowserHooks();
it('should have default context', async () => { it('should have default context', async () => {
const {browser} = await getTestState({ const {browser} = await getTestState({
skipContextCreation: true, skipContextCreation: true,
@ -240,7 +242,6 @@ describe('BrowserContext', function () {
expect(browser.browserContexts()[0]!.id).toBeUndefined(); expect(browser.browserContexts()[0]!.id).toBeUndefined();
const context = await browser.createIncognitoBrowserContext(); const context = await browser.createIncognitoBrowserContext();
console.log('2');
expect(browser.browserContexts()).toHaveLength(2); expect(browser.browserContexts()).toHaveLength(2);
expect(browser.browserContexts()[1]!.id).toBeDefined(); expect(browser.browserContexts()[1]!.id).toBeDefined();
await context.close(); await context.close();

View File

@ -16,10 +16,10 @@
import {IncomingMessage} from 'http'; import {IncomingMessage} from 'http';
import expect from 'expect'; import expect from 'expect';
import {Deferred} from 'puppeteer-core/internal/util/Deferred.js';
import {getTestState, launch} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks, launch} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
// TODO: rename this test suite to launch/connect test suite as it actually // TODO: rename this test suite to launch/connect test suite as it actually
// works across browsers. // works across browsers.
describe('Chromium-Specific Launcher tests', function () { describe('Chromium-Specific Launcher tests', function () {
@ -124,13 +124,19 @@ describe('Chromium-Specific Launcher tests', function () {
await close(); await close();
} }
}); });
it('should fire "disconnected" when closing with pipe', async () => { it('should fire "disconnected" when closing with pipe', async function () {
const {browser, close} = await launch({pipe: true}); const {browser, close} = await launch({pipe: true});
try { try {
const disconnectedEventPromise = waitEvent(browser, 'disconnected'); const disconnectedEventPromise = waitEvent(browser, 'disconnected');
// Emulate user exiting browser. // Emulate user exiting browser.
browser.process()!.kill(); browser.process()!.kill();
await disconnectedEventPromise; await Deferred.race([
disconnectedEventPromise,
Deferred.create({
message: `Failed in after Hook`,
timeout: this.timeout() - 1000,
}),
]);
} finally { } finally {
await close(); await close();
} }
@ -139,6 +145,8 @@ describe('Chromium-Specific Launcher tests', function () {
}); });
describe('Chromium-Specific Page Tests', function () { describe('Chromium-Specific Page Tests', function () {
setupTestBrowserHooks();
it('Page.setRequestInterception should work with intervention headers', async () => { it('Page.setRequestInterception should work with intervention headers', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();

View File

@ -17,10 +17,12 @@
import expect from 'expect'; import expect from 'expect';
import {KnownDevices} from 'puppeteer'; import {KnownDevices} from 'puppeteer';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame} from './utils.js'; import {attachFrame} from './utils.js';
describe('Page.click', function () { describe('Page.click', function () {
setupTestBrowserHooks();
it('should click the button', async () => { it('should click the button', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -15,9 +15,16 @@
*/ */
import expect from 'expect'; import expect from 'expect';
import {expectCookieEquals, getTestState, launch} from './mocha-utils.js'; import {
expectCookieEquals,
getTestState,
launch,
setupTestBrowserHooks,
} from './mocha-utils.js';
describe('Cookie specs', () => { describe('Cookie specs', () => {
setupTestBrowserHooks();
describe('Page.cookies', function () { describe('Page.cookies', function () {
it('should return no cookies in pristine browser context', async () => { it('should return no cookies in pristine browser context', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Coverage specs', function () { describe('Coverage specs', function () {
setupTestBrowserHooks();
describe('JSCoverage', function () { describe('JSCoverage', function () {
it('should work', async () => { it('should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
@ -269,7 +271,6 @@ describe('Coverage specs', function () {
await page.goto(server.PREFIX + '/csscoverage/media.html'); await page.goto(server.PREFIX + '/csscoverage/media.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
expect(coverage).toHaveLength(1); expect(coverage).toHaveLength(1);
console.log(coverage);
expect(coverage[0]!.url).toContain('/csscoverage/media.html'); expect(coverage[0]!.url).toContain('/csscoverage/media.html');
expect(coverage[0]!.ranges).toEqual([{start: 8, end: 40}]); expect(coverage[0]!.ranges).toEqual([{start: 8, end: 40}]);
}); });

View File

@ -15,9 +15,15 @@
*/ */
import expect from 'expect'; import expect from 'expect';
import {expectCookieEquals, getTestState} from './mocha-utils.js'; import {
expectCookieEquals,
getTestState,
setupTestBrowserHooks,
} from './mocha-utils.js';
describe('DefaultBrowserContext', function () { describe('DefaultBrowserContext', function () {
setupTestBrowserHooks();
it('page.cookies() should work', async () => { it('page.cookies() should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import sinon from 'sinon'; import sinon from 'sinon';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Page.Events.Dialog', function () { describe('Page.Events.Dialog', function () {
setupTestBrowserHooks();
it('should fire', async () => { it('should fire', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Input.drag', function () { describe('Input.drag', function () {
setupTestBrowserHooks();
it('should throw an exception if not enabled before usage', async () => { it('should throw an exception if not enabled before usage', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -21,11 +21,14 @@ import sinon from 'sinon';
import { import {
getTestState, getTestState,
setupTestBrowserHooks,
shortWaitForArrayToHaveAtLeastNElements, shortWaitForArrayToHaveAtLeastNElements,
} from './mocha-utils.js'; } from './mocha-utils.js';
import {attachFrame} from './utils.js'; import {attachFrame} from './utils.js';
describe('ElementHandle specs', function () { describe('ElementHandle specs', function () {
setupTestBrowserHooks();
describe('ElementHandle.boundingBox', function () { describe('ElementHandle.boundingBox', function () {
it('should work', async () => { it('should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -17,12 +17,14 @@
import expect from 'expect'; import expect from 'expect';
import {KnownDevices, PredefinedNetworkConditions} from 'puppeteer'; import {KnownDevices, PredefinedNetworkConditions} from 'puppeteer';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
const iPhone = KnownDevices['iPhone 6']; const iPhone = KnownDevices['iPhone 6'];
const iPhoneLandscape = KnownDevices['iPhone 6 landscape']; const iPhoneLandscape = KnownDevices['iPhone 6 landscape'];
describe('Emulation', () => { describe('Emulation', () => {
setupTestBrowserHooks();
describe('Page.viewport', function () { describe('Page.viewport', function () {
it('should get the proper viewport size', async () => { it('should get the proper viewport size', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -16,10 +16,12 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame} from './utils.js'; import {attachFrame} from './utils.js';
describe('Evaluation specs', function () { describe('Evaluation specs', function () {
setupTestBrowserHooks();
describe('Page.evaluate', function () { describe('Page.evaluate', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -20,10 +20,12 @@ import path from 'path';
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
describe('Fixtures', function () { describe('Fixtures', function () {
setupTestBrowserHooks();
it('dumpio option should work with pipe option', async () => { it('dumpio option should work with pipe option', async () => {
const {defaultBrowserOptions, puppeteerPath, headless} = const {defaultBrowserOptions, puppeteerPath, headless} =
await getTestState(); await getTestState();
@ -49,7 +51,6 @@ describe('Fixtures', function () {
await new Promise(resolve => { await new Promise(resolve => {
return res.on('close', resolve); return res.on('close', resolve);
}); });
console.log(dumpioData);
expect(dumpioData).toContain('message from dumpio'); expect(dumpioData).toContain('message from dumpio');
}); });
it('should dump browser process stderr', async () => { it('should dump browser process stderr', async () => {

View File

@ -18,7 +18,7 @@ import expect from 'expect';
import {Frame} from 'puppeteer-core/internal/api/Frame.js'; import {Frame} from 'puppeteer-core/internal/api/Frame.js';
import {CDPSession} from 'puppeteer-core/internal/common/Connection.js'; import {CDPSession} from 'puppeteer-core/internal/common/Connection.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import { import {
attachFrame, attachFrame,
detachFrame, detachFrame,
@ -28,6 +28,8 @@ import {
} from './utils.js'; } from './utils.js';
describe('Frame specs', function () { describe('Frame specs', function () {
setupTestBrowserHooks();
describe('Frame.executionContext', function () { describe('Frame.executionContext', function () {
it('should work', async () => { it('should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -18,9 +18,11 @@ import expect from 'expect';
import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js'; import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js';
import {Page} from 'puppeteer-core/internal/api/Page.js'; import {Page} from 'puppeteer-core/internal/api/Page.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Emulate idle state', () => { describe('Emulate idle state', () => {
setupTestBrowserHooks();
async function getIdleState(page: Page) { async function getIdleState(page: Page) {
const stateElement = (await page.$('#state')) as ElementHandle<HTMLElement>; const stateElement = (await page.$('#state')) as ElementHandle<HTMLElement>;
return await page.evaluate(element => { return await page.evaluate(element => {

View File

@ -17,48 +17,42 @@
import {TLSSocket} from 'tls'; import {TLSSocket} from 'tls';
import expect from 'expect'; import expect from 'expect';
import {Browser} from 'puppeteer-core/internal/api/Browser.js';
import {BrowserContext} from 'puppeteer-core/internal/api/BrowserContext.js';
import {HTTPResponse} from 'puppeteer-core/internal/api/HTTPResponse.js'; import {HTTPResponse} from 'puppeteer-core/internal/api/HTTPResponse.js';
import {Page} from 'puppeteer-core/internal/api/Page.js';
import {getTestState} from './mocha-utils.js'; import {launch} from './mocha-utils.js';
describe('ignoreHTTPSErrors', function () { describe('ignoreHTTPSErrors', function () {
/* Note that this test creates its own browser rather than use /* Note that this test creates its own browser rather than use
* the one provided by the test set-up as we need one * the one provided by the test set-up as we need one
* with ignoreHTTPSErrors set to true * with ignoreHTTPSErrors set to true
*/ */
let browser!: Browser; let state: Awaited<ReturnType<typeof launch>>;
let context: BrowserContext;
let page!: Page;
before(async () => { before(async () => {
const {defaultBrowserOptions, puppeteer} = await getTestState(); state = await launch(
const options = Object.assign(
{ignoreHTTPSErrors: true}, {ignoreHTTPSErrors: true},
defaultBrowserOptions {
after: 'all',
}
); );
// eslint-disable-next-line no-restricted-syntax
browser = await puppeteer.launch(options);
}); });
after(async () => { after(async () => {
await browser.close(); await state.close();
}); });
beforeEach(async () => { beforeEach(async () => {
context = await browser.createIncognitoBrowserContext(); state.context = await state.browser.createIncognitoBrowserContext();
page = await context.newPage(); state.page = await state.context.newPage();
}); });
afterEach(async () => { afterEach(async () => {
await context.close(); await state.context.close();
}); });
describe('Response.securityDetails', function () { describe('Response.securityDetails', function () {
it('should work', async () => { it('should work', async () => {
const {httpsServer} = await getTestState(); const {httpsServer, page} = state;
const [serverRequest, response] = await Promise.all([ const [serverRequest, response] = await Promise.all([
httpsServer.waitForRequest('/empty.html'), httpsServer.waitForRequest('/empty.html'),
@ -79,13 +73,13 @@ describe('ignoreHTTPSErrors', function () {
]); ]);
}); });
it('should be |null| for non-secure requests', async () => { it('should be |null| for non-secure requests', async () => {
const {server} = await getTestState(); const {server, page} = state;
const response = (await page.goto(server.EMPTY_PAGE))!; const response = (await page.goto(server.EMPTY_PAGE))!;
expect(response.securityDetails()).toBe(null); expect(response.securityDetails()).toBe(null);
}); });
it('Network redirects should report SecurityDetails', async () => { it('Network redirects should report SecurityDetails', async () => {
const {httpsServer} = await getTestState(); const {httpsServer, page} = state;
httpsServer.setRedirect('/plzredirect', '/empty.html'); httpsServer.setRedirect('/plzredirect', '/empty.html');
const responses: HTTPResponse[] = []; const responses: HTTPResponse[] = [];
@ -107,7 +101,7 @@ describe('ignoreHTTPSErrors', function () {
}); });
it('should work', async () => { it('should work', async () => {
const {httpsServer} = await getTestState(); const {httpsServer, page} = state;
let error!: Error; let error!: Error;
const response = await page.goto(httpsServer.EMPTY_PAGE).catch(error_ => { const response = await page.goto(httpsServer.EMPTY_PAGE).catch(error_ => {
@ -117,7 +111,7 @@ describe('ignoreHTTPSErrors', function () {
expect(response.ok()).toBe(true); expect(response.ok()).toBe(true);
}); });
it('should work with request interception', async () => { it('should work with request interception', async () => {
const {httpsServer} = await getTestState(); const {httpsServer, page} = state;
await page.setRequestInterception(true); await page.setRequestInterception(true);
page.on('request', request => { page.on('request', request => {
@ -127,7 +121,7 @@ describe('ignoreHTTPSErrors', function () {
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
it('should work with mixed content', async () => { it('should work with mixed content', async () => {
const {server, httpsServer} = await getTestState(); const {server, httpsServer, page} = state;
httpsServer.setRoute('/mixedcontent.html', (_req, res) => { httpsServer.setRoute('/mixedcontent.html', (_req, res) => {
res.end(`<iframe src=${server.EMPTY_PAGE}></iframe>`); res.end(`<iframe src=${server.EMPTY_PAGE}></iframe>`);

View File

@ -18,9 +18,11 @@ import expect from 'expect';
import {PUPPETEER_WORLD} from 'puppeteer-core/internal/common/IsolatedWorlds.js'; import {PUPPETEER_WORLD} from 'puppeteer-core/internal/common/IsolatedWorlds.js';
import {LazyArg} from 'puppeteer-core/internal/common/LazyArg.js'; import {LazyArg} from 'puppeteer-core/internal/common/LazyArg.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('PuppeteerUtil tests', function () { describe('PuppeteerUtil tests', function () {
setupTestBrowserHooks();
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -19,12 +19,14 @@ import path from 'path';
import expect from 'expect'; import expect from 'expect';
import {TimeoutError} from 'puppeteer'; import {TimeoutError} from 'puppeteer';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
const FILE_TO_UPLOAD = path.join(__dirname, '/../assets/file-to-upload.txt'); const FILE_TO_UPLOAD = path.join(__dirname, '/../assets/file-to-upload.txt');
describe('input tests', function () { describe('input tests', function () {
setupTestBrowserHooks();
describe('input', function () { describe('input', function () {
it('should upload the file', async () => { it('should upload the file', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('JSHandle', function () { describe('JSHandle', function () {
setupTestBrowserHooks();
describe('Page.evaluateHandle', function () { describe('Page.evaluateHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
@ -158,6 +160,7 @@ describe('JSHandle', function () {
return new Date('2017-09-26T00:00:00.000Z'); return new Date('2017-09-26T00:00:00.000Z');
}); });
const date = await dateHandle.jsonValue(); const date = await dateHandle.jsonValue();
expect(date).toBeInstanceOf(Date);
expect(date.toISOString()).toEqual('2017-09-26T00:00:00.000Z'); expect(date.toISOString()).toEqual('2017-09-26T00:00:00.000Z');
}); });
it('should throw for circular objects', async () => { it('should throw for circular objects', async () => {

View File

@ -19,10 +19,12 @@ import os from 'os';
import expect from 'expect'; import expect from 'expect';
import {KeyInput} from 'puppeteer-core/internal/common/USKeyboardLayout.js'; import {KeyInput} from 'puppeteer-core/internal/common/USKeyboardLayout.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame} from './utils.js'; import {attachFrame} from './utils.js';
describe('Keyboard', function () { describe('Keyboard', function () {
setupTestBrowserHooks();
it('should type into a textarea', async () => { it('should type into a textarea', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -574,7 +574,9 @@ describe('Launcher specs', function () {
...defaultBrowserOptions, ...defaultBrowserOptions,
args: ['--no-startup-window'], args: ['--no-startup-window'],
}; };
const {browser, close} = await launch(options, {createContext: false}); const {browser, close} = await launch(options, {
createContext: false,
});
try { try {
const pages = await browser.pages(); const pages = await browser.pages();
expect(pages).toHaveLength(0); expect(pages).toHaveLength(0);

View File

@ -22,9 +22,11 @@ import {
} from 'puppeteer-core/internal/api/Locator.js'; } from 'puppeteer-core/internal/api/Locator.js';
import sinon from 'sinon'; import sinon from 'sinon';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Locator', function () { describe('Locator', function () {
setupTestBrowserHooks();
it('should work with a frame', async () => { it('should work with a frame', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -34,6 +34,7 @@ import {
PuppeteerNode, PuppeteerNode,
} from 'puppeteer-core/internal/node/PuppeteerNode.js'; } from 'puppeteer-core/internal/node/PuppeteerNode.js';
import {rmSync} from 'puppeteer-core/internal/node/util/fs.js'; import {rmSync} from 'puppeteer-core/internal/node/util/fs.js';
import {Deferred} from 'puppeteer-core/internal/util/Deferred.js';
import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js'; import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js';
import sinon from 'sinon'; import sinon from 'sinon';
@ -135,6 +136,22 @@ const setupServer = async () => {
return {server, httpsServer}; return {server, httpsServer};
}; };
export const setupTestBrowserHooks = (): void => {
before(async function () {
try {
if (!state.browser) {
state.browser = await puppeteer.launch({
...processVariables.defaultBrowserOptions,
timeout: this.timeout() - 1_000,
});
}
} catch {
// Intentionally empty as `getTestState` will throw
// if browser is not found
}
});
};
export const getTestState = async ( export const getTestState = async (
options: { options: {
skipLaunch?: boolean; skipLaunch?: boolean;
@ -147,25 +164,15 @@ export const getTestState = async (
JSON.stringify(processVariables.defaultBrowserOptions) JSON.stringify(processVariables.defaultBrowserOptions)
); );
if (!state.puppeteer) { state.server?.reset();
const {server, httpsServer} = await setupServer(); state.httpsServer?.reset();
state.puppeteer = puppeteer; if (skipLaunch) {
state.server = server; return state as PuppeteerTestState;
state.httpsServer = httpsServer;
state.isFirefox = processVariables.isFirefox;
state.isChrome = processVariables.isChrome;
state.isHeadless = processVariables.isHeadless;
state.headless = processVariables.headless;
state.puppeteerPath = path.resolve(
path.join(__dirname, '..', '..', 'packages', 'puppeteer')
);
} }
if (!state.browser && !skipLaunch) { if (!state.browser) {
state.browser = await puppeteer.launch( throw new Error('Browser was not set-up in time!');
processVariables.defaultBrowserOptions
);
} }
if (state.context) { if (state.context) {
@ -174,14 +181,10 @@ export const getTestState = async (
state.page = undefined; state.page = undefined;
} }
if (!skipLaunch && !skipContextCreation) { if (!skipContextCreation) {
state.context = await state.browser!.createIncognitoBrowserContext(); state.context = await state.browser!.createIncognitoBrowserContext();
state.page = await state.context.newPage(); state.page = await state.context.newPage();
} }
state.server?.reset();
state.httpsServer?.reset();
return state as PuppeteerTestState; return state as PuppeteerTestState;
}; };
@ -197,7 +200,7 @@ const setupGoldenAssertions = (): void => {
setupGoldenAssertions(); setupGoldenAssertions();
interface PuppeteerTestState { export interface PuppeteerTestState {
browser: Browser; browser: Browser;
context: BrowserContext; context: BrowserContext;
page: Page; page: Page;
@ -253,16 +256,53 @@ const browserNotClosedError = new Error(
'A manually launched browser was not closed!' 'A manually launched browser was not closed!'
); );
export const mochaHooks = { export const mochaHooks = {
async beforeAll(): Promise<void> {
const {server, httpsServer} = await setupServer();
state.puppeteer = puppeteer;
state.server = server;
state.httpsServer = httpsServer;
state.isFirefox = processVariables.isFirefox;
state.isChrome = processVariables.isChrome;
state.isHeadless = processVariables.isHeadless;
state.headless = processVariables.headless;
state.puppeteerPath = path.resolve(
path.join(__dirname, '..', '..', 'packages', 'puppeteer')
);
},
async afterAll(): Promise<void> { async afterAll(): Promise<void> {
await state.browser?.close(); (this as any).timeout(0);
await state.server?.stop(); const lastTestFile = (this as any)?.test?.parent?.suites?.[0]?.file
await state.httpsServer?.stop(); ?.split('/')
?.at(-1);
try {
await Promise.all([
state.server?.stop(),
state.httpsServer?.stop(),
state.browser?.close(),
]);
} catch (error) {
throw new Error(
`Closing defaults (HTTP TestServer, HTTPS TestServer, Browser ) failed in ${lastTestFile}}`
);
}
if (browserCleanupsAfterAll.length > 0) {
await closeLaunched(browserCleanupsAfterAll)();
throw new Error(`Browser was not closed in ${lastTestFile}`);
}
}, },
async afterEach(): Promise<void> { async afterEach(): Promise<void> {
if (browserCleanups.length > 0) { if (browserCleanups.length > 0) {
await closeLaunched();
(this as any).test.error(browserNotClosedError); (this as any).test.error(browserNotClosedError);
await Deferred.race([
closeLaunched(browserCleanups)(),
Deferred.create({
message: `Failed in after Hook`,
timeout: (this as any).timeout() - 1000,
}),
]);
} }
sinon.restore(); sinon.restore();
}, },
@ -381,30 +421,34 @@ export const createTimeout = <T>(
}); });
}; };
let browserCleanups: Array<() => Promise<void>> = []; const browserCleanupsAfterAll: Array<() => Promise<void>> = [];
const browserCleanups: Array<() => Promise<void>> = [];
const closeLaunched = async () => { const closeLaunched = (storage: Array<() => Promise<void>>) => {
let cleanup = browserCleanups.pop(); return async () => {
try { let cleanup = storage.pop();
while (cleanup) { try {
await cleanup(); while (cleanup) {
cleanup = browserCleanups.pop(); await cleanup();
} cleanup = storage.pop();
} catch (error) { }
// If the browser was closed by other mean swallow the error } catch (error) {
// and mark he browser as closed // If the browser was closed by other means, swallow the error
if ((error as any)?.message.includes('Connection closed')) { // and mark the browser as closed.
browserCleanups = []; if ((error as Error)?.message.includes('Connection closed')) {
return; storage.splice(0, storage.length);
} return;
}
throw error; throw error;
} }
};
}; };
export const launch = async ( export const launch = async (
launchOptions: PuppeteerLaunchOptions, launchOptions: PuppeteerLaunchOptions,
options: { options: {
after?: 'each' | 'all';
createContext?: boolean; createContext?: boolean;
createPage?: boolean; createPage?: boolean;
} = {} } = {}
@ -413,17 +457,18 @@ export const launch = async (
close: () => Promise<void>; close: () => Promise<void>;
} }
> => { > => {
const {createContext = true, createPage = true} = options; const {after = 'each', createContext = true, createPage = true} = options;
const initState = await getTestState({ const initState = await getTestState({
skipLaunch: true, skipLaunch: true,
}); });
const cleanupStorage =
after === 'each' ? browserCleanups : browserCleanupsAfterAll;
try { try {
const browser = await puppeteer.launch({ const browser = await puppeteer.launch({
...initState.defaultBrowserOptions, ...initState.defaultBrowserOptions,
...launchOptions, ...launchOptions,
}); });
browserCleanups.push(() => { cleanupStorage.push(() => {
return browser.close(); return browser.close();
}); });
@ -431,13 +476,13 @@ export const launch = async (
let page: Page; let page: Page;
if (createContext) { if (createContext) {
context = await browser.createIncognitoBrowserContext(); context = await browser.createIncognitoBrowserContext();
browserCleanups.push(() => { cleanupStorage.push(() => {
return context.close(); return context.close();
}); });
if (createPage) { if (createPage) {
page = await context.newPage(); page = await context.newPage();
browserCleanups.push(() => { cleanupStorage.push(() => {
return page.close(); return page.close();
}); });
} }
@ -448,10 +493,10 @@ export const launch = async (
browser, browser,
context: context!, context: context!,
page: page!, page: page!,
close: closeLaunched, close: closeLaunched(cleanupStorage),
}; };
} catch (error) { } catch (error) {
await closeLaunched(); await closeLaunched(cleanupStorage)();
throw error; throw error;
} }

View File

@ -20,7 +20,7 @@ import {MouseButton} from 'puppeteer-core/internal/api/Input.js';
import {Page} from 'puppeteer-core/internal/api/Page.js'; import {Page} from 'puppeteer-core/internal/api/Page.js';
import {KeyInput} from 'puppeteer-core/internal/common/USKeyboardLayout.js'; import {KeyInput} from 'puppeteer-core/internal/common/USKeyboardLayout.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
interface ClickData { interface ClickData {
type: string; type: string;
@ -50,6 +50,8 @@ function dimensions(): Dimensions {
} }
describe('Mouse', function () { describe('Mouse', function () {
setupTestBrowserHooks();
it('should click the document', async () => { it('should click the document', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -19,11 +19,14 @@ import {ServerResponse} from 'http';
import expect from 'expect'; import expect from 'expect';
import {Frame, TimeoutError} from 'puppeteer'; import {Frame, TimeoutError} from 'puppeteer';
import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js'; import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js';
import {Deferred} from 'puppeteer-core/internal/util/Deferred.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame, isFavicon, waitEvent} from './utils.js'; import {attachFrame, isFavicon, waitEvent} from './utils.js';
describe('navigation', function () { describe('navigation', function () {
setupTestBrowserHooks();
describe('Page.goto', function () { describe('Page.goto', function () {
it('should work', async () => { it('should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
@ -702,7 +705,7 @@ describe('navigation', function () {
server.setRoute('/frames/style.css', () => {}); server.setRoute('/frames/style.css', () => {});
let frame: Frame | undefined; let frame: Frame | undefined;
let timeout: NodeJS.Timeout | undefined; let timeout: NodeJS.Timeout | undefined;
const eventPromises = Promise.race([ const eventPromises = Deferred.race([
Promise.all([ Promise.all([
waitEvent(page, 'frameattached').then(_frame => { waitEvent(page, 'frameattached').then(_frame => {
return (frame = _frame); return (frame = _frame);
@ -711,10 +714,9 @@ describe('navigation', function () {
return f === frame; return f === frame;
}), }),
]), ]),
new Promise((_, rej) => { Deferred.create({
timeout = setTimeout(() => { message: `should work when subframe issues window.stop()`,
return rej(new Error('Timeout')); timeout: this.timeout() - 1000,
}, this.timeout());
}), }),
]); ]);
const navigationPromise = page.goto( const navigationPromise = page.goto(

View File

@ -22,10 +22,12 @@ import expect from 'expect';
import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js'; import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js';
import {HTTPResponse} from 'puppeteer-core/internal/api/HTTPResponse.js'; import {HTTPResponse} from 'puppeteer-core/internal/api/HTTPResponse.js';
import {getTestState, launch} from './mocha-utils.js'; import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame, isFavicon, waitEvent} from './utils.js'; import {attachFrame, isFavicon, waitEvent} from './utils.js';
describe('network', function () { describe('network', function () {
setupTestBrowserHooks();
describe('Page.Events.Request', function () { describe('Page.Events.Request', function () {
it('should fire for navigation requests', async () => { it('should fire for navigation requests', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -15,48 +15,45 @@
*/ */
import expect from 'expect'; import expect from 'expect';
import {Browser} from 'puppeteer-core/internal/api/Browser.js';
import {BrowserContext} from 'puppeteer-core/internal/api/BrowserContext.js'; import {BrowserContext} from 'puppeteer-core/internal/api/BrowserContext.js';
import {Page} from 'puppeteer-core/internal/api/Page.js';
import {describeWithDebugLogs, getTestState} from './mocha-utils.js'; import {describeWithDebugLogs, getTestState, launch} from './mocha-utils.js';
import {attachFrame, detachFrame, navigateFrame} from './utils.js'; import {attachFrame, detachFrame, navigateFrame} from './utils.js';
describeWithDebugLogs('OOPIF', function () { describeWithDebugLogs('OOPIF', function () {
/* We use a special browser for this test as we need the --site-per-process flag */ /* We use a special browser for this test as we need the --site-per-process flag */
let browser: Browser; let state: Awaited<ReturnType<typeof launch>>;
let context: BrowserContext;
let page: Page;
before(async () => { before(async () => {
const {puppeteer, defaultBrowserOptions} = await getTestState(); const {defaultBrowserOptions} = await getTestState({skipLaunch: true});
// eslint-disable-next-line no-restricted-syntax
browser = await puppeteer.launch( state = await launch(
Object.assign({}, defaultBrowserOptions, { Object.assign({}, defaultBrowserOptions, {
args: (defaultBrowserOptions.args || []).concat([ args: (defaultBrowserOptions.args || []).concat([
'--site-per-process', '--site-per-process',
'--remote-debugging-port=21222', '--remote-debugging-port=21222',
'--host-rules=MAP * 127.0.0.1', '--host-rules=MAP * 127.0.0.1',
]), ]),
}) }),
{after: 'all'}
); );
}); });
beforeEach(async () => { beforeEach(async () => {
context = await browser.createIncognitoBrowserContext(); state.context = await state.browser.createIncognitoBrowserContext();
page = await context.newPage(); state.page = await state.context.newPage();
}); });
afterEach(async () => { afterEach(async () => {
await context.close(); await state.context.close();
}); });
after(async () => { after(async () => {
await browser.close(); await state.close();
}); });
it('should treat OOP iframes and normal iframes the same', async () => { it('should treat OOP iframes and normal iframes the same', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -72,7 +69,7 @@ describeWithDebugLogs('OOPIF', function () {
expect(page.mainFrame().childFrames()).toHaveLength(2); expect(page.mainFrame().childFrames()).toHaveLength(2);
}); });
it('should track navigations within OOP iframes', async () => { it('should track navigations within OOP iframes', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -93,7 +90,7 @@ describeWithDebugLogs('OOPIF', function () {
expect(frame.url()).toContain('/assets/frame.html'); expect(frame.url()).toContain('/assets/frame.html');
}); });
it('should support OOP iframes becoming normal iframes again', async () => { it('should support OOP iframes becoming normal iframes again', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -114,7 +111,7 @@ describeWithDebugLogs('OOPIF', function () {
expect(page.frames()).toHaveLength(2); expect(page.frames()).toHaveLength(2);
}); });
it('should support frames within OOP frames', async () => { it('should support frames within OOP frames', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const frame1Promise = page.waitForFrame(frame => { const frame1Promise = page.waitForFrame(frame => {
@ -143,7 +140,7 @@ describeWithDebugLogs('OOPIF', function () {
).toMatch(/frames\/frame\.html$/); ).toMatch(/frames\/frame\.html$/);
}); });
it('should support OOP iframes getting detached', async () => { it('should support OOP iframes getting detached', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -164,7 +161,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should support wait for navigation for transitions from local to OOPIF', async () => { it('should support wait for navigation for transitions from local to OOPIF', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -187,7 +184,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should keep track of a frames OOP state', async () => { it('should keep track of a frames OOP state', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -205,7 +202,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should support evaluating in oop iframes', async () => { it('should support evaluating in oop iframes', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
@ -230,7 +227,7 @@ describeWithDebugLogs('OOPIF', function () {
expect(result).toBe('Test 123!'); expect(result).toBe('Test 123!');
}); });
it('should provide access to elements', async () => { it('should provide access to elements', async () => {
const {server, isHeadless, headless} = await getTestState(); const {server, isHeadless, headless, page} = state;
if (!isHeadless || headless === 'new') { if (!isHeadless || headless === 'new') {
// TODO: this test is partially blocked on crbug.com/1334119. Enable test once // TODO: this test is partially blocked on crbug.com/1334119. Enable test once
@ -276,7 +273,7 @@ describeWithDebugLogs('OOPIF', function () {
await frame.waitForSelector('#clicked'); await frame.waitForSelector('#clicked');
}); });
it('should report oopif frames', async () => { it('should report oopif frames', async () => {
const {server} = await getTestState(); const {server, page, context} = state;
const frame = page.waitForFrame(frame => { const frame = page.waitForFrame(frame => {
return frame.url().endsWith('/oopif.html'); return frame.url().endsWith('/oopif.html');
@ -288,7 +285,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should wait for inner OOPIFs', async () => { it('should wait for inner OOPIFs', async () => {
const {server} = await getTestState(); const {server, page, context} = state;
await page.goto(`http://mainframe:${server.PORT}/main-frame.html`); await page.goto(`http://mainframe:${server.PORT}/main-frame.html`);
const frame2 = await page.waitForFrame(frame => { const frame2 = await page.waitForFrame(frame => {
return frame.url().endsWith('inner-frame2.html'); return frame.url().endsWith('inner-frame2.html');
@ -307,7 +304,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should load oopif iframes with subresources and request interception', async () => { it('should load oopif iframes with subresources and request interception', async () => {
const {server} = await getTestState(); const {server, page, context} = state;
const frame = page.waitForFrame(frame => { const frame = page.waitForFrame(frame => {
return frame.url().endsWith('/oopif.html'); return frame.url().endsWith('/oopif.html');
@ -321,7 +318,7 @@ describeWithDebugLogs('OOPIF', function () {
expect(oopifs(context)).toHaveLength(1); expect(oopifs(context)).toHaveLength(1);
}); });
it('should support frames within OOP iframes', async () => { it('should support frames within OOP iframes', async () => {
const {server} = await getTestState(); const {server, page} = state;
const oopIframePromise = page.waitForFrame(frame => { const oopIframePromise = page.waitForFrame(frame => {
return frame.url().endsWith('/oopif.html'); return frame.url().endsWith('/oopif.html');
@ -352,7 +349,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('clickablePoint, boundingBox, boxModel should work for elements inside OOPIFs', async () => { it('clickablePoint, boundingBox, boxModel should work for elements inside OOPIFs', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame(frame => { const framePromise = page.waitForFrame(frame => {
return page.frames().indexOf(frame) === 1; return page.frames().indexOf(frame) === 1;
@ -398,7 +395,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should detect existing OOPIFs when Puppeteer connects to an existing page', async () => { it('should detect existing OOPIFs when Puppeteer connects to an existing page', async () => {
const {server, puppeteer} = await getTestState(); const {server, puppeteer, page, context} = state;
const frame = page.waitForFrame(frame => { const frame = page.waitForFrame(frame => {
return frame.url().endsWith('/oopif.html'); return frame.url().endsWith('/oopif.html');
@ -418,7 +415,7 @@ describeWithDebugLogs('OOPIF', function () {
}); });
it('should support lazy OOP frames', async () => { it('should support lazy OOP frames', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.PREFIX + '/lazy-oopif-frame.html'); await page.goto(server.PREFIX + '/lazy-oopif-frame.html');
await page.setViewport({width: 1000, height: 1000}); await page.setViewport({width: 1000, height: 1000});
@ -432,7 +429,7 @@ describeWithDebugLogs('OOPIF', function () {
describe('waitForFrame', () => { describe('waitForFrame', () => {
it('should resolve immediately if the frame already exists', async () => { it('should resolve immediately if the frame already exists', async () => {
const {server} = await getTestState(); const {server, page} = state;
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await attachFrame( await attachFrame(

View File

@ -25,10 +25,12 @@ import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
import {CDPPage} from 'puppeteer-core/internal/common/Page.js'; import {CDPPage} from 'puppeteer-core/internal/common/Page.js';
import sinon from 'sinon'; import sinon from 'sinon';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {attachFrame, detachFrame, isFavicon, waitEvent} from './utils.js'; import {attachFrame, detachFrame, isFavicon, waitEvent} from './utils.js';
describe('Page', function () { describe('Page', function () {
setupTestBrowserHooks();
describe('Page.close', function () { describe('Page.close', function () {
it('should reject all promises when page is closed', async () => { it('should reject all promises when page is closed', async () => {
const {context} = await getTestState(); const {context} = await getTestState();

View File

@ -19,9 +19,11 @@ import expect from 'expect';
import {Puppeteer} from 'puppeteer-core'; import {Puppeteer} from 'puppeteer-core';
import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js'; import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Query handler tests', function () { describe('Query handler tests', function () {
setupTestBrowserHooks();
describe('Pierce selectors', function () { describe('Pierce selectors', function () {
async function setUpPage(): ReturnType<typeof getTestState> { async function setUpPage(): ReturnType<typeof getTestState> {
const state = await getTestState(); const state = await getTestState();

View File

@ -17,9 +17,11 @@ import expect from 'expect';
import {Puppeteer} from 'puppeteer'; import {Puppeteer} from 'puppeteer';
import type {CustomQueryHandler} from 'puppeteer-core/internal/common/CustomQueryHandler.js'; import type {CustomQueryHandler} from 'puppeteer-core/internal/common/CustomQueryHandler.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('querySelector', function () { describe('querySelector', function () {
setupTestBrowserHooks();
describe('Page.$eval', function () { describe('Page.$eval', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -25,10 +25,12 @@ import {
} from 'puppeteer-core/internal/api/HTTPRequest.js'; } from 'puppeteer-core/internal/api/HTTPRequest.js';
import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js'; import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {isFavicon, waitEvent} from './utils.js'; import {isFavicon, waitEvent} from './utils.js';
describe('request interception', function () { describe('request interception', function () {
setupTestBrowserHooks();
describe('Page.setRequestInterception', function () { describe('Page.setRequestInterception', function () {
const expectedActions: ActionResult[] = ['abort', 'continue', 'respond']; const expectedActions: ActionResult[] = ['abort', 'continue', 'respond'];
while (expectedActions.length > 0) { while (expectedActions.length > 0) {

View File

@ -21,10 +21,12 @@ import expect from 'expect';
import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js'; import {HTTPRequest} from 'puppeteer-core/internal/api/HTTPRequest.js';
import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js'; import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {isFavicon, waitEvent} from './utils.js'; import {isFavicon, waitEvent} from './utils.js';
describe('request interception', function () { describe('request interception', function () {
setupTestBrowserHooks();
describe('Page.setRequestInterception', function () { describe('Page.setRequestInterception', function () {
it('should intercept', async () => { it('should intercept', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -16,9 +16,11 @@
import expect from 'expect'; import expect from 'expect';
import {getTestState, launch} from './mocha-utils.js'; import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
describe('Screenshots', function () { describe('Screenshots', function () {
setupTestBrowserHooks();
describe('Page.screenshot', function () { describe('Page.screenshot', function () {
it('should work', async () => { it('should work', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -18,12 +18,19 @@ import assert from 'assert';
import expect from 'expect'; import expect from 'expect';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
const FILENAME = __filename.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&'); const FILENAME = __filename.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
const parseStackTrace = (stack: string): string => {
stack = stack.replace(new RegExp(FILENAME, 'g'), '<filename>');
stack = stack.replace(/<filename>:(\d+):(\d+)/g, '<filename>:<line>:<col>');
return stack;
};
describe('Stack trace', function () { describe('Stack trace', function () {
setupTestBrowserHooks();
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
@ -39,10 +46,12 @@ describe('Stack trace', function () {
expect(error.message).toEqual('Test'); expect(error.message).toEqual('Test');
assert(error.stack); assert(error.stack);
error.stack = error.stack.replace(new RegExp(FILENAME, 'g'), '<filename>'); error.stack = error.stack.replace(new RegExp(FILENAME, 'g'), '<filename>');
expect(error.stack.split('\n at ').slice(0, 2)).toMatchObject({ expect(
parseStackTrace(error.stack).split('\n at ').slice(0, 2)
).toMatchObject({
...[ ...[
'Error: Test', 'Error: Test',
'evaluate (evaluate at Context.<anonymous> (<filename>:30:14), <anonymous>:1:18)', 'evaluate (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:1:18)',
], ],
}); });
}); });
@ -61,11 +70,12 @@ describe('Stack trace', function () {
expect(error.name).toEqual('Error'); expect(error.name).toEqual('Error');
expect(error.message).toEqual('Test'); expect(error.message).toEqual('Test');
assert(error.stack); assert(error.stack);
error.stack = error.stack.replace(new RegExp(FILENAME, 'g'), '<filename>'); expect(
expect(error.stack.split('\n at ').slice(0, 2)).toMatchObject({ parseStackTrace(error.stack).split('\n at ').slice(0, 2)
).toMatchObject({
...[ ...[
'Error: Test', 'Error: Test',
'evaluateHandle (evaluateHandle at Context.<anonymous> (<filename>:50:14), <anonymous>:1:18)', 'evaluateHandle (evaluateHandle at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:1:18)',
], ],
}); });
}); });
@ -89,12 +99,13 @@ describe('Stack trace', function () {
expect(error.name).toEqual('Error'); expect(error.name).toEqual('Error');
expect(error.message).toEqual('Test'); expect(error.message).toEqual('Test');
assert(error.stack); assert(error.stack);
error.stack = error.stack.replace(new RegExp(FILENAME, 'g'), '<filename>'); expect(
expect(error.stack.split('\n at ').slice(0, 3)).toMatchObject({ parseStackTrace(error.stack).split('\n at ').slice(0, 3)
).toMatchObject({
...[ ...[
'Error: Test', 'Error: Test',
'evaluateHandle (evaluateHandle at Context.<anonymous> (<filename>:69:36), <anonymous>:2:22)', 'evaluateHandle (evaluateHandle at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:2:22)',
'evaluate (evaluate at Context.<anonymous> (<filename>:75:14), <anonymous>:1:12)', 'evaluate (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:1:12)',
], ],
}); });
}); });
@ -125,15 +136,16 @@ describe('Stack trace', function () {
expect(error.name).toEqual('Error'); expect(error.name).toEqual('Error');
expect(error.message).toEqual('Test'); expect(error.message).toEqual('Test');
assert(error.stack); assert(error.stack);
error.stack = error.stack.replace(new RegExp(FILENAME, 'g'), '<filename>'); expect(
expect(error.stack.split('\n at ').slice(0, 6)).toMatchObject({ parseStackTrace(error.stack).split('\n at ').slice(0, 6)
).toMatchObject({
...[ ...[
'Error: Test', 'Error: Test',
'a (evaluate at Context.<anonymous> (<filename>:96:14), <anonymous>:2:22)', 'a (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:2:22)',
'b (evaluate at Context.<anonymous> (<filename>:96:14), <anonymous>:5:16)', 'b (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:5:16)',
'c (evaluate at Context.<anonymous> (<filename>:96:14), <anonymous>:8:16)', 'c (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:8:16)',
'd (evaluate at Context.<anonymous> (<filename>:96:14), <anonymous>:11:16)', 'd (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:11:16)',
'evaluate (evaluate at Context.<anonymous> (<filename>:96:14), <anonymous>:13:12)', 'evaluate (evaluate at Context.<anonymous> (<filename>:<line>:<col>), <anonymous>:13:12)',
], ],
}); });
}); });

View File

@ -21,10 +21,12 @@ import {TimeoutError} from 'puppeteer';
import {Page} from 'puppeteer-core/internal/api/Page.js'; import {Page} from 'puppeteer-core/internal/api/Page.js';
import {Target} from 'puppeteer-core/internal/common/Target.js'; import {Target} from 'puppeteer-core/internal/common/Target.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
describe('Target', function () { describe('Target', function () {
setupTestBrowserHooks();
it('Browser.targets should return all of the targets', async () => { it('Browser.targets should return all of the targets', async () => {
const {browser} = await getTestState(); const {browser} = await getTestState();

View File

@ -17,9 +17,11 @@
import expect from 'expect'; import expect from 'expect';
import {KnownDevices, BoundingBox} from 'puppeteer'; import {KnownDevices, BoundingBox} from 'puppeteer';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Touchscreen', function () { describe('Touchscreen', function () {
setupTestBrowserHooks();
it('should tap the button', async () => { it('should tap the button', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
const iPhone = KnownDevices['iPhone 6']!; const iPhone = KnownDevices['iPhone 6']!;

View File

@ -18,10 +18,16 @@ import expect from 'expect';
import {TimeoutError, ElementHandle} from 'puppeteer'; import {TimeoutError, ElementHandle} from 'puppeteer';
import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js'; import {isErrorLike} from 'puppeteer-core/internal/util/ErrorLike.js';
import {createTimeout, getTestState} from './mocha-utils.js'; import {
createTimeout,
getTestState,
setupTestBrowserHooks,
} from './mocha-utils.js';
import {attachFrame, detachFrame} from './utils.js'; import {attachFrame, detachFrame} from './utils.js';
describe('waittask specs', function () { describe('waittask specs', function () {
setupTestBrowserHooks();
describe('Frame.waitForFunction', function () { describe('Frame.waitForFunction', function () {
it('should accept a string', async () => { it('should accept a string', async () => {
const {page} = await getTestState(); const {page} = await getTestState();

View File

@ -18,10 +18,12 @@ import expect from 'expect';
import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js'; import {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
import {WebWorker} from 'puppeteer-core/internal/common/WebWorker.js'; import {WebWorker} from 'puppeteer-core/internal/common/WebWorker.js';
import {getTestState} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {waitEvent} from './utils.js'; import {waitEvent} from './utils.js';
describe('Workers', function () { describe('Workers', function () {
setupTestBrowserHooks();
it('Page.workers', async () => { it('Page.workers', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();

View File

@ -135,12 +135,6 @@ export function getExpectationUpdates(
const output: Map<string, RecommendedExpectation> = new Map(); const output: Map<string, RecommendedExpectation> = new Map();
for (const pass of results.passes) { for (const pass of results.passes) {
// If an error occurs during a hook
// the error not have a file associated with it
if (!pass.file) {
continue;
}
const expectationEntry = findEffectiveExpectationForTest( const expectationEntry = findEffectiveExpectationForTest(
expectations, expectations,
pass pass
@ -171,6 +165,15 @@ export function getExpectationUpdates(
// If an error occurs during a hook // If an error occurs during a hook
// the error not have a file associated with it // the error not have a file associated with it
if (!failure.file) { if (!failure.file) {
addEntry({
expectation: {
testIdPattern: 'Hook failed!',
platforms: context.platforms,
parameters: context.parameters,
expectations: [],
},
action: 'add',
});
continue; continue;
} }