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
This commit is contained in:
Maja Frydrychowicz 2020-06-12 09:55:51 -04:00 committed by Mathias Bynens
parent 5c91dfbf3f
commit 3d56a9e76f
20 changed files with 337 additions and 370 deletions

View File

@ -429,9 +429,6 @@ function extractTar(tarPath: string, folderPath: string): Promise<unknown> {
tarStream.on('error', reject); tarStream.on('error', reject);
tarStream.on('finish', fulfill); tarStream.on('finish', fulfill);
const readStream = fs.createReadStream(tarPath); const readStream = fs.createReadStream(tarPath);
readStream.on('data', () => {
process.stdout.write('\rExtracting...');
});
readStream.pipe(bzip()).pipe(tarStream); readStream.pipe(bzip()).pipe(tarStream);
}); });
} }

View File

@ -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. 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`. 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-<browser>`, for example. Such tests are skipped with
`itOnlyRegularInstall` which checks `BINARY` and `PUPPETEER_ALT_INSTALL` environment variables.
[Mocha]: https://mochajs.org/ [Mocha]: https://mochajs.org/
[Expect]: https://www.npmjs.com/package/expect [Expect]: https://www.npmjs.com/package/expect

View File

@ -20,7 +20,7 @@ const utils = require('./utils');
describe('BrowserContext', function () { describe('BrowserContext', function () {
setupTestBrowserHooks(); setupTestBrowserHooks();
itFailsFirefox('should have default context', async () => { it('should have default context', async () => {
const { browser } = getTestState(); const { browser } = getTestState();
expect(browser.browserContexts().length).toEqual(1); expect(browser.browserContexts().length).toEqual(1);
const defaultContext = browser.browserContexts()[0]; const defaultContext = browser.browserContexts()[0];
@ -30,7 +30,7 @@ describe('BrowserContext', function () {
expect(browser.defaultBrowserContext()).toBe(defaultContext); expect(browser.defaultBrowserContext()).toBe(defaultContext);
expect(error.message).toContain('cannot be closed'); expect(error.message).toContain('cannot be closed');
}); });
itFailsFirefox('should create new incognito context', async () => { it('should create new incognito context', async () => {
const { browser } = getTestState(); const { browser } = getTestState();
expect(browser.browserContexts().length).toBe(1); expect(browser.browserContexts().length).toBe(1);
@ -41,22 +41,19 @@ describe('BrowserContext', function () {
await context.close(); await context.close();
expect(browser.browserContexts().length).toBe(1); expect(browser.browserContexts().length).toBe(1);
}); });
itFailsFirefox( it('should close all belonging targets once closing context', async () => {
'should close all belonging targets once closing context', const { browser } = getTestState();
async () => {
const { browser } = getTestState();
expect((await browser.pages()).length).toBe(1); expect((await browser.pages()).length).toBe(1);
const context = await browser.createIncognitoBrowserContext(); const context = await browser.createIncognitoBrowserContext();
await context.newPage(); await context.newPage();
expect((await browser.pages()).length).toBe(2); expect((await browser.pages()).length).toBe(2);
expect((await context.pages()).length).toBe(1); expect((await context.pages()).length).toBe(1);
await context.close(); await context.close();
expect((await browser.pages()).length).toBe(1); expect((await browser.pages()).length).toBe(1);
} });
);
itFailsFirefox('window.open should use parent tab context', async () => { itFailsFirefox('window.open should use parent tab context', async () => {
const { browser, server } = getTestState(); const { browser, server } = getTestState();

View File

@ -32,7 +32,7 @@ describe('Page.click', function () {
await page.click('button'); await page.click('button');
expect(await page.evaluate(() => result)).toBe('Clicked'); expect(await page.evaluate(() => result)).toBe('Clicked');
}); });
itFailsFirefox('should click svg', async () => { it('should click svg', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent(` await page.setContent(`
@ -55,12 +55,10 @@ describe('Page.click', function () {
} }
); );
// @see https://github.com/puppeteer/puppeteer/issues/4281 // @see https://github.com/puppeteer/puppeteer/issues/4281
itFailsFirefox( it('should click on a span with an inline element inside', async () => {
'should click on a span with an inline element inside', const { page } = getTestState();
async () => {
const { page } = getTestState();
await page.setContent(` await page.setContent(`
<style> <style>
span::before { span::before {
content: 'q'; content: 'q';
@ -68,10 +66,9 @@ describe('Page.click', function () {
</style> </style>
<span onclick='javascript:window.CLICKED=42'></span> <span onclick='javascript:window.CLICKED=42'></span>
`); `);
await page.click('span'); await page.click('span');
expect(await page.evaluate(() => window.CLICKED)).toBe(42); expect(await page.evaluate(() => window.CLICKED)).toBe(42);
} });
);
it('should not throw UnhandledPromiseRejection when page closes', async () => { it('should not throw UnhandledPromiseRejection when page closes', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -98,12 +95,10 @@ describe('Page.click', function () {
await Promise.all([page.click('a'), page.waitForNavigation()]); await Promise.all([page.click('a'), page.waitForNavigation()]);
expect(page.url()).toBe(server.PREFIX + '/wrappedlink.html#clicked'); expect(page.url()).toBe(server.PREFIX + '/wrappedlink.html#clicked');
}); });
itFailsFirefox( it('should click when one of inline box children is outside of viewport', async () => {
'should click when one of inline box children is outside of viewport', const { page } = getTestState();
async () => {
const { page } = getTestState();
await page.setContent(` await page.setContent(`
<style> <style>
i { i {
position: absolute; position: absolute;
@ -112,10 +107,9 @@ describe('Page.click', function () {
</style> </style>
<span onclick='javascript:window.CLICKED = 42;'><i>woof</i><b>doggo</b></span> <span onclick='javascript:window.CLICKED = 42;'><i>woof</i><b>doggo</b></span>
`); `);
await page.click('span'); await page.click('span');
expect(await page.evaluate(() => window.CLICKED)).toBe(42); expect(await page.evaluate(() => window.CLICKED)).toBe(42);
} });
);
it('should select the text by triple clicking', async () => { it('should select the text by triple clicking', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -244,7 +238,7 @@ describe('Page.click', function () {
) )
).toBe('clicked'); ).toBe('clicked');
}); });
itFailsFirefox('should double click the button', async () => { it('should double click the button', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
@ -290,7 +284,7 @@ describe('Page.click', function () {
).toBe('context menu'); ).toBe('context menu');
}); });
// @see https://github.com/puppeteer/puppeteer/issues/206 // @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(); const { page, server } = getTestState();
await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`); await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);

View File

@ -220,21 +220,18 @@ describe('Cookie specs', () => {
}) })
).toEqual(['foo=bar', 'password=123456']); ).toEqual(['foo=bar', 'password=123456']);
}); });
itFailsFirefox( it('should have |expires| set to |-1| for session cookies', async () => {
'should have |expires| set to |-1| for session cookies', const { page, server } = getTestState();
async () => {
const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.setCookie({ await page.setCookie({
name: 'password', name: 'password',
value: '123456', value: '123456',
}); });
const cookies = await page.cookies(); const cookies = await page.cookies();
expect(cookies[0].session).toBe(true); expect(cookies[0].session).toBe(true);
expect(cookies[0].expires).toBe(-1); expect(cookies[0].expires).toBe(-1);
} });
);
itFailsFirefox('should set cookie with reasonable defaults', async () => { itFailsFirefox('should set cookie with reasonable defaults', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -348,22 +345,19 @@ describe('Cookie specs', () => {
expect(cookie.secure).toBe(true); expect(cookie.secure).toBe(true);
} }
); );
itFailsFirefox( it('should be able to set unsecure cookie for HTTP website', async () => {
'should be able to set unsecure cookie for HTTP website', const { page, server } = getTestState();
async () => {
const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const HTTP_URL = 'http://example.com'; const HTTP_URL = 'http://example.com';
await page.setCookie({ await page.setCookie({
url: HTTP_URL, url: HTTP_URL,
name: 'foo', name: 'foo',
value: 'bar', value: 'bar',
}); });
const [cookie] = await page.cookies(HTTP_URL); const [cookie] = await page.cookies(HTTP_URL);
expect(cookie.secure).toBe(false); expect(cookie.secure).toBe(false);
} });
);
itFailsFirefox('should set a cookie on a different domain', async () => { itFailsFirefox('should set a cookie on a different domain', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();

View File

@ -233,7 +233,7 @@ describe('ElementHandle specs', function () {
'Node is either not visible or not an HTMLElement' 'Node is either not visible or not an HTMLElement'
); );
}); });
itFailsFirefox('should throw for <br> elements', async () => { it('should throw for <br> elements', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('hello<br>goodbye'); await page.setContent('hello<br>goodbye');

View File

@ -127,7 +127,7 @@ describe('Emulation', () => {
'iPhone' 'iPhone'
); );
}); });
it('should support clicking', async () => { itFailsFirefox('should support clicking', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.emulate(iPhone); await page.emulate(iPhone);

View File

@ -35,31 +35,31 @@ describe('Evaluation specs', function () {
const result = await page.evaluate(() => 7 * 3); const result = await page.evaluate(() => 7 * 3);
expect(result).toBe(21); expect(result).toBe(21);
}); });
(bigint ? itFailsFirefox : xit)('should transfer BigInt', async () => { (bigint ? it : xit)('should transfer BigInt', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate((a) => a, BigInt(42)); const result = await page.evaluate((a) => a, BigInt(42));
expect(result).toBe(BigInt(42)); expect(result).toBe(BigInt(42));
}); });
itFailsFirefox('should transfer NaN', async () => { it('should transfer NaN', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate((a) => a, NaN); const result = await page.evaluate((a) => a, NaN);
expect(Object.is(result, NaN)).toBe(true); expect(Object.is(result, NaN)).toBe(true);
}); });
itFailsFirefox('should transfer -0', async () => { it('should transfer -0', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate((a) => a, -0); const result = await page.evaluate((a) => a, -0);
expect(Object.is(result, -0)).toBe(true); expect(Object.is(result, -0)).toBe(true);
}); });
itFailsFirefox('should transfer Infinity', async () => { it('should transfer Infinity', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate((a) => a, Infinity); const result = await page.evaluate((a) => a, Infinity);
expect(Object.is(result, Infinity)).toBe(true); expect(Object.is(result, Infinity)).toBe(true);
}); });
itFailsFirefox('should transfer -Infinity', async () => { it('should transfer -Infinity', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate((a) => a, -Infinity); const result = await page.evaluate((a) => a, -Infinity);
@ -202,31 +202,31 @@ describe('Evaluation specs', function () {
expect(result).not.toBe(object); expect(result).not.toBe(object);
expect(result).toEqual(object); expect(result).toEqual(object);
}); });
(bigint ? itFailsFirefox : xit)('should return BigInt', async () => { (bigint ? it : xit)('should return BigInt', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate(() => BigInt(42)); const result = await page.evaluate(() => BigInt(42));
expect(result).toBe(BigInt(42)); expect(result).toBe(BigInt(42));
}); });
itFailsFirefox('should return NaN', async () => { it('should return NaN', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate(() => NaN); const result = await page.evaluate(() => NaN);
expect(Object.is(result, NaN)).toBe(true); expect(Object.is(result, NaN)).toBe(true);
}); });
itFailsFirefox('should return -0', async () => { it('should return -0', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate(() => -0); const result = await page.evaluate(() => -0);
expect(Object.is(result, -0)).toBe(true); expect(Object.is(result, -0)).toBe(true);
}); });
itFailsFirefox('should return Infinity', async () => { it('should return Infinity', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate(() => Infinity); const result = await page.evaluate(() => Infinity);
expect(Object.is(result, Infinity)).toBe(true); expect(Object.is(result, Infinity)).toBe(true);
}); });
itFailsFirefox('should return -Infinity', async () => { it('should return -Infinity', async () => {
const { page } = getTestState(); const { page } = getTestState();
const result = await page.evaluate(() => -Infinity); 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!'); const result = await page.evaluate('2 + 5;\n// do some math!');
expect(result).toBe(7); 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(); const { page } = getTestState();
await page.setContent('<section>42</section>'); await page.setContent('<section>42</section>');
@ -306,22 +306,19 @@ describe('Evaluation specs', function () {
const text = await page.evaluate((e) => e.textContent, element); const text = await page.evaluate((e) => e.textContent, element);
expect(text).toBe('42'); expect(text).toBe('42');
}); });
itFailsFirefox( it('should throw if underlying element was disposed', async () => {
'should throw if underlying element was disposed', const { page } = getTestState();
async () => {
const { page } = getTestState();
await page.setContent('<section>39</section>'); await page.setContent('<section>39</section>');
const element = await page.$('section'); const element = await page.$('section');
expect(element).toBeTruthy(); expect(element).toBeTruthy();
await element.dispose(); await element.dispose();
let error = null; let error = null;
await page await page
.evaluate((e) => e.textContent, element) .evaluate((e) => e.textContent, element)
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
expect(error.message).toContain('JSHandle is disposed'); expect(error.message).toContain('JSHandle is disposed');
} });
);
itFailsFirefox( itFailsFirefox(
'should throw if elementHandles are from other frames', 'should throw if elementHandles are from other frames',
async () => { async () => {
@ -376,17 +373,14 @@ describe('Evaluation specs', function () {
expect(result).toEqual([42]); expect(result).toEqual([42]);
} }
); );
itFailsFirefox( it('should transfer 100Mb of data from page to node.js', async function () {
'should transfer 100Mb of data from page to node.js', const { page } = getTestState();
async function () {
const { page } = getTestState();
const a = await page.evaluate(() => const a = await page.evaluate(() =>
Array(100 * 1024 * 1024 + 1).join('a') Array(100 * 1024 * 1024 + 1).join('a')
); );
expect(a.length).toBe(100 * 1024 * 1024); expect(a.length).toBe(100 * 1024 * 1024);
} });
);
it('should throw error with detailed information on exception inside promise ', async () => { it('should throw error with detailed information on exception inside promise ', async () => {
const { page } = getTestState(); const { page } = getTestState();

View File

@ -20,7 +20,7 @@ const { getTestState } = require('./mocha-utils');
const path = require('path'); const path = require('path');
describe('Fixtures', function () { 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(); const { defaultBrowserOptions, puppeteerPath } = getTestState();
let dumpioData = ''; let dumpioData = '';

View File

@ -17,7 +17,7 @@
const expect = require('expect'); const expect = require('expect');
const { getTestState } = require('./mocha-utils'); const { getTestState } = require('./mocha-utils');
describeFailsFirefox('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
@ -51,7 +51,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () {
page = null; page = null;
}); });
describe('Response.securityDetails', function () { describeFailsFirefox('Response.securityDetails', function () {
it('should work', async () => { it('should work', async () => {
const { httpsServer } = getTestState(); const { httpsServer } = getTestState();
@ -105,7 +105,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () {
expect(error).toBe(null); expect(error).toBe(null);
expect(response.ok()).toBe(true); expect(response.ok()).toBe(true);
}); });
it('should work with request interception', async () => { itFailsFirefox('should work with request interception', async () => {
const { httpsServer } = getTestState(); const { httpsServer } = getTestState();
await page.setRequestInterception(true); await page.setRequestInterception(true);
@ -113,7 +113,7 @@ describeFailsFirefox('ignoreHTTPSErrors', function () {
const response = await page.goto(httpsServer.EMPTY_PAGE); const response = await page.goto(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
it('should work with mixed content', async () => { itFailsFirefox('should work with mixed content', async () => {
const { server, httpsServer } = getTestState(); const { server, httpsServer } = getTestState();
httpsServer.setRoute('/mixedcontent.html', (req, res) => { httpsServer.setRoute('/mixedcontent.html', (req, res) => {

View File

@ -179,7 +179,7 @@ describe('JSHandle', function () {
const element = aHandle.asElement(); const element = aHandle.asElement();
expect(element).toBeFalsy(); expect(element).toBeFalsy();
}); });
itFailsFirefox('should return ElementHandle for TextNodes', async () => { it('should return ElementHandle for TextNodes', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('<div>ee!</div>'); await page.setContent('<div>ee!</div>');
@ -195,7 +195,7 @@ describe('JSHandle', function () {
) )
); );
}); });
itFailsFirefox('should work with nullified Node', async () => { it('should work with nullified Node', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('<section>test</section>'); await page.setContent('<section>test</section>');

View File

@ -125,7 +125,7 @@ describe('Keyboard', function () {
await page.evaluate(() => document.querySelector('textarea').value) await page.evaluate(() => document.querySelector('textarea').value)
).toBe('嗨a'); ).toBe('嗨a');
}); });
itFailsFirefox('should report shiftKey', async () => { it('should report shiftKey', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.PREFIX + '/input/keyboard.html'); await page.goto(server.PREFIX + '/input/keyboard.html');

View File

@ -28,6 +28,8 @@ const expect = require('expect');
const { getTestState } = require('./mocha-utils'); const { getTestState } = require('./mocha-utils');
describe('Launcher specs', function () { describe('Launcher specs', function () {
if (getTestState().isFirefox) this.timeout(30 * 1000);
describe('Puppeteer', function () { describe('Puppeteer', function () {
describe('BrowserFetcher', function () { describe('BrowserFetcher', function () {
it('should download and extract chrome linux binary', async () => { it('should download and extract chrome linux binary', async () => {
@ -327,7 +329,7 @@ describe('Launcher specs', function () {
if (isChrome) expect(puppeteer.product).toBe('chrome'); if (isChrome) expect(puppeteer.product).toBe('chrome');
else if (isFirefox) expect(puppeteer.product).toBe('firefox'); 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 { defaultBrowserOptions, puppeteer } = getTestState();
const options = Object.assign({}, defaultBrowserOptions); const options = Object.assign({}, defaultBrowserOptions);
options.ignoreDefaultArgs = true; options.ignoreDefaultArgs = true;
@ -337,25 +339,22 @@ describe('Launcher specs', function () {
await page.close(); await page.close();
await browser.close(); await browser.close();
}); });
itFailsFirefox( it('should filter out ignored default arguments', async () => {
'should filter out ignored default arguments', const { defaultBrowserOptions, puppeteer } = getTestState();
async () => { // Make sure we launch with `--enable-automation` by default.
const { defaultBrowserOptions, puppeteer } = getTestState(); const defaultArgs = puppeteer.defaultArgs();
// Make sure we launch with `--enable-automation` by default. const browser = await puppeteer.launch(
const defaultArgs = puppeteer.defaultArgs(); Object.assign({}, defaultBrowserOptions, {
const browser = await puppeteer.launch( // Ignore first and third default argument.
Object.assign({}, defaultBrowserOptions, { ignoreDefaultArgs: [defaultArgs[0], defaultArgs[2]],
// Ignore first and third default argument. })
ignoreDefaultArgs: [defaultArgs[0], defaultArgs[2]], );
}) const spawnargs = browser.process().spawnargs;
); expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1);
const spawnargs = browser.process().spawnargs; expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1);
expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1); expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1);
expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1); await browser.close();
expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1); });
await browser.close();
}
);
it('should have default URL when launching browser', async function () { it('should have default URL when launching browser', async function () {
const { defaultBrowserOptions, puppeteer } = getTestState(); const { defaultBrowserOptions, puppeteer } = getTestState();
const browser = await puppeteer.launch(defaultBrowserOptions); const browser = await puppeteer.launch(defaultBrowserOptions);
@ -403,24 +402,21 @@ describe('Launcher specs', function () {
expect(page.viewport()).toBe(null); expect(page.viewport()).toBe(null);
await browser.close(); await browser.close();
}); });
itFailsFirefox( it('should take fullPage screenshots when defaultViewport is null', async () => {
'should take fullPage screenshots when defaultViewport is null', const { server, puppeteer, defaultBrowserOptions } = getTestState();
async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const options = Object.assign({}, defaultBrowserOptions, { const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: null, defaultViewport: null,
}); });
const browser = await puppeteer.launch(options); const browser = await puppeteer.launch(options);
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot({ const screenshot = await page.screenshot({
fullPage: true, fullPage: true,
}); });
expect(screenshot).toBeInstanceOf(Buffer); expect(screenshot).toBeInstanceOf(Buffer);
await browser.close(); await browser.close();
} });
);
}); });
describe('Puppeteer.launch', function () { describe('Puppeteer.launch', function () {
@ -437,7 +433,7 @@ describe('Launcher specs', function () {
puppeteer._productName = productName; puppeteer._productName = productName;
}); });
it('should be able to launch Chrome', async () => { itOnlyRegularInstall('should be able to launch Chrome', async () => {
const { puppeteer } = getTestState(); const { puppeteer } = getTestState();
const browser = await puppeteer.launch({ product: 'chrome' }); const browser = await puppeteer.launch({ product: 'chrome' });
const userAgent = await browser.userAgent(); const userAgent = await browser.userAgent();
@ -507,7 +503,7 @@ describe('Launcher specs', function () {
remoteBrowser.close(), remoteBrowser.close(),
]); ]);
}); });
itFailsFirefox('should support ignoreHTTPSErrors option', async () => { it('should support ignoreHTTPSErrors option', async () => {
const { const {
httpsServer, httpsServer,
puppeteer, puppeteer,
@ -586,7 +582,7 @@ describe('Launcher specs', function () {
); );
}); });
describe('Puppeteer.executablePath', function () { describe('Puppeteer.executablePath', function () {
itFailsFirefox('should work', async () => { itOnlyRegularInstall('should work', async () => {
const { puppeteer } = getTestState(); const { puppeteer } = getTestState();
const executablePath = puppeteer.executablePath(); const executablePath = puppeteer.executablePath();

View File

@ -53,17 +53,32 @@ exports.getTestState = () => state;
const product = const product =
process.env.PRODUCT || process.env.PUPPETEER_PRODUCT || 'Chromium'; process.env.PRODUCT || process.env.PUPPETEER_PRODUCT || 'Chromium';
const alternativeInstall = process.env.PUPPETEER_ALT_INSTALL || false;
const isHeadless = const isHeadless =
(process.env.HEADLESS || 'true').trim().toLowerCase() === 'true'; (process.env.HEADLESS || 'true').trim().toLowerCase() === 'true';
const isFirefox = product === 'firefox'; const isFirefox = product === 'firefox';
const isChrome = product === 'Chromium'; const isChrome = product === 'Chromium';
const defaultBrowserOptions = {
handleSIGINT: false, let extraLaunchOptions = {};
executablePath: process.env.BINARY, try {
slowMo: false, extraLaunchOptions = JSON.parse(process.env.EXTRA_LAUNCH_OPTIONS || '{}');
headless: isHeadless, } catch (error) {
dumpio: !!process.env.DUMPIO, 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 () => { (async () => {
if (defaultBrowserOptions.executablePath) { if (defaultBrowserOptions.executablePath) {
@ -97,6 +112,16 @@ global.itFailsFirefox = (...args) => {
else return it(...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) => { global.itFailsWindowsUntilDate = (date, ...args) => {
if (os.platform() === 'win32' && Date.now() < date) { if (os.platform() === 'win32' && Date.now() < date) {
// we are within the deferred time so skip the test // we are within the deferred time so skip the test
@ -120,7 +145,10 @@ if (process.env.COVERAGE) trackCoverage();
console.log( console.log(
`Running unit tests with: `Running unit tests with:
-> product: ${product} -> product: ${product}
-> binary: ${path.relative(process.cwd(), puppeteer.executablePath())}` -> binary: ${
defaultBrowserOptions.executablePath ||
path.relative(process.cwd(), puppeteer.executablePath())
}`
); );
exports.setupTestBrowserHooks = () => { exports.setupTestBrowserHooks = () => {

View File

@ -57,15 +57,12 @@ describe('navigation', function () {
const response = await page.goto('about:blank'); const response = await page.goto('about:blank');
expect(response).toBe(null); expect(response).toBe(null);
}); });
itFailsFirefox( it('should return response when page changes its URL after load', async () => {
'should return response when page changes its URL after load', const { page, server } = getTestState();
async () => {
const { page, server } = getTestState();
const response = await page.goto(server.PREFIX + '/historyapi.html'); const response = await page.goto(server.PREFIX + '/historyapi.html');
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
} });
);
it('should work with subframes return 204', async () => { it('should work with subframes return 204', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -88,34 +85,28 @@ describe('navigation', function () {
if (isChrome) expect(error.message).toContain('net::ERR_ABORTED'); if (isChrome) expect(error.message).toContain('net::ERR_ABORTED');
else expect(error.message).toContain('NS_BINDING_ABORTED'); else expect(error.message).toContain('NS_BINDING_ABORTED');
}); });
itFailsFirefox( it('should navigate to empty page with domcontentloaded', async () => {
'should navigate to empty page with domcontentloaded', const { page, server } = getTestState();
async () => {
const { page, server } = getTestState();
const response = await page.goto(server.EMPTY_PAGE, { const response = await page.goto(server.EMPTY_PAGE, {
waitUntil: 'domcontentloaded', waitUntil: 'domcontentloaded',
}); });
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
} });
); it('should work when page calls history API in beforeunload', async () => {
itFailsFirefox( const { page, server } = getTestState();
'should work when page calls history API in beforeunload',
async () => {
const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => { await page.evaluate(() => {
window.addEventListener( window.addEventListener(
'beforeunload', 'beforeunload',
() => history.replaceState(null, 'initial', window.location.href), () => history.replaceState(null, 'initial', window.location.href),
false false
); );
}); });
const response = await page.goto(server.PREFIX + '/grid.html'); const response = await page.goto(server.PREFIX + '/grid.html');
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
} });
);
itFailsFirefox( itFailsFirefox(
'should navigate to empty page with networkidle0', 'should navigate to empty page with networkidle0',
async () => { async () => {
@ -179,22 +170,18 @@ describe('navigation', function () {
expect(requests[0]).toBe('request'); expect(requests[0]).toBe('request');
expect(requests[1]).toBe('requestfailed'); expect(requests[1]).toBe('requestfailed');
}); });
itFailsFirefox( it('should fail when navigating to bad SSL after redirects', async () => {
'should fail when navigating to bad SSL after redirects', const { page, server, httpsServer, isChrome } = getTestState();
async () => {
const { page, server, httpsServer, isChrome } = getTestState();
server.setRedirect('/redirect/1.html', '/redirect/2.html'); server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/empty.html'); server.setRedirect('/redirect/2.html', '/empty.html');
let error = null; let error = null;
await page await page
.goto(httpsServer.PREFIX + '/redirect/1.html') .goto(httpsServer.PREFIX + '/redirect/1.html')
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
if (isChrome) if (isChrome) expect(error.message).toContain(EXPECTED_SSL_CERT_MESSAGE);
expect(error.message).toContain(EXPECTED_SSL_CERT_MESSAGE); else expect(error.message).toContain('SSL_ERROR_UNKNOWN');
else expect(error.message).toContain('SSL_ERROR_UNKNOWN'); });
}
);
it('should throw if networkidle is passed as an option', async () => { it('should throw if networkidle is passed as an option', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -206,20 +193,17 @@ describe('navigation', function () {
'"networkidle" option is no longer supported' '"networkidle" option is no longer supported'
); );
}); });
itFailsFirefox( it('should fail when main resources failed to load', async () => {
'should fail when main resources failed to load', const { page, isChrome } = getTestState();
async () => {
const { page, isChrome } = getTestState();
let error = null; let error = null;
await page await page
.goto('http://localhost:44123/non-existing-url') .goto('http://localhost:44123/non-existing-url')
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
if (isChrome) if (isChrome)
expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); expect(error.message).toContain('net::ERR_CONNECTION_REFUSED');
else expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED'); else expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');
} });
);
it('should fail when exceeding maximum navigation timeout', async () => { it('should fail when exceeding maximum navigation timeout', async () => {
const { page, server, puppeteer } = getTestState(); const { page, server, puppeteer } = getTestState();
@ -284,7 +268,7 @@ describe('navigation', function () {
expect(error).toBe(null); expect(error).toBe(null);
expect(loaded).toBe(true); 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 { page, server } = getTestState();
const response = await page.goto(server.EMPTY_PAGE); const response = await page.goto(server.EMPTY_PAGE);
@ -296,26 +280,23 @@ describe('navigation', function () {
const response = await page.goto('data:text/html,hello'); const response = await page.goto('data:text/html,hello');
expect(response.ok()).toBe(true); 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 { page, server } = getTestState();
const response = await page.goto(server.PREFIX + '/not-found'); const response = await page.goto(server.PREFIX + '/not-found');
expect(response.ok()).toBe(false); expect(response.ok()).toBe(false);
expect(response.status()).toBe(404); expect(response.status()).toBe(404);
}); });
itFailsFirefox( it('should return last response in redirect chain', async () => {
'should return last response in redirect chain', const { page, server } = getTestState();
async () => {
const { page, server } = getTestState();
server.setRedirect('/redirect/1.html', '/redirect/2.html'); server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/redirect/3.html'); server.setRedirect('/redirect/2.html', '/redirect/3.html');
server.setRedirect('/redirect/3.html', server.EMPTY_PAGE); server.setRedirect('/redirect/3.html', server.EMPTY_PAGE);
const response = await page.goto(server.PREFIX + '/redirect/1.html'); const response = await page.goto(server.PREFIX + '/redirect/1.html');
expect(response.ok()).toBe(true); expect(response.ok()).toBe(true);
expect(response.url()).toBe(server.EMPTY_PAGE); expect(response.url()).toBe(server.EMPTY_PAGE);
} });
);
itFailsFirefox( itFailsFirefox(
'should wait for network idle to succeed navigation', 'should wait for network idle to succeed navigation',
async () => { async () => {
@ -401,22 +382,19 @@ describe('navigation', function () {
process.removeListener('warning', warningHandler); process.removeListener('warning', warningHandler);
expect(warning).toBe(null); expect(warning).toBe(null);
}); });
itFailsFirefox( it('should not leak listeners during bad navigation', async () => {
'should not leak listeners during bad navigation', const { page } = getTestState();
async () => {
const { page } = getTestState();
let warning = null; let warning = null;
const warningHandler = (w) => (warning = w); const warningHandler = (w) => (warning = w);
process.on('warning', warningHandler); process.on('warning', warningHandler);
for (let i = 0; i < 20; ++i) for (let i = 0; i < 20; ++i)
await page.goto('asdf').catch((error) => { await page.goto('asdf').catch((error) => {
/* swallow navigation error */ /* swallow navigation error */
}); });
process.removeListener('warning', warningHandler); process.removeListener('warning', warningHandler);
expect(warning).toBe(null); expect(warning).toBe(null);
} });
);
it('should not leak listeners during navigation of 11 pages', async () => { it('should not leak listeners during navigation of 11 pages', async () => {
const { context, server } = getTestState(); const { context, server } = getTestState();
@ -467,28 +445,25 @@ describe('navigation', function () {
expect(requests[0].url()).toBe(server.EMPTY_PAGE); 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 { page, server } = getTestState();
const response = await page.goto(server.PREFIX + '/self-request.html'); const response = await page.goto(server.PREFIX + '/self-request.html');
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
expect(response.url()).toContain('self-request.html'); expect(response.url()).toContain('self-request.html');
}); });
itFailsFirefox( it('should fail when navigating and show the url at the error message', async () => {
'should fail when navigating and show the url at the error message', const { page, httpsServer } = getTestState();
async () => {
const { page, httpsServer } = getTestState();
const url = httpsServer.PREFIX + '/redirect/1.html'; const url = httpsServer.PREFIX + '/redirect/1.html';
let error = null; let error = null;
try { try {
await page.goto(url); await page.goto(url);
} catch (error_) { } catch (error_) {
error = error_; error = error_;
}
expect(error.message).toContain(url);
} }
); expect(error.message).toContain(url);
});
itFailsFirefox('should send referer', async () => { itFailsFirefox('should send referer', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -644,7 +619,7 @@ describe('navigation', function () {
); );
}); });
describeFailsFirefox('Page.goBack', function () { describe('Page.goBack', function () {
it('should work', async () => { it('should work', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -662,7 +637,7 @@ describe('navigation', function () {
response = await page.goForward(); response = await page.goForward();
expect(response).toBe(null); expect(response).toBe(null);
}); });
it('should work with HistoryAPI', async () => { itFailsFirefox('should work with HistoryAPI', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);

View File

@ -40,7 +40,7 @@ describe('network', function () {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
expect(requests.length).toBe(1); expect(requests.length).toBe(1);
}); });
itFailsFirefox('should fire for iframes', async () => { it('should fire for iframes', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
const requests = []; const requests = [];
@ -110,7 +110,7 @@ describe('network', function () {
}); });
}); });
describeFailsFirefox('Request.headers', function () { describe('Request.headers', function () {
it('should work', async () => { it('should work', async () => {
const { page, server, isChrome } = getTestState(); const { page, server, isChrome } = getTestState();
@ -122,7 +122,7 @@ describe('network', function () {
}); });
}); });
describeFailsFirefox('Response.headers', function () { describe('Response.headers', function () {
it('should work', async () => { it('should work', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
@ -325,7 +325,7 @@ describe('network', function () {
}); });
}); });
describeFailsFirefox('Response.statusText', function () { describe('Response.statusText', function () {
it('should work', async () => { it('should work', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();

View File

@ -694,7 +694,7 @@ describe('Page', function () {
}); });
describe('Page.waitForResponse', function () { describe('Page.waitForResponse', function () {
itFailsFirefox('should work', async () => { it('should work', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -727,7 +727,7 @@ describe('Page', function () {
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError); expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
}); });
itFailsFirefox('should work with predicate', async () => { it('should work with predicate', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -743,7 +743,7 @@ describe('Page', function () {
]); ]);
expect(response.url()).toBe(server.PREFIX + '/digits/2.png'); 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(); const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -909,7 +909,7 @@ describe('Page', function () {
]); ]);
expect(request.headers['user-agent']).toBe('foobar'); expect(request.headers['user-agent']).toBe('foobar');
}); });
itFailsFirefox('should work for subframes', async () => { it('should work for subframes', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
expect(await page.evaluate(() => navigator.userAgent)).toContain( expect(await page.evaluate(() => navigator.userAgent)).toContain(
@ -936,7 +936,7 @@ describe('Page', function () {
}); });
}); });
describeFailsFirefox('Page.setContent', function () { describe('Page.setContent', function () {
const expectedOutput = const expectedOutput =
'<html><head></head><body><div>hello</div></body></html>'; '<html><head></head><body><div>hello</div></body></html>';
it('should work', async () => { it('should work', async () => {
@ -1321,7 +1321,7 @@ describe('Page', function () {
expect(styleContent).toContain(path.join('assets', 'injectedstyle.css')); expect(styleContent).toContain(path.join('assets', 'injectedstyle.css'));
}); });
itFailsFirefox('should work with content', async () => { it('should work with content', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -1433,7 +1433,7 @@ describe('Page', function () {
}); });
describe('printing to PDF', 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 // Printing to pdf is currently only supported in headless
const { isHeadless, page } = getTestState(); const { isHeadless, page } = getTestState();
@ -1591,7 +1591,7 @@ describe('Page', function () {
) )
).toEqual(true); ).toEqual(true);
}); });
itFailsFirefox('should throw if passed in non-strings', async () => { it('should throw if passed in non-strings', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('<select><option value="12"/></select>'); await page.setContent('<select><option value="12"/></select>');

View File

@ -23,7 +23,7 @@ const {
describe('querySelector', function () { describe('querySelector', function () {
setupTestBrowserHooks(); setupTestBrowserHooks();
setupTestPageAndContextHooks(); setupTestPageAndContextHooks();
describeFailsFirefox('Page.$eval', function () { describe('Page.$eval', function () {
it('should work', async () => { it('should work', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -67,7 +67,7 @@ describe('querySelector', function () {
}); });
}); });
describeFailsFirefox('Page.$$eval', function () { describe('Page.$$eval', function () {
it('should work', async () => { it('should work', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -79,7 +79,7 @@ describe('querySelector', function () {
}); });
}); });
describeFailsFirefox('Page.$', function () { describe('Page.$', function () {
it('should query existing element', async () => { it('should query existing element', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -96,7 +96,7 @@ describe('querySelector', function () {
}); });
describe('Page.$$', function () { describe('Page.$$', function () {
itFailsFirefox('should query existing elements', async () => { it('should query existing elements', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('<div>A</div><br/><div>B</div>'); await page.setContent('<div>A</div><br/><div>B</div>');
@ -116,7 +116,7 @@ describe('querySelector', function () {
}); });
}); });
describeFailsFirefox('Path.$x', function () { describe('Path.$x', function () {
it('should query existing element', async () => { it('should query existing element', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -155,7 +155,7 @@ describe('querySelector', function () {
expect(content).toBe('A'); 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(); const { page } = getTestState();
await page.setContent( await page.setContent(
@ -166,7 +166,7 @@ describe('querySelector', function () {
expect(second).toBe(null); expect(second).toBe(null);
}); });
}); });
describeFailsFirefox('ElementHandle.$eval', function () { describe('ElementHandle.$eval', function () {
it('should work', async () => { it('should work', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -204,7 +204,7 @@ describe('querySelector', function () {
); );
}); });
}); });
describeFailsFirefox('ElementHandle.$$eval', function () { describe('ElementHandle.$$eval', function () {
it('should work', async () => { it('should work', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -246,7 +246,7 @@ describe('querySelector', function () {
}); });
}); });
describeFailsFirefox('ElementHandle.$$', function () { describe('ElementHandle.$$', function () {
it('should query existing elements', async () => { it('should query existing elements', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -289,7 +289,7 @@ describe('querySelector', function () {
expect(content).toBe('A'); 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(); const { page } = getTestState();
await page.setContent( await page.setContent(

View File

@ -177,7 +177,7 @@ describe('Screenshots', function () {
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png'); 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(); const { page } = getTestState();
await page.setViewport({ width: 500, height: 500 }); await page.setViewport({ width: 500, height: 500 });
@ -196,14 +196,12 @@ describe('Screenshots', function () {
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-padding-border.png'); expect(screenshot).toBeGolden('screenshot-element-padding-border.png');
}); });
itFailsFirefox( it('should capture full element when larger than viewport', async () => {
'should capture full element when larger than viewport', const { page } = getTestState();
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 something above
<style> <style>
div.to-screenshot { div.to-screenshot {
@ -218,21 +216,20 @@ describe('Screenshots', function () {
</style> </style>
<div class="to-screenshot"></div> <div class="to-screenshot"></div>
`); `);
const elementHandle = await page.$('div.to-screenshot'); const elementHandle = await page.$('div.to-screenshot');
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden( expect(screenshot).toBeGolden(
'screenshot-element-larger-than-viewport.png' 'screenshot-element-larger-than-viewport.png'
); );
expect( expect(
await page.evaluate(() => ({ await page.evaluate(() => ({
w: window.innerWidth, w: window.innerWidth,
h: window.innerHeight, h: window.innerHeight,
})) }))
).toEqual({ w: 500, h: 500 }); ).toEqual({ w: 500, h: 500 });
} });
); it('should scroll element into view', async () => {
itFailsFirefox('should scroll element into view', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setViewport({ width: 500, height: 500 }); await page.setViewport({ width: 500, height: 500 });
@ -287,30 +284,24 @@ describe('Screenshots', function () {
'Node is either not visible or not an HTMLElement' 'Node is either not visible or not an HTMLElement'
); );
}); });
itFailsFirefox( it('should not hang with zero width/height element', async () => {
'should not hang with zero width/height element', const { page } = getTestState();
async () => {
const { page } = getTestState();
await page.setContent('<div style="width: 50px; height: 0"></div>'); await page.setContent('<div style="width: 50px; height: 0"></div>');
const div = await page.$('div'); const div = await page.$('div');
const error = await div.screenshot().catch((error_) => error_); const error = await div.screenshot().catch((error_) => error_);
expect(error.message).toBe('Node has 0 height.'); expect(error.message).toBe('Node has 0 height.');
} });
); it('should work for an element with fractional dimensions', async () => {
itFailsFirefox( const { page } = getTestState();
'should work for an element with fractional dimensions',
async () => {
const { page } = getTestState();
await page.setContent( await page.setContent(
'<div style="width:48.51px;height:19.8px;border:1px solid black;"></div>' '<div style="width:48.51px;height:19.8px;border:1px solid black;"></div>'
); );
const elementHandle = await page.$('div'); const elementHandle = await page.$('div');
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-fractional.png'); expect(screenshot).toBeGolden('screenshot-element-fractional.png');
} });
);
itFailsFirefox('should work for an element with an offset', async () => { itFailsFirefox('should work for an element with an offset', async () => {
const { page } = getTestState(); const { page } = getTestState();

View File

@ -27,7 +27,7 @@ describe('waittask specs', function () {
setupTestPageAndContextHooks(); setupTestPageAndContextHooks();
describe('Page.waitFor', function () { describe('Page.waitFor', function () {
itFailsFirefox('should wait for selector', async () => { it('should wait for selector', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
let found = false; let found = false;
@ -39,7 +39,7 @@ describe('waittask specs', function () {
expect(found).toBe(true); expect(found).toBe(true);
}); });
itFailsFirefox('should wait for an xpath', async () => { it('should wait for an xpath', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
let found = false; let found = false;
@ -50,19 +50,14 @@ describe('waittask specs', function () {
await waitFor; await waitFor;
expect(found).toBe(true); expect(found).toBe(true);
}); });
itFailsFirefox( it('should not allow you to select an element with single slash xpath', async () => {
'should not allow you to select an element with single slash xpath', const { page } = getTestState();
async () => {
const { page } = getTestState();
await page.setContent(`<div>some text</div>`); await page.setContent(`<div>some text</div>`);
let error = null; let error = null;
await page await page.waitFor('/html/body/div').catch((error_) => (error = error_));
.waitFor('/html/body/div') expect(error).toBeTruthy();
.catch((error_) => (error = error_)); });
expect(error).toBeTruthy();
}
);
it('should timeout', async () => { it('should timeout', async () => {
const { page } = getTestState(); const { page } = getTestState();
@ -255,7 +250,7 @@ describe('waittask specs', function () {
expect(await page.waitForFunction(() => window)).toBeTruthy(); expect(await page.waitForFunction(() => window)).toBeTruthy();
}); });
itFailsFirefox('should accept ElementHandle arguments', async () => { it('should accept ElementHandle arguments', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent('<div></div>'); await page.setContent('<div></div>');
@ -330,7 +325,7 @@ describe('waittask specs', function () {
}); });
}); });
describeFailsFirefox('Frame.waitForSelector', function () { describe('Frame.waitForSelector', function () {
const addElement = (tag) => const addElement = (tag) =>
document.body.appendChild(document.createElement(tag)); document.body.appendChild(document.createElement(tag));
@ -344,7 +339,7 @@ describe('waittask specs', function () {
await frame.waitForSelector('div'); await frame.waitForSelector('div');
}); });
it('should work with removed MutationObserver', async () => { itFailsFirefox('should work with removed MutationObserver', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.evaluate(() => delete window.MutationObserver); await page.evaluate(() => delete window.MutationObserver);
@ -385,20 +380,23 @@ describe('waittask specs', function () {
await watchdog; await watchdog;
}); });
it('Page.waitForSelector is shortcut for main frame', async () => { itFailsFirefox(
const { page, server } = getTestState(); 'Page.waitForSelector is shortcut for main frame',
async () => {
const { page, server } = getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
const otherFrame = page.frames()[1]; const otherFrame = page.frames()[1];
const watchdog = page.waitForSelector('div'); const watchdog = page.waitForSelector('div');
await otherFrame.evaluate(addElement, 'div'); await otherFrame.evaluate(addElement, 'div');
await page.evaluate(addElement, 'div'); await page.evaluate(addElement, 'div');
const eHandle = await watchdog; const eHandle = await watchdog;
expect(eHandle.executionContext().frame()).toBe(page.mainFrame()); 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(); const { page, server } = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -412,7 +410,7 @@ describe('waittask specs', function () {
expect(eHandle.executionContext().frame()).toBe(frame2); 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(); const { page, server } = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -580,7 +578,7 @@ describe('waittask specs', function () {
); );
expect(await waitForSelector).toBe(true); expect(await waitForSelector).toBe(true);
}); });
itFailsFirefox('should return the element handle', async () => { it('should return the element handle', async () => {
const { page } = getTestState(); const { page } = getTestState();
const waitForSelector = page.waitForSelector('.zombo'); const waitForSelector = page.waitForSelector('.zombo');
@ -600,7 +598,7 @@ describe('waittask specs', function () {
}); });
}); });
describeFailsFirefox('Frame.waitForXPath', function () { describe('Frame.waitForXPath', function () {
const addElement = (tag) => const addElement = (tag) =>
document.body.appendChild(document.createElement(tag)); document.body.appendChild(document.createElement(tag));
@ -628,7 +626,7 @@ describe('waittask specs', function () {
); );
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError); expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
}); });
it('should run in specified frame', async () => { itFailsFirefox('should run in specified frame', async () => {
const { page, server } = getTestState(); const { page, server } = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -641,7 +639,7 @@ describe('waittask specs', function () {
const eHandle = await waitForXPathPromise; const eHandle = await waitForXPathPromise;
expect(eHandle.executionContext().frame()).toBe(frame2); 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(); const { page, server } = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);