test: introduce global setup (#3544)

This commit is contained in:
Pavel Feldman 2020-08-20 12:51:05 -07:00 committed by GitHub
parent eab5ff4eae
commit db2e66aa76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 375 additions and 298 deletions

View file

@ -35,7 +35,7 @@ it('should work', async function({page}) {
// autofocus happens after a delay in chrome these days // autofocus happens after a delay in chrome these days
await page.waitForFunction(() => document.activeElement.hasAttribute('autofocus')); await page.waitForFunction(() => document.activeElement.hasAttribute('autofocus'));
const golden = options.FIREFOX() ? { const golden = options.FIREFOX ? {
role: 'document', role: 'document',
name: 'Accessibility Test', name: 'Accessibility Test',
children: [ children: [
@ -48,7 +48,7 @@ it('should work', async function({page}) {
{role: 'textbox', name: '', value: 'and a value'}, // firefox doesn't use aria-placeholder for the name {role: 'textbox', name: '', value: 'and a value'}, // firefox doesn't use aria-placeholder for the name
{role: 'textbox', name: '', value: 'and a value', description: 'This is a description!'}, // and here {role: 'textbox', name: '', value: 'and a value', description: 'This is a description!'}, // and here
] ]
} : options.CHROMIUM() ? { } : options.CHROMIUM ? {
role: 'WebArea', role: 'WebArea',
name: 'Accessibility Test', name: 'Accessibility Test',
children: [ children: [
@ -82,7 +82,7 @@ it('should work with regular text', async({page}) => {
await page.setContent(`<div>Hello World</div>`); await page.setContent(`<div>Hello World</div>`);
const snapshot = await page.accessibility.snapshot(); const snapshot = await page.accessibility.snapshot();
expect(snapshot.children[0]).toEqual({ expect(snapshot.children[0]).toEqual({
role: options.FIREFOX() ? 'text leaf' : 'text', role: options.FIREFOX ? 'text leaf' : 'text',
name: 'Hello World', name: 'Hello World',
}); });
}); });
@ -124,7 +124,7 @@ it('should not report text nodes inside controls', async function({page}) {
<div role="tab">Tab2</div> <div role="tab">Tab2</div>
</div>`); </div>`);
const golden = { const golden = {
role: options.FIREFOX() ? 'document' : 'WebArea', role: options.FIREFOX ? 'document' : 'WebArea',
name: '', name: '',
children: [{ children: [{
role: 'tab', role: 'tab',
@ -139,12 +139,12 @@ it('should not report text nodes inside controls', async function({page}) {
}); });
// WebKit rich text accessibility is iffy // WebKit rich text accessibility is iffy
it.skip(options.WEBKIT())('rich text editable fields should have children', async function({page}) { it.skip(options.WEBKIT)('rich text editable fields should have children', async function({page}) {
await page.setContent(` await page.setContent(`
<div contenteditable="true"> <div contenteditable="true">
Edit this image: <img src="fakeimage.png" alt="my fake image"> Edit this image: <img src="fakeimage.png" alt="my fake image">
</div>`); </div>`);
const golden = options.FIREFOX() ? { const golden = options.FIREFOX ? {
role: 'section', role: 'section',
name: '', name: '',
children: [{ children: [{
@ -170,12 +170,12 @@ it.skip(options.WEBKIT())('rich text editable fields should have children', asyn
expect(snapshot.children[0]).toEqual(golden); expect(snapshot.children[0]).toEqual(golden);
}); });
// WebKit rich text accessibility is iffy // WebKit rich text accessibility is iffy
it.skip(options.WEBKIT())('rich text editable fields with role should have children', async function({page}) { it.skip(options.WEBKIT)('rich text editable fields with role should have children', async function({page}) {
await page.setContent(` await page.setContent(`
<div contenteditable="true" role='textbox'> <div contenteditable="true" role='textbox'>
Edit this image: <img src="fakeimage.png" alt="my fake image"> Edit this image: <img src="fakeimage.png" alt="my fake image">
</div>`); </div>`);
const golden = options.FIREFOX() ? { const golden = options.FIREFOX ? {
role: 'textbox', role: 'textbox',
name: '', name: '',
value: 'Edit this image: my fake image', value: 'Edit this image: my fake image',
@ -199,7 +199,7 @@ it.skip(options.WEBKIT())('rich text editable fields with role should have child
expect(snapshot.children[0]).toEqual(golden); expect(snapshot.children[0]).toEqual(golden);
}); });
it.skip(options.FIREFOX() || options.WEBKIT())('plain text field with role should not have children', async function({page}) { it.skip(options.FIREFOX || options.WEBKIT)('plain text field with role should not have children', async function({page}) {
// Firefox does not support contenteditable="plaintext-only". // Firefox does not support contenteditable="plaintext-only".
// WebKit rich text accessibility is iffy // WebKit rich text accessibility is iffy
await page.setContent(` await page.setContent(`
@ -212,7 +212,7 @@ it.skip(options.FIREFOX() || options.WEBKIT())('plain text field with role shoul
}); });
}); });
it.skip(options.FIREFOX() || options.WEBKIT())('plain text field without role should not have content', async function({page}) { it.skip(options.FIREFOX || options.WEBKIT)('plain text field without role should not have content', async function({page}) {
await page.setContent(` await page.setContent(`
<div contenteditable="plaintext-only">Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`); <div contenteditable="plaintext-only">Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
const snapshot = await page.accessibility.snapshot(); const snapshot = await page.accessibility.snapshot();
@ -222,7 +222,7 @@ it.skip(options.FIREFOX() || options.WEBKIT())('plain text field without role sh
}); });
}); });
it.skip(options.FIREFOX() || options.WEBKIT())('plain text field with tabindex and without role should not have content', async function({page}) { it.skip(options.FIREFOX || options.WEBKIT)('plain text field with tabindex and without role should not have content', async function({page}) {
await page.setContent(` await page.setContent(`
<div contenteditable="plaintext-only" tabIndex=0>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`); <div contenteditable="plaintext-only" tabIndex=0>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
const snapshot = await page.accessibility.snapshot(); const snapshot = await page.accessibility.snapshot();
@ -238,11 +238,11 @@ it('non editable textbox with role and tabIndex and label should not have childr
this is the inner content this is the inner content
<img alt="yo" src="fakeimg.png"> <img alt="yo" src="fakeimg.png">
</div>`); </div>`);
const golden = options.FIREFOX() ? { const golden = options.FIREFOX ? {
role: 'textbox', role: 'textbox',
name: 'my favorite textbox', name: 'my favorite textbox',
value: 'this is the inner content yo' value: 'this is the inner content yo'
} : options.CHROMIUM() ? { } : options.CHROMIUM ? {
role: 'textbox', role: 'textbox',
name: 'my favorite textbox', name: 'my favorite textbox',
value: 'this is the inner content ' value: 'this is the inner content '
@ -276,7 +276,7 @@ it('checkbox without label should not have children', async function({page}) {
this is the inner content this is the inner content
<img alt="yo" src="fakeimg.png"> <img alt="yo" src="fakeimg.png">
</div>`); </div>`);
const golden = options.FIREFOX() ? { const golden = options.FIREFOX ? {
role: 'checkbox', role: 'checkbox',
name: 'this is the inner content yo', name: 'this is the inner content yo',
checked: true checked: true
@ -327,7 +327,7 @@ it('should work on a menu', async({page}) => {
[ { role: 'menuitem', name: 'First Item' }, [ { role: 'menuitem', name: 'First Item' },
{ role: 'menuitem', name: 'Second Item' }, { role: 'menuitem', name: 'Second Item' },
{ role: 'menuitem', name: 'Third Item' } ], { role: 'menuitem', name: 'Third Item' } ],
orientation: options.WEBKIT() ? 'vertical' : undefined orientation: options.WEBKIT ? 'vertical' : undefined
}); });
}); });

View file

@ -39,7 +39,7 @@ it('should throw upon second create new page', async function({browser}) {
it('version should work', async function({browser}) { it('version should work', async function({browser}) {
const version = browser.version(); const version = browser.version();
if (options.CHROMIUM()) if (options.CHROMIUM)
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

@ -325,7 +325,7 @@ it('should(not) block third party cookies', async({context, page, server}) => {
}, server.CROSS_PROCESS_PREFIX + '/grid.html'); }, server.CROSS_PROCESS_PREFIX + '/grid.html');
await page.frames()[1].evaluate(`document.cookie = 'username=John Doe'`); await page.frames()[1].evaluate(`document.cookie = 'username=John Doe'`);
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
const allowsThirdParty = options.CHROMIUM() || options.FIREFOX(); const allowsThirdParty = options.CHROMIUM || options.FIREFOX;
const cookies = await context.cookies(server.CROSS_PROCESS_PREFIX + '/grid.html'); const cookies = await context.cookies(server.CROSS_PROCESS_PREFIX + '/grid.html');
if (allowsThirdParty) { if (allowsThirdParty) {
expect(cookies).toEqual([ expect(cookies).toEqual([

View file

@ -184,7 +184,7 @@ it('should disable javascript', async({browser}) => {
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 (options.WEBKIT()) if (options.WEBKIT)
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

@ -72,7 +72,7 @@ it('should properly report httpOnly cookie', async({context, page, server}) => {
expect(cookies[0].httpOnly).toBe(true); expect(cookies[0].httpOnly).toBe(true);
}); });
it.fail(options.WEBKIT() && WIN)('should properly report "Strict" sameSite cookie', async({context, page, server}) => { it.fail(options.WEBKIT && WIN)('should properly report "Strict" sameSite cookie', async({context, page, server}) => {
server.setRoute('/empty.html', (req, res) => { server.setRoute('/empty.html', (req, res) => {
res.setHeader('Set-Cookie', 'name=value;SameSite=Strict'); res.setHeader('Set-Cookie', 'name=value;SameSite=Strict');
res.end(); res.end();
@ -83,7 +83,7 @@ it.fail(options.WEBKIT() && WIN)('should properly report "Strict" sameSite cooki
expect(cookies[0].sameSite).toBe('Strict'); expect(cookies[0].sameSite).toBe('Strict');
}); });
it.fail(options.WEBKIT() && WIN)('should properly report "Lax" sameSite cookie', async({context, page, server}) => { it.fail(options.WEBKIT && WIN)('should properly report "Lax" sameSite cookie', async({context, page, server}) => {
server.setRoute('/empty.html', (req, res) => { server.setRoute('/empty.html', (req, res) => {
res.setHeader('Set-Cookie', 'name=value;SameSite=Lax'); res.setHeader('Set-Cookie', 'name=value;SameSite=Lax');
res.end(); res.end();

View file

@ -16,7 +16,7 @@
*/ */
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.fail(options.CHROMIUM() && !options.HEADLESS)('should fail without credentials', async({browser, server}) => { it.fail(options.CHROMIUM && !options.HEADLESS)('should fail without credentials', async({browser, server}) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
@ -25,7 +25,7 @@ it.fail(options.CHROMIUM() && !options.HEADLESS)('should fail without credential
await context.close(); await context.close();
}); });
it.fail(options.CHROMIUM() && !options.HEADLESS)('should work with setHTTPCredentials', async({browser, server}) => { it.fail(options.CHROMIUM && !options.HEADLESS)('should work with setHTTPCredentials', async({browser, server}) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
@ -48,7 +48,7 @@ it('should work with correct credentials', async({browser, server}) => {
await context.close(); await context.close();
}); });
it.fail(options.CHROMIUM() && !options.HEADLESS)('should fail with wrong credentials', async({browser, server}) => { it.fail(options.CHROMIUM && !options.HEADLESS)('should fail with wrong credentials', async({browser, server}) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const context = await browser.newContext({ const context = await browser.newContext({
httpCredentials: { username: 'foo', password: 'bar' } httpCredentials: { username: 'foo', password: 'bar' }

View file

@ -16,7 +16,7 @@
*/ */
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.skip(options.FIREFOX())('should work', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should work', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const context = await browser.newContext({ ...iPhone }); const context = await browser.newContext({ ...iPhone });
const page = await context.newPage(); const page = await context.newPage();
@ -26,7 +26,7 @@ it.skip(options.FIREFOX())('should work', async({playwright, browser, server}) =
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should support clicking', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should support clicking', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const context = await browser.newContext({ ...iPhone }); const context = await browser.newContext({ ...iPhone });
const page = await context.newPage(); const page = await context.newPage();
@ -38,7 +38,7 @@ it.skip(options.FIREFOX())('should support clicking', async({playwright, browser
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should scroll to click', async({browser, server}) => { it.skip(options.FIREFOX)('should scroll to click', async({browser, server}) => {
const context = await browser.newContext({ const context = await browser.newContext({
viewport: { viewport: {
width: 400, width: 400,

View file

@ -137,7 +137,7 @@ it('should be isolated between contexts', async({browser, server}) => {
]); ]);
}); });
it.fail(options.FIREFOX())('should not change default locale in another context', async({browser, server}) => { it.fail(options.FIREFOX)('should not change default locale in another context', async({browser, server}) => {
async function getContextLocale(context) { async function getContextLocale(context) {
const page = await context.newPage(); const page = await context.newPage();
return await page.evaluate(() => (new Intl.NumberFormat()).resolvedOptions().locale); return await page.evaluate(() => (new Intl.NumberFormat()).resolvedOptions().locale);

View file

@ -156,7 +156,7 @@ it('should fire page lifecycle events', async function({browser, server}) {
await context.close(); await context.close();
}); });
it.fail(options.WEBKIT())('should work with Shift-clicking', async({browser, server}) => { it.fail(options.WEBKIT)('should work with Shift-clicking', async({browser, server}) => {
// WebKit: Shift+Click does not open a new window. // WebKit: Shift+Click does not open a new window.
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
@ -170,7 +170,7 @@ it.fail(options.WEBKIT())('should work with Shift-clicking', async({browser, ser
await context.close(); await context.close();
}); });
it.fail(options.WEBKIT() || options.FIREFOX())('should work with Ctrl-clicking', async({browser, server}) => { it.fail(options.WEBKIT || options.FIREFOX)('should work with Ctrl-clicking', async({browser, server}) => {
// Firefox: reports an opener in this case. // Firefox: reports an opener in this case.
// WebKit: Ctrl+Click does not open a new tab. // WebKit: Ctrl+Click does not open a new tab.
const context = await browser.newContext(); const context = await browser.newContext();

View file

@ -69,7 +69,7 @@ it('should work for multiple pages sharing same process', async({browser, server
await context.close(); await context.close();
}); });
it.fail(options.FIREFOX())('should not change default timezone in another context', async({browser, server}) => { it.fail(options.FIREFOX)('should not change default timezone in another context', async({browser, server}) => {
async function getContextTimezone(context) { async function getContextTimezone(context) {
const page = await context.newPage(); const page = await context.newPage();
return await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZone); return await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZone);

View file

@ -17,7 +17,7 @@
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.skip(options.FIREFOX())('should support mobile emulation', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should support mobile emulation', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const context = await browser.newContext({ ...iPhone }); const context = await browser.newContext({ ...iPhone });
const page = await context.newPage(); const page = await context.newPage();
@ -28,7 +28,7 @@ it.skip(options.FIREFOX())('should support mobile emulation', async({playwright,
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should support touch emulation', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should support touch emulation', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const context = await browser.newContext({ ...iPhone }); const context = await browser.newContext({ ...iPhone });
const page = await context.newPage(); const page = await context.newPage();
@ -51,7 +51,7 @@ it.skip(options.FIREFOX())('should support touch emulation', async({playwright,
} }
}); });
it.skip(options.FIREFOX())('should be detectable by Modernizr', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should be detectable by Modernizr', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const context = await browser.newContext({ ...iPhone }); const context = await browser.newContext({ ...iPhone });
const page = await context.newPage(); const page = await context.newPage();
@ -60,7 +60,7 @@ it.skip(options.FIREFOX())('should be detectable by Modernizr', async({playwrigh
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should detect touch when applying viewport with touches', async({browser, server}) => { it.skip(options.FIREFOX)('should detect touch when applying viewport with touches', async({browser, server}) => {
const context = await browser.newContext({ viewport: { width: 800, height: 600 }, hasTouch: true }); const context = await browser.newContext({ viewport: { width: 800, height: 600 }, hasTouch: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -69,7 +69,7 @@ it.skip(options.FIREFOX())('should detect touch when applying viewport with touc
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should support landscape emulation', async({playwright, browser, server}) => { it.skip(options.FIREFOX)('should support landscape emulation', async({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6']; const iPhone = playwright.devices['iPhone 6'];
const iPhoneLandscape = playwright.devices['iPhone 6 landscape']; const iPhoneLandscape = playwright.devices['iPhone 6 landscape'];
const context1 = await browser.newContext({ ...iPhone }); const context1 = await browser.newContext({ ...iPhone });
@ -83,7 +83,7 @@ it.skip(options.FIREFOX())('should support landscape emulation', async({playwrig
await context2.close(); await context2.close();
}); });
it.skip(options.FIREFOX())('should support window.orientation emulation', async({browser, server}) => { it.skip(options.FIREFOX)('should support window.orientation emulation', async({browser, server}) => {
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true }); const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/mobile.html'); await page.goto(server.PREFIX + '/mobile.html');
@ -93,7 +93,7 @@ it.skip(options.FIREFOX())('should support window.orientation emulation', async(
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should fire orientationchange event', async({browser, server}) => { it.skip(options.FIREFOX)('should fire orientationchange event', async({browser, server}) => {
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true }); const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/mobile.html'); await page.goto(server.PREFIX + '/mobile.html');
@ -112,7 +112,7 @@ it.skip(options.FIREFOX())('should fire orientationchange event', async({browser
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('default mobile viewports to 980 width', async({browser, server}) => { it.skip(options.FIREFOX)('default mobile viewports to 980 width', async({browser, server}) => {
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true }); const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/empty.html'); await page.goto(server.PREFIX + '/empty.html');
@ -120,7 +120,7 @@ it.skip(options.FIREFOX())('default mobile viewports to 980 width', async({brows
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('respect meta viewport tag', async({browser, server}) => { it.skip(options.FIREFOX)('respect meta viewport tag', async({browser, server}) => {
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true }); const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/mobile.html'); await page.goto(server.PREFIX + '/mobile.html');

View file

@ -25,11 +25,11 @@ it.skip(Boolean(process.env.CRPATH || process.env.FFPATH || process.env.WKPATH))
}); });
it('browserType.name should work', async({browserType}) => { it('browserType.name should work', async({browserType}) => {
if (options.WEBKIT()) if (options.WEBKIT)
expect(browserType.name()).toBe('webkit'); expect(browserType.name()).toBe('webkit');
else if (options.FIREFOX()) else if (options.FIREFOX)
expect(browserType.name()).toBe('firefox'); expect(browserType.name()).toBe('firefox');
else if (options.CHROMIUM()) else if (options.CHROMIUM)
expect(browserType.name()).toBe('chromium'); expect(browserType.name()).toBe('chromium');
else else
throw new Error('Unknown browser'); throw new Error('Unknown browser');

View file

@ -36,7 +36,7 @@ it.skip(options.WIRE).slow()('should be able to reconnect to a browser', async({
await browserServer.close(); await browserServer.close();
}); });
it.skip(options.WIRE).fail(options.CHROMIUM() && WIN).slow()('should handle exceptions during connect', async({browserType, defaultBrowserOptions}) => { it.skip(options.WIRE).fail(options.CHROMIUM && WIN).slow()('should handle exceptions during connect', async({browserType, defaultBrowserOptions}) => {
const browserServer = await browserType.launchServer(defaultBrowserOptions); const browserServer = await browserType.launchServer(defaultBrowserOptions);
const __testHookBeforeCreateBrowser = () => { throw new Error('Dummy') }; const __testHookBeforeCreateBrowser = () => { throw new Error('Dummy') };
const error = await browserType.connect({ wsEndpoint: browserServer.wsEndpoint(), __testHookBeforeCreateBrowser } as any).catch(e => e); const error = await browserType.connect({ wsEndpoint: browserServer.wsEndpoint(), __testHookBeforeCreateBrowser } as any).catch(e => e);

View file

@ -36,7 +36,7 @@ it('should throw if userDataDir option is passed', async({browserType, defaultBr
expect(waitError.message).toContain('launchPersistentContext'); expect(waitError.message).toContain('launchPersistentContext');
}); });
it.skip(options.FIREFOX())('should throw if page argument is passed', async({browserType, defaultBrowserOptions}) => { it.skip(options.FIREFOX)('should throw if page argument is passed', async({browserType, defaultBrowserOptions}) => {
let waitError = null; let waitError = null;
const options = Object.assign({}, defaultBrowserOptions, { args: ['http://example.com'] }); const options = Object.assign({}, defaultBrowserOptions, { args: ['http://example.com'] });
await browserType.launch(options).catch(e => waitError = e); await browserType.launch(options).catch(e => waitError = e);

View file

@ -17,7 +17,7 @@
import url from 'url'; import url from 'url';
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.fail(options.WEBKIT() && WIN)('Web Assembly should work', async function({page, server}) { it.fail(options.WEBKIT && WIN)('Web Assembly should work', async function({page, server}) {
await page.goto(server.PREFIX + '/wasm/table2.html'); await page.goto(server.PREFIX + '/wasm/table2.html');
expect(await page.evaluate('loadTable()')).toBe('42, 83'); expect(await page.evaluate('loadTable()')).toBe('42, 83');
}); });
@ -48,13 +48,13 @@ it('should respect CSP', async({page, server}) => {
expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS'); expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS');
}); });
it.fail(options.WEBKIT() && (WIN || LINUX))('should play video', async({page, asset}) => { it.fail(options.WEBKIT && (WIN || LINUX))('should play video', async({page, asset}) => {
// TODO: the test passes on Windows locally but fails on GitHub Action bot, // TODO: the test passes on Windows locally but fails on GitHub Action bot,
// apparently due to a Media Pack issue in the Windows Server. // apparently due to a Media Pack issue in the Windows Server.
// Also the test is very flaky on Linux WebKit. // Also the test is very flaky on Linux WebKit.
// //
// Safari only plays mp4 so we test WebKit with an .mp4 clip. // Safari only plays mp4 so we test WebKit with an .mp4 clip.
const fileName = options.WEBKIT() ? 'video_mp4.html' : 'video.html'; const fileName = options.WEBKIT ? 'video_mp4.html' : 'video.html';
const absolutePath = asset(fileName); const absolutePath = asset(fileName);
// Our test server doesn't support range requests required to play on Mac, // Our test server doesn't support range requests required to play on Mac,
// so we load the page using a file url. // so we load the page using a file url.

View file

@ -65,7 +65,7 @@ it('should scope context handles', async({browserType, browser, server}) => {
await expectScopeState(browser, GOLDEN_PRECONDITION); await expectScopeState(browser, GOLDEN_PRECONDITION);
}); });
it.skip(!options.CHROMIUM())('should scope CDPSession handles', async({browserType, browser, server}) => { it.skip(!options.CHROMIUM)('should scope CDPSession handles', async({browserType, browser, server}) => {
const GOLDEN_PRECONDITION = { const GOLDEN_PRECONDITION = {
_guid: '', _guid: '',
objects: [ objects: [

View file

@ -15,7 +15,7 @@
*/ */
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.skip(!options.CHROMIUM())('should work', async function({browserType, page, server}) { it.skip(!options.CHROMIUM)('should work', async function({browserType, page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/simple.html'); await page.goto(server.PREFIX + '/csscoverage/simple.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
@ -28,7 +28,7 @@ it.skip(!options.CHROMIUM())('should work', async function({browserType, page, s
expect(coverage[0].text.substring(range.start, range.end)).toBe('div { color: green; }'); expect(coverage[0].text.substring(range.start, range.end)).toBe('div { color: green; }');
}); });
it.skip(!options.CHROMIUM())('should report sourceURLs', async function({page, server}) { it.skip(!options.CHROMIUM)('should report sourceURLs', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/sourceurl.html'); await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
@ -36,7 +36,7 @@ it.skip(!options.CHROMIUM())('should report sourceURLs', async function({page, s
expect(coverage[0].url).toBe('nicename.css'); expect(coverage[0].url).toBe('nicename.css');
}); });
it.skip(!options.CHROMIUM())('should report multiple stylesheets', async function({page, server}) { it.skip(!options.CHROMIUM)('should report multiple stylesheets', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/multiple.html'); await page.goto(server.PREFIX + '/csscoverage/multiple.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
@ -46,7 +46,7 @@ it.skip(!options.CHROMIUM())('should report multiple stylesheets', async functio
expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css'); expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css');
}); });
it.skip(!options.CHROMIUM())('should report stylesheets that have no coverage', async function({page, server}) { it.skip(!options.CHROMIUM)('should report stylesheets that have no coverage', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/unused.html'); await page.goto(server.PREFIX + '/csscoverage/unused.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
@ -55,7 +55,7 @@ it.skip(!options.CHROMIUM())('should report stylesheets that have no coverage',
expect(coverage[0].ranges.length).toBe(0); expect(coverage[0].ranges.length).toBe(0);
}); });
it.skip(!options.CHROMIUM())('should work with media queries', async function({page, server}) { it.skip(!options.CHROMIUM)('should work with media queries', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/media.html'); await page.goto(server.PREFIX + '/csscoverage/media.html');
const coverage = await page.coverage.stopCSSCoverage(); const coverage = await page.coverage.stopCSSCoverage();
@ -66,7 +66,7 @@ it.skip(!options.CHROMIUM())('should work with media queries', async function({p
]); ]);
}); });
it.skip(!options.CHROMIUM())('should work with complicated usecases', async function({page, server}) { it.skip(!options.CHROMIUM)('should work with complicated usecases', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/involved.html'); await page.goto(server.PREFIX + '/csscoverage/involved.html');
const coverage: any = await page.coverage.stopCSSCoverage(); const coverage: any = await page.coverage.stopCSSCoverage();
@ -90,7 +90,7 @@ it.skip(!options.CHROMIUM())('should work with complicated usecases', async func
); );
}); });
it.skip(!options.CHROMIUM())('should ignore injected stylesheets', async function({page, server}) { it.skip(!options.CHROMIUM)('should ignore injected stylesheets', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.addStyleTag({content: 'body { margin: 10px;}'}); await page.addStyleTag({content: 'body { margin: 10px;}'});
// trigger style recalc // trigger style recalc
@ -100,7 +100,7 @@ it.skip(!options.CHROMIUM())('should ignore injected stylesheets', async functio
expect(coverage.length).toBe(0); expect(coverage.length).toBe(0);
}); });
it.skip(!options.CHROMIUM())('should report stylesheets across navigations', async function({page, server}) { it.skip(!options.CHROMIUM)('should report stylesheets across navigations', async function({page, server}) {
await page.coverage.startCSSCoverage({resetOnNavigation: false}); await page.coverage.startCSSCoverage({resetOnNavigation: false});
await page.goto(server.PREFIX + '/csscoverage/multiple.html'); await page.goto(server.PREFIX + '/csscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -108,7 +108,7 @@ it.skip(!options.CHROMIUM())('should report stylesheets across navigations', asy
expect(coverage.length).toBe(2); expect(coverage.length).toBe(2);
}); });
it.skip(!options.CHROMIUM())('should NOT report scripts across navigations', async function({page, server}) { it.skip(!options.CHROMIUM)('should NOT report scripts across navigations', async function({page, server}) {
await page.coverage.startCSSCoverage(); // Enabled by default. await page.coverage.startCSSCoverage(); // Enabled by default.
await page.goto(server.PREFIX + '/csscoverage/multiple.html'); await page.goto(server.PREFIX + '/csscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -116,7 +116,7 @@ it.skip(!options.CHROMIUM())('should NOT report scripts across navigations', asy
expect(coverage.length).toBe(0); expect(coverage.length).toBe(0);
}); });
it.skip(!options.CHROMIUM())('should work with a recently loaded stylesheet', async function({page, server}) { it.skip(!options.CHROMIUM)('should work with a recently loaded stylesheet', async function({page, server}) {
await page.coverage.startCSSCoverage(); await page.coverage.startCSSCoverage();
await page.evaluate(async url => { await page.evaluate(async url => {
document.body.textContent = 'hello, world'; document.body.textContent = 'hello, world';

View file

@ -15,11 +15,11 @@
*/ */
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.skip(options.CHROMIUM())('should be missing', async function({page, server}) { it.skip(options.CHROMIUM)('should be missing', async function({page, server}) {
expect(page.coverage).toBe(null); expect(page.coverage).toBe(null);
}); });
it.skip(!options.CHROMIUM())('should work', async function({browserType, page, server}) { it.skip(!options.CHROMIUM)('should work', async function({browserType, page, server}) {
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' }); await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
const coverage = await page.coverage.stopJSCoverage(); const coverage = await page.coverage.stopJSCoverage();
@ -28,7 +28,7 @@ it.skip(!options.CHROMIUM())('should work', async function({browserType, page, s
expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1); expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1);
}); });
it.skip(!options.CHROMIUM())('should report sourceURLs', async function({page, server}) { it.skip(!options.CHROMIUM)('should report sourceURLs', async function({page, server}) {
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/sourceurl.html'); await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');
const coverage = await page.coverage.stopJSCoverage(); const coverage = await page.coverage.stopJSCoverage();
@ -36,14 +36,14 @@ it.skip(!options.CHROMIUM())('should report sourceURLs', async function({page, s
expect(coverage[0].url).toBe('nicename.js'); expect(coverage[0].url).toBe('nicename.js');
}); });
it.skip(!options.CHROMIUM())('should ignore eval() scripts by default', async function({page, server}) { it.skip(!options.CHROMIUM)('should ignore eval() scripts by default', async function({page, server}) {
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/eval.html'); await page.goto(server.PREFIX + '/jscoverage/eval.html');
const coverage = await page.coverage.stopJSCoverage(); const coverage = await page.coverage.stopJSCoverage();
expect(coverage.length).toBe(1); expect(coverage.length).toBe(1);
}); });
it.skip(!options.CHROMIUM())('shouldn\'t ignore eval() scripts if reportAnonymousScripts is true', async function({page, server}) { it.skip(!options.CHROMIUM)('shouldn\'t ignore eval() scripts if reportAnonymousScripts is true', async function({page, server}) {
await page.coverage.startJSCoverage({reportAnonymousScripts: true}); await page.coverage.startJSCoverage({reportAnonymousScripts: true});
await page.goto(server.PREFIX + '/jscoverage/eval.html'); await page.goto(server.PREFIX + '/jscoverage/eval.html');
const coverage = await page.coverage.stopJSCoverage(); const coverage = await page.coverage.stopJSCoverage();
@ -51,7 +51,7 @@ it.skip(!options.CHROMIUM())('shouldn\'t ignore eval() scripts if reportAnonymou
expect(coverage.length).toBe(2); expect(coverage.length).toBe(2);
}); });
it.skip(!options.CHROMIUM())('should ignore playwright internal scripts if reportAnonymousScripts is true', async function({page, server}) { it.skip(!options.CHROMIUM)('should ignore playwright internal scripts if reportAnonymousScripts is true', async function({page, server}) {
await page.coverage.startJSCoverage({reportAnonymousScripts: true}); await page.coverage.startJSCoverage({reportAnonymousScripts: true});
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.evaluate('console.log("foo")'); await page.evaluate('console.log("foo")');
@ -60,7 +60,7 @@ it.skip(!options.CHROMIUM())('should ignore playwright internal scripts if repor
expect(coverage.length).toBe(0); expect(coverage.length).toBe(0);
}); });
it.skip(!options.CHROMIUM())('should report multiple scripts', async function({page, server}) { it.skip(!options.CHROMIUM)('should report multiple scripts', async function({page, server}) {
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/multiple.html'); await page.goto(server.PREFIX + '/jscoverage/multiple.html');
const coverage = await page.coverage.stopJSCoverage(); const coverage = await page.coverage.stopJSCoverage();
@ -70,7 +70,7 @@ it.skip(!options.CHROMIUM())('should report multiple scripts', async function({p
expect(coverage[1].url).toContain('/jscoverage/script2.js'); expect(coverage[1].url).toContain('/jscoverage/script2.js');
}); });
it.skip(!options.CHROMIUM())('should report scripts across navigations when disabled', async function({page, server}) { it.skip(!options.CHROMIUM)('should report scripts across navigations when disabled', async function({page, server}) {
await page.coverage.startJSCoverage({resetOnNavigation: false}); await page.coverage.startJSCoverage({resetOnNavigation: false});
await page.goto(server.PREFIX + '/jscoverage/multiple.html'); await page.goto(server.PREFIX + '/jscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -78,7 +78,7 @@ it.skip(!options.CHROMIUM())('should report scripts across navigations when disa
expect(coverage.length).toBe(2); expect(coverage.length).toBe(2);
}); });
it.skip(!options.CHROMIUM())('should NOT report scripts across navigations when enabled', async function({page, server}) { it.skip(!options.CHROMIUM)('should NOT report scripts across navigations when enabled', async function({page, server}) {
await page.coverage.startJSCoverage(); // Enabled by default. await page.coverage.startJSCoverage(); // Enabled by default.
await page.goto(server.PREFIX + '/jscoverage/multiple.html'); await page.goto(server.PREFIX + '/jscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -86,7 +86,7 @@ it.skip(!options.CHROMIUM())('should NOT report scripts across navigations when
expect(coverage.length).toBe(0); expect(coverage.length).toBe(0);
}); });
it.skip(!options.CHROMIUM())('should not hang when there is a debugger statement', async function({page, server}) { it.skip(!options.CHROMIUM)('should not hang when there is a debugger statement', async function({page, server}) {
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => { await page.evaluate(() => {

View file

@ -16,7 +16,7 @@
import { options } from '../playwright.fixtures'; import { options } from '../playwright.fixtures';
import { ChromiumBrowserContext } from '../..'; import { ChromiumBrowserContext } from '../..';
it.skip(!options.CHROMIUM())('should create a worker from a service worker', async({page, server, context}) => { it.skip(!options.CHROMIUM)('should create a worker from a service worker', async({page, server, context}) => {
const [worker] = await Promise.all([ const [worker] = await Promise.all([
(context as ChromiumBrowserContext).waitForEvent('serviceworker'), (context as ChromiumBrowserContext).waitForEvent('serviceworker'),
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html') page.goto(server.PREFIX + '/serviceworkers/empty/sw.html')
@ -24,7 +24,7 @@ it.skip(!options.CHROMIUM())('should create a worker from a service worker', asy
expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]'); expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]');
}); });
it.skip(!options.CHROMIUM())('serviceWorkers() should return current workers', async({page, server, context}) => { it.skip(!options.CHROMIUM)('serviceWorkers() should return current workers', async({page, server, context}) => {
const [worker1] = await Promise.all([ const [worker1] = await Promise.all([
(context as ChromiumBrowserContext).waitForEvent('serviceworker'), (context as ChromiumBrowserContext).waitForEvent('serviceworker'),
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html') page.goto(server.PREFIX + '/serviceworkers/empty/sw.html')
@ -42,7 +42,7 @@ it.skip(!options.CHROMIUM())('serviceWorkers() should return current workers', a
expect(workers).toContain(worker2); expect(workers).toContain(worker2);
}); });
it.skip(!options.CHROMIUM())('should not create a worker from a shared worker', async({page, server, context}) => { it.skip(!options.CHROMIUM)('should not create a worker from a shared worker', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
let serviceWorkerCreated; let serviceWorkerCreated;
(context as ChromiumBrowserContext).once('serviceworker', () => serviceWorkerCreated = true); (context as ChromiumBrowserContext).once('serviceworker', () => serviceWorkerCreated = true);
@ -52,7 +52,7 @@ it.skip(!options.CHROMIUM())('should not create a worker from a shared worker',
expect(serviceWorkerCreated).not.toBeTruthy(); expect(serviceWorkerCreated).not.toBeTruthy();
}); });
it.skip(!options.CHROMIUM())('should close service worker together with the context', async({browser, server}) => { it.skip(!options.CHROMIUM)('should close service worker together with the context', async({browser, server}) => {
const context = await browser.newContext() as ChromiumBrowserContext; const context = await browser.newContext() as ChromiumBrowserContext;
const page = await context.newPage(); const page = await context.newPage();
const [worker] = await Promise.all([ const [worker] = await Promise.all([
@ -66,7 +66,7 @@ it.skip(!options.CHROMIUM())('should close service worker together with the cont
expect(messages.join('|')).toBe('worker|context'); expect(messages.join('|')).toBe('worker|context');
}); });
it.skip(!options.CHROMIUM())('Page.route should work with intervention headers', async({server, page}) => { it.skip(!options.CHROMIUM)('Page.route should work with intervention headers', async({server, page}) => {
server.setRoute('/intervention', (req, res) => res.end(` server.setRoute('/intervention', (req, res) => res.end(`
<script> <script>
document.write('<script src="${server.CROSS_PROCESS_PREFIX}/intervention.js">' + '</scr' + 'ipt>'); document.write('<script src="${server.CROSS_PROCESS_PREFIX}/intervention.js">' + '</scr' + 'ipt>');

View file

@ -20,21 +20,21 @@ import utils from '../utils';
import { ChromiumBrowser, ChromiumBrowserContext } from '../..'; import { ChromiumBrowser, ChromiumBrowserContext } from '../..';
const { makeUserDataDir, removeUserDataDir } = utils; const { makeUserDataDir, removeUserDataDir } = utils;
it.skip(options.WIRE || !options.CHROMIUM())('should throw with remote-debugging-pipe argument', async({browserType, defaultBrowserOptions}) => { it.skip(options.WIRE || !options.CHROMIUM)('should throw with remote-debugging-pipe argument', async({browserType, defaultBrowserOptions}) => {
const options = Object.assign({}, defaultBrowserOptions); const options = Object.assign({}, defaultBrowserOptions);
options.args = ['--remote-debugging-pipe'].concat(options.args || []); options.args = ['--remote-debugging-pipe'].concat(options.args || []);
const error = await browserType.launchServer(options).catch(e => e); const error = await browserType.launchServer(options).catch(e => e);
expect(error.message).toContain('Playwright manages remote debugging connection itself'); expect(error.message).toContain('Playwright manages remote debugging connection itself');
}); });
it.skip(options.WIRE || !options.CHROMIUM())('should not throw with remote-debugging-port argument', async({browserType, defaultBrowserOptions}) => { it.skip(options.WIRE || !options.CHROMIUM)('should not throw with remote-debugging-port argument', async({browserType, defaultBrowserOptions}) => {
const options = Object.assign({}, defaultBrowserOptions); const options = Object.assign({}, defaultBrowserOptions);
options.args = ['--remote-debugging-port=0'].concat(options.args || []); options.args = ['--remote-debugging-port=0'].concat(options.args || []);
const browser = await browserType.launchServer(options); const browser = await browserType.launchServer(options);
await browser.close(); await browser.close();
}); });
it.skip(!options.CHROMIUM() || options.WIRE || WIN)('should open devtools when "devtools: true" option is given', async({browserType, defaultBrowserOptions}) => { it.skip(!options.CHROMIUM || options.WIRE || WIN)('should open devtools when "devtools: true" option is given', async({browserType, defaultBrowserOptions}) => {
let devtoolsCallback; let devtoolsCallback;
const devtoolsPromise = new Promise(f => devtoolsCallback = f); const devtoolsPromise = new Promise(f => devtoolsCallback = f);
const __testHookForDevTools = devtools => devtools.__testHookOnBinding = parsed => { const __testHookForDevTools = devtools => devtools.__testHookOnBinding = parsed => {
@ -50,7 +50,7 @@ it.skip(!options.CHROMIUM() || options.WIRE || WIN)('should open devtools when "
await browser.close(); await browser.close();
}); });
it.skip(!options.CHROMIUM())('should return background pages', async({browserType, defaultBrowserOptions}) => { it.skip(!options.CHROMIUM)('should return background pages', async({browserType, defaultBrowserOptions}) => {
const userDataDir = await makeUserDataDir(); const userDataDir = await makeUserDataDir();
const extensionPath = path.join(__dirname, '..', 'assets', 'simple-extension'); const extensionPath = path.join(__dirname, '..', 'assets', 'simple-extension');
const extensionOptions = {...defaultBrowserOptions, const extensionOptions = {...defaultBrowserOptions,
@ -72,7 +72,7 @@ it.skip(!options.CHROMIUM())('should return background pages', async({browserTyp
await removeUserDataDir(userDataDir); await removeUserDataDir(userDataDir);
}); });
it.skip(!options.CHROMIUM())('should not create pages automatically', async ({browserType, defaultBrowserOptions}) => { it.skip(!options.CHROMIUM)('should not create pages automatically', async ({browserType, defaultBrowserOptions}) => {
const browser = await browserType.launch(defaultBrowserOptions); const browser = await browserType.launch(defaultBrowserOptions);
const browserSession = await (browser as ChromiumBrowser).newBrowserCDPSession(); const browserSession = await (browser as ChromiumBrowser).newBrowserCDPSession();
const targets = []; const targets = [];

View file

@ -26,14 +26,14 @@ registerWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, te
await browser.close(); await browser.close();
}); });
it.skip(!options.CHROMIUM())('should report oopif frames', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should report oopif frames', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html'); expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
}); });
it.skip(!options.CHROMIUM())('should handle oopif detach', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should handle oopif detach', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
@ -46,7 +46,7 @@ it.skip(!options.CHROMIUM())('should handle oopif detach', async function({brows
expect(detachedFrame).toBe(frame); expect(detachedFrame).toBe(frame);
}); });
it.skip(!options.CHROMIUM())('should handle remote -> local -> remote transitions', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should handle remote -> local -> remote transitions', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
@ -84,7 +84,7 @@ it.fail(true)('should get the proper viewport', async({browser, page, server}) =
expect(await oopif.evaluate(() => 'ontouchstart' in window)).toBe(false); expect(await oopif.evaluate(() => 'ontouchstart' in window)).toBe(false);
}); });
it.skip(!options.CHROMIUM())('should expose function', async({browser, page, server}) => { it.skip(!options.CHROMIUM)('should expose function', async({browser, page, server}) => {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
@ -96,7 +96,7 @@ it.skip(!options.CHROMIUM())('should expose function', async({browser, page, ser
expect(result).toBe(36); expect(result).toBe(36);
}); });
it.skip(!options.CHROMIUM())('should emulate media', async({browser, page, server}) => { it.skip(!options.CHROMIUM)('should emulate media', async({browser, page, server}) => {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
@ -106,7 +106,7 @@ it.skip(!options.CHROMIUM())('should emulate media', async({browser, page, serve
expect(await oopif.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true); expect(await oopif.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should emulate offline', async({browser, page, context, server}) => { it.skip(!options.CHROMIUM)('should emulate offline', async({browser, page, context, server}) => {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
@ -116,7 +116,7 @@ it.skip(!options.CHROMIUM())('should emulate offline', async({browser, page, con
expect(await oopif.evaluate(() => navigator.onLine)).toBe(false); expect(await oopif.evaluate(() => navigator.onLine)).toBe(false);
}); });
it.skip(!options.CHROMIUM())('should support context options', async({browser, server, playwright}) => { it.skip(!options.CHROMIUM)('should support context options', async({browser, server, playwright}) => {
const iPhone = playwright.devices['iPhone 6'] const iPhone = playwright.devices['iPhone 6']
const context = await browser.newContext({ ...iPhone, timezoneId: 'America/Jamaica', locale: 'fr-CH', userAgent: 'UA' }); const context = await browser.newContext({ ...iPhone, timezoneId: 'America/Jamaica', locale: 'fr-CH', userAgent: 'UA' });
const page = await context.newPage(); const page = await context.newPage();
@ -138,7 +138,7 @@ it.skip(!options.CHROMIUM())('should support context options', async({browser, s
await context.close(); await context.close();
}); });
it.skip(!options.CHROMIUM())('should respect route', async({browser, page, server}) => { it.skip(!options.CHROMIUM)('should respect route', async({browser, page, server}) => {
let intercepted = false; let intercepted = false;
await page.route('**/digits/0.png', route => { await page.route('**/digits/0.png', route => {
intercepted = true; intercepted = true;
@ -150,7 +150,7 @@ it.skip(!options.CHROMIUM())('should respect route', async({browser, page, serve
expect(intercepted).toBe(true); expect(intercepted).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should take screenshot', async({browser, page, server, golden}) => { it.skip(!options.CHROMIUM)('should take screenshot', async({browser, page, server, golden}) => {
await page.setViewportSize({width: 500, height: 500}); await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(page.frames().length).toBe(2); expect(page.frames().length).toBe(2);
@ -158,13 +158,13 @@ it.skip(!options.CHROMIUM())('should take screenshot', async({browser, page, ser
expect(await page.screenshot()).toMatchImage(golden('screenshot-oopif.png'), { threshold: 0.3 }); expect(await page.screenshot()).toMatchImage(golden('screenshot-oopif.png'), { threshold: 0.3 });
}); });
it.skip(!options.CHROMIUM())('should load oopif iframes with subresources and request interception', async function({browser, page, server, context}) { it.skip(!options.CHROMIUM)('should load oopif iframes with subresources and request interception', async function({browser, page, server, context}) {
await page.route('**/*', route => route.continue()); await page.route('**/*', route => route.continue());
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
}); });
it.skip(!options.CHROMIUM())('should report main requests', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should report main requests', async function({browser, page, server}) {
const requestFrames = []; const requestFrames = [];
page.on('request', r => requestFrames.push(r.frame())); page.on('request', r => requestFrames.push(r.frame()));
const finishedFrames = []; const finishedFrames = [];
@ -202,7 +202,7 @@ it.skip(!options.CHROMIUM())('should report main requests', async function({brow
expect(finishedFrames[2]).toBe(grandChild); expect(finishedFrames[2]).toBe(grandChild);
}); });
it.skip(!options.CHROMIUM())('should support exposeFunction', async function({browser, context, page, server}) { it.skip(!options.CHROMIUM)('should support exposeFunction', async function({browser, context, page, server}) {
await context.exposeFunction('dec', a => a - 1); await context.exposeFunction('dec', a => a - 1);
await page.exposeFunction('inc', a => a + 1); await page.exposeFunction('inc', a => a + 1);
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
@ -214,7 +214,7 @@ it.skip(!options.CHROMIUM())('should support exposeFunction', async function({br
expect(await page.frames()[1].evaluate(() => window['dec'](4))).toBe(3); expect(await page.frames()[1].evaluate(() => window['dec'](4))).toBe(3);
}); });
it.skip(!options.CHROMIUM())('should support addInitScript', async function({browser, context, page, server}) { it.skip(!options.CHROMIUM)('should support addInitScript', async function({browser, context, page, server}) {
await context.addInitScript(() => window['bar'] = 17); await context.addInitScript(() => window['bar'] = 17);
await page.addInitScript(() => window['foo'] = 42); await page.addInitScript(() => window['foo'] = 42);
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
@ -226,14 +226,14 @@ it.skip(!options.CHROMIUM())('should support addInitScript', async function({bro
expect(await page.frames()[1].evaluate(() => window['bar'])).toBe(17); expect(await page.frames()[1].evaluate(() => window['bar'])).toBe(17);
}); });
// @see https://github.com/microsoft/playwright/issues/1240 // @see https://github.com/microsoft/playwright/issues/1240
it.skip(!options.CHROMIUM())('should click a button when it overlays oopif', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should click a button when it overlays oopif', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/button-overlay-oopif.html'); await page.goto(server.PREFIX + '/button-overlay-oopif.html');
expect(await countOOPIFs(browser)).toBe(1); expect(await countOOPIFs(browser)).toBe(1);
await page.click('button'); await page.click('button');
expect(await page.evaluate(() => window['BUTTON_CLICKED'])).toBe(true); expect(await page.evaluate(() => window['BUTTON_CLICKED'])).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should report google.com frame with headful', async({browserType, defaultBrowserOptions, server}) => { it.skip(!options.CHROMIUM)('should report google.com frame with headful', async({browserType, defaultBrowserOptions, server}) => {
// @see https://github.com/GoogleChrome/puppeteer/issues/2548 // @see https://github.com/GoogleChrome/puppeteer/issues/2548
// https://google.com is isolated by default in Chromium embedder. // https://google.com is isolated by default in Chromium embedder.
const browser = await browserType.launch({...defaultBrowserOptions, headless: false}); const browser = await browserType.launch({...defaultBrowserOptions, headless: false});
@ -258,7 +258,7 @@ it.skip(!options.CHROMIUM())('should report google.com frame with headful', asyn
await browser.close(); await browser.close();
}); });
it.skip(!options.CHROMIUM())('ElementHandle.boundingBox() should work', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('ElementHandle.boundingBox() should work', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
await page.$eval('iframe', iframe => { await page.$eval('iframe', iframe => {
iframe.style.width = '500px'; iframe.style.width = '500px';
@ -281,7 +281,7 @@ it.skip(!options.CHROMIUM())('ElementHandle.boundingBox() should work', async fu
expect(await handle2.boundingBox()).toEqual({ x: 100 + 42, y: 50 + 17, width: 50, height: 50 }); expect(await handle2.boundingBox()).toEqual({ x: 100 + 42, y: 50 + 17, width: 50, height: 50 });
}); });
it.skip(!options.CHROMIUM())('should click', async function({browser, page, server}) { it.skip(!options.CHROMIUM)('should click', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html'); await page.goto(server.PREFIX + '/dynamic-oopif.html');
await page.$eval('iframe', iframe => { await page.$eval('iframe', iframe => {
iframe.style.width = '500px'; iframe.style.width = '500px';

View file

@ -16,7 +16,7 @@
import { options } from '../playwright.fixtures'; import { options } from '../playwright.fixtures';
import { ChromiumBrowserContext, ChromiumBrowser } from "../../types/types"; import { ChromiumBrowserContext, ChromiumBrowser } from "../../types/types";
it.skip(!options.CHROMIUM())('should work', async function({page}) { it.skip(!options.CHROMIUM)('should work', async function({page}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
await Promise.all([ await Promise.all([
@ -27,7 +27,7 @@ it.skip(!options.CHROMIUM())('should work', async function({page}) {
expect(foo).toBe('bar'); expect(foo).toBe('bar');
}); });
it.skip(!options.CHROMIUM())('should send events', async function({page, server}) { it.skip(!options.CHROMIUM)('should send events', async function({page, server}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
await client.send('Network.enable'); await client.send('Network.enable');
const events = []; const events = [];
@ -36,12 +36,12 @@ it.skip(!options.CHROMIUM())('should send events', async function({page, server}
expect(events.length).toBe(1); expect(events.length).toBe(1);
}); });
it.skip(!options.CHROMIUM())('should only accept a page', async function({page}) { it.skip(!options.CHROMIUM)('should only accept a page', async function({page}) {
const error = await (page.context() as ChromiumBrowserContext).newCDPSession(page.context() as any).catch(e => e); const error = await (page.context() as ChromiumBrowserContext).newCDPSession(page.context() as any).catch(e => e);
expect(error.message).toContain('page: expected Page'); expect(error.message).toContain('page: expected Page');
}); });
it.skip(!options.CHROMIUM())('should enable and disable domains independently', async function({page}) { it.skip(!options.CHROMIUM)('should enable and disable domains independently', async function({page}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
await client.send('Runtime.enable'); await client.send('Runtime.enable');
await client.send('Debugger.enable'); await client.send('Debugger.enable');
@ -59,7 +59,7 @@ it.skip(!options.CHROMIUM())('should enable and disable domains independently',
]); ]);
}); });
it.skip(!options.CHROMIUM())('should be able to detach session', async function({page}) { it.skip(!options.CHROMIUM)('should be able to detach session', async function({page}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
await client.send('Runtime.enable'); await client.send('Runtime.enable');
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true}); const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
@ -74,7 +74,7 @@ it.skip(!options.CHROMIUM())('should be able to detach session', async function(
expect(error.message).toContain('Target browser or context has been closed'); expect(error.message).toContain('Target browser or context has been closed');
}); });
it.skip(!options.CHROMIUM())('should throw nice errors', async function({page}) { it.skip(!options.CHROMIUM)('should throw nice errors', async function({page}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
const error = await theSourceOfTheProblems().catch(error => error); const error = await theSourceOfTheProblems().catch(error => error);
expect(error.stack).toContain('theSourceOfTheProblems'); expect(error.stack).toContain('theSourceOfTheProblems');
@ -85,7 +85,7 @@ it.skip(!options.CHROMIUM())('should throw nice errors', async function({page})
} }
}); });
it.skip(!options.CHROMIUM())('should not break page.close()', async function({browser}) { it.skip(!options.CHROMIUM)('should not break page.close()', async function({browser}) {
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
const session = await (page.context() as ChromiumBrowserContext).newCDPSession(page); const session = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
@ -94,7 +94,7 @@ it.skip(!options.CHROMIUM())('should not break page.close()', async function({br
await context.close(); await context.close();
}); });
it.skip(!options.CHROMIUM())('should detach when page closes', async function({browser}) { it.skip(!options.CHROMIUM)('should detach when page closes', async function({browser}) {
const context = await browser.newContext() as ChromiumBrowserContext; const context = await browser.newContext() as ChromiumBrowserContext;
const page = await context.newPage(); const page = await context.newPage();
const session = await context.newCDPSession(page); const session = await context.newCDPSession(page);
@ -105,7 +105,7 @@ it.skip(!options.CHROMIUM())('should detach when page closes', async function({b
await context.close(); await context.close();
}); });
it.skip(!options.CHROMIUM())('should work', async function({browser}) { it.skip(!options.CHROMIUM)('should work', async function({browser}) {
const session = await (browser as ChromiumBrowser).newBrowserCDPSession(); const session = await (browser as ChromiumBrowser).newBrowserCDPSession();
const version = await session.send('Browser.getVersion'); const version = await session.send('Browser.getVersion');

View file

@ -22,7 +22,7 @@ import path from 'path';
import { ChromiumBrowser } from '../..'; import { ChromiumBrowser } from '../..';
declare global { declare global {
interface FixtureState { interface TestState {
outputFile: string; outputFile: string;
} }
} }
@ -34,14 +34,14 @@ registerFixture('outputFile', async ({tmpDir}, test) => {
fs.unlinkSync(outputFile); fs.unlinkSync(outputFile);
}); });
it.skip(!options.CHROMIUM())('should output a trace', async({browser, page, server, outputFile}) => { it.skip(!options.CHROMIUM)('should output a trace', async({browser, page, server, outputFile}) => {
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile}); await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
await (browser as ChromiumBrowser).stopTracing(); await (browser as ChromiumBrowser).stopTracing();
expect(fs.existsSync(outputFile)).toBe(true); expect(fs.existsSync(outputFile)).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should create directories as needed', async({browser, page, server, tmpDir}) => { it.skip(!options.CHROMIUM)('should create directories as needed', async({browser, page, server, tmpDir}) => {
const filePath = path.join(tmpDir, 'these', 'are', 'directories'); const filePath = path.join(tmpDir, 'these', 'are', 'directories');
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath}); await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath});
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
@ -49,7 +49,7 @@ it.skip(!options.CHROMIUM())('should create directories as needed', async({brows
expect(fs.existsSync(filePath)).toBe(true); expect(fs.existsSync(filePath)).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should run with custom categories if provided', async({browser, page, outputFile}) => { it.skip(!options.CHROMIUM)('should run with custom categories if provided', async({browser, page, outputFile}) => {
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']}); await (browser as ChromiumBrowser).startTracing(page, {path: outputFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']});
await (browser as ChromiumBrowser).stopTracing(); await (browser as ChromiumBrowser).stopTracing();
@ -57,7 +57,7 @@ it.skip(!options.CHROMIUM())('should run with custom categories if provided', as
expect(traceJson.metadata['trace-config']).toContain('disabled-by-default-v8.cpu_profiler.hires'); expect(traceJson.metadata['trace-config']).toContain('disabled-by-default-v8.cpu_profiler.hires');
}); });
it.skip(!options.CHROMIUM())('should throw if tracing on two pages', async({browser, page, outputFile}) => { it.skip(!options.CHROMIUM)('should throw if tracing on two pages', async({browser, page, outputFile}) => {
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile}); await (browser as ChromiumBrowser).startTracing(page, {path: outputFile});
const newPage = await browser.newPage(); const newPage = await browser.newPage();
let error = null; let error = null;
@ -67,7 +67,7 @@ it.skip(!options.CHROMIUM())('should throw if tracing on two pages', async({brow
await (browser as ChromiumBrowser).stopTracing(); await (browser as ChromiumBrowser).stopTracing();
}); });
it.skip(!options.CHROMIUM())('should return a buffer', async({browser, page, server, outputFile}) => { it.skip(!options.CHROMIUM)('should return a buffer', async({browser, page, server, outputFile}) => {
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile}); await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const trace = await (browser as ChromiumBrowser).stopTracing(); const trace = await (browser as ChromiumBrowser).stopTracing();
@ -75,14 +75,14 @@ it.skip(!options.CHROMIUM())('should return a buffer', async({browser, page, ser
expect(trace.toString()).toEqual(buf.toString()); expect(trace.toString()).toEqual(buf.toString());
}); });
it.skip(!options.CHROMIUM())('should work without options', async({browser, page, server}) => { it.skip(!options.CHROMIUM)('should work without options', async({browser, page, server}) => {
await (browser as ChromiumBrowser).startTracing(page); await (browser as ChromiumBrowser).startTracing(page);
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const trace = await (browser as ChromiumBrowser).stopTracing(); const trace = await (browser as ChromiumBrowser).stopTracing();
expect(trace).toBeTruthy(); expect(trace).toBeTruthy();
}); });
it.skip(!options.CHROMIUM())('should support a buffer without a path', async({browser, page, server}) => { it.skip(!options.CHROMIUM)('should support a buffer without a path', async({browser, page, server}) => {
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true}); await (browser as ChromiumBrowser).startTracing(page, {screenshots: true});
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const trace = await (browser as ChromiumBrowser).stopTracing(); const trace = await (browser as ChromiumBrowser).stopTracing();

View file

@ -316,7 +316,7 @@ it('should click the button inside an iframe', async({page, server}) => {
expect(await frame.evaluate(() => window['result'])).toBe('Clicked'); expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
}); });
it.fail(options.CHROMIUM() || options.WEBKIT())('should click the button with fixed position inside an iframe', async({page, server}) => { it.fail(options.CHROMIUM || options.WEBKIT)('should click the button with fixed position inside an iframe', async({page, server}) => {
// @see https://github.com/GoogleChrome/puppeteer/issues/4110 // @see https://github.com/GoogleChrome/puppeteer/issues/4110
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=986390 // @see https://bugs.chromium.org/p/chromium/issues/detail?id=986390
// @see https://chromium-review.googlesource.com/c/chromium/src/+/1742784 // @see https://chromium-review.googlesource.com/c/chromium/src/+/1742784
@ -349,8 +349,8 @@ it('should click the button with px border with offset', async({page, server}) =
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(options.WEBKIT() ? 20 + 8 : 20); expect(await page.evaluate('offsetX')).toBe(options.WEBKIT ? 20 + 8 : 20);
expect(await page.evaluate('offsetY')).toBe(options.WEBKIT() ? 10 + 8 : 10); expect(await page.evaluate('offsetY')).toBe(options.WEBKIT ? 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}) => {
@ -360,8 +360,8 @@ it('should click the button with em border with offset', async({page, server}) =
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(options.WEBKIT() ? 12 * 2 + 20 : 20); expect(await page.evaluate('offsetX')).toBe(options.WEBKIT ? 12 * 2 + 20 : 20);
expect(await page.evaluate('offsetY')).toBe(options.WEBKIT() ? 12 * 2 + 10 : 10); expect(await page.evaluate('offsetY')).toBe(options.WEBKIT ? 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}) => {
@ -371,8 +371,8 @@ it('should click a very large button with offset', async({page, server}) => {
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(options.WEBKIT() ? 1900 + 8 : 1900); expect(await page.evaluate('offsetX')).toBe(options.WEBKIT ? 1900 + 8 : 1900);
expect(await page.evaluate('offsetY')).toBe(options.WEBKIT() ? 1910 + 8 : 1910); expect(await page.evaluate('offsetY')).toBe(options.WEBKIT ? 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}) => {
@ -391,11 +391,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(options.WEBKIT() ? 1900 + 8 : 1900); expect(await page.evaluate('offsetX')).toBe(options.WEBKIT ? 1900 + 8 : 1900);
expect(await page.evaluate('offsetY')).toBe(options.WEBKIT() ? 1910 + 8 : 1910); expect(await page.evaluate('offsetY')).toBe(options.WEBKIT ? 1910 + 8 : 1910);
}); });
it.skip(options.FIREFOX())('should click the button with offset with page scale', async({browser, server}) => { it.skip(options.FIREFOX)('should click the button with offset with page scale', async({browser, server}) => {
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');
@ -407,10 +407,10 @@ it.skip(options.FIREFOX())('should click the button with offset with page scale'
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 (options.WEBKIT()) { if (options.WEBKIT) {
// 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 (options.CHROMIUM() && options.HEADLESS) { } else if (options.CHROMIUM && options.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

@ -23,7 +23,7 @@ import { BrowserType, Browser, BrowserContext, Page } from '..';
const { removeUserDataDir, makeUserDataDir } = utils; const { removeUserDataDir, makeUserDataDir } = utils;
declare global { declare global {
interface FixtureState { interface TestState {
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>; launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>;
} }
} }
@ -119,7 +119,7 @@ it('should(not) block third party cookies', async ({server, launchPersistent}) =
return document.cookie; return document.cookie;
}); });
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
const allowsThirdParty = options.CHROMIUM() || options.FIREFOX(); const allowsThirdParty = options.CHROMIUM || options.FIREFOX;
expect(documentCookie).toBe(allowsThirdParty ? 'username=John Doe' : ''); expect(documentCookie).toBe(allowsThirdParty ? 'username=John Doe' : '');
const cookies = await context.cookies(server.CROSS_PROCESS_PREFIX + '/grid.html'); const cookies = await context.cookies(server.CROSS_PROCESS_PREFIX + '/grid.html');
if (allowsThirdParty) { if (allowsThirdParty) {
@ -174,7 +174,7 @@ it('should support javascriptEnabled option', async ({launchPersistent}) => {
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 (options.WEBKIT()) if (options.WEBKIT)
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');
@ -217,7 +217,7 @@ it('should support hasTouch option', async ({server, launchPersistent}) => {
expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(true); expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(true);
}); });
it.skip(options.FIREFOX())('should work in persistent context', async ({server, launchPersistent}) => { it.skip(options.FIREFOX)('should work in persistent context', async ({server, launchPersistent}) => {
// Firefox does not support mobile. // Firefox does not support mobile.
const {page, context} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true}); const {page, context} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true});
await page.goto(server.PREFIX + '/empty.html'); await page.goto(server.PREFIX + '/empty.html');
@ -302,7 +302,7 @@ it.slow()('should restore state from userDataDir', async({browserType, defaultBr
await removeUserDataDir(userDataDir2); await removeUserDataDir(userDataDir2);
}); });
it.fail(options.CHROMIUM() && (WIN || MAC)).slow()('should restore cookies from userDataDir', async({browserType, defaultBrowserOptions, server, launchPersistent}) => { it.fail(options.CHROMIUM && (WIN || MAC)).slow()('should restore cookies from userDataDir', async({browserType, defaultBrowserOptions, server, launchPersistent}) => {
const userDataDir = await makeUserDataDir(); const userDataDir = await makeUserDataDir();
const browserContext = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions); const browserContext = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions);
const page = await browserContext.newPage(); const page = await browserContext.newPage();
@ -338,7 +338,7 @@ it('should have default URL when launching browser', async ({launchPersistent})
expect(urls).toEqual(['about:blank']); expect(urls).toEqual(['about:blank']);
}); });
it.skip(options.FIREFOX())('should throw if page argument is passed', async ({browserType, defaultBrowserOptions, server, tmpDir}) => { it.skip(options.FIREFOX)('should throw if page argument is passed', async ({browserType, defaultBrowserOptions, server, tmpDir}) => {
const options = {...defaultBrowserOptions, args: [server.EMPTY_PAGE] }; const options = {...defaultBrowserOptions, args: [server.EMPTY_PAGE] };
const error = await browserType.launchPersistentContext(tmpDir, options).catch(e => e); const error = await browserType.launchPersistentContext(tmpDir, options).catch(e => e);
expect(error.message).toContain('can not specify page'); expect(error.message).toContain('can not specify page');
@ -381,7 +381,7 @@ it('should fire close event for a persistent context', async({launchPersistent})
expect(closed).toBe(true); expect(closed).toBe(true);
}); });
it.skip(!options.CHROMIUM())('coverage should work', async ({server, launchPersistent}) => { it.skip(!options.CHROMIUM)('coverage should work', async ({server, launchPersistent}) => {
const {page, context} = await launchPersistent(); const {page, context} = await launchPersistent();
await page.coverage.startJSCoverage(); await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' }); await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
@ -391,7 +391,7 @@ it.skip(!options.CHROMIUM())('coverage should work', async ({server, launchPersi
expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1); expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1);
}); });
it.skip(options.CHROMIUM())('coverage should be missing', async ({launchPersistent}) => { it.skip(options.CHROMIUM)('coverage should be missing', async ({launchPersistent}) => {
const {page, context} = await launchPersistent(); const {page, context} = await launchPersistent();
expect(page.coverage).toBe(null); expect(page.coverage).toBe(null);
}); });

View file

@ -62,7 +62,7 @@ it('should dismiss the confirm prompt', async({page}) => {
expect(result).toBe(false); expect(result).toBe(false);
}); });
it.fail(options.WEBKIT())('should be able to close context with open alert', async({browser}) => { it.fail(options.WEBKIT)('should be able to close context with open alert', async({browser}) => {
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
const alertPromise = page.waitForEvent('dialog'); const alertPromise = page.waitForEvent('dialog');

View file

@ -126,7 +126,7 @@ it('should be atomic', async({playwright, page}) => {
expect(await page.evaluate(() => window['_clicked'])).toBe(true); expect(await page.evaluate(() => window['_clicked'])).toBe(true);
}); });
it.fail(options.WEBKIT())('should dispatch drag drop events', async({page, server}) => { it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}) => {
await page.goto(server.PREFIX + '/drag-n-drop.html'); await page.goto(server.PREFIX + '/drag-n-drop.html');
const dataTransfer = await page.evaluateHandle(() => new DataTransfer()); const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
await page.dispatchEvent('#source', 'dragstart', { dataTransfer }); await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
@ -138,7 +138,7 @@ it.fail(options.WEBKIT())('should dispatch drag drop events', async({page, serve
}, {source, target})).toBeTruthy(); }, {source, target})).toBeTruthy();
}); });
it.fail(options.WEBKIT())('should dispatch drag drop events', async({page, server}) => { it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}) => {
await page.goto(server.PREFIX + '/drag-n-drop.html'); await page.goto(server.PREFIX + '/drag-n-drop.html');
const dataTransfer = await page.evaluateHandle(() => new DataTransfer()); const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
const source = await page.$('#source'); const source = await page.$('#source');

View file

@ -217,7 +217,7 @@ it(`should report download path within page.on('download', …) handler for Blob
expect(fs.readFileSync(path).toString()).toBe('Hello world'); expect(fs.readFileSync(path).toString()).toBe('Hello world');
await page.close(); await page.close();
}) })
it.fail(options.FIREFOX() || options.WEBKIT())('should report alt-click downloads', async({browser, server}) => { it.fail(options.FIREFOX || options.WEBKIT)('should report alt-click downloads', async({browser, server}) => {
// Firefox does not download on alt-click by default. // Firefox does not download on alt-click by default.
// Our WebKit embedder does not download on alt-click, although Safari does. // Our WebKit embedder does not download on alt-click, although Safari does.
server.setRoute('/download', (req, res) => { server.setRoute('/download', (req, res) => {
@ -238,7 +238,7 @@ it.fail(options.FIREFOX() || options.WEBKIT())('should report alt-click download
await page.close(); await page.close();
}); });
it.fail(options.CHROMIUM() && !options.HEADLESS)('should report new window downloads', async({browser, server}) => { it.fail(options.CHROMIUM && !options.HEADLESS)('should report new window downloads', async({browser, server}) => {
// TODO: - the test fails in headful Chromium as the popup page gets closed along // TODO: - the test fails in headful Chromium as the popup page gets closed along
// with the session before download completed event arrives. // with the session before download completed event arrives.
// - WebKit doesn't close the popup page // - WebKit doesn't close the popup page

View file

@ -26,7 +26,7 @@ import {mkdtempAsync, removeFolderAsync} from './utils';
import { Browser, BrowserContext } from '..'; import { Browser, BrowserContext } from '..';
declare global { declare global {
interface FixtureState { interface TestState {
downloadsBrowser: Browser; downloadsBrowser: Browser;
persistentDownloadsContext: BrowserContext; persistentDownloadsContext: BrowserContext;
} }

View file

@ -21,7 +21,7 @@ import path from 'path';
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron'; const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
it.skip(!options.CHROMIUM())('should fire close event', async ({ playwright }) => { it.skip(!options.CHROMIUM)('should fire close event', async ({ playwright }) => {
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName); const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
const application = await playwright.electron.launch(electronPath, { const application = await playwright.electron.launch(electronPath, {
args: [path.join(__dirname, 'testApp.js')], args: [path.join(__dirname, 'testApp.js')],
@ -36,12 +36,12 @@ it.skip(!options.CHROMIUM())('should fire close event', async ({ playwright }) =
expect(events.join('|')).toBe('context|application'); expect(events.join('|')).toBe('context|application');
}); });
it.skip(!options.CHROMIUM())('should script application', async ({ application }) => { it.skip(!options.CHROMIUM)('should script application', async ({ application }) => {
const appPath = await application.evaluate(async ({ app }) => app.getAppPath()); const appPath = await application.evaluate(async ({ app }) => app.getAppPath());
expect(appPath).toContain('electron'); expect(appPath).toContain('electron');
}); });
it.skip(!options.CHROMIUM())('should create window', async ({ application }) => { it.skip(!options.CHROMIUM)('should create window', async ({ application }) => {
const [ page ] = await Promise.all([ const [ page ] = await Promise.all([
application.waitForEvent('window'), application.waitForEvent('window'),
application.evaluate(({ BrowserWindow }) => { application.evaluate(({ BrowserWindow }) => {
@ -53,13 +53,13 @@ it.skip(!options.CHROMIUM())('should create window', async ({ application }) =>
expect(await page.title()).toBe('Hello World 1'); expect(await page.title()).toBe('Hello World 1');
}); });
it.skip(!options.CHROMIUM())('should create window 2', async ({ application }) => { it.skip(!options.CHROMIUM)('should create window 2', async ({ application }) => {
const page = await application.newBrowserWindow({ width: 800, height: 600 }); const page = await application.newBrowserWindow({ width: 800, height: 600 });
await page.goto('data:text/html,<title>Hello World 2</title>'); await page.goto('data:text/html,<title>Hello World 2</title>');
expect(await page.title()).toBe('Hello World 2'); expect(await page.title()).toBe('Hello World 2');
}); });
it.skip(!options.CHROMIUM())('should create multiple windows', async ({ application }) => { it.skip(!options.CHROMIUM)('should create multiple windows', async ({ application }) => {
const createPage = async ordinal => { const createPage = async ordinal => {
const page = await application.newBrowserWindow({ width: 800, height: 600 }); const page = await application.newBrowserWindow({ width: 800, height: 600 });
await Promise.all([ await Promise.all([
@ -80,7 +80,7 @@ it.skip(!options.CHROMIUM())('should create multiple windows', async ({ applicat
expect(titles).toEqual(['Hello World 2', 'Hello World 3', 'Hello World 4']); expect(titles).toEqual(['Hello World 2', 'Hello World 3', 'Hello World 4']);
}); });
it.skip(!options.CHROMIUM())('should route network', async ({ application }) => { it.skip(!options.CHROMIUM)('should route network', async ({ application }) => {
await application.context().route('**/empty.html', (route, request) => { await application.context().route('**/empty.html', (route, request) => {
route.fulfill({ route.fulfill({
status: 200, status: 200,
@ -93,14 +93,14 @@ it.skip(!options.CHROMIUM())('should route network', async ({ application }) =>
expect(await page.title()).toBe('Hello World'); expect(await page.title()).toBe('Hello World');
}); });
it.skip(!options.CHROMIUM())('should support init script', async ({ application }) => { it.skip(!options.CHROMIUM)('should support init script', async ({ application }) => {
await application.context().addInitScript('window.magic = 42;') await application.context().addInitScript('window.magic = 42;')
const page = await application.newBrowserWindow({ width: 800, height: 600 }); const page = await application.newBrowserWindow({ width: 800, height: 600 });
await page.goto('data:text/html,<script>window.copy = magic</script>'); await page.goto('data:text/html,<script>window.copy = magic</script>');
expect(await page.evaluate(() => window['copy'])).toBe(42); expect(await page.evaluate(() => window['copy'])).toBe(42);
}); });
it.skip(!options.CHROMIUM())('should expose function', async ({ application }) => { it.skip(!options.CHROMIUM)('should expose function', async ({ application }) => {
const t = Date.now(); const t = Date.now();
await application.context().exposeFunction('add', (a, b) => a + b); await application.context().exposeFunction('add', (a, b) => a + b);
const page = await application.newBrowserWindow({ width: 800, height: 600 }); const page = await application.newBrowserWindow({ width: 800, height: 600 });
@ -108,7 +108,7 @@ it.skip(!options.CHROMIUM())('should expose function', async ({ application }) =
expect(await page.evaluate(() => window['result'])).toBe(42); expect(await page.evaluate(() => window['result'])).toBe(42);
}); });
it.skip(!options.CHROMIUM())('should wait for first window', async ({ application }) => { it.skip(!options.CHROMIUM)('should wait for first window', async ({ application }) => {
application.evaluate(({ BrowserWindow }) => { application.evaluate(({ BrowserWindow }) => {
const window = new BrowserWindow({ width: 800, height: 600 }); const window = new BrowserWindow({ width: 800, height: 600 });
window.loadURL('data:text/html,<title>Hello World!</title>'); window.loadURL('data:text/html,<title>Hello World!</title>');
@ -117,7 +117,7 @@ it.skip(!options.CHROMIUM())('should wait for first window', async ({ applicatio
expect(await window.title()).toBe('Hello World!'); expect(await window.title()).toBe('Hello World!');
}); });
it.skip(!options.CHROMIUM())('should have a clipboard instance', async ({ application }) => { it.skip(!options.CHROMIUM)('should have a clipboard instance', async ({ application }) => {
const clipboardContentToWrite = 'Hello from Playwright'; const clipboardContentToWrite = 'Hello from Playwright';
await application.evaluate(async ({clipboard}, text) => clipboard.writeText(text), clipboardContentToWrite); await application.evaluate(async ({clipboard}, text) => clipboard.writeText(text), clipboardContentToWrite);
const clipboardContentRead = await application.evaluate(async ({clipboard}) => clipboard.readText()); const clipboardContentRead = await application.evaluate(async ({clipboard}) => clipboard.readText());

View file

@ -17,25 +17,25 @@
import { options } from '../playwright.fixtures'; import { options } from '../playwright.fixtures';
import './electron.fixture'; import './electron.fixture';
it.skip(!options.CHROMIUM())('should click the button', async({window, server}) => { it.skip(!options.CHROMIUM)('should click the button', async({window, server}) => {
await window.goto(server.PREFIX + '/input/button.html'); await window.goto(server.PREFIX + '/input/button.html');
await window.click('button'); await window.click('button');
expect(await window.evaluate('result')).toBe('Clicked'); expect(await window.evaluate('result')).toBe('Clicked');
}); });
it.skip(!options.CHROMIUM())('should check the box', async({window}) => { it.skip(!options.CHROMIUM)('should check the box', async({window}) => {
await window.setContent(`<input id='checkbox' type='checkbox'></input>`); await window.setContent(`<input id='checkbox' type='checkbox'></input>`);
await window.check('input'); await window.check('input');
expect(await window.evaluate('checkbox.checked')).toBe(true); expect(await window.evaluate('checkbox.checked')).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should not check the checked box', async({window}) => { it.skip(!options.CHROMIUM)('should not check the checked box', async({window}) => {
await window.setContent(`<input id='checkbox' type='checkbox' checked></input>`); await window.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
await window.check('input'); await window.check('input');
expect(await window.evaluate('checkbox.checked')).toBe(true); expect(await window.evaluate('checkbox.checked')).toBe(true);
}); });
it.skip(!options.CHROMIUM())('should type into a textarea', async({window, server}) => { it.skip(!options.CHROMIUM)('should type into a textarea', async({window, server}) => {
await window.evaluate(() => { await window.evaluate(() => {
const textarea = document.createElement('textarea'); const textarea = document.createElement('textarea');
document.body.appendChild(textarea); document.body.appendChild(textarea);

View file

@ -22,7 +22,7 @@ import path from 'path';
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron'; const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
declare global { declare global {
interface FixtureState { interface TestState {
application: ElectronApplication; application: ElectronApplication;
window: ElectronPage; window: ElectronPage;
} }

View file

@ -17,7 +17,7 @@
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.fail(options.FIREFOX() && !options.HEADLESS)('should work', async ({ page, server }) => { it.fail(options.FIREFOX && !options.HEADLESS)('should work', async ({ page, server }) => {
await page.setViewportSize({ width: 500, height: 500 }); await page.setViewportSize({ width: 500, height: 500 });
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const elementHandle = await page.$('.box:nth-of-type(13)'); const elementHandle = await page.$('.box:nth-of-type(13)');
@ -64,7 +64,7 @@ it('should work with SVG nodes', async ({ page, server }) => {
expect(pwBoundingBox).toEqual(webBoundingBox); expect(pwBoundingBox).toEqual(webBoundingBox);
}); });
it.skip(options.FIREFOX())('should work with page scale', async ({ browser, server }) => { it.skip(options.FIREFOX)('should work with page scale', async ({ browser, server }) => {
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');

View file

@ -22,7 +22,7 @@ import path from 'path';
import fs from 'fs'; import fs from 'fs';
// Firefox headful produces a different image. // Firefox headful produces a different image.
const ffheadful = options.FIREFOX() && !options.HEADLESS; const ffheadful = options.FIREFOX && !options.HEADLESS;
it.skip(ffheadful)('should work', async({page, server, golden}) => { it.skip(ffheadful)('should work', async({page, server, golden}) => {
await page.setViewportSize({width: 500, height: 500}); await page.setViewportSize({width: 500, height: 500});
@ -210,7 +210,7 @@ it.skip(ffheadful)('should work for an element with fractional dimensions', asyn
expect(screenshot).toMatchImage(golden('screenshot-element-fractional.png')); expect(screenshot).toMatchImage(golden('screenshot-element-fractional.png'));
}); });
it.skip(options.FIREFOX())('should work with a mobile viewport', async({browser, server, golden}) => { it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true}); const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
@ -221,7 +221,7 @@ it.skip(options.FIREFOX())('should work with a mobile viewport', async({browser,
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should work with device scale factor', async({browser, server, golden}) => { it.skip(options.FIREFOX)('should work with device scale factor', async({browser, server, golden}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 }); const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');

View file

@ -22,7 +22,7 @@ it('should select textarea', async ({ page, server }) => {
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 (options.FIREFOX()) { if (options.FIREFOX) {
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 {
@ -35,7 +35,7 @@ it('should select input', async ({ page, server }) => {
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 (options.FIREFOX()) { if (options.FIREFOX) {
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

@ -101,7 +101,7 @@ it('should change document.activeElement', async({page, server}) => {
expect(active).toEqual(['INPUT', 'TEXTAREA']); expect(active).toEqual(['INPUT', 'TEXTAREA']);
}); });
it.skip(options.FIREFOX() && !options.HEADLESS)('should not affect screenshots', async({page, server, golden}) => { it.skip(options.FIREFOX && !options.HEADLESS)('should not affect screenshots', async({page, server, golden}) => {
// Firefox headful produces a different image. // Firefox headful produces a different image.
const page2 = await page.context().newPage(); const page2 = await page.context().newPage();
await Promise.all([ await Promise.all([

View file

@ -15,7 +15,7 @@
*/ */
import { options } from '../playwright.fixtures'; import { options } from '../playwright.fixtures';
it.skip(!options.FIREFOX())('should pass firefox user preferences', async({browserType, defaultBrowserOptions}) => { it.skip(!options.FIREFOX)('should pass firefox user preferences', async({browserType, defaultBrowserOptions}) => {
const browser = await browserType.launch({ const browser = await browserType.launch({
...defaultBrowserOptions, ...defaultBrowserOptions,
firefoxUserPrefs: { firefoxUserPrefs: {

View file

@ -100,7 +100,7 @@ class Wrapper {
} }
declare global { declare global {
interface FixtureState { interface TestState {
wrapper: Wrapper; wrapper: Wrapper;
stallingWrapper: Wrapper; stallingWrapper: Wrapper;
} }

View file

@ -15,7 +15,7 @@
*/ */
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
it.skip(options.FIREFOX())('should work', async function({page, server}) { it.skip(options.FIREFOX)('should work', async function({page, server}) {
await page.setContent(`<div id=d1 tabIndex=0></div>`); await page.setContent(`<div id=d1 tabIndex=0></div>`);
expect(await page.evaluate(() => document.activeElement.nodeName)).toBe('BODY'); expect(await page.evaluate(() => document.activeElement.nodeName)).toBe('BODY');
await page.focus('#d1'); await page.focus('#d1');
@ -77,7 +77,7 @@ it('should traverse focus in all directions', async function({page}) {
// Chromium and WebKit both have settings for tab traversing all links, but // Chromium and WebKit both have settings for tab traversing all links, but
// it is only on by default in WebKit. // it is only on by default in WebKit.
it.skip(!MAC || !options.WEBKIT())('should traverse only form elements', async function({page}) { it.skip(!MAC || !options.WEBKIT)('should traverse only form elements', async function({page}) {
await page.setContent(` await page.setContent(`
<input id="input-1"> <input id="input-1">
<button id="button">buttton</button> <button id="button">buttton</button>

View file

@ -36,7 +36,7 @@ it('should have correct execution contexts', async ({ page, server }) => {
}); });
function expectContexts(pageImpl, count) { function expectContexts(pageImpl, count) {
if (options.CHROMIUM()) if (options.CHROMIUM)
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);
@ -126,7 +126,7 @@ it('should be isolated between frames', async({page, server}) => {
expect(a2).toBe(2); expect(a2).toBe(2);
}); });
it.fail(options.CHROMIUM() || options.FIREFOX())('should work in iframes that failed initial navigation', async({page, server}) => { it.fail(options.CHROMIUM || options.FIREFOX)('should work in iframes that failed initial navigation', async({page, server}) => {
// - Firefox does not report domcontentloaded for the iframe. // - Firefox does not report domcontentloaded for the iframe.
// - Chromium and Firefox report empty url. // - Chromium and Firefox report empty url.
// - Chromium does not report main/utility worlds for the iframe. // - Chromium does not report main/utility worlds for the iframe.
@ -147,7 +147,7 @@ it.fail(options.CHROMIUM() || options.FIREFOX())('should work in iframes that fa
expect(await page.frames()[1].$('div')).toBeTruthy(); expect(await page.frames()[1].$('div')).toBeTruthy();
}); });
it.fail(options.CHROMIUM())('should work in iframes that interrupted initial javascript url navigation', async({page, server}) => { it.fail(options.CHROMIUM)('should work in iframes that interrupted initial javascript url navigation', async({page, server}) => {
// Chromium does not report isolated world for the iframe. // Chromium does not report isolated world for the iframe.
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => { await page.evaluate(() => {

View file

@ -171,7 +171,7 @@ it('should report different frame instance when frame re-attaches', async({page,
expect(frame1).not.toBe(frame2); expect(frame1).not.toBe(frame2);
}); });
it.fail(options.FIREFOX())('should refuse to display x-frame-options:deny iframe', async({page, server}) => { it.fail(options.FIREFOX)('should refuse to display x-frame-options:deny iframe', async({page, server}) => {
server.setRoute('/x-frame-options-deny.html', async (req, res) => { server.setRoute('/x-frame-options-deny.html', async (req, res) => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Frame-Options', 'DENY'); res.setHeader('X-Frame-Options', 'DENY');

View file

@ -26,7 +26,7 @@ it('should have default url when launching browser', async ({browserType, defaul
await browserContext.close(); await browserContext.close();
}); });
it.fail(WIN && options.CHROMIUM()).slow()('headless should be able to read cookies written by headful', async({browserType, defaultBrowserOptions, server}) => { it.fail(WIN && options.CHROMIUM).slow()('headless should be able to read cookies written by headful', async({browserType, defaultBrowserOptions, server}) => {
// see https://github.com/microsoft/playwright/issues/717 // see https://github.com/microsoft/playwright/issues/717
const userDataDir = await makeUserDataDir(); const userDataDir = await makeUserDataDir();
// Write a cookie in headful chrome // Write a cookie in headful chrome
@ -106,7 +106,7 @@ it('should(not) block third party cookies', async({browserType, defaultBrowserOp
return document.cookie; return document.cookie;
}); });
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
const allowsThirdParty = options.CHROMIUM() || options.FIREFOX(); const allowsThirdParty = options.CHROMIUM || options.FIREFOX;
expect(documentCookie).toBe(allowsThirdParty ? 'username=John Doe' : ''); expect(documentCookie).toBe(allowsThirdParty ? 'username=John Doe' : '');
const cookies = await page.context().cookies(server.CROSS_PROCESS_PREFIX + '/grid.html'); const cookies = await page.context().cookies(server.CROSS_PROCESS_PREFIX + '/grid.html');
if (allowsThirdParty) { if (allowsThirdParty) {
@ -128,7 +128,7 @@ it('should(not) block third party cookies', async({browserType, defaultBrowserOp
await browser.close(); await browser.close();
}); });
it.fail(options.WEBKIT())('should not override viewport size when passed null', async function({browserType, defaultBrowserOptions, server}) { it.fail(options.WEBKIT)('should not override viewport size when passed null', async function({browserType, defaultBrowserOptions, server}) {
// Our WebKit embedder does not respect window features. // Our WebKit embedder does not respect window features.
const browser = await browserType.launch({...defaultBrowserOptions, headless: false }); const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
const context = await browser.newContext({ viewport: null }); const context = await browser.newContext({ viewport: null });

View file

@ -54,6 +54,6 @@ it('should work with different subtypes', async({page}) => {
expect((await page.evaluateHandle('new WeakSet()')).toString()).toBe('JSHandle@weakset'); expect((await page.evaluateHandle('new WeakSet()')).toString()).toBe('JSHandle@weakset');
expect((await page.evaluateHandle('new Error()')).toString()).toBe('JSHandle@error'); expect((await page.evaluateHandle('new Error()')).toString()).toBe('JSHandle@error');
// TODO(yurys): change subtype from array to typedarray in WebKit. // TODO(yurys): change subtype from array to typedarray in WebKit.
expect((await page.evaluateHandle('new Int32Array()')).toString()).toBe(options.WEBKIT() ? 'JSHandle@array' : 'JSHandle@typedarray'); expect((await page.evaluateHandle('new Int32Array()')).toString()).toBe(options.WEBKIT ? 'JSHandle@array' : 'JSHandle@typedarray');
expect((await page.evaluateHandle('new Proxy({}, {})')).toString()).toBe('JSHandle@proxy'); expect((await page.evaluateHandle('new Proxy({}, {})')).toString()).toBe('JSHandle@proxy');
}); });

View file

@ -82,7 +82,7 @@ it('insertText should only emit input event', async ({page, server}) => {
expect(await events.jsonValue()).toEqual(['input']); expect(await events.jsonValue()).toEqual(['input']);
}); });
it.fail(options.FIREFOX() && MAC)('should report shiftKey', async ({page, server}) => { it.fail(options.FIREFOX && MAC)('should report shiftKey', async ({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html'); await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard; const keyboard = page.keyboard;
const codeForKey = {'Shift': 16, 'Alt': 18, 'Control': 17}; const codeForKey = {'Shift': 16, 'Alt': 18, 'Control': 17};
@ -353,17 +353,17 @@ it('should press the meta key', async ({page}) => {
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 (options.FIREFOX() && !MAC) if (options.FIREFOX && !MAC)
expect(key).toBe('OS'); expect(key).toBe('OS');
else else
expect(key).toBe('Meta'); expect(key).toBe('Meta');
if (options.FIREFOX()) if (options.FIREFOX)
expect(code).toBe('OSLeft'); expect(code).toBe('OSLeft');
else else
expect(code).toBe('MetaLeft'); expect(code).toBe('MetaLeft');
if (options.FIREFOX() && !MAC) if (options.FIREFOX && !MAC)
expect(metaKey).toBe(false); expect(metaKey).toBe(false);
else else
expect(metaKey).toBe(true); expect(metaKey).toBe(true);
@ -379,7 +379,7 @@ it('should work after a cross origin navigation', async ({page, server}) => {
}); });
// event.keyIdentifier has been removed from all browsers except WebKit // event.keyIdentifier has been removed from all browsers except WebKit
it.skip(!options.WEBKIT())('should expose keyIdentifier in webkit', async ({page, server}) => { it.skip(!options.WEBKIT)('should expose keyIdentifier in webkit', async ({page, server}) => {
const lastEvent = await captureLastKeydown(page); const lastEvent = await captureLastKeydown(page);
const keyMap = { const keyMap = {
'ArrowUp': 'Up', 'ArrowUp': 'Up',

View file

@ -27,8 +27,8 @@ function dimensions() {
}; };
} }
it.fail(options.FIREFOX() && WIN)('should click the document', async({page, server}) => { it.fail(options.FIREFOX && WIN)('should click the document', async({page, server}) => {
// Occasionally times out on options.FIREFOX() on Windows: https://github.com/microsoft/playwright/pull/1911/checks?check_run_id=607149016 // Occasionally times out on options.FIREFOX on Windows: https://github.com/microsoft/playwright/pull/1911/checks?check_run_id=607149016
await page.evaluate(() => { await page.evaluate(() => {
window["clickPromise"] = new Promise(resolve => { window["clickPromise"] = new Promise(resolve => {
document.addEventListener('click', event => { document.addEventListener('click', event => {
@ -127,7 +127,7 @@ it('should set modifier keys on click', async({page, server}) => {
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 (options.FIREFOX() && !MAC) if (options.FIREFOX && !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);
@ -145,7 +145,7 @@ it('should set modifier keys on click', async({page, server}) => {
it('should tween mouse movement', async({page}) => { it('should tween mouse movement', async({page}) => {
// The test becomes flaky on WebKit without next line. // The test becomes flaky on WebKit without next line.
if (options.WEBKIT()) if (options.WEBKIT)
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(() => {
@ -164,7 +164,7 @@ it('should tween mouse movement', async({page}) => {
]); ]);
}); });
it.skip(options.FIREFOX())('should work with mobile viewports and cross process navigations', async({browser, server}) => { it.skip(options.FIREFOX)('should work with mobile viewports and cross process navigations', async({browser, server}) => {
// @see https://crbug.com/929806 // @see https://crbug.com/929806
const context = await browser.newContext({ viewport: {width: 360, height: 640}, isMobile: true }); const context = await browser.newContext({ viewport: {width: 360, height: 640}, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();

View file

@ -47,15 +47,15 @@ it('should work for fetch requests', async({page, server}) => {
it('should return headers', async({page, server}) => { it('should return headers', async({page, server}) => {
const response = await page.goto(server.EMPTY_PAGE); const response = await page.goto(server.EMPTY_PAGE);
if (options.CHROMIUM()) if (options.CHROMIUM)
expect(response.request().headers()['user-agent']).toContain('Chrome'); expect(response.request().headers()['user-agent']).toContain('Chrome');
else if (options.FIREFOX()) else if (options.FIREFOX)
expect(response.request().headers()['user-agent']).toContain('Firefox'); expect(response.request().headers()['user-agent']).toContain('Firefox');
else if (options.WEBKIT()) else if (options.WEBKIT)
expect(response.request().headers()['user-agent']).toContain('WebKit'); expect(response.request().headers()['user-agent']).toContain('WebKit');
}); });
it.fail(options.CHROMIUM()||options.WEBKIT())('should get the same headers as the server', async({page, server}) => { it.fail(options.CHROMIUM||options.WEBKIT)('should get the same headers as the server', async({page, server}) => {
await page.goto(server.PREFIX + '/empty.html'); await page.goto(server.PREFIX + '/empty.html');
let serverRequest; let serverRequest;
server.setRoute('/something', (request, response) => { server.setRoute('/something', (request, response) => {

View file

@ -74,7 +74,7 @@ it('should work with a path', async({page, server}) => {
expect(await page.evaluate(() => window['__injected'])).toBe(42); expect(await page.evaluate(() => window['__injected'])).toBe(42);
}); });
it.skip(options.WEBKIT())('should include sourceURL when path is provided', async({page, server}) => { it.skip(options.WEBKIT)('should include sourceURL when path is provided', async({page, server}) => {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') }); await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
const result = await page.evaluate(() => window['__injectedError'].stack); const result = await page.evaluate(() => window['__injectedError'].stack);
@ -88,7 +88,7 @@ it('should work with content', async({page, server}) => {
expect(await page.evaluate(() => window['__injected'])).toBe(35); expect(await page.evaluate(() => window['__injected'])).toBe(35);
}); });
it.fail(options.FIREFOX())('should throw when added with content to the CSP page', async({page, server}) => { it.fail(options.FIREFOX)('should throw when added with content to the CSP page', async({page, server}) => {
// Firefox fires onload for blocked script before it issues the CSP console error. // Firefox fires onload for blocked script before it issues the CSP console error.
await page.goto(server.PREFIX + '/csp.html'); await page.goto(server.PREFIX + '/csp.html');
let error = null; let error = null;

View file

@ -44,9 +44,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 (options.CHROMIUM()) if (options.CHROMIUM)
expect(dialog.message()).toBe(''); expect(dialog.message()).toBe('');
else if (options.WEBKIT()) else if (options.WEBKIT)
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.');
@ -211,7 +211,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 (options.FIREFOX()) { if (options.FIREFOX) {
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);
@ -219,13 +219,13 @@ it('should have sane user agent', async ({page}) => {
expect(part5).toBe(undefined); expect(part5).toBe(undefined);
return; return;
} }
// For both options.CHROMIUM() and options.WEBKIT(), third part is the AppleWebKit version. // For both options.CHROMIUM and options.WEBKIT, third part is the AppleWebKit version.
expect(part3.startsWith('AppleWebKit/')).toBe(true); expect(part3.startsWith('AppleWebKit/')).toBe(true);
expect(part4).toBe('KHTML, like Gecko'); expect(part4).toBe('KHTML, like Gecko');
// 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 (options.CHROMIUM()) if (options.CHROMIUM)
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);
@ -244,7 +244,7 @@ it('frame.press should work', async({page, server}) => {
expect(await frame.evaluate(() => document.querySelector('textarea').value)).toBe('a'); expect(await frame.evaluate(() => document.querySelector('textarea').value)).toBe('a');
}); });
it.fail(options.FIREFOX())('frame.focus should work multiple times', async ({ context, server }) => { it.fail(options.FIREFOX)('frame.focus should work multiple times', async ({ context, server }) => {
const page1 = await context.newPage() const page1 = await context.newPage()
const page2 = await context.newPage() const page2 = await context.newPage()
for (const page of [page1, page2]) { for (const page of [page1, page2]) {

View file

@ -114,7 +114,7 @@ it('should work in cross-process iframe', async({browser, server}) => {
await page.close(); await page.close();
}); });
it.fail(options.FIREFOX())('should change the actual colors in css', async({page}) => { it.fail(options.FIREFOX)('should change the actual colors in css', async({page}) => {
await page.setContent(` await page.setContent(`
<style> <style>
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {

View file

@ -415,7 +415,7 @@ it('should not throw an error when evaluation does a navigation', async ({ page,
expect(result).toEqual([42]); expect(result).toEqual([42]);
}); });
it.fail(options.WEBKIT())('should not throw an error when evaluation does a synchronous navigation and returns an object', async ({ page, server }) => { it.fail(options.WEBKIT)('should not throw an error when evaluation does a synchronous navigation and returns an object', async ({ page, server }) => {
// It is imporant to be on about:blank for sync reload. // It is imporant to be on about:blank for sync reload.
const result = await page.evaluate(() => { const result = await page.evaluate(() => {
window.location.reload(); window.location.reload();
@ -453,7 +453,7 @@ it('should work even when JSON is set to null', async ({ page }) => {
expect(result).toEqual({ abc: 123 }); expect(result).toEqual({ abc: 123 });
}); });
it.fail(options.FIREFOX())('should await promise from popup', async ({ page, server }) => { it.fail(options.FIREFOX)('should await promise from popup', async ({ page, server }) => {
// Something is wrong about the way Firefox waits for the chained promise // Something is wrong about the way Firefox waits for the chained promise
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const result = await page.evaluate(() => { const result = await page.evaluate(() => {

View file

@ -17,7 +17,7 @@
import { options } from './playwright.fixtures'; import { options } from './playwright.fixtures';
const CRASH_FAIL = (options.FIREFOX() && WIN) || options.WIRE; const CRASH_FAIL = (options.FIREFOX && WIN) || options.WIRE;
// Firefox Win: it just doesn't crash sometimes. // Firefox Win: it just doesn't crash sometimes.
function crash(pageImpl, browserName) { function crash(pageImpl, browserName) {
if (browserName === 'chromium') if (browserName === 'chromium')

View file

@ -53,9 +53,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 (options.CHROMIUM()) { if (options.CHROMIUM) {
expect(failedRequests[0].failure().errorText).toBe('net::ERR_EMPTY_RESPONSE'); expect(failedRequests[0].failure().errorText).toBe('net::ERR_EMPTY_RESPONSE');
} else if (options.WEBKIT()) { } else if (options.WEBKIT) {
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

@ -26,12 +26,12 @@ 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 (options.WEBKIT()) if (options.WEBKIT)
stack = stack.replace('14:25', '15:19'); stack = stack.replace('14:25', '15:19');
expect(error.stack).toBe(stack); expect(error.stack).toBe(stack);
}); });
it.fail(options.WEBKIT())('should contain sourceURL', async({page, server}) => { it.fail(options.WEBKIT)('should contain sourceURL', async({page, server}) => {
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'),
@ -51,24 +51,24 @@ it('should handle odd values', async ({page}) => {
page.waitForEvent('pageerror'), page.waitForEvent('pageerror'),
page.evaluate(value => setTimeout(() => { throw value; }, 0), value), page.evaluate(value => setTimeout(() => { throw value; }, 0), value),
]); ]);
expect(error.message).toBe(options.FIREFOX() ? 'uncaught exception: ' + message : message); expect(error.message).toBe(options.FIREFOX ? 'uncaught exception: ' + message : message);
} }
}); });
it.fail(options.FIREFOX())('should handle object', async ({page}) => { it.fail(options.FIREFOX)('should handle object', async ({page}) => {
// Firefox just does not report this error. // Firefox just does not report this error.
const [error] = await Promise.all([ const [error] = await Promise.all([
page.waitForEvent('pageerror'), page.waitForEvent('pageerror'),
page.evaluate(() => setTimeout(() => { throw {}; }, 0)), page.evaluate(() => setTimeout(() => { throw {}; }, 0)),
]); ]);
expect(error.message).toBe(options.CHROMIUM() ? 'Object' : '[object Object]'); expect(error.message).toBe(options.CHROMIUM ? 'Object' : '[object Object]');
}); });
it.fail(options.FIREFOX())('should handle window', async ({page}) => { it.fail(options.FIREFOX)('should handle window', async ({page}) => {
// Firefox just does not report this error. // Firefox just does not report this error.
const [error] = await Promise.all([ const [error] = await Promise.all([
page.waitForEvent('pageerror'), page.waitForEvent('pageerror'),
page.evaluate(() => setTimeout(() => { throw window; }, 0)), page.evaluate(() => setTimeout(() => { throw window; }, 0)),
]); ]);
expect(error.message).toBe(options.CHROMIUM() ? 'Window' : '[object Window]'); expect(error.message).toBe(options.CHROMIUM ? 'Window' : '[object Window]');
}); });

View file

@ -60,7 +60,7 @@ it('should fill date input after clicking', async({page, server}) => {
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02'); expect(await page.$eval('input', input => input.value)).toBe('2020-03-02');
}); });
it.skip(options.WEBKIT())('should throw on incorrect date', async({page, server}) => { it.skip(options.WEBKIT)('should throw on incorrect date', async({page, server}) => {
await page.setContent('<input type=date>'); await page.setContent('<input type=date>');
const error = await page.fill('input', '2020-13-05').catch(e => e); const error = await page.fill('input', '2020-13-05').catch(e => e);
expect(error.message).toContain('Malformed value'); expect(error.message).toContain('Malformed value');
@ -72,7 +72,7 @@ it('should fill time input', async({page, server}) => {
expect(await page.$eval('input', input => input.value)).toBe('13:15'); expect(await page.$eval('input', input => input.value)).toBe('13:15');
}); });
it.skip(options.WEBKIT())('should throw on incorrect time', async({page, server}) => { it.skip(options.WEBKIT)('should throw on incorrect time', async({page, server}) => {
await page.setContent('<input type=time>'); await page.setContent('<input type=time>');
const error = await page.fill('input', '25:05').catch(e => e); const error = await page.fill('input', '25:05').catch(e => e);
expect(error.message).toContain('Malformed value'); expect(error.message).toContain('Malformed value');
@ -84,7 +84,7 @@ it('should fill datetime-local input', async({page, server}) => {
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02T05:15'); expect(await page.$eval('input', input => input.value)).toBe('2020-03-02T05:15');
}); });
it.skip(options.WEBKIT() || options.FIREFOX())('should throw on incorrect datetime-local', async({page, server}) => { it.skip(options.WEBKIT || options.FIREFOX)('should throw on incorrect datetime-local', async({page, server}) => {
await page.setContent('<input type=datetime-local>'); await page.setContent('<input type=datetime-local>');
const error = await page.fill('input', 'abc').catch(e => e); const error = await page.fill('input', 'abc').catch(e => e);
expect(error.message).toContain('Malformed value'); expect(error.message).toContain('Malformed value');

View file

@ -143,9 +143,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 (options.CHROMIUM()) if (options.CHROMIUM)
expect(error.message).toContain('net::ERR_ABORTED'); expect(error.message).toContain('net::ERR_ABORTED');
else if (options.WEBKIT()) else if (options.WEBKIT)
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');
@ -168,7 +168,7 @@ it('should work when page calls history API in beforeunload', async({page, serve
it('should fail when navigating to bad url', async({page}) => { it('should fail when navigating to bad url', async({page}) => {
let error = null; let error = null;
await page.goto('asdfasdf').catch(e => error = e); await page.goto('asdfasdf').catch(e => error = e);
if (options.CHROMIUM() || options.WEBKIT()) if (options.CHROMIUM || options.WEBKIT)
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');
@ -212,11 +212,11 @@ it('should throw if networkidle2 is passed as an option', async({page, server})
it('should fail when main resources failed to load', async({page}) => { it('should fail when main resources failed to load', async({page}) => {
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 (options.CHROMIUM()) if (options.CHROMIUM)
expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); expect(error.message).toContain('net::ERR_CONNECTION_REFUSED');
else if (options.WEBKIT() && WIN) else if (options.WEBKIT && WIN)
expect(error.message).toContain(`Couldn\'t connect to server`); expect(error.message).toContain(`Couldn\'t connect to server`);
else if (options.WEBKIT()) else if (options.WEBKIT)
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');
@ -307,9 +307,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 (options.CHROMIUM()) if (options.CHROMIUM)
expect(error.message).toContain('net::ERR_ABORTED'); expect(error.message).toContain('net::ERR_ABORTED');
else if (options.WEBKIT()) else if (options.WEBKIT)
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

@ -52,7 +52,7 @@ it('page.goBack should work with HistoryAPI', async({page, server}) => {
expect(page.url()).toBe(server.PREFIX + '/first.html'); expect(page.url()).toBe(server.PREFIX + '/first.html');
}); });
it.fail(options.WEBKIT() && MAC)('page.goBack should work for file urls', async ({page, server, asset}) => { it.fail(options.WEBKIT && MAC)('page.goBack should work for file urls', async ({page, server, asset}) => {
// WebKit embedder fails to go back/forward to the file url. // WebKit embedder fails to go back/forward to the file url.
const url1 = url.pathToFileURL(asset('empty.html')).href; const url1 = url.pathToFileURL(asset('empty.html')).href;
const url2 = server.EMPTY_PAGE; const url2 = server.EMPTY_PAGE;

View file

@ -189,9 +189,9 @@ it('should be abortable with custom error codes', async({page, server}) => {
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 (options.WEBKIT()) if (options.WEBKIT)
expect(failedRequest.failure().errorText).toBe('Request intercepted'); expect(failedRequest.failure().errorText).toBe('Request intercepted');
else if (options.FIREFOX()) else if (options.FIREFOX)
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');
@ -214,9 +214,9 @@ it('should fail navigation when aborting main resource', 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).toBeTruthy(); expect(error).toBeTruthy();
if (options.WEBKIT()) if (options.WEBKIT)
expect(error.message).toContain('Request intercepted'); expect(error.message).toContain('Request intercepted');
else if (options.FIREFOX()) else if (options.FIREFOX)
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,7 +21,7 @@ import path from 'path';
import fs from 'fs'; import fs from 'fs';
// Firefox headful produces a different image. // Firefox headful produces a different image.
const ffheadful = options.FIREFOX() && !options.HEADLESS; const ffheadful = options.FIREFOX && !options.HEADLESS;
it.skip(ffheadful)('should work', async({page, server, golden}) => { it.skip(ffheadful)('should work', async({page, server, golden}) => {
await page.setViewportSize({width: 500, height: 500}); await page.setViewportSize({width: 500, height: 500});
@ -139,7 +139,7 @@ it.skip(ffheadful)('should run in parallel in multiple pages', async({server, co
await Promise.all(pages.map(page => page.close())); await Promise.all(pages.map(page => page.close()));
}); });
it.fail(options.FIREFOX())('should allow transparency', async({page, golden}) => { it.fail(options.FIREFOX)('should allow transparency', async({page, golden}) => {
await page.setViewportSize({ width: 50, height: 150 }); await page.setViewportSize({ width: 50, height: 150 });
await page.setContent(` await page.setContent(`
<style> <style>
@ -173,7 +173,7 @@ it.skip(ffheadful)('should work with odd clip size on Retina displays', async({p
expect(screenshot).toMatchImage(golden('screenshot-clip-odd-size.png')); expect(screenshot).toMatchImage(golden('screenshot-clip-odd-size.png'));
}); });
it.skip(options.FIREFOX())('should work with a mobile viewport', async({browser, server, golden}) => { it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true }); const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/overflow.html'); await page.goto(server.PREFIX + '/overflow.html');
@ -182,7 +182,7 @@ it.skip(options.FIREFOX())('should work with a mobile viewport', async({browser,
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should work with a mobile viewport and clip', async({browser, server, golden}) => { it.skip(options.FIREFOX)('should work with a mobile viewport and clip', async({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true}); const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/overflow.html'); await page.goto(server.PREFIX + '/overflow.html');
@ -191,7 +191,7 @@ it.skip(options.FIREFOX())('should work with a mobile viewport and clip', async(
await context.close(); await context.close();
}); });
it.skip(options.FIREFOX())('should work with a mobile viewport and fullPage', async({browser, server, golden}) => { it.skip(options.FIREFOX)('should work with a mobile viewport and fullPage', async({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true}); const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/overflow-large.html'); await page.goto(server.PREFIX + '/overflow-large.html');
@ -214,7 +214,7 @@ it.skip(ffheadful)('should work for translateZ', async({page, server, golden}) =
expect(screenshot).toMatchImage(golden('screenshot-translateZ.png')); expect(screenshot).toMatchImage(golden('screenshot-translateZ.png'));
}); });
it.fail(options.FIREFOX() || options.WEBKIT())('should work for webgl', async({page, server, golden}) => { it.fail(options.FIREFOX || options.WEBKIT)('should work for webgl', async({page, server, golden}) => {
await page.setViewportSize({width: 640, height: 480}); await page.setViewportSize({width: 640, height: 480});
await page.goto(server.PREFIX + '/screenshots/webgl.html'); await page.goto(server.PREFIX + '/screenshots/webgl.html');
const screenshot = await page.screenshot(); const screenshot = await page.screenshot();

View file

@ -77,8 +77,8 @@ it('should wait for load state of empty url popup', async({browser, page}) => {
}), }),
]); ]);
await popup.waitForLoadState(); await popup.waitForLoadState();
expect(readyState).toBe(options.FIREFOX() ? 'uninitialized' : 'complete'); expect(readyState).toBe(options.FIREFOX ? 'uninitialized' : 'complete');
expect(await popup.evaluate(() => document.readyState)).toBe(options.FIREFOX() ? 'uninitialized' : 'complete'); expect(await popup.evaluate(() => document.readyState)).toBe(options.FIREFOX ? 'uninitialized' : 'complete');
}); });
it('should wait for load state of about:blank popup ', async({browser, page}) => { it('should wait for load state of about:blank popup ', async({browser, page}) => {

View file

@ -141,7 +141,7 @@ it('should work with DOM history.back()/history.forward()', async({page, server}
expect(page.url()).toBe(server.PREFIX + '/second.html'); expect(page.url()).toBe(server.PREFIX + '/second.html');
}); });
it.fail(options.FIREFOX())('should work when subframe issues window.stop()', async({page, server}) => { it.fail(options.FIREFOX)('should work when subframe issues window.stop()', async({page, server}) => {
server.setRoute('/frames/style.css', (req, res) => {}); server.setRoute('/frames/style.css', (req, res) => {});
const navigationPromise = page.goto(server.PREFIX + '/frames/one-frame.html'); const navigationPromise = page.goto(server.PREFIX + '/frames/one-frame.html');
const frame = await new Promise<Frame>(f => page.once('frameattached', f)); const frame = await new Promise<Frame>(f => page.once('frameattached', f));

View file

@ -21,13 +21,13 @@ import path from 'path'
// Printing to pdf is currently only supported in headless chromium. // Printing to pdf is currently only supported in headless chromium.
it.skip(!(options.HEADLESS && options.CHROMIUM()))('should be able to save file', async({page, tmpDir}) => { it.skip(!(options.HEADLESS && options.CHROMIUM))('should be able to save file', async({page, tmpDir}) => {
const outputFile = path.join(tmpDir, 'output.pdf'); const outputFile = path.join(tmpDir, 'output.pdf');
await page.pdf({path: outputFile}); await page.pdf({path: outputFile});
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0); expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
fs.unlinkSync(outputFile); fs.unlinkSync(outputFile);
}); });
it.skip(options.CHROMIUM())('should be able to save file', async({page}) => { it.skip(options.CHROMIUM)('should be able to save file', async({page}) => {
expect(page.pdf).toBe(undefined); expect(page.pdf).toBe(undefined);
}); });

View file

@ -20,7 +20,7 @@ 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);
} }
describe.skip(options.WEBKIT())('permissions', () => { describe.skip(options.WEBKIT)('permissions', () => {
it('should be prompt by default', async({page, server, context}) => { 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) // 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); await page.goto(server.EMPTY_PAGE);
@ -91,7 +91,7 @@ describe.skip(options.WEBKIT())('permissions', () => {
expect(await getPermission(page, 'geolocation')).toBe('prompt'); expect(await getPermission(page, 'geolocation')).toBe('prompt');
}); });
it.fail(options.WEBKIT() || options.FIREFOX() || (options.CHROMIUM() && !options.HEADLESS))('should trigger permission onchange', async({page, server, context}) => { it.fail(options.WEBKIT || options.FIREFOX || (options.CHROMIUM && !options.HEADLESS))('should trigger permission onchange', async({page, server, context}) => {
//TODO: flaky //TODO: flaky
// - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883 // - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883
// - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536 // - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536
@ -133,7 +133,7 @@ describe.skip(options.WEBKIT())('permissions', () => {
await otherContext.close(); await otherContext.close();
}); });
it.fail(options.WEBKIT() || options.FIREFOX() || (options.CHROMIUM() && !options.HEADLESS))('should support clipboard read', async({page, server, context, browser}) => { it.fail(options.WEBKIT || options.FIREFOX || (options.CHROMIUM && !options.HEADLESS))('should support clipboard read', async({page, server, context, browser}) => {
// No such permissions (requires flag) in Firefox // No such permissions (requires flag) in Firefox
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'clipboard-read')).toBe('prompt'); expect(await getPermission(page, 'clipboard-read')).toBe('prompt');

View file

@ -24,7 +24,7 @@ import { Connection } from '../lib/rpc/client/connection';
import { Transport } from '../lib/rpc/transport'; import { Transport } from '../lib/rpc/transport';
import { setUnderTest } from '../lib/helper'; import { setUnderTest } from '../lib/helper';
import { installCoverageHooks } from './coverage'; import { installCoverageHooks } from './coverage';
import { parameters, registerFixture, registerWorkerFixture, registerParameter } from './runner'; import { parameters, registerFixture, registerWorkerFixture } from './runner';
import {mkdtempAsync, removeFolderAsync} from './utils'; import {mkdtempAsync, removeFolderAsync} from './utils';
@ -39,10 +39,9 @@ declare global {
golden: (path: string) => string; golden: (path: string) => string;
playwright: typeof import('../index'); playwright: typeof import('../index');
browserType: BrowserType<Browser>; browserType: BrowserType<Browser>;
browserName: string;
browser: Browser; browser: Browser;
} }
interface FixtureState { interface TestState {
toImpl: (rpcObject: any) => any; toImpl: (rpcObject: any) => any;
context: BrowserContext; context: BrowserContext;
server: TestServer; server: TestServer;
@ -52,6 +51,9 @@ declare global {
} }
interface FixtureParameters { interface FixtureParameters {
browserName: string; browserName: string;
headless: boolean;
wire: boolean;
slowMo: boolean;
} }
} }
@ -88,22 +90,22 @@ const getExecutablePath = (browserName) => {
return process.env.WKPATH; return process.env.WKPATH;
} }
registerWorkerFixture('defaultBrowserOptions', async({browserName}, test) => { registerWorkerFixture('defaultBrowserOptions', async({browserName, headless, slowMo}, test) => {
let executablePath = getExecutablePath(browserName); let executablePath = getExecutablePath(browserName);
if (executablePath) if (executablePath)
console.error(`Using executable at ${executablePath}`); console.error(`Using executable at ${executablePath}`);
await test({ await test({
handleSIGINT: false, handleSIGINT: false,
slowMo: valueFromEnv('SLOW_MO', 0), slowMo,
headless: options.HEADLESS, headless,
executablePath executablePath
}); });
}); });
registerWorkerFixture('playwright', async({browserName}, test) => { registerWorkerFixture('playwright', async({browserName, wire}, test) => {
const {coverage, uninstall} = installCoverageHooks(browserName); const {coverage, uninstall} = installCoverageHooks(browserName);
if (options.WIRE) { if (wire) {
const connection = new Connection(); const connection = new Connection();
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'rpc', 'server'), [], { const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'rpc', 'server'), [], {
stdio: 'pipe', stdio: 'pipe',
@ -148,6 +150,10 @@ registerWorkerFixture('browserType', async ({playwright, browserName}, test) =>
await test(browserType); await test(browserType);
}); });
registerWorkerFixture('browserName', async ({}, test) => {
await test('chromium');
});
registerWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => { registerWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => {
const browser = await browserType.launch(defaultBrowserOptions); const browser = await browserType.launch(defaultBrowserOptions);
await test(browser); await test(browser);
@ -193,22 +199,10 @@ registerWorkerFixture('golden', async ({browserName}, test) => {
await test(p => path.join(browserName, p)); await test(p => path.join(browserName, p));
}); });
registerParameter('browserName', () => {
if (process.env.BROWSER)
return [process.env.BROWSER];
return ['chromium', 'webkit', 'firefox'];
});
export const options = { export const options = {
CHROMIUM: () => parameters.browserName === 'chromium', CHROMIUM: parameters.browserName === 'chromium',
FIREFOX: () => parameters.browserName === 'firefox', FIREFOX: parameters.browserName === 'firefox',
WEBKIT: () => parameters.browserName === 'webkit', WEBKIT: parameters.browserName === 'webkit',
HEADLESS : !!valueFromEnv('HEADLESS', true), HEADLESS : parameters.headless,
WIRE: !!process.env.PWWIRE, WIRE: parameters.wire,
}
function valueFromEnv(name, defaultValue) {
if (!(name in process.env))
return defaultValue;
return JSON.parse(process.env[name]);
} }

View file

@ -232,7 +232,7 @@ it('should not dispatch binding on a closed page', async function({browser, serv
}), }),
]); ]);
await context.close(); await context.close();
if (options.FIREFOX()) if (options.FIREFOX)
expect(messages.join('|')).toBe('alreadyclosed'); expect(messages.join('|')).toBe('alreadyclosed');
else else
expect(messages.join('|')).toBe('binding|close'); expect(messages.join('|')).toBe('binding|close');

View file

@ -56,7 +56,7 @@ it('should authenticate', async ({browserType, defaultBrowserOptions, server}) =
await browser.close(); await browser.close();
}); });
it.fail(options.CHROMIUM() && !options.HEADLESS)('should exclude patterns', async ({browserType, defaultBrowserOptions, server}) => { it.fail(options.CHROMIUM && !options.HEADLESS)('should exclude patterns', async ({browserType, defaultBrowserOptions, server}) => {
// Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame. // Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.
server.setRoute('/target.html', async (req, res) => { server.setRoute('/target.html', async (req, res) => {
res.end('<html><title>Served by the proxy</title></html>'); res.end('<html><title>Served by the proxy</title></html>');

View file

@ -50,7 +50,7 @@ it('should work with status code 422', async({page, server}) => {
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!'); expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
}); });
it.skip(options.FIREFOX() && !options.HEADLESS)('should allow mocking binary responses', async({page, server, golden}) => { it.skip(options.FIREFOX && !options.HEADLESS)('should allow mocking binary responses', async({page, server, golden}) => {
// Firefox headful produces a different image. // Firefox headful produces a different image.
await page.route('**/*', route => { await page.route('**/*', route => {
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png')); const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
@ -69,7 +69,7 @@ it.skip(options.FIREFOX() && !options.HEADLESS)('should allow mocking binary res
expect(await img.screenshot()).toMatchImage(golden('mock-binary-response.png')); expect(await img.screenshot()).toMatchImage(golden('mock-binary-response.png'));
}); });
it.skip(options.FIREFOX() && !options.HEADLESS)('should allow mocking svg with charset', async({page, server, golden}) => { it.skip(options.FIREFOX && !options.HEADLESS)('should allow mocking svg with charset', async({page, server, golden}) => {
// Firefox headful produces a different image. // Firefox headful produces a different image.
await page.route('**/*', route => { await page.route('**/*', route => {
route.fulfill({ route.fulfill({

View file

@ -17,9 +17,18 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const program = require('commander'); const program = require('commander');
const { installTransform } = require('./transform');
const { Runner } = require('./runner'); const { Runner } = require('./runner');
const { TestCollector } = require('./testCollector'); const { TestCollector } = require('./testCollector');
let beforeFunction;
let afterFunction;
let matrix = {};
global.before = (fn => beforeFunction = fn);
global.after = (fn => afterFunction = fn);
global.matrix = (m => matrix = m);
program program
.version('Version ' + require('../../package.json').version) .version('Version ' + require('../../package.json').version)
.option('--forbid-only', 'Fail if exclusive test(s) encountered', false) .option('--forbid-only', 'Fail if exclusive test(s) encountered', false)
@ -37,7 +46,22 @@ program
const testDir = path.join(process.cwd(), command.args[0]); const testDir = path.join(process.cwd(), command.args[0]);
const files = collectFiles(testDir, '', command.args.slice(1)); const files = collectFiles(testDir, '', command.args.slice(1));
const testCollector = new TestCollector(files, { const revertBabelRequire = installTransform();
let hasSetup = false;
try {
hasSetup = fs.statSync(path.join(testDir, 'setup.js')).isFile();
} catch (e) {
}
try {
hasSetup = hasSetup || fs.statSync(path.join(testDir, 'setup.ts')).isFile();
} catch (e) {
}
if (hasSetup)
require(path.join(testDir, 'setup'));
revertBabelRequire();
const testCollector = new TestCollector(files, matrix, {
forbidOnly: command.forbidOnly || undefined, forbidOnly: command.forbidOnly || undefined,
grep: command.grep, grep: command.grep,
timeout: command.timeout, timeout: command.timeout,
@ -74,8 +98,15 @@ program
trialRun: command.trialRun, trialRun: command.trialRun,
updateSnapshots: command.updateSnapshots updateSnapshots: command.updateSnapshots
}); });
await runner.run(files); try {
await runner.stop(); if (beforeFunction)
await beforeFunction();
await runner.run(files);
await runner.stop();
} finally {
if (afterFunction)
await afterFunction();
}
process.exit(runner.stats.failures ? 1 : 0); process.exit(runner.stats.failures ? 1 : 0);
}); });

View file

@ -22,7 +22,9 @@ let parameters = {};
const parameterRegistrations = new Map(); const parameterRegistrations = new Map();
function setParameters(params) { function setParameters(params) {
parameters = Object.assign(parameters, params) parameters = Object.assign(parameters, params);
for (const name of Object.keys(params))
registerWorkerFixture(name, async ({}, test) => await test(parameters[name]));
} }
class Fixture { class Fixture {
@ -139,7 +141,10 @@ function fixturesForCallback(callback) {
if (name in names) if (name in names)
continue; continue;
names.add(name); names.add(name);
const { fn } = registrations.get(name) if (!registrations.has(name)) {
throw new Error('Using undefined fixture ' + name);
}
const { fn } = registrations.get(name);
visit(fn); visit(fn);
} }
}; };

View file

@ -16,13 +16,16 @@
const path = require('path'); const path = require('path');
const Mocha = require('mocha'); const Mocha = require('mocha');
const { fixturesForCallback, parameterRegistrations } = require('./fixtures'); const { fixturesForCallback, registerWorkerFixture } = require('./fixtures');
const { fixturesUI } = require('./fixturesUI'); const { fixturesUI } = require('./fixturesUI');
class NullReporter {} class NullReporter {}
class TestCollector { class TestCollector {
constructor(files, options) { constructor(files, matrix, options) {
this._matrix = matrix;
for (const name of Object.keys(matrix))
registerWorkerFixture(name, async ({}, test) => test());
this._options = options; this._options = options;
this.suite = new Mocha.Suite('', new Mocha.Context(), true); this.suite = new Mocha.Suite('', new Mocha.Context(), true);
this._total = 0; this._total = 0;
@ -69,9 +72,9 @@ class TestCollector {
// to build different workers for them. // to build different workers for them.
const generatorConfigurations = []; const generatorConfigurations = [];
for (const name of fixtures) { for (const name of fixtures) {
if (!parameterRegistrations.has(name)) const values = this._matrix[name];
if (!values)
continue; continue;
const values = parameterRegistrations.get(name)();
let state = generatorConfigurations.length ? generatorConfigurations.slice() : [[]]; let state = generatorConfigurations.length ? generatorConfigurations.slice() : [[]];
generatorConfigurations.length = 0; generatorConfigurations.length = 0;
for (const gen of state) { for (const gen of state) {

View file

@ -16,7 +16,7 @@
const path = require('path'); const path = require('path');
const Mocha = require('mocha'); const Mocha = require('mocha');
const { FixturePool, rerunRegistrations, setParameters } = require('./fixtures'); const { FixturePool, registerWorkerFixture, rerunRegistrations, setParameters } = require('./fixtures');
const { fixturesUI } = require('./fixturesUI'); const { fixturesUI } = require('./fixturesUI');
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
@ -51,8 +51,10 @@ class TestRunner extends EventEmitter {
this._configurationObject = entry.configurationObject; this._configurationObject = entry.configurationObject;
this._configurationString = entry.configurationString; this._configurationString = entry.configurationString;
this._parsedGeneratorConfiguration = {}; this._parsedGeneratorConfiguration = {};
for (const {name, value} of this._configurationObject) for (const {name, value} of this._configurationObject) {
this._parsedGeneratorConfiguration[name] = value; this._parsedGeneratorConfiguration[name] = value;
registerWorkerFixture(name, async ({}, test) => await test(value));
}
this._parsedGeneratorConfiguration['parallelIndex'] = workerId; this._parsedGeneratorConfiguration['parallelIndex'] = workerId;
this._relativeTestFile = path.relative(options.testDir, this._file); this._relativeTestFile = path.relative(options.testDir, this._file);
this.mocha.addFile(this._file); this.mocha.addFile(this._file);

View file

@ -24,14 +24,14 @@ import url from 'url';
declare global { declare global {
interface FixtureState { interface TestState {
videoPlayer: VideoPlayer; videoPlayer: VideoPlayer;
} }
} }
registerFixture('videoPlayer', async ({playwright, context}, test) => { registerFixture('videoPlayer', async ({playwright, context}, test) => {
let firefox; let firefox;
if (options.WEBKIT() && !LINUX) { if (options.WEBKIT && !LINUX) {
// WebKit on Mac & Windows cannot replay webm/vp8 video, so we launch Firefox. // WebKit on Mac & Windows cannot replay webm/vp8 video, so we launch Firefox.
firefox = await playwright.firefox.launch(); firefox = await playwright.firefox.launch();
context = await firefox.newContext(); context = await firefox.newContext();
@ -172,7 +172,7 @@ class VideoPlayer {
} }
} }
it.fail(options.CHROMIUM())('should capture static page', async({page, tmpDir, videoPlayer, toImpl}) => { it.fail(options.CHROMIUM)('should capture static page', async({page, tmpDir, videoPlayer, toImpl}) => {
if (!toImpl) if (!toImpl)
return; return;
const videoFile = path.join(tmpDir, 'v.webm'); const videoFile = path.join(tmpDir, 'v.webm');
@ -180,7 +180,7 @@ it.fail(options.CHROMIUM())('should capture static page', async({page, tmpDir, v
await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480}); await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480});
// TODO: in WebKit figure out why video size is not reported correctly for // TODO: in WebKit figure out why video size is not reported correctly for
// static pictures. // static pictures.
if (options.HEADLESS && options.WEBKIT()) if (options.HEADLESS && options.WEBKIT)
await page.setViewportSize({width: 1270, height: 950}); await page.setViewportSize({width: 1270, height: 950});
await new Promise(r => setTimeout(r, 300)); await new Promise(r => setTimeout(r, 300));
await toImpl(page)._delegate.stopScreencast(); await toImpl(page)._delegate.stopScreencast();
@ -198,7 +198,7 @@ it.fail(options.CHROMIUM())('should capture static page', async({page, tmpDir, v
expectAll(pixels, almostRed); expectAll(pixels, almostRed);
}); });
it.fail(options.CHROMIUM())('should capture navigation', async({page, tmpDir, server, videoPlayer, toImpl}) => { it.fail(options.CHROMIUM)('should capture navigation', async({page, tmpDir, server, videoPlayer, toImpl}) => {
if (!toImpl) if (!toImpl)
return; return;
const videoFile = path.join(tmpDir, 'v.webm'); const videoFile = path.join(tmpDir, 'v.webm');
@ -206,7 +206,7 @@ it.fail(options.CHROMIUM())('should capture navigation', async({page, tmpDir, se
await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480}); await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480});
// TODO: in WebKit figure out why video size is not reported correctly for // TODO: in WebKit figure out why video size is not reported correctly for
// static pictures. // static pictures.
if (options.HEADLESS && options.WEBKIT()) if (options.HEADLESS && options.WEBKIT)
await page.setViewportSize({width: 1270, height: 950}); await page.setViewportSize({width: 1270, height: 950});
await new Promise(r => setTimeout(r, 300)); await new Promise(r => setTimeout(r, 300));
await page.goto(server.CROSS_PROCESS_PREFIX + '/background-color.html#rgb(100,100,100)'); await page.goto(server.CROSS_PROCESS_PREFIX + '/background-color.html#rgb(100,100,100)');
@ -232,7 +232,7 @@ it.fail(options.CHROMIUM())('should capture navigation', async({page, tmpDir, se
}); });
// Accelerated compositing is disabled in WebKit on Windows. // Accelerated compositing is disabled in WebKit on Windows.
it.fail(options.CHROMIUM() || (options.WEBKIT() && WIN))('should capture css transformation', async({page, tmpDir, server, videoPlayer, toImpl}) => { it.fail(options.CHROMIUM || (options.WEBKIT && WIN))('should capture css transformation', async({page, tmpDir, server, videoPlayer, toImpl}) => {
if (!toImpl) if (!toImpl)
return; return;
const videoFile = path.join(tmpDir, 'v.webm'); const videoFile = path.join(tmpDir, 'v.webm');
@ -240,7 +240,7 @@ it.fail(options.CHROMIUM() || (options.WEBKIT() && WIN))('should capture css tra
await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480}); await toImpl(page)._delegate.startScreencast({outputFile: videoFile, width: 640, height: 480});
// TODO: in WebKit figure out why video size is not reported correctly for // TODO: in WebKit figure out why video size is not reported correctly for
// static pictures. // static pictures.
if (options.HEADLESS && options.WEBKIT()) if (options.HEADLESS && options.WEBKIT)
await page.setViewportSize({width: 1270, height: 950}); await page.setViewportSize({width: 1270, height: 950});
await new Promise(r => setTimeout(r, 300)); await new Promise(r => setTimeout(r, 300));
await toImpl(page)._delegate.stopScreencast(); await toImpl(page)._delegate.stopScreencast();
@ -257,7 +257,7 @@ it.fail(options.CHROMIUM() || (options.WEBKIT() && WIN))('should capture css tra
} }
}); });
it.fail(options.CHROMIUM() || options.FIREFOX())('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => { it.fail(options.CHROMIUM || options.FIREFOX)('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => {
if (!toImpl) if (!toImpl)
return; return;
// Use server side of the context. All the code below also uses server side APIs. // Use server side of the context. All the code below also uses server side APIs.

View file

@ -59,9 +59,9 @@ it('query', async ({page}) => {
expect(await page.$eval(`"x"`, e => e.outerHTML)).toBe('<div>x</div>'); expect(await page.$eval(`"x"`, e => e.outerHTML)).toBe('<div>x</div>');
expect(await page.$eval(`'x'`, e => e.outerHTML)).toBe('<div>x</div>'); expect(await page.$eval(`'x'`, e => e.outerHTML)).toBe('<div>x</div>');
let error = await page.$(`"`).catch(e => e); let error = await page.$(`"`).catch(e => e);
expect(error.message).toContain(options.WEBKIT() ? 'SyntaxError' : 'querySelector'); expect(error.message).toContain(options.WEBKIT ? 'SyntaxError' : 'querySelector');
error = await page.$(`'`).catch(e => e); error = await page.$(`'`).catch(e => e);
expect(error.message).toContain(options.WEBKIT() ? 'SyntaxError' : 'querySelector'); expect(error.message).toContain(options.WEBKIT ? 'SyntaxError' : 'querySelector');
await page.setContent(`<div> ' </div><div> " </div>`); await page.setContent(`<div> ' </div><div> " </div>`);
expect(await page.$eval(`text="`, e => e.outerHTML)).toBe('<div> " </div>'); expect(await page.$eval(`text="`, e => e.outerHTML)).toBe('<div> " </div>');

34
test/setup.ts Normal file
View file

@ -0,0 +1,34 @@
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
matrix({
'browserName': process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox'],
'headless': [!!valueFromEnv('HEADLESS', true)],
'wire': [!!process.env.PWWIRE],
'slowMo': [valueFromEnv('SLOW_MO', 0)]
});
before(async () => {
});
after(async () => {
});
function valueFromEnv(name, defaultValue) {
if (!(name in process.env))
return defaultValue;
return JSON.parse(process.env[name]);
}

View file

@ -1,5 +1,6 @@
/** /**
* Copyright (c) Microsoft Corporation.
* Copyright (c) Microsoft Corporation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +18,7 @@
import { registerFixture } from './runner'; import { registerFixture } from './runner';
declare global { declare global {
interface FixtureState { interface TestState {
helperFixture: string; helperFixture: string;
} }
} }

21
test/types.d.ts vendored
View file

@ -31,10 +31,13 @@ type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>)
repeat(n: number): ItFunction<STATE>; repeat(n: number): ItFunction<STATE>;
}; };
interface FixtureParameters {
}
interface WorkerState { interface WorkerState {
} }
interface FixtureState { interface TestState {
} }
declare module '' { declare module '' {
@ -50,13 +53,13 @@ declare const expect: typeof import('expect');
declare const describe: DescribeFunction; declare const describe: DescribeFunction;
declare const fdescribe: DescribeFunction; declare const fdescribe: DescribeFunction;
declare const xdescribe: DescribeFunction; declare const xdescribe: DescribeFunction;
declare const it: ItFunction<FixtureState & WorkerState>; declare const it: ItFunction<TestState & WorkerState & FixtureParameters>;
declare const fit: ItFunction<FixtureState & WorkerState>; declare const fit: ItFunction<TestState & WorkerState & FixtureParameters>;
declare const dit: ItFunction<FixtureState & WorkerState>; declare const dit: ItFunction<TestState & WorkerState & FixtureParameters>;
declare const xit: ItFunction<FixtureState & WorkerState>; declare const xit: ItFunction<TestState & WorkerState & FixtureParameters>;
declare const beforeEach: (inner: (state: FixtureState & WorkerState) => Promise<void>) => void; declare const beforeEach: (inner: (state: TestState & WorkerState & FixtureParameters) => Promise<void>) => void;
declare const afterEach: (inner: (state: FixtureState & WorkerState) => Promise<void>) => void; declare const afterEach: (inner: (state: TestState & WorkerState & FixtureParameters) => Promise<void>) => void;
declare const beforeAll: (inner: (state: WorkerState) => Promise<void>) => void; declare const beforeAll: (inner: (state: WorkerState) => Promise<void>) => void;
declare const afterAll: (inner: (state: WorkerState) => Promise<void>) => void; declare const afterAll: (inner: (state: WorkerState) => Promise<void>) => void;
@ -68,3 +71,7 @@ declare var WIN: boolean;
// keyboard.html // keyboard.html
declare function getResult(): string; declare function getResult(): string;
declare const before: (f: () => Promise<any>) => void;
declare const after: (f: () => Promise<any>) => void;
declare const matrix: (m: any) => void;