From 3d56a9e76f5f4460cb837fd84e5f2763f731e79d Mon Sep 17 00:00:00 2001 From: Maja Frydrychowicz Date: Fri, 12 Jun 2020 09:55:51 -0400 Subject: [PATCH] chore: add test configuration options for running tests against multiple products (#5964) * chore: remove "Extracting..." log message Fixes #5741. * test: support extra Launcher options and skips The extra Launcher options and skipping conditions enable unit tests to be run more easily by third-parties, e.g. browser vendors that are interested in Puppeteer support. Extra Launcher options were previously removed as part of switching away from the custom test harness. * test: enable more tests for Firefox --- src/BrowserFetcher.ts | 3 - test/README.md | 7 +- test/browsercontext.spec.js | 33 +++--- test/click.spec.js | 36 +++--- test/cookies.spec.js | 52 ++++----- test/elementhandle.spec.js | 2 +- test/emulation.spec.js | 2 +- test/evaluation.spec.js | 66 +++++------ test/fixtures.spec.js | 2 +- test/ignorehttpserrors.spec.js | 8 +- test/jshandle.spec.js | 4 +- test/keyboard.spec.js | 2 +- test/launcher.spec.js | 76 ++++++------- test/mocha-utils.js | 44 ++++++-- test/navigation.spec.js | 195 ++++++++++++++------------------- test/network.spec.js | 8 +- test/page.spec.js | 16 +-- test/queryselector.spec.js | 20 ++-- test/screenshot.spec.js | 77 ++++++------- test/waittask.spec.js | 68 ++++++------ 20 files changed, 344 insertions(+), 377 deletions(-) diff --git a/src/BrowserFetcher.ts b/src/BrowserFetcher.ts index 608dc0bf22f7d..cd60777781f06 100644 --- a/src/BrowserFetcher.ts +++ b/src/BrowserFetcher.ts @@ -429,9 +429,6 @@ function extractTar(tarPath: string, folderPath: string): Promise { tarStream.on('error', reject); tarStream.on('finish', fulfill); const readStream = fs.createReadStream(tarPath); - readStream.on('data', () => { - process.stdout.write('\rExtracting...'); - }); readStream.pipe(bzip()).pipe(tarStream); }); } diff --git a/test/README.md b/test/README.md index 11a83310a0607..304e3e0b0a41b 100644 --- a/test/README.md +++ b/test/README.md @@ -24,11 +24,14 @@ If your test needs a Puppeteer page and context, you can use the `setupTestPageA The best place to look is an existing test to see how they use the helpers. -## Skipping tests for Firefox +## Skipping tests in specific conditions Tests that are not expected to pass in Firefox can be skipped. You can skip an individual test by using `itFailsFirefox` rather than `it`. Similarly you can skip a describe block with `describeFailsFirefox`. -There is also `describeChromeOnly` which will only execute the test if running in Chromium. Note that this is different from `describeFailsFirefox`: the goal is to get any `FailsFirefox` calls passing in Firefox, whereas `describeChromeOnly` should be used to test behaviour that will only ever apply in Chromium. +There is also `describeChromeOnly` and `itChromeOnly` which will only execute the test if running in Chromium. Note that this is different from `describeFailsFirefox`: the goal is to get any `FailsFirefox` calls passing in Firefox, whereas `describeChromeOnly` should be used to test behaviour that will only ever apply in Chromium. + +There are also tests that assume a normal install flow, with browser binaries ending up in `.local-`, for example. Such tests are skipped with +`itOnlyRegularInstall` which checks `BINARY` and `PUPPETEER_ALT_INSTALL` environment variables. [Mocha]: https://mochajs.org/ [Expect]: https://www.npmjs.com/package/expect diff --git a/test/browsercontext.spec.js b/test/browsercontext.spec.js index 130870af9b456..8d29a6ab9db27 100644 --- a/test/browsercontext.spec.js +++ b/test/browsercontext.spec.js @@ -20,7 +20,7 @@ const utils = require('./utils'); describe('BrowserContext', function () { setupTestBrowserHooks(); - itFailsFirefox('should have default context', async () => { + it('should have default context', async () => { const { browser } = getTestState(); expect(browser.browserContexts().length).toEqual(1); const defaultContext = browser.browserContexts()[0]; @@ -30,7 +30,7 @@ describe('BrowserContext', function () { expect(browser.defaultBrowserContext()).toBe(defaultContext); expect(error.message).toContain('cannot be closed'); }); - itFailsFirefox('should create new incognito context', async () => { + it('should create new incognito context', async () => { const { browser } = getTestState(); expect(browser.browserContexts().length).toBe(1); @@ -41,22 +41,19 @@ describe('BrowserContext', function () { await context.close(); expect(browser.browserContexts().length).toBe(1); }); - itFailsFirefox( - 'should close all belonging targets once closing context', - async () => { - const { browser } = getTestState(); - - expect((await browser.pages()).length).toBe(1); - - const context = await browser.createIncognitoBrowserContext(); - await context.newPage(); - expect((await browser.pages()).length).toBe(2); - expect((await context.pages()).length).toBe(1); - - await context.close(); - expect((await browser.pages()).length).toBe(1); - } - ); + it('should close all belonging targets once closing context', async () => { + const { browser } = getTestState(); + + expect((await browser.pages()).length).toBe(1); + + const context = await browser.createIncognitoBrowserContext(); + await context.newPage(); + expect((await browser.pages()).length).toBe(2); + expect((await context.pages()).length).toBe(1); + + await context.close(); + expect((await browser.pages()).length).toBe(1); + }); itFailsFirefox('window.open should use parent tab context', async () => { const { browser, server } = getTestState(); diff --git a/test/click.spec.js b/test/click.spec.js index 85f3bfc5c9a96..cc8be5a6806a6 100644 --- a/test/click.spec.js +++ b/test/click.spec.js @@ -32,7 +32,7 @@ describe('Page.click', function () { await page.click('button'); expect(await page.evaluate(() => result)).toBe('Clicked'); }); - itFailsFirefox('should click svg', async () => { + it('should click svg', async () => { const { page } = getTestState(); await page.setContent(` @@ -55,12 +55,10 @@ describe('Page.click', function () { } ); // @see https://github.com/puppeteer/puppeteer/issues/4281 - itFailsFirefox( - 'should click on a span with an inline element inside', - async () => { - const { page } = getTestState(); + it('should click on a span with an inline element inside', async () => { + const { page } = getTestState(); - await page.setContent(` + await page.setContent(` `); - await page.click('span'); - expect(await page.evaluate(() => window.CLICKED)).toBe(42); - } - ); + await page.click('span'); + expect(await page.evaluate(() => window.CLICKED)).toBe(42); + }); it('should not throw UnhandledPromiseRejection when page closes', async () => { const { page } = getTestState(); @@ -98,12 +95,10 @@ describe('Page.click', function () { await Promise.all([page.click('a'), page.waitForNavigation()]); expect(page.url()).toBe(server.PREFIX + '/wrappedlink.html#clicked'); }); - itFailsFirefox( - 'should click when one of inline box children is outside of viewport', - async () => { - const { page } = getTestState(); + it('should click when one of inline box children is outside of viewport', async () => { + const { page } = getTestState(); - await page.setContent(` + await page.setContent(` woofdoggo `); - await page.click('span'); - expect(await page.evaluate(() => window.CLICKED)).toBe(42); - } - ); + await page.click('span'); + expect(await page.evaluate(() => window.CLICKED)).toBe(42); + }); it('should select the text by triple clicking', async () => { const { page, server } = getTestState(); @@ -244,7 +238,7 @@ describe('Page.click', function () { ) ).toBe('clicked'); }); - itFailsFirefox('should double click the button', async () => { + it('should double click the button', async () => { const { page, server } = getTestState(); await page.goto(server.PREFIX + '/input/button.html'); @@ -290,7 +284,7 @@ describe('Page.click', function () { ).toBe('context menu'); }); // @see https://github.com/puppeteer/puppeteer/issues/206 - itFailsFirefox('should click links which cause navigation', async () => { + it('should click links which cause navigation', async () => { const { page, server } = getTestState(); await page.setContent(`empty.html`); diff --git a/test/cookies.spec.js b/test/cookies.spec.js index 7d0f86a60824b..2408518889ad3 100644 --- a/test/cookies.spec.js +++ b/test/cookies.spec.js @@ -220,21 +220,18 @@ describe('Cookie specs', () => { }) ).toEqual(['foo=bar', 'password=123456']); }); - itFailsFirefox( - 'should have |expires| set to |-1| for session cookies', - async () => { - const { page, server } = getTestState(); + it('should have |expires| set to |-1| for session cookies', async () => { + const { page, server } = getTestState(); - await page.goto(server.EMPTY_PAGE); - await page.setCookie({ - name: 'password', - value: '123456', - }); - const cookies = await page.cookies(); - expect(cookies[0].session).toBe(true); - expect(cookies[0].expires).toBe(-1); - } - ); + await page.goto(server.EMPTY_PAGE); + await page.setCookie({ + name: 'password', + value: '123456', + }); + const cookies = await page.cookies(); + expect(cookies[0].session).toBe(true); + expect(cookies[0].expires).toBe(-1); + }); itFailsFirefox('should set cookie with reasonable defaults', async () => { const { page, server } = getTestState(); @@ -348,22 +345,19 @@ describe('Cookie specs', () => { expect(cookie.secure).toBe(true); } ); - itFailsFirefox( - 'should be able to set unsecure cookie for HTTP website', - async () => { - const { page, server } = getTestState(); + it('should be able to set unsecure cookie for HTTP website', async () => { + const { page, server } = getTestState(); - await page.goto(server.EMPTY_PAGE); - const HTTP_URL = 'http://example.com'; - await page.setCookie({ - url: HTTP_URL, - name: 'foo', - value: 'bar', - }); - const [cookie] = await page.cookies(HTTP_URL); - expect(cookie.secure).toBe(false); - } - ); + await page.goto(server.EMPTY_PAGE); + const HTTP_URL = 'http://example.com'; + await page.setCookie({ + url: HTTP_URL, + name: 'foo', + value: 'bar', + }); + const [cookie] = await page.cookies(HTTP_URL); + expect(cookie.secure).toBe(false); + }); itFailsFirefox('should set a cookie on a different domain', async () => { const { page, server } = getTestState(); diff --git a/test/elementhandle.spec.js b/test/elementhandle.spec.js index 881846e6ba9c4..2e66f8378b5cb 100644 --- a/test/elementhandle.spec.js +++ b/test/elementhandle.spec.js @@ -233,7 +233,7 @@ describe('ElementHandle specs', function () { 'Node is either not visible or not an HTMLElement' ); }); - itFailsFirefox('should throw for
elements', async () => { + it('should throw for
elements', async () => { const { page } = getTestState(); await page.setContent('hello
goodbye'); diff --git a/test/emulation.spec.js b/test/emulation.spec.js index 9c5e1a449a55d..6a1466519c4d2 100644 --- a/test/emulation.spec.js +++ b/test/emulation.spec.js @@ -127,7 +127,7 @@ describe('Emulation', () => { 'iPhone' ); }); - it('should support clicking', async () => { + itFailsFirefox('should support clicking', async () => { const { page, server } = getTestState(); await page.emulate(iPhone); diff --git a/test/evaluation.spec.js b/test/evaluation.spec.js index 686d620516aa9..2d870583ad901 100644 --- a/test/evaluation.spec.js +++ b/test/evaluation.spec.js @@ -35,31 +35,31 @@ describe('Evaluation specs', function () { const result = await page.evaluate(() => 7 * 3); expect(result).toBe(21); }); - (bigint ? itFailsFirefox : xit)('should transfer BigInt', async () => { + (bigint ? it : xit)('should transfer BigInt', async () => { const { page } = getTestState(); const result = await page.evaluate((a) => a, BigInt(42)); expect(result).toBe(BigInt(42)); }); - itFailsFirefox('should transfer NaN', async () => { + it('should transfer NaN', async () => { const { page } = getTestState(); const result = await page.evaluate((a) => a, NaN); expect(Object.is(result, NaN)).toBe(true); }); - itFailsFirefox('should transfer -0', async () => { + it('should transfer -0', async () => { const { page } = getTestState(); const result = await page.evaluate((a) => a, -0); expect(Object.is(result, -0)).toBe(true); }); - itFailsFirefox('should transfer Infinity', async () => { + it('should transfer Infinity', async () => { const { page } = getTestState(); const result = await page.evaluate((a) => a, Infinity); expect(Object.is(result, Infinity)).toBe(true); }); - itFailsFirefox('should transfer -Infinity', async () => { + it('should transfer -Infinity', async () => { const { page } = getTestState(); const result = await page.evaluate((a) => a, -Infinity); @@ -202,31 +202,31 @@ describe('Evaluation specs', function () { expect(result).not.toBe(object); expect(result).toEqual(object); }); - (bigint ? itFailsFirefox : xit)('should return BigInt', async () => { + (bigint ? it : xit)('should return BigInt', async () => { const { page } = getTestState(); const result = await page.evaluate(() => BigInt(42)); expect(result).toBe(BigInt(42)); }); - itFailsFirefox('should return NaN', async () => { + it('should return NaN', async () => { const { page } = getTestState(); const result = await page.evaluate(() => NaN); expect(Object.is(result, NaN)).toBe(true); }); - itFailsFirefox('should return -0', async () => { + it('should return -0', async () => { const { page } = getTestState(); const result = await page.evaluate(() => -0); expect(Object.is(result, -0)).toBe(true); }); - itFailsFirefox('should return Infinity', async () => { + it('should return Infinity', async () => { const { page } = getTestState(); const result = await page.evaluate(() => Infinity); expect(Object.is(result, Infinity)).toBe(true); }); - itFailsFirefox('should return -Infinity', async () => { + it('should return -Infinity', async () => { const { page } = getTestState(); const result = await page.evaluate(() => -Infinity); @@ -298,7 +298,7 @@ describe('Evaluation specs', function () { const result = await page.evaluate('2 + 5;\n// do some math!'); expect(result).toBe(7); }); - itFailsFirefox('should accept element handle as an argument', async () => { + it('should accept element handle as an argument', async () => { const { page } = getTestState(); await page.setContent('
42
'); @@ -306,22 +306,19 @@ describe('Evaluation specs', function () { const text = await page.evaluate((e) => e.textContent, element); expect(text).toBe('42'); }); - itFailsFirefox( - 'should throw if underlying element was disposed', - async () => { - const { page } = getTestState(); + it('should throw if underlying element was disposed', async () => { + const { page } = getTestState(); - await page.setContent('
39
'); - const element = await page.$('section'); - expect(element).toBeTruthy(); - await element.dispose(); - let error = null; - await page - .evaluate((e) => e.textContent, element) - .catch((error_) => (error = error_)); - expect(error.message).toContain('JSHandle is disposed'); - } - ); + await page.setContent('
39
'); + const element = await page.$('section'); + expect(element).toBeTruthy(); + await element.dispose(); + let error = null; + await page + .evaluate((e) => e.textContent, element) + .catch((error_) => (error = error_)); + expect(error.message).toContain('JSHandle is disposed'); + }); itFailsFirefox( 'should throw if elementHandles are from other frames', async () => { @@ -376,17 +373,14 @@ describe('Evaluation specs', function () { expect(result).toEqual([42]); } ); - itFailsFirefox( - 'should transfer 100Mb of data from page to node.js', - async function () { - const { page } = getTestState(); + it('should transfer 100Mb of data from page to node.js', async function () { + const { page } = getTestState(); - const a = await page.evaluate(() => - Array(100 * 1024 * 1024 + 1).join('a') - ); - expect(a.length).toBe(100 * 1024 * 1024); - } - ); + const a = await page.evaluate(() => + Array(100 * 1024 * 1024 + 1).join('a') + ); + expect(a.length).toBe(100 * 1024 * 1024); + }); it('should throw error with detailed information on exception inside promise ', async () => { const { page } = getTestState(); diff --git a/test/fixtures.spec.js b/test/fixtures.spec.js index 62af097db8f30..cb577ad3c5fb1 100644 --- a/test/fixtures.spec.js +++ b/test/fixtures.spec.js @@ -20,7 +20,7 @@ const { getTestState } = require('./mocha-utils'); const path = require('path'); describe('Fixtures', function () { - itFailsFirefox('dumpio option should work with pipe option ', async () => { + itChromeOnly('dumpio option should work with pipe option ', async () => { const { defaultBrowserOptions, puppeteerPath } = getTestState(); let dumpioData = ''; diff --git a/test/ignorehttpserrors.spec.js b/test/ignorehttpserrors.spec.js index d4871b90450d8..170088ae270df 100644 --- a/test/ignorehttpserrors.spec.js +++ b/test/ignorehttpserrors.spec.js @@ -17,7 +17,7 @@ const expect = require('expect'); const { getTestState } = require('./mocha-utils'); -describeFailsFirefox('ignoreHTTPSErrors', function () { +describe('ignoreHTTPSErrors', function () { /* Note that this test creates its own browser rather than use * the one provided by the test set-up as we need one * with ignoreHTTPSErrors set to true @@ -51,7 +51,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () { page = null; }); - describe('Response.securityDetails', function () { + describeFailsFirefox('Response.securityDetails', function () { it('should work', async () => { const { httpsServer } = getTestState(); @@ -105,7 +105,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () { expect(error).toBe(null); expect(response.ok()).toBe(true); }); - it('should work with request interception', async () => { + itFailsFirefox('should work with request interception', async () => { const { httpsServer } = getTestState(); await page.setRequestInterception(true); @@ -113,7 +113,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () { const response = await page.goto(httpsServer.EMPTY_PAGE); expect(response.status()).toBe(200); }); - it('should work with mixed content', async () => { + itFailsFirefox('should work with mixed content', async () => { const { server, httpsServer } = getTestState(); httpsServer.setRoute('/mixedcontent.html', (req, res) => { diff --git a/test/jshandle.spec.js b/test/jshandle.spec.js index 2a287fa504556..7542af3d0aaea 100644 --- a/test/jshandle.spec.js +++ b/test/jshandle.spec.js @@ -179,7 +179,7 @@ describe('JSHandle', function () { const element = aHandle.asElement(); expect(element).toBeFalsy(); }); - itFailsFirefox('should return ElementHandle for TextNodes', async () => { + it('should return ElementHandle for TextNodes', async () => { const { page } = getTestState(); await page.setContent('
ee!
'); @@ -195,7 +195,7 @@ describe('JSHandle', function () { ) ); }); - itFailsFirefox('should work with nullified Node', async () => { + it('should work with nullified Node', async () => { const { page } = getTestState(); await page.setContent('
test
'); diff --git a/test/keyboard.spec.js b/test/keyboard.spec.js index a1ca84ab19712..03be64d73828e 100644 --- a/test/keyboard.spec.js +++ b/test/keyboard.spec.js @@ -125,7 +125,7 @@ describe('Keyboard', function () { await page.evaluate(() => document.querySelector('textarea').value) ).toBe('嗨a'); }); - itFailsFirefox('should report shiftKey', async () => { + it('should report shiftKey', async () => { const { page, server } = getTestState(); await page.goto(server.PREFIX + '/input/keyboard.html'); diff --git a/test/launcher.spec.js b/test/launcher.spec.js index d09303ebb78f3..960d1e6ba7b79 100644 --- a/test/launcher.spec.js +++ b/test/launcher.spec.js @@ -28,6 +28,8 @@ const expect = require('expect'); const { getTestState } = require('./mocha-utils'); describe('Launcher specs', function () { + if (getTestState().isFirefox) this.timeout(30 * 1000); + describe('Puppeteer', function () { describe('BrowserFetcher', function () { it('should download and extract chrome linux binary', async () => { @@ -327,7 +329,7 @@ describe('Launcher specs', function () { if (isChrome) expect(puppeteer.product).toBe('chrome'); else if (isFirefox) expect(puppeteer.product).toBe('firefox'); }); - itFailsFirefox('should work with no default arguments', async () => { + it('should work with no default arguments', async () => { const { defaultBrowserOptions, puppeteer } = getTestState(); const options = Object.assign({}, defaultBrowserOptions); options.ignoreDefaultArgs = true; @@ -337,25 +339,22 @@ describe('Launcher specs', function () { await page.close(); await browser.close(); }); - itFailsFirefox( - 'should filter out ignored default arguments', - async () => { - const { defaultBrowserOptions, puppeteer } = getTestState(); - // Make sure we launch with `--enable-automation` by default. - const defaultArgs = puppeteer.defaultArgs(); - const browser = await puppeteer.launch( - Object.assign({}, defaultBrowserOptions, { - // Ignore first and third default argument. - ignoreDefaultArgs: [defaultArgs[0], defaultArgs[2]], - }) - ); - const spawnargs = browser.process().spawnargs; - expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1); - expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1); - expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1); - await browser.close(); - } - ); + it('should filter out ignored default arguments', async () => { + const { defaultBrowserOptions, puppeteer } = getTestState(); + // Make sure we launch with `--enable-automation` by default. + const defaultArgs = puppeteer.defaultArgs(); + const browser = await puppeteer.launch( + Object.assign({}, defaultBrowserOptions, { + // Ignore first and third default argument. + ignoreDefaultArgs: [defaultArgs[0], defaultArgs[2]], + }) + ); + const spawnargs = browser.process().spawnargs; + expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1); + expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1); + expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1); + await browser.close(); + }); it('should have default URL when launching browser', async function () { const { defaultBrowserOptions, puppeteer } = getTestState(); const browser = await puppeteer.launch(defaultBrowserOptions); @@ -403,24 +402,21 @@ describe('Launcher specs', function () { expect(page.viewport()).toBe(null); await browser.close(); }); - itFailsFirefox( - 'should take fullPage screenshots when defaultViewport is null', - async () => { - const { server, puppeteer, defaultBrowserOptions } = getTestState(); + it('should take fullPage screenshots when defaultViewport is null', async () => { + const { server, puppeteer, defaultBrowserOptions } = getTestState(); - const options = Object.assign({}, defaultBrowserOptions, { - defaultViewport: null, - }); - const browser = await puppeteer.launch(options); - const page = await browser.newPage(); - await page.goto(server.PREFIX + '/grid.html'); - const screenshot = await page.screenshot({ - fullPage: true, - }); - expect(screenshot).toBeInstanceOf(Buffer); - await browser.close(); - } - ); + const options = Object.assign({}, defaultBrowserOptions, { + defaultViewport: null, + }); + const browser = await puppeteer.launch(options); + const page = await browser.newPage(); + await page.goto(server.PREFIX + '/grid.html'); + const screenshot = await page.screenshot({ + fullPage: true, + }); + expect(screenshot).toBeInstanceOf(Buffer); + await browser.close(); + }); }); describe('Puppeteer.launch', function () { @@ -437,7 +433,7 @@ describe('Launcher specs', function () { puppeteer._productName = productName; }); - it('should be able to launch Chrome', async () => { + itOnlyRegularInstall('should be able to launch Chrome', async () => { const { puppeteer } = getTestState(); const browser = await puppeteer.launch({ product: 'chrome' }); const userAgent = await browser.userAgent(); @@ -507,7 +503,7 @@ describe('Launcher specs', function () { remoteBrowser.close(), ]); }); - itFailsFirefox('should support ignoreHTTPSErrors option', async () => { + it('should support ignoreHTTPSErrors option', async () => { const { httpsServer, puppeteer, @@ -586,7 +582,7 @@ describe('Launcher specs', function () { ); }); describe('Puppeteer.executablePath', function () { - itFailsFirefox('should work', async () => { + itOnlyRegularInstall('should work', async () => { const { puppeteer } = getTestState(); const executablePath = puppeteer.executablePath(); diff --git a/test/mocha-utils.js b/test/mocha-utils.js index 6320eba00e3ca..80ab4768b69dc 100644 --- a/test/mocha-utils.js +++ b/test/mocha-utils.js @@ -53,17 +53,32 @@ exports.getTestState = () => state; const product = process.env.PRODUCT || process.env.PUPPETEER_PRODUCT || 'Chromium'; +const alternativeInstall = process.env.PUPPETEER_ALT_INSTALL || false; + const isHeadless = (process.env.HEADLESS || 'true').trim().toLowerCase() === 'true'; const isFirefox = product === 'firefox'; const isChrome = product === 'Chromium'; -const defaultBrowserOptions = { - handleSIGINT: false, - executablePath: process.env.BINARY, - slowMo: false, - headless: isHeadless, - dumpio: !!process.env.DUMPIO, -}; + +let extraLaunchOptions = {}; +try { + extraLaunchOptions = JSON.parse(process.env.EXTRA_LAUNCH_OPTIONS || '{}'); +} catch (error) { + console.warn( + `Error parsing EXTRA_LAUNCH_OPTIONS: ${error.message}. Skipping.` + ); +} + +const defaultBrowserOptions = Object.assign( + { + handleSIGINT: false, + executablePath: process.env.BINARY, + slowMo: false, + headless: isHeadless, + dumpio: !!process.env.DUMPIO, + }, + extraLaunchOptions +); (async () => { if (defaultBrowserOptions.executablePath) { @@ -97,6 +112,16 @@ global.itFailsFirefox = (...args) => { else return it(...args); }; +global.itChromeOnly = (...args) => { + if (isChrome) return it(...args); + else return xit(...args); +}; + +global.itOnlyRegularInstall = (...args) => { + if (alternativeInstall || process.env.BINARY) return xit(...args); + else return it(...args); +}; + global.itFailsWindowsUntilDate = (date, ...args) => { if (os.platform() === 'win32' && Date.now() < date) { // we are within the deferred time so skip the test @@ -120,7 +145,10 @@ if (process.env.COVERAGE) trackCoverage(); console.log( `Running unit tests with: -> product: ${product} - -> binary: ${path.relative(process.cwd(), puppeteer.executablePath())}` + -> binary: ${ + defaultBrowserOptions.executablePath || + path.relative(process.cwd(), puppeteer.executablePath()) + }` ); exports.setupTestBrowserHooks = () => { diff --git a/test/navigation.spec.js b/test/navigation.spec.js index 0feb39e76fb91..330d8d0d89137 100644 --- a/test/navigation.spec.js +++ b/test/navigation.spec.js @@ -57,15 +57,12 @@ describe('navigation', function () { const response = await page.goto('about:blank'); expect(response).toBe(null); }); - itFailsFirefox( - 'should return response when page changes its URL after load', - async () => { - const { page, server } = getTestState(); + it('should return response when page changes its URL after load', async () => { + const { page, server } = getTestState(); - const response = await page.goto(server.PREFIX + '/historyapi.html'); - expect(response.status()).toBe(200); - } - ); + const response = await page.goto(server.PREFIX + '/historyapi.html'); + expect(response.status()).toBe(200); + }); it('should work with subframes return 204', async () => { const { page, server } = getTestState(); @@ -88,34 +85,28 @@ describe('navigation', function () { if (isChrome) expect(error.message).toContain('net::ERR_ABORTED'); else expect(error.message).toContain('NS_BINDING_ABORTED'); }); - itFailsFirefox( - 'should navigate to empty page with domcontentloaded', - async () => { - const { page, server } = getTestState(); + it('should navigate to empty page with domcontentloaded', async () => { + const { page, server } = getTestState(); - const response = await page.goto(server.EMPTY_PAGE, { - waitUntil: 'domcontentloaded', - }); - expect(response.status()).toBe(200); - } - ); - itFailsFirefox( - 'should work when page calls history API in beforeunload', - async () => { - const { page, server } = getTestState(); + const response = await page.goto(server.EMPTY_PAGE, { + waitUntil: 'domcontentloaded', + }); + expect(response.status()).toBe(200); + }); + it('should work when page calls history API in beforeunload', async () => { + const { page, server } = getTestState(); - await page.goto(server.EMPTY_PAGE); - await page.evaluate(() => { - window.addEventListener( - 'beforeunload', - () => history.replaceState(null, 'initial', window.location.href), - false - ); - }); - const response = await page.goto(server.PREFIX + '/grid.html'); - expect(response.status()).toBe(200); - } - ); + await page.goto(server.EMPTY_PAGE); + await page.evaluate(() => { + window.addEventListener( + 'beforeunload', + () => history.replaceState(null, 'initial', window.location.href), + false + ); + }); + const response = await page.goto(server.PREFIX + '/grid.html'); + expect(response.status()).toBe(200); + }); itFailsFirefox( 'should navigate to empty page with networkidle0', async () => { @@ -179,22 +170,18 @@ describe('navigation', function () { expect(requests[0]).toBe('request'); expect(requests[1]).toBe('requestfailed'); }); - itFailsFirefox( - 'should fail when navigating to bad SSL after redirects', - async () => { - const { page, server, httpsServer, isChrome } = getTestState(); - - server.setRedirect('/redirect/1.html', '/redirect/2.html'); - server.setRedirect('/redirect/2.html', '/empty.html'); - let error = null; - await page - .goto(httpsServer.PREFIX + '/redirect/1.html') - .catch((error_) => (error = error_)); - if (isChrome) - expect(error.message).toContain(EXPECTED_SSL_CERT_MESSAGE); - else expect(error.message).toContain('SSL_ERROR_UNKNOWN'); - } - ); + it('should fail when navigating to bad SSL after redirects', async () => { + const { page, server, httpsServer, isChrome } = getTestState(); + + server.setRedirect('/redirect/1.html', '/redirect/2.html'); + server.setRedirect('/redirect/2.html', '/empty.html'); + let error = null; + await page + .goto(httpsServer.PREFIX + '/redirect/1.html') + .catch((error_) => (error = error_)); + if (isChrome) expect(error.message).toContain(EXPECTED_SSL_CERT_MESSAGE); + else expect(error.message).toContain('SSL_ERROR_UNKNOWN'); + }); it('should throw if networkidle is passed as an option', async () => { const { page, server } = getTestState(); @@ -206,20 +193,17 @@ describe('navigation', function () { '"networkidle" option is no longer supported' ); }); - itFailsFirefox( - 'should fail when main resources failed to load', - async () => { - const { page, isChrome } = getTestState(); - - let error = null; - await page - .goto('http://localhost:44123/non-existing-url') - .catch((error_) => (error = error_)); - if (isChrome) - expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); - else expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED'); - } - ); + it('should fail when main resources failed to load', async () => { + const { page, isChrome } = getTestState(); + + let error = null; + await page + .goto('http://localhost:44123/non-existing-url') + .catch((error_) => (error = error_)); + if (isChrome) + expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); + else expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED'); + }); it('should fail when exceeding maximum navigation timeout', async () => { const { page, server, puppeteer } = getTestState(); @@ -284,7 +268,7 @@ describe('navigation', function () { expect(error).toBe(null); expect(loaded).toBe(true); }); - itFailsFirefox('should work when navigating to valid url', async () => { + it('should work when navigating to valid url', async () => { const { page, server } = getTestState(); const response = await page.goto(server.EMPTY_PAGE); @@ -296,26 +280,23 @@ describe('navigation', function () { const response = await page.goto('data:text/html,hello'); expect(response.ok()).toBe(true); }); - itFailsFirefox('should work when navigating to 404', async () => { + it('should work when navigating to 404', async () => { const { page, server } = getTestState(); const response = await page.goto(server.PREFIX + '/not-found'); expect(response.ok()).toBe(false); expect(response.status()).toBe(404); }); - itFailsFirefox( - 'should return last response in redirect chain', - async () => { - const { page, server } = getTestState(); + it('should return last response in redirect chain', async () => { + const { page, server } = getTestState(); - server.setRedirect('/redirect/1.html', '/redirect/2.html'); - server.setRedirect('/redirect/2.html', '/redirect/3.html'); - server.setRedirect('/redirect/3.html', server.EMPTY_PAGE); - const response = await page.goto(server.PREFIX + '/redirect/1.html'); - expect(response.ok()).toBe(true); - expect(response.url()).toBe(server.EMPTY_PAGE); - } - ); + server.setRedirect('/redirect/1.html', '/redirect/2.html'); + server.setRedirect('/redirect/2.html', '/redirect/3.html'); + server.setRedirect('/redirect/3.html', server.EMPTY_PAGE); + const response = await page.goto(server.PREFIX + '/redirect/1.html'); + expect(response.ok()).toBe(true); + expect(response.url()).toBe(server.EMPTY_PAGE); + }); itFailsFirefox( 'should wait for network idle to succeed navigation', async () => { @@ -401,22 +382,19 @@ describe('navigation', function () { process.removeListener('warning', warningHandler); expect(warning).toBe(null); }); - itFailsFirefox( - 'should not leak listeners during bad navigation', - async () => { - const { page } = getTestState(); + it('should not leak listeners during bad navigation', async () => { + const { page } = getTestState(); - let warning = null; - const warningHandler = (w) => (warning = w); - process.on('warning', warningHandler); - for (let i = 0; i < 20; ++i) - await page.goto('asdf').catch((error) => { - /* swallow navigation error */ - }); - process.removeListener('warning', warningHandler); - expect(warning).toBe(null); - } - ); + let warning = null; + const warningHandler = (w) => (warning = w); + process.on('warning', warningHandler); + for (let i = 0; i < 20; ++i) + await page.goto('asdf').catch((error) => { + /* swallow navigation error */ + }); + process.removeListener('warning', warningHandler); + expect(warning).toBe(null); + }); it('should not leak listeners during navigation of 11 pages', async () => { const { context, server } = getTestState(); @@ -467,28 +445,25 @@ describe('navigation', function () { expect(requests[0].url()).toBe(server.EMPTY_PAGE); } ); - itFailsFirefox('should work with self requesting page', async () => { + it('should work with self requesting page', async () => { const { page, server } = getTestState(); const response = await page.goto(server.PREFIX + '/self-request.html'); expect(response.status()).toBe(200); expect(response.url()).toContain('self-request.html'); }); - itFailsFirefox( - 'should fail when navigating and show the url at the error message', - async () => { - const { page, httpsServer } = getTestState(); - - const url = httpsServer.PREFIX + '/redirect/1.html'; - let error = null; - try { - await page.goto(url); - } catch (error_) { - error = error_; - } - expect(error.message).toContain(url); + it('should fail when navigating and show the url at the error message', async () => { + const { page, httpsServer } = getTestState(); + + const url = httpsServer.PREFIX + '/redirect/1.html'; + let error = null; + try { + await page.goto(url); + } catch (error_) { + error = error_; } - ); + expect(error.message).toContain(url); + }); itFailsFirefox('should send referer', async () => { const { page, server } = getTestState(); @@ -644,7 +619,7 @@ describe('navigation', function () { ); }); - describeFailsFirefox('Page.goBack', function () { + describe('Page.goBack', function () { it('should work', async () => { const { page, server } = getTestState(); @@ -662,7 +637,7 @@ describe('navigation', function () { response = await page.goForward(); expect(response).toBe(null); }); - it('should work with HistoryAPI', async () => { + itFailsFirefox('should work with HistoryAPI', async () => { const { page, server } = getTestState(); await page.goto(server.EMPTY_PAGE); diff --git a/test/network.spec.js b/test/network.spec.js index 4bacc4c5be5b2..13f0efc3841e8 100644 --- a/test/network.spec.js +++ b/test/network.spec.js @@ -40,7 +40,7 @@ describe('network', function () { await page.goto(server.EMPTY_PAGE); expect(requests.length).toBe(1); }); - itFailsFirefox('should fire for iframes', async () => { + it('should fire for iframes', async () => { const { page, server } = getTestState(); const requests = []; @@ -110,7 +110,7 @@ describe('network', function () { }); }); - describeFailsFirefox('Request.headers', function () { + describe('Request.headers', function () { it('should work', async () => { const { page, server, isChrome } = getTestState(); @@ -122,7 +122,7 @@ describe('network', function () { }); }); - describeFailsFirefox('Response.headers', function () { + describe('Response.headers', function () { it('should work', async () => { const { page, server } = getTestState(); @@ -325,7 +325,7 @@ describe('network', function () { }); }); - describeFailsFirefox('Response.statusText', function () { + describe('Response.statusText', function () { it('should work', async () => { const { page, server } = getTestState(); diff --git a/test/page.spec.js b/test/page.spec.js index 1d041288aa846..f098df8fd455f 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -694,7 +694,7 @@ describe('Page', function () { }); describe('Page.waitForResponse', function () { - itFailsFirefox('should work', async () => { + it('should work', async () => { const { page, server } = getTestState(); await page.goto(server.EMPTY_PAGE); @@ -727,7 +727,7 @@ describe('Page', function () { .catch((error_) => (error = error_)); expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError); }); - itFailsFirefox('should work with predicate', async () => { + it('should work with predicate', async () => { const { page, server } = getTestState(); await page.goto(server.EMPTY_PAGE); @@ -743,7 +743,7 @@ describe('Page', function () { ]); expect(response.url()).toBe(server.PREFIX + '/digits/2.png'); }); - itFailsFirefox('should work with no timeout', async () => { + it('should work with no timeout', async () => { const { page, server } = getTestState(); await page.goto(server.EMPTY_PAGE); @@ -909,7 +909,7 @@ describe('Page', function () { ]); expect(request.headers['user-agent']).toBe('foobar'); }); - itFailsFirefox('should work for subframes', async () => { + it('should work for subframes', async () => { const { page, server } = getTestState(); expect(await page.evaluate(() => navigator.userAgent)).toContain( @@ -936,7 +936,7 @@ describe('Page', function () { }); }); - describeFailsFirefox('Page.setContent', function () { + describe('Page.setContent', function () { const expectedOutput = '
hello
'; it('should work', async () => { @@ -1321,7 +1321,7 @@ describe('Page', function () { expect(styleContent).toContain(path.join('assets', 'injectedstyle.css')); }); - itFailsFirefox('should work with content', async () => { + it('should work with content', async () => { const { page, server } = getTestState(); await page.goto(server.EMPTY_PAGE); @@ -1433,7 +1433,7 @@ describe('Page', function () { }); describe('printing to PDF', function () { - itFailsFirefox('can print to PDF and save to file', async () => { + it('can print to PDF and save to file', async () => { // Printing to pdf is currently only supported in headless const { isHeadless, page } = getTestState(); @@ -1591,7 +1591,7 @@ describe('Page', function () { ) ).toEqual(true); }); - itFailsFirefox('should throw if passed in non-strings', async () => { + it('should throw if passed in non-strings', async () => { const { page } = getTestState(); await page.setContent(''); diff --git a/test/queryselector.spec.js b/test/queryselector.spec.js index 11c068fa46bfd..720095e674fb6 100644 --- a/test/queryselector.spec.js +++ b/test/queryselector.spec.js @@ -23,7 +23,7 @@ const { describe('querySelector', function () { setupTestBrowserHooks(); setupTestPageAndContextHooks(); - describeFailsFirefox('Page.$eval', function () { + describe('Page.$eval', function () { it('should work', async () => { const { page } = getTestState(); @@ -67,7 +67,7 @@ describe('querySelector', function () { }); }); - describeFailsFirefox('Page.$$eval', function () { + describe('Page.$$eval', function () { it('should work', async () => { const { page } = getTestState(); @@ -79,7 +79,7 @@ describe('querySelector', function () { }); }); - describeFailsFirefox('Page.$', function () { + describe('Page.$', function () { it('should query existing element', async () => { const { page } = getTestState(); @@ -96,7 +96,7 @@ describe('querySelector', function () { }); describe('Page.$$', function () { - itFailsFirefox('should query existing elements', async () => { + it('should query existing elements', async () => { const { page } = getTestState(); await page.setContent('
A

B
'); @@ -116,7 +116,7 @@ describe('querySelector', function () { }); }); - describeFailsFirefox('Path.$x', function () { + describe('Path.$x', function () { it('should query existing element', async () => { const { page } = getTestState(); @@ -155,7 +155,7 @@ describe('querySelector', function () { expect(content).toBe('A'); }); - itFailsFirefox('should return null for non-existing element', async () => { + it('should return null for non-existing element', async () => { const { page } = getTestState(); await page.setContent( @@ -166,7 +166,7 @@ describe('querySelector', function () { expect(second).toBe(null); }); }); - describeFailsFirefox('ElementHandle.$eval', function () { + describe('ElementHandle.$eval', function () { it('should work', async () => { const { page } = getTestState(); @@ -204,7 +204,7 @@ describe('querySelector', function () { ); }); }); - describeFailsFirefox('ElementHandle.$$eval', function () { + describe('ElementHandle.$$eval', function () { it('should work', async () => { const { page } = getTestState(); @@ -246,7 +246,7 @@ describe('querySelector', function () { }); }); - describeFailsFirefox('ElementHandle.$$', function () { + describe('ElementHandle.$$', function () { it('should query existing elements', async () => { const { page } = getTestState(); @@ -289,7 +289,7 @@ describe('querySelector', function () { expect(content).toBe('A'); }); - itFailsFirefox('should return null for non-existing element', async () => { + it('should return null for non-existing element', async () => { const { page } = getTestState(); await page.setContent( diff --git a/test/screenshot.spec.js b/test/screenshot.spec.js index 55be4bb1bf15a..cb756127c378d 100644 --- a/test/screenshot.spec.js +++ b/test/screenshot.spec.js @@ -177,7 +177,7 @@ describe('Screenshots', function () { const screenshot = await elementHandle.screenshot(); expect(screenshot).toBeGolden('screenshot-element-bounding-box.png'); }); - itFailsFirefox('should take into account padding and border', async () => { + it('should take into account padding and border', async () => { const { page } = getTestState(); await page.setViewport({ width: 500, height: 500 }); @@ -196,14 +196,12 @@ describe('Screenshots', function () { const screenshot = await elementHandle.screenshot(); expect(screenshot).toBeGolden('screenshot-element-padding-border.png'); }); - itFailsFirefox( - 'should capture full element when larger than viewport', - async () => { - const { page } = getTestState(); + it('should capture full element when larger than viewport', async () => { + const { page } = getTestState(); - await page.setViewport({ width: 500, height: 500 }); + await page.setViewport({ width: 500, height: 500 }); - await page.setContent(` + await page.setContent(` something above
`); - const elementHandle = await page.$('div.to-screenshot'); - const screenshot = await elementHandle.screenshot(); - expect(screenshot).toBeGolden( - 'screenshot-element-larger-than-viewport.png' - ); + const elementHandle = await page.$('div.to-screenshot'); + const screenshot = await elementHandle.screenshot(); + expect(screenshot).toBeGolden( + 'screenshot-element-larger-than-viewport.png' + ); - expect( - await page.evaluate(() => ({ - w: window.innerWidth, - h: window.innerHeight, - })) - ).toEqual({ w: 500, h: 500 }); - } - ); - itFailsFirefox('should scroll element into view', async () => { + expect( + await page.evaluate(() => ({ + w: window.innerWidth, + h: window.innerHeight, + })) + ).toEqual({ w: 500, h: 500 }); + }); + it('should scroll element into view', async () => { const { page } = getTestState(); await page.setViewport({ width: 500, height: 500 }); @@ -287,30 +284,24 @@ describe('Screenshots', function () { 'Node is either not visible or not an HTMLElement' ); }); - itFailsFirefox( - 'should not hang with zero width/height element', - async () => { - const { page } = getTestState(); + it('should not hang with zero width/height element', async () => { + const { page } = getTestState(); - await page.setContent('
'); - const div = await page.$('div'); - const error = await div.screenshot().catch((error_) => error_); - expect(error.message).toBe('Node has 0 height.'); - } - ); - itFailsFirefox( - 'should work for an element with fractional dimensions', - async () => { - const { page } = getTestState(); + await page.setContent('
'); + const div = await page.$('div'); + const error = await div.screenshot().catch((error_) => error_); + expect(error.message).toBe('Node has 0 height.'); + }); + it('should work for an element with fractional dimensions', async () => { + const { page } = getTestState(); - await page.setContent( - '
' - ); - const elementHandle = await page.$('div'); - const screenshot = await elementHandle.screenshot(); - expect(screenshot).toBeGolden('screenshot-element-fractional.png'); - } - ); + await page.setContent( + '
' + ); + const elementHandle = await page.$('div'); + const screenshot = await elementHandle.screenshot(); + expect(screenshot).toBeGolden('screenshot-element-fractional.png'); + }); itFailsFirefox('should work for an element with an offset', async () => { const { page } = getTestState(); diff --git a/test/waittask.spec.js b/test/waittask.spec.js index 1d604a6544622..efb5f6ef8bfd1 100644 --- a/test/waittask.spec.js +++ b/test/waittask.spec.js @@ -27,7 +27,7 @@ describe('waittask specs', function () { setupTestPageAndContextHooks(); describe('Page.waitFor', function () { - itFailsFirefox('should wait for selector', async () => { + it('should wait for selector', async () => { const { page, server } = getTestState(); let found = false; @@ -39,7 +39,7 @@ describe('waittask specs', function () { expect(found).toBe(true); }); - itFailsFirefox('should wait for an xpath', async () => { + it('should wait for an xpath', async () => { const { page, server } = getTestState(); let found = false; @@ -50,19 +50,14 @@ describe('waittask specs', function () { await waitFor; expect(found).toBe(true); }); - itFailsFirefox( - 'should not allow you to select an element with single slash xpath', - async () => { - const { page } = getTestState(); + it('should not allow you to select an element with single slash xpath', async () => { + const { page } = getTestState(); - await page.setContent(`
some text
`); - let error = null; - await page - .waitFor('/html/body/div') - .catch((error_) => (error = error_)); - expect(error).toBeTruthy(); - } - ); + await page.setContent(`
some text
`); + let error = null; + await page.waitFor('/html/body/div').catch((error_) => (error = error_)); + expect(error).toBeTruthy(); + }); it('should timeout', async () => { const { page } = getTestState(); @@ -255,7 +250,7 @@ describe('waittask specs', function () { expect(await page.waitForFunction(() => window)).toBeTruthy(); }); - itFailsFirefox('should accept ElementHandle arguments', async () => { + it('should accept ElementHandle arguments', async () => { const { page } = getTestState(); await page.setContent('
'); @@ -330,7 +325,7 @@ describe('waittask specs', function () { }); }); - describeFailsFirefox('Frame.waitForSelector', function () { + describe('Frame.waitForSelector', function () { const addElement = (tag) => document.body.appendChild(document.createElement(tag)); @@ -344,7 +339,7 @@ describe('waittask specs', function () { await frame.waitForSelector('div'); }); - it('should work with removed MutationObserver', async () => { + itFailsFirefox('should work with removed MutationObserver', async () => { const { page } = getTestState(); await page.evaluate(() => delete window.MutationObserver); @@ -385,20 +380,23 @@ describe('waittask specs', function () { await watchdog; }); - it('Page.waitForSelector is shortcut for main frame', async () => { - const { page, server } = getTestState(); - - await page.goto(server.EMPTY_PAGE); - await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); - const otherFrame = page.frames()[1]; - const watchdog = page.waitForSelector('div'); - await otherFrame.evaluate(addElement, 'div'); - await page.evaluate(addElement, 'div'); - const eHandle = await watchdog; - expect(eHandle.executionContext().frame()).toBe(page.mainFrame()); - }); + itFailsFirefox( + 'Page.waitForSelector is shortcut for main frame', + async () => { + const { page, server } = getTestState(); + + await page.goto(server.EMPTY_PAGE); + await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); + const otherFrame = page.frames()[1]; + const watchdog = page.waitForSelector('div'); + await otherFrame.evaluate(addElement, 'div'); + await page.evaluate(addElement, 'div'); + const eHandle = await watchdog; + expect(eHandle.executionContext().frame()).toBe(page.mainFrame()); + } + ); - it('should run in specified frame', async () => { + itFailsFirefox('should run in specified frame', async () => { const { page, server } = getTestState(); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); @@ -412,7 +410,7 @@ describe('waittask specs', function () { expect(eHandle.executionContext().frame()).toBe(frame2); }); - it('should throw when frame is detached', async () => { + itFailsFirefox('should throw when frame is detached', async () => { const { page, server } = getTestState(); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); @@ -580,7 +578,7 @@ describe('waittask specs', function () { ); expect(await waitForSelector).toBe(true); }); - itFailsFirefox('should return the element handle', async () => { + it('should return the element handle', async () => { const { page } = getTestState(); const waitForSelector = page.waitForSelector('.zombo'); @@ -600,7 +598,7 @@ describe('waittask specs', function () { }); }); - describeFailsFirefox('Frame.waitForXPath', function () { + describe('Frame.waitForXPath', function () { const addElement = (tag) => document.body.appendChild(document.createElement(tag)); @@ -628,7 +626,7 @@ describe('waittask specs', function () { ); expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError); }); - it('should run in specified frame', async () => { + itFailsFirefox('should run in specified frame', async () => { const { page, server } = getTestState(); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); @@ -641,7 +639,7 @@ describe('waittask specs', function () { const eHandle = await waitForXPathPromise; expect(eHandle.executionContext().frame()).toBe(frame2); }); - it('should throw when frame is detached', async () => { + itFailsFirefox('should throw when frame is detached', async () => { const { page, server } = getTestState(); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);