From 510182f0b9b869790943791ce620dc6cfb540815 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 18 Aug 2020 12:48:32 -0700 Subject: [PATCH] test: use isChromium, etc fixtures for browser name sniffing (#3508) --- test/base.fixture.ts | 15 ++ test/browser.spec.ts | 4 +- test/browsercontext-basic.spec.ts | 4 +- test/browsertype-basic.spec.ts | 8 +- test/click.spec.ts | 30 ++-- test/defaultbrowsercontext.spec.ts | 4 +- test/elementhandle-select-text.spec.ts | 8 +- test/frame-evaluate.spec.ts | 16 +- test/keyboard.spec.ts | 8 +- test/mouse.spec.ts | 8 +- test/network-request.spec.ts | 8 +- test/page-basic.spec.ts | 12 +- test/page-event-crash.spec.ts | 28 ++-- test/page-event-network.spec.ts | 6 +- test/page-event-pageerror.spec.ts | 4 +- test/page-goto.spec.ts | 26 +-- test/page-route.spec.ts | 12 +- test/permissions.spec.ts | 216 +++++++++++++------------ test/popup.spec.ts | 4 +- test/types.d.ts | 7 +- 20 files changed, 225 insertions(+), 203 deletions(-) diff --git a/test/base.fixture.ts b/test/base.fixture.ts index 12836a4222e07..6f3eff898c842 100644 --- a/test/base.fixture.ts +++ b/test/base.fixture.ts @@ -44,6 +44,9 @@ declare global { browserType: BrowserType; browserName: string; browser: Browser; + isChromium: boolean; + isFirefox: boolean; + isWebKit: boolean; } interface FixtureState { toImpl: (rpcObject: any) => any; @@ -185,6 +188,18 @@ registerWorkerFixture('browserName', async ({}, test) => { 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) => { httpService.httpsServer.reset(); await test(httpService.httpsServer); diff --git a/test/browser.spec.ts b/test/browser.spec.ts index 239a7b252a646..56b03c2e57dc9 100644 --- a/test/browser.spec.ts +++ b/test/browser.spec.ts @@ -39,9 +39,9 @@ it('should throw upon second create new page', async function({browser}) { 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(); - if (CHROMIUM) + if (isChromium) expect(version.match(/^\d+\.\d+\.\d+\.\d+$/)).toBeTruthy(); else expect(version.match(/^\d+\.\d+/)).toBeTruthy(); diff --git a/test/browsercontext-basic.spec.ts b/test/browsercontext-basic.spec.ts index 5acb9abcdda8c..4213023aa2066 100644 --- a/test/browsercontext-basic.spec.ts +++ b/test/browsercontext-basic.spec.ts @@ -177,14 +177,14 @@ it('should close all belonging pages once closing context', async function({brow 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 page = await context.newPage(); await page.goto('data:text/html, '); let error = null; await page.evaluate('something').catch(e => error = e); - if (WEBKIT) + if (isWebKit) expect(error.message).toContain('Can\'t find variable: something'); else expect(error.message).toContain('something is not defined'); diff --git a/test/browsertype-basic.spec.ts b/test/browsertype-basic.spec.ts index d4bdaa2a15b80..a0075f7f87863 100644 --- a/test/browsertype-basic.spec.ts +++ b/test/browsertype-basic.spec.ts @@ -24,12 +24,12 @@ it('browserType.executablePath should work', async({browserType}) => { expect(fs.realpathSync(executablePath)).toBe(executablePath); }); -it('browserType.name should work', async({browserType}) => { - if (WEBKIT) +it('browserType.name should work', async({browserType, isWebKit, isFirefox, isChromium}) => { + if (isWebKit) expect(browserType.name()).toBe('webkit'); - else if (FFOX) + else if (isFirefox) expect(browserType.name()).toBe('firefox'); - else if (CHROMIUM) + else if (isChromium) expect(browserType.name()).toBe('chromium'); else throw new Error('Unknown browser'); diff --git a/test/click.spec.ts b/test/click.spec.ts index f095a5bb96e16..d558c88a86287 100644 --- a/test/click.spec.ts +++ b/test/click.spec.ts @@ -344,39 +344,39 @@ it('should click the button with deviceScaleFactor set', async({browser, server} 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.$eval('button', button => button.style.borderWidth = '8px'); await page.click('button', { position: { x: 20, y: 10 } }); expect(await page.evaluate('result')).toBe('Clicked'); // Safari reports border-relative offsetX/offsetY. - expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 20 + 8 : 20); - expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 10 + 8 : 10); + expect(await page.evaluate('offsetX')).toBe(isWebKit ? 20 + 8 : 20); + 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.$eval('button', button => button.style.borderWidth = '2em'); await page.$eval('button', button => button.style.fontSize = '12px'); await page.click('button', { position: { x: 20, y: 10 } }); expect(await page.evaluate('result')).toBe('Clicked'); // Safari reports border-relative offsetX/offsetY. - expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 12 * 2 + 20 : 20); - expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 12 * 2 + 10 : 10); + expect(await page.evaluate('offsetX')).toBe(isWebKit ? 12 * 2 + 20 : 20); + 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.$eval('button', button => button.style.borderWidth = '8px'); await page.$eval('button', button => button.style.height = button.style.width = '2000px'); await page.click('button', { position: { x: 1900, y: 1910 } }); expect(await page.evaluate(() => window['result'])).toBe('Clicked'); // Safari reports border-relative offsetX/offsetY. - expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900); - expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910); + expect(await page.evaluate('offsetX')).toBe(isWebKit ? 1900 + 8 : 1900); + 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.$eval('button', button => { 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 } }); expect(await page.evaluate(() => window['result'])).toBe('Clicked'); // Safari reports border-relative offsetX/offsetY. - expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900); - expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910); + expect(await page.evaluate('offsetX')).toBe(isWebKit ? 1900 + 8 : 1900); + 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 page = await context.newPage(); 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'); const round = x => Math.round(x + 0.01); 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. expected = { x: 29, y: 19 }; - } else if (CHROMIUM && HEADLESS) { + } else if (isChromium && HEADLESS) { // Headless Chromium rounds down during css -> dip -> css conversion. expected = { x: 27, y: 18 }; } diff --git a/test/defaultbrowsercontext.spec.ts b/test/defaultbrowsercontext.spec.ts index b49acf26f9a4c..7f6092543b242 100644 --- a/test/defaultbrowsercontext.spec.ts +++ b/test/defaultbrowsercontext.spec.ts @@ -171,12 +171,12 @@ it('should support bypassCSP option', async ({server, launchPersistent}) => { 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}); await page.goto('data:text/html, '); let error = null; await page.evaluate('something').catch(e => error = e); - if (WEBKIT) + if (isWebKit) expect(error.message).toContain('Can\'t find variable: something'); else expect(error.message).toContain('something is not defined'); diff --git a/test/elementhandle-select-text.spec.ts b/test/elementhandle-select-text.spec.ts index ce23882a59c23..6829694056e78 100644 --- a/test/elementhandle-select-text.spec.ts +++ b/test/elementhandle-select-text.spec.ts @@ -16,12 +16,12 @@ */ 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'); const textarea = await page.$('textarea'); await textarea.evaluate(textarea => textarea.value = 'some value'); await textarea.selectText(); - if (FFOX) { + if (isFirefox) { expect(await textarea.evaluate(el => el.selectionStart)).toBe(0); expect(await textarea.evaluate(el => el.selectionEnd)).toBe(10); } 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'); const input = await page.$('input'); await input.evaluate(input => input.value = 'some value'); await input.selectText(); - if (FFOX) { + if (isFirefox) { expect(await input.evaluate(el => el.selectionStart)).toBe(0); expect(await input.evaluate(el => el.selectionEnd)).toBe(10); } else { diff --git a/test/frame-evaluate.spec.ts b/test/frame-evaluate.spec.ts index 3df5ba3d94a3f..6a47f0ed1927a 100644 --- a/test/frame-evaluate.spec.ts +++ b/test/frame-evaluate.spec.ts @@ -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`); }); -function expectContexts(pageImpl, count) { - if (CHROMIUM) +function expectContexts(pageImpl, count, isChromium) { + if (isChromium) expect(pageImpl._delegate._mainFrameSession._contextIdToContext.size).toBe(count); else 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'); expect(page.frames().length).toBe(2); - expectContexts(toImpl(page), 4); + expectContexts(toImpl(page), 4, isChromium); 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'); expect(page.frames().length).toBe(2); - expectContexts(toImpl(page), 4); + expectContexts(toImpl(page), 4, isChromium); 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 }) => { diff --git a/test/keyboard.spec.ts b/test/keyboard.spec.ts index 8b5f94d1debc4..0ec51c665da02 100644 --- a/test/keyboard.spec.ts +++ b/test/keyboard.spec.ts @@ -350,21 +350,21 @@ it.skip(!MAC)('should support MacOS shortcuts', async ({page, server}) => { 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); await page.keyboard.press('Meta'); const {key, code, metaKey} = await lastEvent.jsonValue(); - if (FFOX && !MAC) + if (isFirefox && !MAC) expect(key).toBe('OS'); else expect(key).toBe('Meta'); - if (FFOX) + if (isFirefox) expect(code).toBe('OSLeft'); else expect(code).toBe('MetaLeft'); - if (FFOX && !MAC) + if (isFirefox && !MAC) expect(metaKey).toBe(false); else expect(metaKey).toBe(true); diff --git a/test/mouse.spec.ts b/test/mouse.spec.ts index f4a7506fc4ac9..0b6d9bbe70241 100644 --- a/test/mouse.spec.ts +++ b/test/mouse.spec.ts @@ -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'); }); -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.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window["lastEvent"] = e, true)); const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'}; // In Firefox, the Meta modifier only exists on Mac - if (FFOX && !MAC) + if (isFirefox && !MAC) delete modifiers['Meta']; for (const modifier in modifiers) { 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. - if (WEBKIT) + if (isWebKit) await page.evaluate(() => new Promise(requestAnimationFrame)); await page.mouse.move(100, 100); await page.evaluate(() => { diff --git a/test/network-request.spec.ts b/test/network-request.spec.ts index 6ae670796cd3c..22438120d13f9 100644 --- a/test/network-request.spec.ts +++ b/test/network-request.spec.ts @@ -45,13 +45,13 @@ it('should work for fetch requests', async({page, server}) => { 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); - if (CHROMIUM) + if (isChromium) expect(response.request().headers()['user-agent']).toContain('Chrome'); - else if (FFOX) + else if (isFirefox) expect(response.request().headers()['user-agent']).toContain('Firefox'); - else if (WEBKIT) + else if (isWebKit) expect(response.request().headers()['user-agent']).toContain('WebKit'); }); diff --git a/test/page-basic.spec.ts b/test/page-basic.spec.ts index ca52ff6063e11..30997c549e17d 100644 --- a/test/page-basic.spec.ts +++ b/test/page-basic.spec.ts @@ -33,7 +33,7 @@ it('should not be visible in context.pages', async({context}) => { 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(); await newPage.goto(server.PREFIX + '/beforeunload.html'); // 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'); expect(dialog.type()).toBe('beforeunload'); expect(dialog.defaultValue()).toBe(''); - if (CHROMIUM) + if (isChromium) expect(dialog.message()).toBe(''); - else if (WEBKIT) + else if (isWebKit) expect(dialog.message()).toBe('Leave?'); 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.'); @@ -196,7 +196,7 @@ it('page.frame should respect url', async function({page, server}) { 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 [ part1, @@ -210,7 +210,7 @@ it('should have sane user agent', async ({page}) => { // Second part in parenthesis is platform - ignore it. // Third part for Firefox is the last one and encodes engine and browser versions. - if (FFOX) { + if (isFirefox) { const [engine, browser] = part3.split(' '); expect(engine.startsWith('Gecko')).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. const [engine, browser] = part5.split(' '); expect(browser.startsWith('Safari/')).toBe(true); - if (CHROMIUM) + if (isChromium) expect(engine.includes('Chrome/')).toBe(true); else expect(engine.startsWith('Version/')).toBe(true); diff --git a/test/page-event-crash.spec.ts b/test/page-event-crash.spec.ts index daca21574b914..61a828edefccd 100644 --- a/test/page-event-crash.spec.ts +++ b/test/page-event-crash.spec.ts @@ -20,51 +20,51 @@ const { WIRE } = testOptions; const CRASH_FAIL = (FFOX && WIN) || WIRE; // Firefox Win: it just doesn't crash sometimes. -function crash(pageImpl) { - if (CHROMIUM) +function crash(pageImpl, browserName) { + if (browserName === 'chromium') pageImpl.mainFrame().goto('chrome://crash').catch(e => {}); - else if (WEBKIT) + else if (browserName === 'webkit') pageImpl._delegate._session.send('Page.crash', {}).catch(e => {}); - else if (FFOX) + else if (browserName === 'firefox') 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(`
This page should crash
`); - crash(toImpl(page)); + crash(toImpl(page), browserName); 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(`
This page should crash
`); - crash(toImpl(page)); + crash(toImpl(page), browserName); await page.waitForEvent('crash'); const err = await page.evaluate(() => {}).then(() => null, e => e); expect(err).toBeTruthy(); 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(`
This page should crash
`); const promise = page.waitForEvent('response').catch(e => e); - crash(toImpl(page)); + crash(toImpl(page), browserName); const error = await promise; 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(`
This page should crash
`); server.setRoute('/one-style.css', () => {}); const promise = page.goto(server.PREFIX + '/one-style.html').catch(e => e); await page.waitForNavigation({ waitUntil: 'domcontentloaded' }); - crash(toImpl(page)); + crash(toImpl(page), browserName); const error = await promise; 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(`
This page should crash
`); - crash(toImpl(page)); + crash(toImpl(page), browserName); await page.waitForEvent('crash'); await page.context().close(); }); diff --git a/test/page-event-network.spec.ts b/test/page-event-network.spec.ts index 5c1171e7adb7e..33746c88533fe 100644 --- a/test/page-event-network.spec.ts +++ b/test/page-event-network.spec.ts @@ -40,7 +40,7 @@ it('Page.Events.Response', async({page, server}) => { 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) => { res.setHeader('Content-Type', 'text/css'); res.connection.destroy(); @@ -52,9 +52,9 @@ it('Page.Events.RequestFailed', async({page, server}) => { expect(failedRequests[0].url()).toContain('one-style.css'); expect(await failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); - if (CHROMIUM) { + if (isChromium) { expect(failedRequests[0].failure().errorText).toBe('net::ERR_EMPTY_RESPONSE'); - } else if (WEBKIT) { + } else if (isWebKit) { if (MAC) expect(failedRequests[0].failure().errorText).toBe('The network connection was lost.'); else if (WIN) diff --git a/test/page-event-pageerror.spec.ts b/test/page-event-pageerror.spec.ts index 41d87aadf3b3e..db9287b212699 100644 --- a/test/page-event-pageerror.spec.ts +++ b/test/page-event-pageerror.spec.ts @@ -16,7 +16,7 @@ */ import './base.fixture'; -it('should fire', async({page, server}) => { +it('should fire', async({page, server, isWebKit}) => { const [error] = await Promise.all([ page.waitForEvent('pageerror'), page.goto(server.PREFIX + '/error.html'), @@ -25,7 +25,7 @@ it('should fire', async({page, server}) => { expect(error.message).toBe('Fancy error!'); let stack = await page.evaluate(() => window['e'].stack); // 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'); expect(error.stack).toBe(stack); }); diff --git a/test/page-goto.spec.ts b/test/page-goto.spec.ts index 666d23eb4c595..53279de7183c4 100644 --- a/test/page-goto.spec.ts +++ b/test/page-goto.spec.ts @@ -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' }); }); -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. server.setRoute('/empty.html', (req, res) => { res.statusCode = 204; @@ -142,9 +142,9 @@ it('should fail when server returns 204', async({page, server}) => { let error = null; await page.goto(server.EMPTY_PAGE).catch(e => error = e); expect(error).not.toBe(null); - if (CHROMIUM) + if (isChromium) expect(error.message).toContain('net::ERR_ABORTED'); - else if (WEBKIT) + else if (isWebKit) expect(error.message).toContain('Aborted: 204 No Content'); else 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); }); -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; await page.goto('asdfasdf').catch(e => error = e); - if (CHROMIUM || WEBKIT) + if (isChromium || isWebKit) expect(error.message).toContain('Cannot navigate to invalid URL'); else 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()); let error = null; 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}) => { @@ -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)`); }); -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; 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'); - else if (WEBKIT && WIN) + else if (isWebKit && WIN) expect(error.message).toContain(`Couldn\'t connect to server`); - else if (WEBKIT) + else if (isWebKit) expect(error.message).toContain('Could not connect'); else 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); }); -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; server.setRoute('/empty.html', (req, res) => { 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); await anotherPromise; - if (CHROMIUM) + if (isChromium) expect(error.message).toContain('net::ERR_ABORTED'); - else if (WEBKIT) + else if (isWebKit) expect(error.message).toContain('cancelled'); else expect(error.message).toContain('NS_BINDING_ABORTED'); diff --git a/test/page-route.spec.ts b/test/page-route.spec.ts index 7db2d3caabc90..cc410786e9127 100644 --- a/test/page-route.spec.ts +++ b/test/page-route.spec.ts @@ -182,15 +182,15 @@ it('should be abortable', async({page, server}) => { 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')); let failedRequest = null; page.on('requestfailed', request => failedRequest = request); await page.goto(server.EMPTY_PAGE).catch(e => {}); expect(failedRequest).toBeTruthy(); - if (WEBKIT) + if (isWebKit) expect(failedRequest.failure().errorText).toBe('Request intercepted'); - else if (FFOX) + else if (isFirefox) expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE'); else 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/'); }); -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()); let error = null; await page.goto(server.EMPTY_PAGE).catch(e => error = e); expect(error).toBeTruthy(); - if (WEBKIT) + if (isWebKit) expect(error.message).toContain('Request intercepted'); - else if (FFOX) + else if (isFirefox) expect(error.message).toContain('NS_ERROR_FAILURE'); else expect(error.message).toContain('net::ERR_FAILED'); diff --git a/test/permissions.spec.ts b/test/permissions.spec.ts index d2864eea45375..45bd4fde79e39 100644 --- a/test/permissions.spec.ts +++ b/test/permissions.spec.ts @@ -21,126 +21,128 @@ function getPermission(page, 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}) => { - // Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) - await page.goto(server.EMPTY_PAGE); - expect(await getPermission(page, 'geolocation')).toBe('prompt'); -}); +describe.skip(WEBKIT)('permissions', () => { + it('should be prompt by default', async({page, server, context}) => { + // Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) + 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); - await context.grantPermissions([], { origin: server.EMPTY_PAGE }); - expect(await getPermission(page, 'geolocation')).toBe('denied'); -}); + it('should deny permission when not listed', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + 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); - let error: Error; - await context.grantPermissions(['foo'], { origin: server.EMPTY_PAGE }).catch(e => error = e); - expect(error.message).toContain('Unknown permission: foo'); -}); + it('should fail when bad permission is given', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + let error: Error; + 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); - await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); - expect(await getPermission(page, 'geolocation')).toBe('granted'); -}); + it('should grant geolocation permission when listed', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + 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); - await context.grantPermissions(['notifications'], { origin: server.EMPTY_PAGE }); - expect(await getPermission(page, 'notifications')).toBe('granted'); -}); + it('should grant notifications permission when listed', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + 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); - await context.grantPermissions(['geolocation']); - await context.grantPermissions(['notifications']); - expect(await getPermission(page, 'geolocation')).toBe('granted'); - expect(await getPermission(page, 'notifications')).toBe('granted'); -}); + it('should accumulate when adding', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + await context.grantPermissions(['geolocation']); + await context.grantPermissions(['notifications']); + 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); - await context.grantPermissions(['geolocation']); - await context.clearPermissions(); - await context.grantPermissions(['notifications']); - expect(await getPermission(page, 'geolocation')).not.toBe('granted'); - expect(await getPermission(page, 'notifications')).toBe('granted'); -}); + it('should clear permissions', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + await context.grantPermissions(['geolocation']); + await context.clearPermissions(); + await context.grantPermissions(['notifications']); + 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); - await context.grantPermissions(['geolocation']); - expect(await getPermission(page, 'geolocation')).toBe('granted'); -}); + it('should grant permission when listed for all domains', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + 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'] }); - const page = await context.newPage(); - await page.goto(server.EMPTY_PAGE); - expect(await getPermission(page, 'geolocation')).toBe('granted'); - await context.close(); -}); + it('should grant permission when creating context', async({server, browser}) => { + const context = await browser.newContext({ permissions: ['geolocation'] }); + const page = await context.newPage(); + await page.goto(server.EMPTY_PAGE); + 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); - await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); - expect(await getPermission(page, 'geolocation')).toBe('granted'); - await context.clearPermissions(); - expect(await getPermission(page, 'geolocation')).toBe('prompt'); -}); + it('should reset permissions', async({page, server, context}) => { + await page.goto(server.EMPTY_PAGE); + await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); + expect(await getPermission(page, 'geolocation')).toBe('granted'); + 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 - // - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883 - // - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536 - await page.goto(server.EMPTY_PAGE); - await page.evaluate(() => { - window['events'] = []; - return navigator.permissions.query({name: 'geolocation'}).then(function(result) { - window['events'].push(result.state); - result.onchange = function() { + it.fail(WEBKIT || FFOX || (CHROMIUM && !HEADLESS))('should trigger permission onchange', async({page, server, context}) => { + //TODO: flaky + // - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883 + // - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536 + await page.goto(server.EMPTY_PAGE); + await page.evaluate(() => { + window['events'] = []; + return navigator.permissions.query({name: 'geolocation'}).then(function(result) { 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']); }); - 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('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()); + 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()); + }); }); diff --git a/test/popup.spec.ts b/test/popup.spec.ts index 3efd35a6e3602..b3e70e0053fc1 100644 --- a/test/popup.spec.ts +++ b/test/popup.spec.ts @@ -209,7 +209,7 @@ it('should expose function from browser context', async function({browser, serve 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 messages = []; 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(); - if (FFOX) + if (isFirefox) expect(messages.join('|')).toBe('alreadyclosed'); else expect(messages.join('|')).toBe('binding|close'); diff --git a/test/types.d.ts b/test/types.d.ts index d51fcec8e3624..7ec68fd801089 100644 --- a/test/types.d.ts +++ b/test/types.d.ts @@ -17,7 +17,12 @@ type ServerResponse = import('http').ServerResponse; 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 = ((name: string, inner: (state: STATE) => Promise) => void) & { fail(condition: boolean): ItFunction;