test: use isChromium, etc fixtures for browser name sniffing (#3508)

This commit is contained in:
Pavel Feldman 2020-08-18 12:48:32 -07:00 committed by GitHub
parent b2228a660a
commit 510182f0b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 239 additions and 217 deletions

View file

@ -44,6 +44,9 @@ declare global {
browserType: BrowserType<Browser>; browserType: BrowserType<Browser>;
browserName: string; browserName: string;
browser: Browser; browser: Browser;
isChromium: boolean;
isFirefox: boolean;
isWebKit: boolean;
} }
interface FixtureState { interface FixtureState {
toImpl: (rpcObject: any) => any; toImpl: (rpcObject: any) => any;
@ -185,6 +188,18 @@ registerWorkerFixture('browserName', async ({}, test) => {
await test(browserName); await test(browserName);
}); });
registerWorkerFixture('isChromium', async ({browserName}, test) => {
await test(browserName === 'chromium');
});
registerWorkerFixture('isFirefox', async ({browserName}, test) => {
await test(browserName === 'firefox');
});
registerWorkerFixture('isWebKit', async ({browserName}, test) => {
await test(browserName === 'webkit');
});
registerFixture('httpsServer', async ({httpService}, test) => { registerFixture('httpsServer', async ({httpService}, test) => {
httpService.httpsServer.reset(); httpService.httpsServer.reset();
await test(httpService.httpsServer); await test(httpService.httpsServer);

View file

@ -39,9 +39,9 @@ it('should throw upon second create new page', async function({browser}) {
expect(error.message).toContain('Please use browser.newContext()'); expect(error.message).toContain('Please use browser.newContext()');
}); });
it('version should work', async function({browser}) { it('version should work', async function({browser, isChromium}) {
const version = browser.version(); const version = browser.version();
if (CHROMIUM) if (isChromium)
expect(version.match(/^\d+\.\d+\.\d+\.\d+$/)).toBeTruthy(); expect(version.match(/^\d+\.\d+\.\d+\.\d+$/)).toBeTruthy();
else else
expect(version.match(/^\d+\.\d+/)).toBeTruthy(); expect(version.match(/^\d+\.\d+/)).toBeTruthy();

View file

@ -177,14 +177,14 @@ it('should close all belonging pages once closing context', async function({brow
expect(context.pages().length).toBe(0); expect(context.pages().length).toBe(0);
}); });
it('should disable javascript', async({browser}) => { it('should disable javascript', async({browser, isWebKit}) => {
{ {
const context = await browser.newContext({ javaScriptEnabled: false }); const context = await browser.newContext({ javaScriptEnabled: false });
const page = await context.newPage(); const page = await context.newPage();
await page.goto('data:text/html, <script>var something = "forbidden"</script>'); await page.goto('data:text/html, <script>var something = "forbidden"</script>');
let error = null; let error = null;
await page.evaluate('something').catch(e => error = e); await page.evaluate('something').catch(e => error = e);
if (WEBKIT) if (isWebKit)
expect(error.message).toContain('Can\'t find variable: something'); expect(error.message).toContain('Can\'t find variable: something');
else else
expect(error.message).toContain('something is not defined'); expect(error.message).toContain('something is not defined');

View file

@ -24,12 +24,12 @@ it('browserType.executablePath should work', async({browserType}) => {
expect(fs.realpathSync(executablePath)).toBe(executablePath); expect(fs.realpathSync(executablePath)).toBe(executablePath);
}); });
it('browserType.name should work', async({browserType}) => { it('browserType.name should work', async({browserType, isWebKit, isFirefox, isChromium}) => {
if (WEBKIT) if (isWebKit)
expect(browserType.name()).toBe('webkit'); expect(browserType.name()).toBe('webkit');
else if (FFOX) else if (isFirefox)
expect(browserType.name()).toBe('firefox'); expect(browserType.name()).toBe('firefox');
else if (CHROMIUM) else if (isChromium)
expect(browserType.name()).toBe('chromium'); expect(browserType.name()).toBe('chromium');
else else
throw new Error('Unknown browser'); throw new Error('Unknown browser');

View file

@ -344,39 +344,39 @@ it('should click the button with deviceScaleFactor set', async({browser, server}
await context.close(); await context.close();
}); });
it('should click the button with px border with offset', async({page, server}) => { it('should click the button with px border with offset', async({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => button.style.borderWidth = '8px'); await page.$eval('button', button => button.style.borderWidth = '8px');
await page.click('button', { position: { x: 20, y: 10 } }); await page.click('button', { position: { x: 20, y: 10 } });
expect(await page.evaluate('result')).toBe('Clicked'); expect(await page.evaluate('result')).toBe('Clicked');
// Safari reports border-relative offsetX/offsetY. // Safari reports border-relative offsetX/offsetY.
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 20 + 8 : 20); expect(await page.evaluate('offsetX')).toBe(isWebKit ? 20 + 8 : 20);
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 10 + 8 : 10); expect(await page.evaluate('offsetY')).toBe(isWebKit ? 10 + 8 : 10);
}); });
it('should click the button with em border with offset', async({page, server}) => { it('should click the button with em border with offset', async({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => button.style.borderWidth = '2em'); await page.$eval('button', button => button.style.borderWidth = '2em');
await page.$eval('button', button => button.style.fontSize = '12px'); await page.$eval('button', button => button.style.fontSize = '12px');
await page.click('button', { position: { x: 20, y: 10 } }); await page.click('button', { position: { x: 20, y: 10 } });
expect(await page.evaluate('result')).toBe('Clicked'); expect(await page.evaluate('result')).toBe('Clicked');
// Safari reports border-relative offsetX/offsetY. // Safari reports border-relative offsetX/offsetY.
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 12 * 2 + 20 : 20); expect(await page.evaluate('offsetX')).toBe(isWebKit ? 12 * 2 + 20 : 20);
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 12 * 2 + 10 : 10); expect(await page.evaluate('offsetY')).toBe(isWebKit ? 12 * 2 + 10 : 10);
}); });
it('should click a very large button with offset', async({page, server}) => { it('should click a very large button with offset', async({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => button.style.borderWidth = '8px'); await page.$eval('button', button => button.style.borderWidth = '8px');
await page.$eval('button', button => button.style.height = button.style.width = '2000px'); await page.$eval('button', button => button.style.height = button.style.width = '2000px');
await page.click('button', { position: { x: 1900, y: 1910 } }); await page.click('button', { position: { x: 1900, y: 1910 } });
expect(await page.evaluate(() => window['result'])).toBe('Clicked'); expect(await page.evaluate(() => window['result'])).toBe('Clicked');
// Safari reports border-relative offsetX/offsetY. // Safari reports border-relative offsetX/offsetY.
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900); expect(await page.evaluate('offsetX')).toBe(isWebKit ? 1900 + 8 : 1900);
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910); expect(await page.evaluate('offsetY')).toBe(isWebKit ? 1910 + 8 : 1910);
}); });
it('should click a button in scrolling container with offset', async({page, server}) => { it('should click a button in scrolling container with offset', async({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => { await page.$eval('button', button => {
const container = document.createElement('div'); const container = document.createElement('div');
@ -392,11 +392,11 @@ it('should click a button in scrolling container with offset', async({page, serv
await page.click('button', { position: { x: 1900, y: 1910 } }); await page.click('button', { position: { x: 1900, y: 1910 } });
expect(await page.evaluate(() => window['result'])).toBe('Clicked'); expect(await page.evaluate(() => window['result'])).toBe('Clicked');
// Safari reports border-relative offsetX/offsetY. // Safari reports border-relative offsetX/offsetY.
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900); expect(await page.evaluate('offsetX')).toBe(isWebKit ? 1900 + 8 : 1900);
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910); expect(await page.evaluate('offsetY')).toBe(isWebKit ? 1910 + 8 : 1910);
}); });
it.skip(FFOX)('should click the button with offset with page scale', async({browser, server}) => { it.skip(FFOX)('should click the button with offset with page scale', async({browser, server, isChromium, isWebKit}) => {
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true }); const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
@ -408,10 +408,10 @@ it.skip(FFOX)('should click the button with offset with page scale', async({brow
expect(await page.evaluate('result')).toBe('Clicked'); expect(await page.evaluate('result')).toBe('Clicked');
const round = x => Math.round(x + 0.01); const round = x => Math.round(x + 0.01);
let expected = { x: 28, y: 18 }; // 20;10 + 8px of border in each direction let expected = { x: 28, y: 18 }; // 20;10 + 8px of border in each direction
if (WEBKIT) { if (isWebKit) {
// WebKit rounds up during css -> dip -> css conversion. // WebKit rounds up during css -> dip -> css conversion.
expected = { x: 29, y: 19 }; expected = { x: 29, y: 19 };
} else if (CHROMIUM && HEADLESS) { } else if (isChromium && HEADLESS) {
// Headless Chromium rounds down during css -> dip -> css conversion. // Headless Chromium rounds down during css -> dip -> css conversion.
expected = { x: 27, y: 18 }; expected = { x: 27, y: 18 };
} }

View file

@ -171,12 +171,12 @@ it('should support bypassCSP option', async ({server, launchPersistent}) => {
expect(await page.evaluate('__injected')).toBe(42); expect(await page.evaluate('__injected')).toBe(42);
}); });
it('should support javascriptEnabled option', async ({server, launchPersistent}) => { it('should support javascriptEnabled option', async ({launchPersistent, isWebKit}) => {
const {page, context} = await launchPersistent({javaScriptEnabled: false}); const {page, context} = await launchPersistent({javaScriptEnabled: false});
await page.goto('data:text/html, <script>var something = "forbidden"</script>'); await page.goto('data:text/html, <script>var something = "forbidden"</script>');
let error = null; let error = null;
await page.evaluate('something').catch(e => error = e); await page.evaluate('something').catch(e => error = e);
if (WEBKIT) if (isWebKit)
expect(error.message).toContain('Can\'t find variable: something'); expect(error.message).toContain('Can\'t find variable: something');
else else
expect(error.message).toContain('something is not defined'); expect(error.message).toContain('something is not defined');

View file

@ -16,12 +16,12 @@
*/ */
import './base.fixture'; import './base.fixture';
it('should select textarea', async ({ page, server }) => { it('should select textarea', async ({ page, server, isFirefox }) => {
await page.goto(server.PREFIX + '/input/textarea.html'); await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = await page.$('textarea'); const textarea = await page.$('textarea');
await textarea.evaluate(textarea => textarea.value = 'some value'); await textarea.evaluate(textarea => textarea.value = 'some value');
await textarea.selectText(); await textarea.selectText();
if (FFOX) { if (isFirefox) {
expect(await textarea.evaluate(el => el.selectionStart)).toBe(0); expect(await textarea.evaluate(el => el.selectionStart)).toBe(0);
expect(await textarea.evaluate(el => el.selectionEnd)).toBe(10); expect(await textarea.evaluate(el => el.selectionEnd)).toBe(10);
} else { } else {
@ -29,12 +29,12 @@ it('should select textarea', async ({ page, server }) => {
} }
}); });
it('should select input', async ({ page, server }) => { it('should select input', async ({ page, server, isFirefox }) => {
await page.goto(server.PREFIX + '/input/textarea.html'); await page.goto(server.PREFIX + '/input/textarea.html');
const input = await page.$('input'); const input = await page.$('input');
await input.evaluate(input => input.value = 'some value'); await input.evaluate(input => input.value = 'some value');
await input.selectText(); await input.selectText();
if (FFOX) { if (isFirefox) {
expect(await input.evaluate(el => el.selectionStart)).toBe(0); expect(await input.evaluate(el => el.selectionStart)).toBe(0);
expect(await input.evaluate(el => el.selectionEnd)).toBe(10); expect(await input.evaluate(el => el.selectionEnd)).toBe(10);
} else { } else {

View file

@ -36,27 +36,27 @@ it('should have correct execution contexts', async ({ page, server }) => {
expect(await page.frames()[1].evaluate(() => document.body.textContent.trim())).toBe(`Hi, I'm frame`); expect(await page.frames()[1].evaluate(() => document.body.textContent.trim())).toBe(`Hi, I'm frame`);
}); });
function expectContexts(pageImpl, count) { function expectContexts(pageImpl, count, isChromium) {
if (CHROMIUM) if (isChromium)
expect(pageImpl._delegate._mainFrameSession._contextIdToContext.size).toBe(count); expect(pageImpl._delegate._mainFrameSession._contextIdToContext.size).toBe(count);
else else
expect(pageImpl._delegate._contextIdToContext.size).toBe(count); expect(pageImpl._delegate._contextIdToContext.size).toBe(count);
} }
it.skip(WIRE)('should dispose context on navigation', async ({ page, server, toImpl }) => { it.skip(WIRE)('should dispose context on navigation', async ({ page, server, toImpl, isChromium }) => {
await page.goto(server.PREFIX + '/frames/one-frame.html'); await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expectContexts(toImpl(page), 4); expectContexts(toImpl(page), 4, isChromium);
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
expectContexts(toImpl(page), 2); expectContexts(toImpl(page), 2, isChromium);
}); });
it.skip(WIRE)('should dispose context on cross-origin navigation', async ({ page, server, toImpl }) => { it.skip(WIRE)('should dispose context on cross-origin navigation', async ({ page, server, toImpl, isChromium }) => {
await page.goto(server.PREFIX + '/frames/one-frame.html'); await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expectContexts(toImpl(page), 4); expectContexts(toImpl(page), 4, isChromium);
await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
expectContexts(toImpl(page), 2); expectContexts(toImpl(page), 2, isChromium);
}); });
it('should execute after cross-site navigation', async ({ page, server }) => { it('should execute after cross-site navigation', async ({ page, server }) => {

View file

@ -350,21 +350,21 @@ it.skip(!MAC)('should support MacOS shortcuts', async ({page, server}) => {
expect(await page.$eval('textarea', textarea => textarea.value)).toBe('some '); expect(await page.$eval('textarea', textarea => textarea.value)).toBe('some ');
}); });
it('should press the meta key', async ({page}) => { it('should press the meta key', async ({page, isFirefox}) => {
const lastEvent = await captureLastKeydown(page); const lastEvent = await captureLastKeydown(page);
await page.keyboard.press('Meta'); await page.keyboard.press('Meta');
const {key, code, metaKey} = await lastEvent.jsonValue(); const {key, code, metaKey} = await lastEvent.jsonValue();
if (FFOX && !MAC) if (isFirefox && !MAC)
expect(key).toBe('OS'); expect(key).toBe('OS');
else else
expect(key).toBe('Meta'); expect(key).toBe('Meta');
if (FFOX) if (isFirefox)
expect(code).toBe('OSLeft'); expect(code).toBe('OSLeft');
else else
expect(code).toBe('MetaLeft'); expect(code).toBe('MetaLeft');
if (FFOX && !MAC) if (isFirefox && !MAC)
expect(metaKey).toBe(false); expect(metaKey).toBe(false);
else else
expect(metaKey).toBe(true); expect(metaKey).toBe(true);

View file

@ -121,12 +121,12 @@ it('should trigger hover state with removed window.Node', async({page, server})
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6'); expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
}); });
it('should set modifier keys on click', async({page, server}) => { it('should set modifier keys on click', async({page, server, isFirefox}) => {
await page.goto(server.PREFIX + '/input/scrollable.html'); await page.goto(server.PREFIX + '/input/scrollable.html');
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window["lastEvent"] = e, true)); await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window["lastEvent"] = e, true));
const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'}; const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
// In Firefox, the Meta modifier only exists on Mac // In Firefox, the Meta modifier only exists on Mac
if (FFOX && !MAC) if (isFirefox && !MAC)
delete modifiers['Meta']; delete modifiers['Meta'];
for (const modifier in modifiers) { for (const modifier in modifiers) {
await page.keyboard.down(modifier); await page.keyboard.down(modifier);
@ -142,9 +142,9 @@ it('should set modifier keys on click', async({page, server}) => {
} }
}); });
it('should tween mouse movement', async({page, server}) => { it('should tween mouse movement', async({page, isWebKit}) => {
// The test becomes flaky on WebKit without next line. // The test becomes flaky on WebKit without next line.
if (WEBKIT) if (isWebKit)
await page.evaluate(() => new Promise(requestAnimationFrame)); await page.evaluate(() => new Promise(requestAnimationFrame));
await page.mouse.move(100, 100); await page.mouse.move(100, 100);
await page.evaluate(() => { await page.evaluate(() => {

View file

@ -45,13 +45,13 @@ it('should work for fetch requests', async({page, server}) => {
expect(requests[0].frame()).toBe(page.mainFrame()); expect(requests[0].frame()).toBe(page.mainFrame());
}); });
it('should return headers', async({page, server}) => { it('should return headers', async({page, server, isChromium, isFirefox, isWebKit}) => {
const response = await page.goto(server.EMPTY_PAGE); const response = await page.goto(server.EMPTY_PAGE);
if (CHROMIUM) if (isChromium)
expect(response.request().headers()['user-agent']).toContain('Chrome'); expect(response.request().headers()['user-agent']).toContain('Chrome');
else if (FFOX) else if (isFirefox)
expect(response.request().headers()['user-agent']).toContain('Firefox'); expect(response.request().headers()['user-agent']).toContain('Firefox');
else if (WEBKIT) else if (isWebKit)
expect(response.request().headers()['user-agent']).toContain('WebKit'); expect(response.request().headers()['user-agent']).toContain('WebKit');
}); });

View file

@ -33,7 +33,7 @@ it('should not be visible in context.pages', async({context}) => {
expect(context.pages()).not.toContain(newPage); expect(context.pages()).not.toContain(newPage);
}); });
it('should run beforeunload if asked for', async({context, server}) => { it('should run beforeunload if asked for', async({context, server, isChromium, isWebKit}) => {
const newPage = await context.newPage(); const newPage = await context.newPage();
await newPage.goto(server.PREFIX + '/beforeunload.html'); await newPage.goto(server.PREFIX + '/beforeunload.html');
// We have to interact with a page so that 'beforeunload' handlers // We have to interact with a page so that 'beforeunload' handlers
@ -43,9 +43,9 @@ it('should run beforeunload if asked for', async({context, server}) => {
const dialog = await newPage.waitForEvent('dialog'); const dialog = await newPage.waitForEvent('dialog');
expect(dialog.type()).toBe('beforeunload'); expect(dialog.type()).toBe('beforeunload');
expect(dialog.defaultValue()).toBe(''); expect(dialog.defaultValue()).toBe('');
if (CHROMIUM) if (isChromium)
expect(dialog.message()).toBe(''); expect(dialog.message()).toBe('');
else if (WEBKIT) else if (isWebKit)
expect(dialog.message()).toBe('Leave?'); expect(dialog.message()).toBe('Leave?');
else else
expect(dialog.message()).toBe('This page is asking you to confirm that you want to leave - data you have entered may not be saved.'); expect(dialog.message()).toBe('This page is asking you to confirm that you want to leave - data you have entered may not be saved.');
@ -196,7 +196,7 @@ it('page.frame should respect url', async function({page, server}) {
expect(page.frame({ url: /empty/ }).url()).toBe(server.EMPTY_PAGE); expect(page.frame({ url: /empty/ }).url()).toBe(server.EMPTY_PAGE);
}); });
it('should have sane user agent', async ({page}) => { it('should have sane user agent', async ({page, isChromium, isFirefox}) => {
const userAgent = await page.evaluate(() => navigator.userAgent); const userAgent = await page.evaluate(() => navigator.userAgent);
const [ const [
part1, part1,
@ -210,7 +210,7 @@ it('should have sane user agent', async ({page}) => {
// Second part in parenthesis is platform - ignore it. // Second part in parenthesis is platform - ignore it.
// Third part for Firefox is the last one and encodes engine and browser versions. // Third part for Firefox is the last one and encodes engine and browser versions.
if (FFOX) { if (isFirefox) {
const [engine, browser] = part3.split(' '); const [engine, browser] = part3.split(' ');
expect(engine.startsWith('Gecko')).toBe(true); expect(engine.startsWith('Gecko')).toBe(true);
expect(browser.startsWith('Firefox')).toBe(true); expect(browser.startsWith('Firefox')).toBe(true);
@ -224,7 +224,7 @@ it('should have sane user agent', async ({page}) => {
// 5th part encodes real browser name and engine version. // 5th part encodes real browser name and engine version.
const [engine, browser] = part5.split(' '); const [engine, browser] = part5.split(' ');
expect(browser.startsWith('Safari/')).toBe(true); expect(browser.startsWith('Safari/')).toBe(true);
if (CHROMIUM) if (isChromium)
expect(engine.includes('Chrome/')).toBe(true); expect(engine.includes('Chrome/')).toBe(true);
else else
expect(engine.startsWith('Version/')).toBe(true); expect(engine.startsWith('Version/')).toBe(true);

View file

@ -20,51 +20,51 @@ const { WIRE } = testOptions;
const CRASH_FAIL = (FFOX && WIN) || WIRE; const CRASH_FAIL = (FFOX && WIN) || WIRE;
// Firefox Win: it just doesn't crash sometimes. // Firefox Win: it just doesn't crash sometimes.
function crash(pageImpl) { function crash(pageImpl, browserName) {
if (CHROMIUM) if (browserName === 'chromium')
pageImpl.mainFrame().goto('chrome://crash').catch(e => {}); pageImpl.mainFrame().goto('chrome://crash').catch(e => {});
else if (WEBKIT) else if (browserName === 'webkit')
pageImpl._delegate._session.send('Page.crash', {}).catch(e => {}); pageImpl._delegate._session.send('Page.crash', {}).catch(e => {});
else if (FFOX) else if (browserName === 'firefox')
pageImpl._delegate._session.send('Page.crash', {}).catch(e => {}); pageImpl._delegate._session.send('Page.crash', {}).catch(e => {});
} }
it.fail(CRASH_FAIL)('should emit crash event when page crashes', async({page, toImpl}) => { it.fail(CRASH_FAIL)('should emit crash event when page crashes', async({page, browserName, toImpl}) => {
await page.setContent(`<div>This page should crash</div>`); await page.setContent(`<div>This page should crash</div>`);
crash(toImpl(page)); crash(toImpl(page), browserName);
await new Promise(f => page.on('crash', f)); await new Promise(f => page.on('crash', f));
}); });
it.fail(CRASH_FAIL)('should throw on any action after page crashes', async({page, toImpl}) => { it.fail(CRASH_FAIL)('should throw on any action after page crashes', async({page, browserName, toImpl}) => {
await page.setContent(`<div>This page should crash</div>`); await page.setContent(`<div>This page should crash</div>`);
crash(toImpl(page)); crash(toImpl(page), browserName);
await page.waitForEvent('crash'); await page.waitForEvent('crash');
const err = await page.evaluate(() => {}).then(() => null, e => e); const err = await page.evaluate(() => {}).then(() => null, e => e);
expect(err).toBeTruthy(); expect(err).toBeTruthy();
expect(err.message).toContain('crash'); expect(err.message).toContain('crash');
}); });
it.fail(CRASH_FAIL)('should cancel waitForEvent when page crashes', async({page, toImpl}) => { it.fail(CRASH_FAIL)('should cancel waitForEvent when page crashes', async({page, browserName, toImpl}) => {
await page.setContent(`<div>This page should crash</div>`); await page.setContent(`<div>This page should crash</div>`);
const promise = page.waitForEvent('response').catch(e => e); const promise = page.waitForEvent('response').catch(e => e);
crash(toImpl(page)); crash(toImpl(page), browserName);
const error = await promise; const error = await promise;
expect(error.message).toContain('Page crashed'); expect(error.message).toContain('Page crashed');
}); });
it.fail(CRASH_FAIL)('should cancel navigation when page crashes', async({page, toImpl, server}) => { it.fail(CRASH_FAIL)('should cancel navigation when page crashes', async({page, browserName, toImpl, server}) => {
await page.setContent(`<div>This page should crash</div>`); await page.setContent(`<div>This page should crash</div>`);
server.setRoute('/one-style.css', () => {}); server.setRoute('/one-style.css', () => {});
const promise = page.goto(server.PREFIX + '/one-style.html').catch(e => e); const promise = page.goto(server.PREFIX + '/one-style.html').catch(e => e);
await page.waitForNavigation({ waitUntil: 'domcontentloaded' }); await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
crash(toImpl(page)); crash(toImpl(page), browserName);
const error = await promise; const error = await promise;
expect(error.message).toContain('Navigation failed because page crashed'); expect(error.message).toContain('Navigation failed because page crashed');
}); });
it.fail(CRASH_FAIL)('should be able to close context when page crashes', async({page, toImpl}) => { it.fail(CRASH_FAIL)('should be able to close context when page crashes', async({page, browserName, toImpl}) => {
await page.setContent(`<div>This page should crash</div>`); await page.setContent(`<div>This page should crash</div>`);
crash(toImpl(page)); crash(toImpl(page), browserName);
await page.waitForEvent('crash'); await page.waitForEvent('crash');
await page.context().close(); await page.context().close();
}); });

View file

@ -40,7 +40,7 @@ it('Page.Events.Response', async({page, server}) => {
expect(responses[0].request()).toBeTruthy(); expect(responses[0].request()).toBeTruthy();
}); });
it('Page.Events.RequestFailed', async({page, server}) => { it('Page.Events.RequestFailed', async({page, server, isChromium, isWebKit}) => {
server.setRoute('/one-style.css', (req, res) => { server.setRoute('/one-style.css', (req, res) => {
res.setHeader('Content-Type', 'text/css'); res.setHeader('Content-Type', 'text/css');
res.connection.destroy(); res.connection.destroy();
@ -52,9 +52,9 @@ it('Page.Events.RequestFailed', async({page, server}) => {
expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].url()).toContain('one-style.css');
expect(await failedRequests[0].response()).toBe(null); expect(await failedRequests[0].response()).toBe(null);
expect(failedRequests[0].resourceType()).toBe('stylesheet'); expect(failedRequests[0].resourceType()).toBe('stylesheet');
if (CHROMIUM) { if (isChromium) {
expect(failedRequests[0].failure().errorText).toBe('net::ERR_EMPTY_RESPONSE'); expect(failedRequests[0].failure().errorText).toBe('net::ERR_EMPTY_RESPONSE');
} else if (WEBKIT) { } else if (isWebKit) {
if (MAC) if (MAC)
expect(failedRequests[0].failure().errorText).toBe('The network connection was lost.'); expect(failedRequests[0].failure().errorText).toBe('The network connection was lost.');
else if (WIN) else if (WIN)

View file

@ -16,7 +16,7 @@
*/ */
import './base.fixture'; import './base.fixture';
it('should fire', async({page, server}) => { it('should fire', async({page, server, isWebKit}) => {
const [error] = await Promise.all([ const [error] = await Promise.all([
page.waitForEvent('pageerror'), page.waitForEvent('pageerror'),
page.goto(server.PREFIX + '/error.html'), page.goto(server.PREFIX + '/error.html'),
@ -25,7 +25,7 @@ it('should fire', async({page, server}) => {
expect(error.message).toBe('Fancy error!'); expect(error.message).toBe('Fancy error!');
let stack = await page.evaluate(() => window['e'].stack); let stack = await page.evaluate(() => window['e'].stack);
// Note that WebKit reports the stack of the 'throw' statement instead of the Error constructor call. // Note that WebKit reports the stack of the 'throw' statement instead of the Error constructor call.
if (WEBKIT) if (isWebKit)
stack = stack.replace('14:25', '15:19'); stack = stack.replace('14:25', '15:19');
expect(error.stack).toBe(stack); expect(error.stack).toBe(stack);
}); });

View file

@ -133,7 +133,7 @@ it('should work with subframes return 204 with domcontentloaded', async({page, s
await page.goto(server.PREFIX + '/frames/one-frame.html', { waitUntil: 'domcontentloaded' }); await page.goto(server.PREFIX + '/frames/one-frame.html', { waitUntil: 'domcontentloaded' });
}); });
it('should fail when server returns 204', async({page, server}) => { it('should fail when server returns 204', async({page, server, isChromium, isWebKit}) => {
// Webkit just loads an empty page. // Webkit just loads an empty page.
server.setRoute('/empty.html', (req, res) => { server.setRoute('/empty.html', (req, res) => {
res.statusCode = 204; res.statusCode = 204;
@ -142,9 +142,9 @@ it('should fail when server returns 204', async({page, server}) => {
let error = null; let error = null;
await page.goto(server.EMPTY_PAGE).catch(e => error = e); await page.goto(server.EMPTY_PAGE).catch(e => error = e);
expect(error).not.toBe(null); expect(error).not.toBe(null);
if (CHROMIUM) if (isChromium)
expect(error.message).toContain('net::ERR_ABORTED'); expect(error.message).toContain('net::ERR_ABORTED');
else if (WEBKIT) else if (isWebKit)
expect(error.message).toContain('Aborted: 204 No Content'); expect(error.message).toContain('Aborted: 204 No Content');
else else
expect(error.message).toContain('NS_BINDING_ABORTED'); expect(error.message).toContain('NS_BINDING_ABORTED');
@ -164,10 +164,10 @@ it('should work when page calls history API in beforeunload', async({page, serve
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
it('should fail when navigating to bad url', async({page, server}) => { it('should fail when navigating to bad url', async({page, server, isChromium, isWebKit}) => {
let error = null; let error = null;
await page.goto('asdfasdf').catch(e => error = e); await page.goto('asdfasdf').catch(e => error = e);
if (CHROMIUM || WEBKIT) if (isChromium || isWebKit)
expect(error.message).toContain('Cannot navigate to invalid URL'); expect(error.message).toContain('Cannot navigate to invalid URL');
else else
expect(error.message).toContain('Invalid url'); expect(error.message).toContain('Invalid url');
@ -181,7 +181,7 @@ it('should fail when navigating to bad SSL', async({page, httpsServer, browserNa
page.on('requestfailed', request => expect(request).toBeTruthy()); page.on('requestfailed', request => expect(request).toBeTruthy());
let error = null; let error = null;
await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e); await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e);
utils.expectSSLError(browserName, error.message, ); utils.expectSSLError(browserName, error.message);
}); });
it('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer, browserName}) => { it('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer, browserName}) => {
@ -208,14 +208,14 @@ it('should throw if networkidle2 is passed as an option', async({page, server})
expect(error.message).toContain(`waitUntil: expected one of (load|domcontentloaded|networkidle)`); expect(error.message).toContain(`waitUntil: expected one of (load|domcontentloaded|networkidle)`);
}); });
it('should fail when main resources failed to load', async({page, server}) => { it('should fail when main resources failed to load', async({page, server, isChromium, isWebKit}) => {
let error = null; let error = null;
await page.goto('http://localhost:44123/non-existing-url').catch(e => error = e); await page.goto('http://localhost:44123/non-existing-url').catch(e => error = e);
if (CHROMIUM) if (isChromium)
expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); expect(error.message).toContain('net::ERR_CONNECTION_REFUSED');
else if (WEBKIT && WIN) else if (isWebKit && WIN)
expect(error.message).toContain(`Couldn\'t connect to server`); expect(error.message).toContain(`Couldn\'t connect to server`);
else if (WEBKIT) else if (isWebKit)
expect(error.message).toContain('Could not connect'); expect(error.message).toContain('Could not connect');
else else
expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED'); expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');
@ -298,7 +298,7 @@ it('should disable timeout when its set to 0', async({page, server}) => {
expect(loaded).toBe(true); expect(loaded).toBe(true);
}); });
it('should fail when replaced by another navigation', async({page, server}) => { it('should fail when replaced by another navigation', async({page, server, isChromium, isWebKit}) => {
let anotherPromise; let anotherPromise;
server.setRoute('/empty.html', (req, res) => { server.setRoute('/empty.html', (req, res) => {
anotherPromise = page.goto(server.PREFIX + '/one-style.html'); anotherPromise = page.goto(server.PREFIX + '/one-style.html');
@ -306,9 +306,9 @@ it('should fail when replaced by another navigation', async({page, server}) => {
}); });
const error = await page.goto(server.PREFIX + '/empty.html').catch(e => e); const error = await page.goto(server.PREFIX + '/empty.html').catch(e => e);
await anotherPromise; await anotherPromise;
if (CHROMIUM) if (isChromium)
expect(error.message).toContain('net::ERR_ABORTED'); expect(error.message).toContain('net::ERR_ABORTED');
else if (WEBKIT) else if (isWebKit)
expect(error.message).toContain('cancelled'); expect(error.message).toContain('cancelled');
else else
expect(error.message).toContain('NS_BINDING_ABORTED'); expect(error.message).toContain('NS_BINDING_ABORTED');

View file

@ -182,15 +182,15 @@ it('should be abortable', async({page, server}) => {
expect(failed).toBe(true); expect(failed).toBe(true);
}); });
it('should be abortable with custom error codes', async({page, server}) => { it('should be abortable with custom error codes', async({page, server, isWebKit, isFirefox}) => {
await page.route('**/*', route => route.abort('internetdisconnected')); await page.route('**/*', route => route.abort('internetdisconnected'));
let failedRequest = null; let failedRequest = null;
page.on('requestfailed', request => failedRequest = request); page.on('requestfailed', request => failedRequest = request);
await page.goto(server.EMPTY_PAGE).catch(e => {}); await page.goto(server.EMPTY_PAGE).catch(e => {});
expect(failedRequest).toBeTruthy(); expect(failedRequest).toBeTruthy();
if (WEBKIT) if (isWebKit)
expect(failedRequest.failure().errorText).toBe('Request intercepted'); expect(failedRequest.failure().errorText).toBe('Request intercepted');
else if (FFOX) else if (isFirefox)
expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE'); expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE');
else else
expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED'); expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED');
@ -208,14 +208,14 @@ it('should send referer', async({page, server}) => {
expect(request.headers['referer']).toBe('http://google.com/'); expect(request.headers['referer']).toBe('http://google.com/');
}); });
it('should fail navigation when aborting main resource', async({page, server}) => { it('should fail navigation when aborting main resource', async({page, server, isWebKit, isFirefox}) => {
await page.route('**/*', route => route.abort()); await page.route('**/*', route => route.abort());
let error = null; let error = null;
await page.goto(server.EMPTY_PAGE).catch(e => error = e); await page.goto(server.EMPTY_PAGE).catch(e => error = e);
expect(error).toBeTruthy(); expect(error).toBeTruthy();
if (WEBKIT) if (isWebKit)
expect(error.message).toContain('Request intercepted'); expect(error.message).toContain('Request intercepted');
else if (FFOX) else if (isFirefox)
expect(error.message).toContain('NS_ERROR_FAILURE'); expect(error.message).toContain('NS_ERROR_FAILURE');
else else
expect(error.message).toContain('net::ERR_FAILED'); expect(error.message).toContain('net::ERR_FAILED');

View file

@ -21,126 +21,128 @@ function getPermission(page, name) {
return page.evaluate(name => navigator.permissions.query({name}).then(result => result.state), name); return page.evaluate(name => navigator.permissions.query({name}).then(result => result.state), name);
} }
it.skip(WEBKIT)('should be prompt by default', async({page, server, context}) => { describe.skip(WEBKIT)('permissions', () => {
// Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) it('should be prompt by default', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); // Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
expect(await getPermission(page, 'geolocation')).toBe('prompt'); await page.goto(server.EMPTY_PAGE);
}); expect(await getPermission(page, 'geolocation')).toBe('prompt');
});
it.skip(WEBKIT)('should deny permission when not listed', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should deny permission when not listed', async({page, server, context}) => {
await context.grantPermissions([], { origin: server.EMPTY_PAGE }); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('denied'); await context.grantPermissions([], { origin: server.EMPTY_PAGE });
}); expect(await getPermission(page, 'geolocation')).toBe('denied');
});
it.skip(WEBKIT)('should fail when bad permission is given', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should fail when bad permission is given', async({page, server, context}) => {
let error: Error; await page.goto(server.EMPTY_PAGE);
await context.grantPermissions(['foo'], { origin: server.EMPTY_PAGE }).catch(e => error = e); let error: Error;
expect(error.message).toContain('Unknown permission: foo'); await context.grantPermissions(['foo'], { origin: server.EMPTY_PAGE }).catch(e => error = e);
}); expect(error.message).toContain('Unknown permission: foo');
});
it.skip(WEBKIT)('should grant geolocation permission when listed', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should grant geolocation permission when listed', async({page, server, context}) => {
await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('granted'); await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
}); expect(await getPermission(page, 'geolocation')).toBe('granted');
});
it.skip(WEBKIT)('should grant notifications permission when listed', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should grant notifications permission when listed', async({page, server, context}) => {
await context.grantPermissions(['notifications'], { origin: server.EMPTY_PAGE }); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'notifications')).toBe('granted'); await context.grantPermissions(['notifications'], { origin: server.EMPTY_PAGE });
}); expect(await getPermission(page, 'notifications')).toBe('granted');
});
it.skip(WEBKIT)('should accumulate when adding', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should accumulate when adding', async({page, server, context}) => {
await context.grantPermissions(['geolocation']); await page.goto(server.EMPTY_PAGE);
await context.grantPermissions(['notifications']); await context.grantPermissions(['geolocation']);
expect(await getPermission(page, 'geolocation')).toBe('granted'); await context.grantPermissions(['notifications']);
expect(await getPermission(page, 'notifications')).toBe('granted'); expect(await getPermission(page, 'geolocation')).toBe('granted');
}); expect(await getPermission(page, 'notifications')).toBe('granted');
});
it.skip(WEBKIT)('should clear permissions', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should clear permissions', async({page, server, context}) => {
await context.grantPermissions(['geolocation']); await page.goto(server.EMPTY_PAGE);
await context.clearPermissions(); await context.grantPermissions(['geolocation']);
await context.grantPermissions(['notifications']); await context.clearPermissions();
expect(await getPermission(page, 'geolocation')).not.toBe('granted'); await context.grantPermissions(['notifications']);
expect(await getPermission(page, 'notifications')).toBe('granted'); expect(await getPermission(page, 'geolocation')).not.toBe('granted');
}); expect(await getPermission(page, 'notifications')).toBe('granted');
});
it.skip(WEBKIT)('should grant permission when listed for all domains', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should grant permission when listed for all domains', async({page, server, context}) => {
await context.grantPermissions(['geolocation']); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('granted'); await context.grantPermissions(['geolocation']);
}); expect(await getPermission(page, 'geolocation')).toBe('granted');
});
it.skip(WEBKIT)('should grant permission when creating context', async({server, browser}) => {
const context = await browser.newContext({ permissions: ['geolocation'] }); it('should grant permission when creating context', async({server, browser}) => {
const page = await context.newPage(); const context = await browser.newContext({ permissions: ['geolocation'] });
await page.goto(server.EMPTY_PAGE); const page = await context.newPage();
expect(await getPermission(page, 'geolocation')).toBe('granted'); await page.goto(server.EMPTY_PAGE);
await context.close(); expect(await getPermission(page, 'geolocation')).toBe('granted');
}); await context.close();
});
it.skip(WEBKIT)('should reset permissions', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); it('should reset permissions', async({page, server, context}) => {
await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('granted'); await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
await context.clearPermissions(); expect(await getPermission(page, 'geolocation')).toBe('granted');
expect(await getPermission(page, 'geolocation')).toBe('prompt'); await context.clearPermissions();
}); expect(await getPermission(page, 'geolocation')).toBe('prompt');
});
it.fail(WEBKIT || FFOX || (CHROMIUM && !HEADLESS))('should trigger permission onchange', async({page, server, context}) => {
//TODO: flaky it.fail(WEBKIT || FFOX || (CHROMIUM && !HEADLESS))('should trigger permission onchange', async({page, server, context}) => {
// - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883 //TODO: flaky
// - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536 // - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883
await page.goto(server.EMPTY_PAGE); // - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536
await page.evaluate(() => { await page.goto(server.EMPTY_PAGE);
window['events'] = []; await page.evaluate(() => {
return navigator.permissions.query({name: 'geolocation'}).then(function(result) { window['events'] = [];
window['events'].push(result.state); return navigator.permissions.query({name: 'geolocation'}).then(function(result) {
result.onchange = function() { window['events'].push(result.state);
window['events'].push(result.state); result.onchange = function() {
}; window['events'].push(result.state);
}); };
});
});
expect(await page.evaluate(() => window['events'])).toEqual(['prompt']);
await context.grantPermissions([], { origin: server.EMPTY_PAGE });
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied']);
await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied', 'granted']);
await context.clearPermissions();
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied', 'granted', 'prompt']);
});
it('should isolate permissions between browser contexts', async({page, server, context, browser}) => {
await page.goto(server.EMPTY_PAGE);
const otherContext = await browser.newContext();
const otherPage = await otherContext.newPage();
await otherPage.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('prompt');
expect(await getPermission(otherPage, 'geolocation')).toBe('prompt');
await context.grantPermissions([], { origin: server.EMPTY_PAGE });
await otherContext.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
expect(await getPermission(page, 'geolocation')).toBe('denied');
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
await context.clearPermissions();
expect(await getPermission(page, 'geolocation')).toBe('prompt');
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
await otherContext.close();
});
it.fail(WEBKIT || FFOX || (CHROMIUM && !HEADLESS))('should support clipboard read', async({page, server, context, browser}) => {
// No such permissions (requires flag) in Firefox
await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');
let error;
await page.evaluate(() => navigator.clipboard.readText()).catch(e => error = e);
expect(error.toString()).toContain('denied');
await context.grantPermissions(['clipboard-read']);
expect(await getPermission(page, 'clipboard-read')).toBe('granted');
await page.evaluate(() => navigator.clipboard.readText());
}); });
expect(await page.evaluate(() => window['events'])).toEqual(['prompt']);
await context.grantPermissions([], { origin: server.EMPTY_PAGE });
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied']);
await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied', 'granted']);
await context.clearPermissions();
expect(await page.evaluate(() => window['events'])).toEqual(['prompt', 'denied', 'granted', 'prompt']);
});
it.skip(WEBKIT)('should isolate permissions between browser contexts', async({page, server, context, browser}) => {
await page.goto(server.EMPTY_PAGE);
const otherContext = await browser.newContext();
const otherPage = await otherContext.newPage();
await otherPage.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'geolocation')).toBe('prompt');
expect(await getPermission(otherPage, 'geolocation')).toBe('prompt');
await context.grantPermissions([], { origin: server.EMPTY_PAGE });
await otherContext.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
expect(await getPermission(page, 'geolocation')).toBe('denied');
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
await context.clearPermissions();
expect(await getPermission(page, 'geolocation')).toBe('prompt');
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
await otherContext.close();
});
it.fail(WEBKIT || FFOX || (CHROMIUM && !HEADLESS))('should support clipboard read', async({page, server, context, browser}) => {
// No such permissions (requires flag) in Firefox
await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');
let error;
await page.evaluate(() => navigator.clipboard.readText()).catch(e => error = e);
expect(error.toString()).toContain('denied');
await context.grantPermissions(['clipboard-read']);
expect(await getPermission(page, 'clipboard-read')).toBe('granted');
await page.evaluate(() => navigator.clipboard.readText());
}); });

View file

@ -209,7 +209,7 @@ it('should expose function from browser context', async function({browser, serve
expect(messages.join('|')).toBe('page|binding'); expect(messages.join('|')).toBe('page|binding');
}); });
it('should not dispatch binding on a closed page', async function({browser, server}) { it('should not dispatch binding on a closed page', async function({browser, server, isFirefox}) {
const context = await browser.newContext(); const context = await browser.newContext();
const messages = []; const messages = [];
await context.exposeFunction('add', (a, b) => { await context.exposeFunction('add', (a, b) => {
@ -232,7 +232,7 @@ it('should not dispatch binding on a closed page', async function({browser, serv
}), }),
]); ]);
await context.close(); await context.close();
if (FFOX) if (isFirefox)
expect(messages.join('|')).toBe('alreadyclosed'); expect(messages.join('|')).toBe('alreadyclosed');
else else
expect(messages.join('|')).toBe('binding|close'); expect(messages.join('|')).toBe('binding|close');

7
test/types.d.ts vendored
View file

@ -17,7 +17,12 @@
type ServerResponse = import('http').ServerResponse; type ServerResponse = import('http').ServerResponse;
type IncomingMessage = import('http').IncomingMessage; type IncomingMessage = import('http').IncomingMessage;
type DescribeFunction = ((name: string, inner: () => void) => void) & {fail(condition: boolean): DescribeFunction}; type DescribeFunction = ((name: string, inner: () => void) => void) & {
fail(condition: boolean): DescribeFunction;
skip(condition: boolean): DescribeFunction;
slow(): DescribeFunction;
repeat(n: number): DescribeFunction;
};
type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>) => void) & { type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>) => void) & {
fail(condition: boolean): ItFunction<STATE>; fail(condition: boolean): ItFunction<STATE>;