diff --git a/test/accessibility.spec.ts b/test/accessibility.spec.ts
index 6120b3cca3772..262d36c9127df 100644
--- a/test/accessibility.spec.ts
+++ b/test/accessibility.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
it('should work', async ({ page, isFirefox, isChromium }) => {
await page.setContent(`
@@ -139,8 +139,8 @@ it('should not report text nodes inside controls', async function({page, isFiref
expect(await page.accessibility.snapshot()).toEqual(golden);
});
-it('rich text editable fields should have children', (test, parameters) => {
- test.skip(options.WEBKIT(parameters), 'WebKit rich text accessibility is iffy');
+it('rich text editable fields should have children', (test, { browserName }) => {
+ test.skip(browserName === 'webkit', 'WebKit rich text accessibility is iffy');
}, async function({page, isFirefox}) {
await page.setContent(`
@@ -172,8 +172,8 @@ it('rich text editable fields should have children', (test, parameters) => {
expect(snapshot.children[0]).toEqual(golden);
});
-it('rich text editable fields with role should have children', (test, parameters) => {
- test.skip(options.WEBKIT(parameters), 'WebKit rich text accessibility is iffy');
+it('rich text editable fields with role should have children', (test, { browserName }) => {
+ test.skip(browserName === 'webkit', 'WebKit rich text accessibility is iffy');
}, async function({page, isFirefox}) {
await page.setContent(`
@@ -203,9 +203,9 @@ it('rich text editable fields with role should have children', (test, parameters
expect(snapshot.children[0]).toEqual(golden);
});
-describe('contenteditable', (suite, parameters) => {
- suite.skip(options.FIREFOX(parameters), 'Firefox does not support contenteditable="plaintext-only"');
- suite.skip(options.WEBKIT(parameters), 'WebKit rich text accessibility is iffy');
+describe('contenteditable', (suite, { browserName }) => {
+ suite.skip(browserName === 'firefox', 'Firefox does not support contenteditable="plaintext-only"');
+ suite.skip(browserName === 'webkit', 'WebKit rich text accessibility is iffy');
}, () => {
it('plain text field with role should not have children', async function({page}) {
await page.setContent(`
diff --git a/test/autowaiting-basic.spec.ts b/test/autowaiting-basic.spec.ts
index a86b3a21f8e04..204786f78415b 100644
--- a/test/autowaiting-basic.spec.ts
+++ b/test/autowaiting-basic.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should await navigation when clicking anchor', async ({page, server}) => {
const messages = [];
@@ -201,8 +201,8 @@ it('should work with goto following click', async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
});
-it('should report navigation in the log when clicking anchor', (test, parameters) => {
- test.skip(options.WIRE);
+it('should report navigation in the log when clicking anchor', (test, { wire }) => {
+ test.skip(wire);
}, async ({page, server}) => {
await page.setContent(`click me`);
const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
diff --git a/test/browsercontext-cookies.spec.ts b/test/browsercontext-cookies.spec.ts
index f71356e621e37..81504c42b2dc6 100644
--- a/test/browsercontext-cookies.spec.ts
+++ b/test/browsercontext-cookies.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should return no cookies in pristine browser context', async ({context, page, server}) => {
expect(await context.cookies()).toEqual([]);
@@ -73,8 +73,8 @@ it('should properly report httpOnly cookie', async ({context, page, server}) =>
expect(cookies[0].httpOnly).toBe(true);
});
-it('should properly report "Strict" sameSite cookie', (test, parameters) => {
- test.fail(options.WEBKIT(parameters) && options.WIN(parameters));
+it('should properly report "Strict" sameSite cookie', (test, { browserName, platform }) => {
+ test.fail(browserName === 'webkit' && platform === 'win32');
}, async ({context, page, server}) => {
server.setRoute('/empty.html', (req, res) => {
res.setHeader('Set-Cookie', 'name=value;SameSite=Strict');
@@ -86,8 +86,8 @@ it('should properly report "Strict" sameSite cookie', (test, parameters) => {
expect(cookies[0].sameSite).toBe('Strict');
});
-it('should properly report "Lax" sameSite cookie', (test, parameters) => {
- test.fail(options.WEBKIT(parameters) && options.WIN(parameters));
+it('should properly report "Lax" sameSite cookie', (test, { browserName, platform }) => {
+ test.fail(browserName === 'webkit' && platform === 'win32');
}, async ({context, page, server}) => {
server.setRoute('/empty.html', (req, res) => {
res.setHeader('Set-Cookie', 'name=value;SameSite=Lax');
diff --git a/test/browsercontext-credentials.spec.ts b/test/browsercontext-credentials.spec.ts
index 84917b6a4ae91..711835dcd3036 100644
--- a/test/browsercontext-credentials.spec.ts
+++ b/test/browsercontext-credentials.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('should fail without credentials', (test, parameters) => {
- test.fail(options.CHROMIUM(parameters) && !options.HEADLESS);
+it('should fail without credentials', (test, { browserName, headful}) => {
+ test.fail(browserName === 'chromium' && headful);
}, async ({browser, server}) => {
server.setAuth('/empty.html', 'user', 'pass');
const context = await browser.newContext();
@@ -28,8 +28,8 @@ it('should fail without credentials', (test, parameters) => {
await context.close();
});
-it('should work with setHTTPCredentials', (test, parameters) => {
- test.fail(options.CHROMIUM(parameters) && !options.HEADLESS);
+it('should work with setHTTPCredentials', (test, { browserName, headful }) => {
+ test.fail(browserName === 'chromium' && headful);
}, async ({browser, server}) => {
server.setAuth('/empty.html', 'user', 'pass');
const context = await browser.newContext();
diff --git a/test/browsercontext-device.spec.ts b/test/browsercontext-device.spec.ts
index 22e7111610f5f..6b6e2170a5e14 100644
--- a/test/browsercontext-device.spec.ts
+++ b/test/browsercontext-device.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
-describe('device', (suite, parameters) => {
- suite.skip(options.FIREFOX(parameters));
+describe('device', (suite, { browserName }) => {
+ suite.skip(browserName === 'firefox');
}, () => {
it('should work', async ({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6'];
diff --git a/test/browsercontext-page-event.spec.ts b/test/browsercontext-page-event.spec.ts
index 0db153b64ec0a..27cce17ae22d0 100644
--- a/test/browsercontext-page-event.spec.ts
+++ b/test/browsercontext-page-event.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should have url', async ({browser, server}) => {
const context = await browser.newContext();
@@ -157,8 +157,8 @@ it('should fire page lifecycle events', async function({browser, server}) {
await context.close();
});
-it('should work with Shift-clicking', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters), 'WebKit: Shift+Click does not open a new window.');
+it('should work with Shift-clicking', (test, { browserName }) => {
+ test.fixme(browserName === 'webkit', 'WebKit: Shift+Click does not open a new window.');
}, async ({browser, server}) => {
const context = await browser.newContext();
const page = await context.newPage();
@@ -172,9 +172,9 @@ it('should work with Shift-clicking', (test, parameters) => {
await context.close();
});
-it('should work with Ctrl-clicking', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters), 'Ctrl+Click does not open a new tab.');
- test.fixme(options.FIREFOX(parameters), 'Reports an opener in this case.');
+it('should work with Ctrl-clicking', (test, { browserName }) => {
+ test.fixme(browserName === 'webkit', 'Ctrl+Click does not open a new tab.');
+ test.fixme(browserName === 'firefox', 'Reports an opener in this case.');
}, async ({browser, server, isMac}) => {
const context = await browser.newContext();
const page = await context.newPage();
diff --git a/test/browsercontext-viewport-mobile.spec.ts b/test/browsercontext-viewport-mobile.spec.ts
index 5d2f6ac4ff776..a5ea4be5038bb 100644
--- a/test/browsercontext-viewport-mobile.spec.ts
+++ b/test/browsercontext-viewport-mobile.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
-describe('mobile viewport', (suite, parameters) => {
- suite.skip(options.FIREFOX(parameters));
+describe('mobile viewport', (suite, { browserName }) => {
+ suite.skip(browserName === 'firefox');
}, () => {
it('should support mobile emulation', async ({playwright, browser, server}) => {
const iPhone = playwright.devices['iPhone 6'];
@@ -131,8 +131,8 @@ describe('mobile viewport', (suite, parameters) => {
await context.close();
});
- it('should emulate the hover media feature', (test, parameters) => {
- test.fail(options.WEBKIT(parameters));
+ it('should emulate the hover media feature', (test, { browserName }) => {
+ test.fail(browserName === 'webkit');
}, async ({playwright, browser}) => {
const iPhone = playwright.devices['iPhone 6'];
const mobilepage = await browser.newPage({ ...iPhone });
diff --git a/test/browsertype-connect.spec.ts b/test/browsertype-connect.spec.ts
index f856a9c08e6f0..7aa2ed0029b5d 100644
--- a/test/browsertype-connect.spec.ts
+++ b/test/browsertype-connect.spec.ts
@@ -15,12 +15,11 @@
* limitations under the License.
*/
-import { options } from './fixtures';
import { serverFixtures } from './remoteServer.fixture';
const { it, expect, describe } = serverFixtures;
-describe('connect', suite => {
- suite.skip(options.WIRE);
+describe('connect', (suite, { wire }) => {
+ suite.skip(wire);
suite.slow();
}, () => {
it('should be able to reconnect to a browser', async ({browserType, remoteServer, server}) => {
diff --git a/test/browsertype-launch-server.spec.ts b/test/browsertype-launch-server.spec.ts
index d90a080fb0dcc..86e4365a76ec8 100644
--- a/test/browsertype-launch-server.spec.ts
+++ b/test/browsertype-launch-server.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
-describe('lauch server', suite => {
- suite.skip(options.WIRE);
+describe('lauch server', (suite, { wire }) => {
+ suite.skip(wire);
}, () => {
it('should work', async ({browserType, defaultBrowserOptions}) => {
const browserServer = await browserType.launchServer(defaultBrowserOptions);
diff --git a/test/browsertype-launch.spec.ts b/test/browsertype-launch.spec.ts
index 0a8769b141088..3eb13c06b4958 100644
--- a/test/browsertype-launch.spec.ts
+++ b/test/browsertype-launch.spec.ts
@@ -16,7 +16,7 @@
*/
import path from 'path';
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should reject all promises when browser is closed', async ({browserType, defaultBrowserOptions}) => {
const browser = await browserType.launch(defaultBrowserOptions);
@@ -48,8 +48,8 @@ it('should throw if port option is passed for persistent context', async ({brows
expect(error.message).toContain('Cannot specify a port without launching as a server.');
});
-it('should throw if page argument is passed', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should throw if page argument is passed', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browserType, defaultBrowserOptions}) => {
let waitError = null;
const options = Object.assign({}, defaultBrowserOptions, { args: ['http://example.com'] });
@@ -73,8 +73,8 @@ it('should reject if executable path is invalid', async ({browserType, defaultBr
expect(waitError.message).toContain('Failed to launch');
});
-it('should handle timeout', (test, parameters) => {
- test.skip(options.WIRE);
+it('should handle timeout', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions}) => {
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
const error = await browserType.launch(options).catch(e => e);
@@ -83,8 +83,8 @@ it('should handle timeout', (test, parameters) => {
expect(error.message).toContain(` pid=`);
});
-it('should handle exception', (test, parameters) => {
- test.skip(options.WIRE);
+it('should handle exception', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions}) => {
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
@@ -92,8 +92,8 @@ it('should handle exception', (test, parameters) => {
expect(error.message).toContain('Dummy');
});
-it('should report launch log', (test, parameters) => {
- test.skip(options.WIRE);
+it('should report launch log', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions}) => {
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
diff --git a/test/capabilities.spec.ts b/test/capabilities.spec.ts
index ef2c1cfde80db..0a3aca9a0eb8f 100644
--- a/test/capabilities.spec.ts
+++ b/test/capabilities.spec.ts
@@ -15,10 +15,10 @@
*/
import url from 'url';
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('Web Assembly should work', (test, parameters) => {
- test.fail(options.WEBKIT(parameters) && options.WIN(parameters));
+it('Web Assembly should work', (test, { browserName, platform }) => {
+ test.fail(browserName === 'webkit' && platform === 'win32');
}, async function({page, server}) {
await page.goto(server.PREFIX + '/wasm/table2.html');
expect(await page.evaluate('loadTable()')).toBe('42, 83');
@@ -50,8 +50,8 @@ it('should respect CSP', async ({page, server}) => {
expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS');
});
-it('should play video', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters) && (options.WIN(parameters) || options.LINUX(parameters)));
+it('should play video', (test, { browserName, platform }) => {
+ test.fixme(browserName === 'webkit' && (platform !== 'darwin'));
}, async ({page, asset, isWebKit}) => {
// TODO: the test passes on Windows locally but fails on GitHub Action bot,
// apparently due to a Media Pack issue in the Windows Server.
diff --git a/test/channels.spec.ts b/test/channels.spec.ts
index 6644db98d5874..fc1b1abfdf0f1 100644
--- a/test/channels.spec.ts
+++ b/test/channels.spec.ts
@@ -16,7 +16,7 @@
*/
import domain from 'domain';
-import { options, fixtures as baseFixtures } from './fixtures';
+import { fixtures as baseFixtures } from './fixtures';
import type { ChromiumBrowser } from '..';
type DomainFixtures = {
@@ -84,8 +84,8 @@ it('should scope context handles', async ({browserType, browser, server}) => {
await expectScopeState(browser, GOLDEN_PRECONDITION);
});
-it('should scope CDPSession handles', (test, parameters) => {
- test.skip(!options.CHROMIUM(parameters));
+it('should scope CDPSession handles', (test, { browserName }) => {
+ test.skip(browserName !== 'chromium');
}, async ({browserType, browser}) => {
const GOLDEN_PRECONDITION = {
_guid: '',
diff --git a/test/chromium-css-coverage.spec.ts b/test/chromium-css-coverage.spec.ts
index 3d25dfff1ba66..d976266128be4 100644
--- a/test/chromium-css-coverage.spec.ts
+++ b/test/chromium-css-coverage.spec.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
-describe('oopif', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('oopif', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should work', async function({browserType, page, server}) {
await page.coverage.startCSSCoverage();
diff --git a/test/chromium-js-coverage.spec.ts b/test/chromium-js-coverage.spec.ts
index 98b02560fbbff..ddb1c23d34089 100644
--- a/test/chromium-js-coverage.spec.ts
+++ b/test/chromium-js-coverage.spec.ts
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
-it('should be missing', (test, parameters) => {
- test.skip(options.CHROMIUM(parameters));
+it('should be missing', (test, { browserName }) => {
+ test.skip(browserName === 'chromium');
},
async function({page}) {
expect(page.coverage).toBe(null);
});
-describe('oopif', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('oopif', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should work', async function({page, server}) {
await page.coverage.startJSCoverage();
diff --git a/test/chromium/chromium.spec.ts b/test/chromium/chromium.spec.ts
index 25153b35f4d30..01ac984d1ac96 100644
--- a/test/chromium/chromium.spec.ts
+++ b/test/chromium/chromium.spec.ts
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { it, expect, describe, options } from '../fixtures';
+import { it, expect, describe } from '../fixtures';
import type { ChromiumBrowserContext } from '../..';
-describe('chromium', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('chromium', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should create a worker from a service worker', async ({page, server, context}) => {
const [worker] = await Promise.all([
diff --git a/test/chromium/launcher.spec.ts b/test/chromium/launcher.spec.ts
index 449310abdfe84..de044a5926cee 100644
--- a/test/chromium/launcher.spec.ts
+++ b/test/chromium/launcher.spec.ts
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { it, expect, options } from '../fixtures';
+import { it, expect } from '../fixtures';
import path from 'path';
import type { ChromiumBrowser, ChromiumBrowserContext } from '../..';
-it('should throw with remote-debugging-pipe argument', (test, parameters) => {
- test.skip(options.WIRE || !options.CHROMIUM(parameters));
+it('should throw with remote-debugging-pipe argument', (test, { browserName, wire }) => {
+ test.skip(wire || browserName !== 'chromium');
}, async ({browserType, defaultBrowserOptions}) => {
const options = Object.assign({}, defaultBrowserOptions);
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
@@ -27,8 +27,8 @@ it('should throw with remote-debugging-pipe argument', (test, parameters) => {
expect(error.message).toContain('Playwright manages remote debugging connection itself');
});
-it('should not throw with remote-debugging-port argument', (test, parameters) => {
- test.skip(options.WIRE || !options.CHROMIUM(parameters));
+it('should not throw with remote-debugging-port argument', (test, { browserName, wire }) => {
+ test.skip(wire || browserName !== 'chromium');
}, async ({browserType, defaultBrowserOptions}) => {
const options = Object.assign({}, defaultBrowserOptions);
options.args = ['--remote-debugging-port=0'].concat(options.args || []);
@@ -36,8 +36,8 @@ it('should not throw with remote-debugging-port argument', (test, parameters) =>
await browser.close();
});
-it('should open devtools when "devtools: true" option is given', (test, parameters) => {
- test.skip(!options.CHROMIUM(parameters) || options.WIRE || options.WIN(parameters));
+it('should open devtools when "devtools: true" option is given', (test, { wire, browserName, platform}) => {
+ test.skip(browserName !== 'chromium' || wire || platform === 'win32');
}, async ({browserType, defaultBrowserOptions}) => {
let devtoolsCallback;
const devtoolsPromise = new Promise(f => devtoolsCallback = f);
@@ -54,8 +54,8 @@ it('should open devtools when "devtools: true" option is given', (test, paramete
await browser.close();
});
-it('should return background pages', (test, parameters) => {
- test.skip(!options.CHROMIUM(parameters));
+it('should return background pages', (test, { browserName }) => {
+ test.skip(browserName !== 'chromium');
}, async ({browserType, defaultBrowserOptions, createUserDataDir}) => {
const userDataDir = await createUserDataDir();
const extensionPath = path.join(__dirname, '..', 'assets', 'simple-extension');
@@ -77,8 +77,8 @@ it('should return background pages', (test, parameters) => {
await context.close();
});
-it('should not create pages automatically', (test, parameters) => {
- test.skip(!options.CHROMIUM(parameters));
+it('should not create pages automatically', (test, { browserName }) => {
+ test.skip(browserName !== 'chromium');
}, async ({browserType, defaultBrowserOptions}) => {
const browser = await browserType.launch(defaultBrowserOptions);
const browserSession = await (browser as ChromiumBrowser).newBrowserCDPSession();
diff --git a/test/chromium/oopif.spec.ts b/test/chromium/oopif.spec.ts
index af7c6e7209dc8..b6077c6c2ffdb 100644
--- a/test/chromium/oopif.spec.ts
+++ b/test/chromium/oopif.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { options, fixtures as playwrightFixtures } from '../fixtures';
+import { fixtures as playwrightFixtures } from '../fixtures';
const { it, expect, describe, overrideWorkerFixture } = playwrightFixtures;
overrideWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => {
@@ -26,8 +26,8 @@ overrideWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, te
await browser.close();
});
-describe('oopif', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('oopif', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should report oopif frames', async function({browser, page, server}) {
await page.goto(server.PREFIX + '/dynamic-oopif.html');
@@ -68,9 +68,9 @@ describe('oopif', (suite, parameters) => {
expect(await countOOPIFs(browser)).toBe(1);
});
- it('should get the proper viewport', (test, parameters) => {
- test.fixme(options.CHROMIUM(parameters));
- test.skip(!options.CHROMIUM(parameters));
+ it('should get the proper viewport', (test, { browserName }) => {
+ test.fixme(browserName === 'chromium');
+ test.skip(browserName !== 'chromium');
}, async ({browser, page, server}) => {
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
await page.goto(server.PREFIX + '/dynamic-oopif.html');
diff --git a/test/chromium/session.spec.ts b/test/chromium/session.spec.ts
index 34eab2641dd43..4402a878bcc1b 100644
--- a/test/chromium/session.spec.ts
+++ b/test/chromium/session.spec.ts
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { it, expect, describe, options } from '../fixtures';
+import { it, expect, describe } from '../fixtures';
import type { ChromiumBrowserContext, ChromiumBrowser } from '../../types/types';
-describe('session', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('session', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should work', async function({page}) {
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
diff --git a/test/chromium/tracing.spec.ts b/test/chromium/tracing.spec.ts
index f2734b3416611..68c2a5e51d557 100644
--- a/test/chromium/tracing.spec.ts
+++ b/test/chromium/tracing.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { options, fixtures as playwrightFixtures } from '../fixtures';
+import { fixtures as playwrightFixtures } from '../fixtures';
import fs from 'fs';
import path from 'path';
import type { ChromiumBrowser } from '../..';
@@ -29,8 +29,8 @@ defineTestFixture('outputTraceFile', async ({testOutputDir}, test) => {
await test(path.join(testOutputDir, `trace.json`));
});
-describe('oopif', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('oopif', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should output a trace', async ({browser, page, server, outputTraceFile}) => {
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputTraceFile});
diff --git a/test/click-timeout-1.spec.ts b/test/click-timeout-1.spec.ts
index 9278fe6e3742e..8d8c1f6eed144 100644
--- a/test/click-timeout-1.spec.ts
+++ b/test/click-timeout-1.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('should avoid side effects after timeout', (test, parameters) => {
- test.skip(options.WIRE);
+it('should avoid side effects after timeout', (test, { wire }) => {
+ test.skip(wire);
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/input/button.html');
const error = await page.click('button', { timeout: 2000, __testHookBeforePointerAction: () => new Promise(f => setTimeout(f, 2500))} as any).catch(e => e);
diff --git a/test/click-timeout-3.spec.ts b/test/click-timeout-3.spec.ts
index f384ac8ee299e..d3c571223d3e9 100644
--- a/test/click-timeout-3.spec.ts
+++ b/test/click-timeout-3.spec.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('should fail when element jumps during hit testing', (test, parameters) => {
- test.skip(options.WIRE);
+it('should fail when element jumps during hit testing', (test, { wire }) => {
+ test.skip(wire);
}, async ({page}) => {
await page.setContent('');
let clicked = false;
diff --git a/test/click.spec.ts b/test/click.spec.ts
index 2e4bd3db7e669..3b3ff68d9e2be 100644
--- a/test/click.spec.ts
+++ b/test/click.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame } from './utils';
async function giveItAChanceToClick(page) {
@@ -322,8 +322,8 @@ it('should click the button inside an iframe', async ({page, server}) => {
expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
});
-it('should click the button with fixed position inside an iframe', (test, parameters) => {
- test.fixme(options.CHROMIUM(parameters) || options.WEBKIT(parameters));
+it('should click the button with fixed position inside an iframe', (test, { browserName }) => {
+ test.fixme(browserName === 'chromium' || browserName === 'webkit');
}, async ({page, server}) => {
// @see https://github.com/GoogleChrome/puppeteer/issues/4110
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=986390
@@ -403,9 +403,9 @@ it('should click a button in scrolling container with offset', async ({page, ser
expect(await page.evaluate('offsetY')).toBe(isWebKit ? 1910 + 8 : 1910);
});
-it('should click the button with offset with page scale', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
-}, async ({browser, server, isWebKit, isChromium}) => {
+it('should click the button with offset with page scale', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
+}, async ({browser, server, isWebKit, isChromium, headful}) => {
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true });
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
@@ -420,7 +420,7 @@ it('should click the button with offset with page scale', (test, parameters) =>
if (isWebKit) {
// WebKit rounds up during css -> dip -> css conversion.
expected = { x: 29, y: 19 };
- } else if (isChromium && options.HEADLESS) {
+ } else if (isChromium && !headful) {
// Headless Chromium rounds down during css -> dip -> css conversion.
expected = { x: 27, y: 18 };
}
diff --git a/test/defaultbrowsercontext-2.spec.ts b/test/defaultbrowsercontext-2.spec.ts
index 1d4848eba34ea..2d0eaa6b0c8f1 100644
--- a/test/defaultbrowsercontext-2.spec.ts
+++ b/test/defaultbrowsercontext-2.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import fs from 'fs';
it('should support hasTouch option', async ({server, launchPersistent}) => {
@@ -24,8 +24,8 @@ it('should support hasTouch option', async ({server, launchPersistent}) => {
expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(true);
});
-it('should work in persistent context', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should work in persistent context', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({server, launchPersistent}) => {
// Firefox does not support mobile.
const {page} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true});
@@ -66,8 +66,8 @@ it('should support ignoreHTTPSErrors option', async ({httpsServer, launchPersist
expect(response.ok()).toBe(true);
});
-it('should support extraHTTPHeaders option', (test, parameters) => {
- test.flaky(options.FIREFOX(parameters) && !options.HEADLESS && options.LINUX(parameters), 'Intermittent timeout on bots');
+it('should support extraHTTPHeaders option', (test, { browserName, platform, headful }) => {
+ test.flaky(browserName === 'firefox' && headful && platform === 'linux', 'Intermittent timeout on bots');
}, async ({server, launchPersistent}) => {
const {page} = await launchPersistent({extraHTTPHeaders: { foo: 'bar' }});
const [request] = await Promise.all([
@@ -77,8 +77,8 @@ it('should support extraHTTPHeaders option', (test, parameters) => {
expect(request.headers['foo']).toBe('bar');
});
-it('should accept userDataDir', (test, parameters) => {
- test.flaky(options.CHROMIUM(parameters));
+it('should accept userDataDir', (test, { browserName }) => {
+ test.flaky(browserName === 'chromium');
}, async ({createUserDataDir, browserType, defaultBrowserOptions}) => {
const userDataDir = await createUserDataDir();
const context = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions);
@@ -87,7 +87,7 @@ it('should accept userDataDir', (test, parameters) => {
expect(fs.readdirSync(userDataDir).length).toBeGreaterThan(0);
});
-it('should restore state from userDataDir', (test, parameters) => {
+it('should restore state from userDataDir', (test, { browserName }) => {
test.slow();
}, async ({browserType, defaultBrowserOptions, server, createUserDataDir}) => {
const userDataDir = await createUserDataDir();
@@ -111,9 +111,9 @@ it('should restore state from userDataDir', (test, parameters) => {
await browserContext3.close();
});
-it('should restore cookies from userDataDir', (test, parameters) => {
+it('should restore cookies from userDataDir', (test, { browserName }) => {
test.slow();
- test.flaky(options.CHROMIUM(parameters));
+ test.flaky(browserName === 'chromium');
}, async ({browserType, defaultBrowserOptions, server, createUserDataDir}) => {
const userDataDir = await createUserDataDir();
const browserContext = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions);
@@ -146,16 +146,16 @@ it('should have default URL when launching browser', async ({launchPersistent})
expect(urls).toEqual(['about:blank']);
});
-it('should throw if page argument is passed', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should throw if page argument is passed', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browserType, defaultBrowserOptions, server, createUserDataDir}) => {
const options = {...defaultBrowserOptions, args: [server.EMPTY_PAGE] };
const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e);
expect(error.message).toContain('can not specify page');
});
-it('should have passed URL when launching with ignoreDefaultArgs: true', (test, parameters) => {
- test.skip(options.WIRE);
+it('should have passed URL when launching with ignoreDefaultArgs: true', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions, server, createUserDataDir, toImpl}) => {
const userDataDir = await createUserDataDir();
const args = toImpl(browserType)._defaultArgs(defaultBrowserOptions, 'persistent', userDataDir, 0).filter(a => a !== 'about:blank');
@@ -173,16 +173,16 @@ it('should have passed URL when launching with ignoreDefaultArgs: true', (test,
await browserContext.close();
});
-it('should handle timeout', (test, parameters) => {
- test.skip(options.WIRE);
+it('should handle timeout', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions, createUserDataDir}) => {
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e);
expect(error.message).toContain(`browserType.launchPersistentContext: Timeout 5000ms exceeded.`);
});
-it('should handle exception', (test, parameters) => {
- test.skip(options.WIRE);
+it('should handle exception', (test, { wire }) => {
+ test.skip(wire);
}, async ({browserType, defaultBrowserOptions, createUserDataDir}) => {
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; } };
@@ -198,8 +198,8 @@ it('should fire close event for a persistent context', async ({launchPersistent}
expect(closed).toBe(true);
});
-it('coverage should work', (test, parameters) => {
- test.skip(!options.CHROMIUM(parameters));
+it('coverage should work', (test, { browserName }) => {
+ test.skip(browserName !== 'chromium');
}, async ({server, launchPersistent}) => {
const {page} = await launchPersistent();
await page.coverage.startJSCoverage();
@@ -210,8 +210,8 @@ it('coverage should work', (test, parameters) => {
expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1);
});
-it('coverage should be missing', (test, parameters) => {
- test.skip(options.CHROMIUM(parameters));
+it('coverage should be missing', (test, { browserName }) => {
+ test.skip(browserName === 'chromium');
}, async ({launchPersistent}) => {
const {page} = await launchPersistent();
expect(page.coverage).toBe(null);
diff --git a/test/dialog.spec.ts b/test/dialog.spec.ts
index a8ff4f2e227fa..3a8de60d0fff6 100644
--- a/test/dialog.spec.ts
+++ b/test/dialog.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should fire', async ({page, server}) => {
page.on('dialog', dialog => {
@@ -62,8 +62,8 @@ it('should dismiss the confirm prompt', async ({page}) => {
expect(result).toBe(false);
});
-it('should be able to close context with open alert', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters) && options.MAC(parameters));
+it('should be able to close context with open alert', (test, { browserName, platform }) => {
+ test.fixme(browserName === 'webkit' && platform === 'darwin');
}, async ({browser}) => {
const context = await browser.newContext();
const page = await context.newPage();
diff --git a/test/download.spec.ts b/test/download.spec.ts
index f153d90e551eb..3f61462e25ed9 100644
--- a/test/download.spec.ts
+++ b/test/download.spec.ts
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { options } from './fixtures';
import { serverFixtures } from './remoteServer.fixture';
const { it, expect, beforeEach } = serverFixtures;
@@ -145,8 +144,8 @@ it('should create subdirectories when saving to non-existent user-specified path
await page.close();
});
-it('should save when connected remotely', (test, parameters) => {
- test.skip(options.WIRE);
+it('should save when connected remotely', (test, { wire }) => {
+ test.skip(wire);
}, async ({testOutputDir, server, browserType, remoteServer}) => {
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
const page = await browser.newPage({ acceptDownloads: true });
@@ -191,8 +190,8 @@ it('should error when saving after deletion', async ({testOutputDir, browser, se
await page.close();
});
-it('should error when saving after deletion when connected remotely', (test, parameters) => {
- test.skip(options.WIRE);
+it('should error when saving after deletion when connected remotely', (test, { wire }) => {
+ test.skip(wire);
}, async ({testOutputDir, server, browserType, remoteServer}) => {
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
const page = await browser.newPage({ acceptDownloads: true });
@@ -255,8 +254,8 @@ it(`should report download path within page.on('download', …) handler for Blob
expect(fs.readFileSync(path).toString()).toBe('Hello world');
await page.close();
});
-it('should report alt-click downloads', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters) || options.WEBKIT(parameters));
+it('should report alt-click downloads', (test, { browserName }) => {
+ test.fixme(browserName === 'firefox' || browserName === 'webkit');
}, async ({browser, server}) => {
// Firefox does not download on alt-click by default.
// Our WebKit embedder does not download on alt-click, although Safari does.
@@ -278,8 +277,8 @@ it('should report alt-click downloads', (test, parameters) => {
await page.close();
});
-it('should report new window downloads', (test, parameters) => {
- test.fixme(options.CHROMIUM(parameters) && !options.HEADLESS);
+it('should report new window downloads', (test, { browserName, headful }) => {
+ test.fixme(browserName === 'chromium' && headful);
}, async ({browser, server}) => {
// TODO: - the test fails in headful Chromium as the popup page gets closed along
// with the session before download completed event arrives.
diff --git a/test/electron/electron-app.spec.ts b/test/electron/electron-app.spec.ts
index a71d08f650781..845cab4cdaf99 100644
--- a/test/electron/electron-app.spec.ts
+++ b/test/electron/electron-app.spec.ts
@@ -14,15 +14,14 @@
* limitations under the License.
*/
-import { options } from '../fixtures';
import { electronFixtures } from './electron.fixture';
const { it, expect, describe } = electronFixtures;
import path from 'path';
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
-describe('electron app', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('electron app', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should fire close event', async ({ playwright }) => {
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
diff --git a/test/electron/electron-window.spec.ts b/test/electron/electron-window.spec.ts
index 1fd4464239b7a..8f8d26595cddb 100644
--- a/test/electron/electron-window.spec.ts
+++ b/test/electron/electron-window.spec.ts
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-import { options } from '../fixtures';
import { electronFixtures } from './electron.fixture';
const { it, expect, describe } = electronFixtures;
-describe('electron window', (suite, parameters) => {
- suite.skip(!options.CHROMIUM(parameters));
+describe('electron window', (suite, { browserName }) => {
+ suite.skip(browserName !== 'chromium');
}, () => {
it('should click the button', async ({window, server}) => {
await window.goto(server.PREFIX + '/input/button.html');
diff --git a/test/elementhandle-bounding-box.spec.ts b/test/elementhandle-bounding-box.spec.ts
index edc06c3e8a0a3..1c954959b6374 100644
--- a/test/elementhandle-bounding-box.spec.ts
+++ b/test/elementhandle-bounding-box.spec.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('should work', (test, parameters) => {
- test.fail(options.FIREFOX(parameters) && !options.HEADLESS);
+it('should work', (test, { browserName, headful }) => {
+ test.fail(browserName === 'firefox' && headful);
}, async ({ page, server }) => {
await page.setViewportSize({ width: 500, height: 500 });
await page.goto(server.PREFIX + '/grid.html');
@@ -67,8 +67,8 @@ it('should work with SVG nodes', async ({ page, server }) => {
expect(pwBoundingBox).toEqual(webBoundingBox);
});
-it('should work with page scale', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should work with page scale', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({ browser, server }) => {
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true });
const page = await context.newPage();
diff --git a/test/elementhandle-owner-frame.spec.ts b/test/elementhandle-owner-frame.spec.ts
index a4986230a0ac2..16b2c6ee08fae 100644
--- a/test/elementhandle-owner-frame.spec.ts
+++ b/test/elementhandle-owner-frame.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame } from './utils';
it('should work', async ({ page, server }) => {
@@ -34,8 +34,8 @@ it('should work for cross-process iframes', async ({ page, server }) => {
expect(await elementHandle.ownerFrame()).toBe(frame);
});
-it('should work for document', (test, parameters) => {
- test.flaky(options.WIN(parameters) && options.WEBKIT(parameters));
+it('should work for document', (test, { browserName, platform }) => {
+ test.flaky(platform === 'win32' && browserName === 'webkit');
}, async ({ page, server }) => {
await page.goto(server.EMPTY_PAGE);
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
diff --git a/test/elementhandle-screenshot.spec.ts b/test/elementhandle-screenshot.spec.ts
index 6ca1bdbbb7619..da62da7d73bde 100644
--- a/test/elementhandle-screenshot.spec.ts
+++ b/test/elementhandle-screenshot.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
import { verifyViewport } from './utils';
import {PNG} from 'pngjs';
@@ -23,7 +23,7 @@ import path from 'path';
import fs from 'fs';
describe('element screenshot', (suite, parameters) => {
- suite.skip(parameters.browserName === 'firefox' && !options.HEADLESS);
+ suite.skip(parameters.browserName === 'firefox' && parameters.headful);
}, () => {
it('should work', async ({page, server, golden}) => {
await page.setViewportSize({width: 500, height: 500});
@@ -211,8 +211,8 @@ describe('element screenshot', (suite, parameters) => {
expect(screenshot).toMatchImage(golden('screenshot-element-fractional.png'));
});
- it('should work with a mobile viewport', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+ it('should work with a mobile viewport', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage();
@@ -224,8 +224,8 @@ describe('element screenshot', (suite, parameters) => {
await context.close();
});
- it('should work with device scale factor', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+ it('should work with device scale factor', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server, golden}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
const page = await context.newPage();
@@ -289,8 +289,8 @@ describe('element screenshot', (suite, parameters) => {
await context.close();
});
- it('should restore viewport after page screenshot and exception', (test, parameters) => {
- test.skip(options.WIRE);
+ it('should restore viewport after page screenshot and exception', (test, { wire }) => {
+ test.skip(wire);
}, async ({ browser, server }) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
@@ -302,8 +302,8 @@ describe('element screenshot', (suite, parameters) => {
await context.close();
});
- it('should restore viewport after page screenshot and timeout', (test, parameters) => {
- test.skip(options.WIRE);
+ it('should restore viewport after page screenshot and timeout', (test, { wire }) => {
+ test.skip(wire);
}, async ({ browser, server }) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
@@ -348,8 +348,8 @@ describe('element screenshot', (suite, parameters) => {
await context.close();
});
- it('should restore viewport after element screenshot and exception', (test, parameters) => {
- test.skip(options.WIRE);
+ it('should restore viewport after element screenshot and exception', (test, { wire }) => {
+ test.skip(wire);
}, async ({browser}) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
@@ -362,8 +362,8 @@ describe('element screenshot', (suite, parameters) => {
await context.close();
});
- it('should wait for element to stop moving', (test, parameters) => {
- test.flaky(options.WEBKIT(parameters) && !options.HEADLESS && options.LINUX(parameters));
+ it('should wait for element to stop moving', (test, { browserName, headful, platform }) => {
+ test.flaky(browserName === 'webkit' && headful && platform === 'linux');
}, async ({ page, server, golden }) => {
await page.setViewportSize({ width: 500, height: 500 });
await page.goto(server.PREFIX + '/grid.html');
diff --git a/test/elementhandle-wait-for-element-state.spec.ts b/test/elementhandle-wait-for-element-state.spec.ts
index b7a2da0165670..dd88c9056ed8a 100644
--- a/test/elementhandle-wait-for-element-state.spec.ts
+++ b/test/elementhandle-wait-for-element-state.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
async function giveItAChanceToResolve(page) {
for (let i = 0; i < 5; i++)
@@ -114,8 +114,8 @@ it('should wait for disabled button', async ({page}) => {
await promise;
});
-it('should wait for stable position', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters) && options.LINUX(parameters));
+it('should wait for stable position', (test, { browserName, platform }) => {
+ test.fixme(browserName === 'firefox' && platform === 'linux');
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/input/button.html');
const button = await page.$('button');
diff --git a/test/emulation-focus.spec.ts b/test/emulation-focus.spec.ts
index 1398326bf3235..9f5d431821b3d 100644
--- a/test/emulation-focus.spec.ts
+++ b/test/emulation-focus.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame } from './utils';
it('should think that it is focused by default', async ({page}) => {
@@ -101,8 +101,8 @@ it('should change document.activeElement', async ({page, server}) => {
expect(active).toEqual(['INPUT', 'TEXTAREA']);
});
-it('should not affect screenshots', (test, parameters) => {
- test.skip(options.FIREFOX(parameters) && !options.HEADLESS);
+it('should not affect screenshots', (test, { browserName, headful }) => {
+ test.skip(browserName === 'firefox' && headful);
}, async ({page, server, golden}) => {
// Firefox headful produces a different image.
const page2 = await page.context().newPage();
diff --git a/test/firefox/launcher.spec.ts b/test/firefox/launcher.spec.ts
index e0744ff51249c..45977d09b3cf6 100644
--- a/test/firefox/launcher.spec.ts
+++ b/test/firefox/launcher.spec.ts
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { it, expect, options } from '../fixtures';
+import { it, expect } from '../fixtures';
-it('should pass firefox user preferences', (test, parameters) => {
- test.skip(!options.FIREFOX(parameters));
+it('should pass firefox user preferences', (test, { browserName }) => {
+ test.skip(browserName !== 'firefox');
}, async ({browserType, defaultBrowserOptions}) => {
const browser = await browserType.launch({
...defaultBrowserOptions,
diff --git a/test/fixtures.spec.ts b/test/fixtures.spec.ts
index 8043a9b986391..55375687f2072 100644
--- a/test/fixtures.spec.ts
+++ b/test/fixtures.spec.ts
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-import { options } from './fixtures';
import { serverFixtures } from './remoteServer.fixture';
import { execSync } from 'child_process';
import path from 'path';
@@ -58,8 +57,8 @@ it('should close the browser when the node process closes', test => {
// so we don't check it here.
});
-describe('fixtures', (suite, parameters) => {
- suite.skip(options.WIN(parameters) || !options.HEADLESS);
+describe('fixtures', (suite, { platform, headful }) => {
+ suite.skip(platform === 'win32' || headful);
suite.slow();
}, () => {
// Cannot reliably send signals on Windows.
diff --git a/test/fixtures.ts b/test/fixtures.ts
index cdff300b24533..24782c1e65a72 100644
--- a/test/fixtures.ts
+++ b/test/fixtures.ts
@@ -26,15 +26,15 @@ import { Transport } from '../lib/protocol/transport';
import { installCoverageHooks } from './coverage';
import { fixtures as httpFixtures } from './http.fixtures';
import { fixtures as implFixtures } from './impl.fixtures';
-import { fixtures as platformFixtures, options as platformOptions } from './platform.fixtures';
-import { fixtures as playwrightFixtures, options as playwrightOptions } from './playwright.fixtures';
+import { fixtures as platformFixtures } from './platform.fixtures';
+import { fixtures as playwrightFixtures } from './playwright.fixtures';
export { expect } from '@playwright/test/out/matcher.fixtures';
export { config } from '@playwright/test-runner';
const removeFolderAsync = util.promisify(require('rimraf'));
type AllParameters = {
- browserName: string;
+ wire: boolean;
};
type AllWorkerFixtures = {
@@ -53,7 +53,6 @@ export const fixtures = playwrightFixtures
.declareParameters()
.declareWorkerFixtures()
.declareTestFixtures();
-const { defineTestFixture, defineWorkerFixture, overrideWorkerFixture } = fixtures;
export const it = fixtures.it;
export const fit = fixtures.fit;
@@ -66,11 +65,7 @@ export const afterEach = fixtures.afterEach;
export const beforeAll = fixtures.beforeAll;
export const afterAll = fixtures.afterAll;
-export const options = {
- ...platformOptions,
- ...playwrightOptions,
- WIRE: !!process.env.PWWIRE,
-};
+fixtures.defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false);
const getExecutablePath = browserName => {
if (browserName === 'chromium' && process.env.CRPATH)
@@ -81,23 +76,23 @@ const getExecutablePath = browserName => {
return process.env.WKPATH;
};
-overrideWorkerFixture('defaultBrowserOptions', async ({browserName}, runTest) => {
+fixtures.overrideWorkerFixture('defaultBrowserOptions', async ({ browserName, headful, slowMo }, runTest) => {
const executablePath = getExecutablePath(browserName);
if (executablePath)
console.error(`Using executable at ${executablePath}`);
await runTest({
- handleSIGINT: false,
- slowMo: options.SLOW_MO,
- headless: options.HEADLESS,
executablePath,
+ handleSIGINT: false,
+ slowMo,
+ headless: !headful,
artifactsPath: config.outputDir,
});
});
-overrideWorkerFixture('playwright', async ({browserName, testWorkerIndex, platform}, test) => {
+fixtures.overrideWorkerFixture('playwright', async ({ browserName, testWorkerIndex, platform, wire }, runTest) => {
assert(platform); // Depend on platform to generate all tests.
const {coverage, uninstall} = installCoverageHooks(browserName);
- if (options.WIRE) {
+ if (wire) {
require('../lib/utils/utils').setUnderTest();
const connection = new Connection();
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'server.js'), [], {
@@ -113,7 +108,7 @@ overrideWorkerFixture('playwright', async ({browserName, testWorkerIndex, platfo
connection.onmessage = message => transport.send(JSON.stringify(message));
transport.onmessage = message => connection.dispatch(JSON.parse(message));
const playwrightObject = await connection.waitForObjectWithKnownName('Playwright');
- await test(playwrightObject);
+ await runTest(playwrightObject);
spawnedProcess.removeListener('exit', onExit);
spawnedProcess.stdin.destroy();
spawnedProcess.stdout.destroy();
@@ -121,7 +116,7 @@ overrideWorkerFixture('playwright', async ({browserName, testWorkerIndex, platfo
await teardownCoverage();
} else {
const playwright = require('../index');
- await test(playwright);
+ await runTest(playwright);
await teardownCoverage();
}
@@ -134,11 +129,11 @@ overrideWorkerFixture('playwright', async ({browserName, testWorkerIndex, platfo
}
});
-defineWorkerFixture('golden', async ({browserName}, test) => {
+fixtures.defineWorkerFixture('golden', async ({browserName}, test) => {
await test(p => path.join(browserName, p));
});
-defineTestFixture('createUserDataDir', async ({testOutputDir}, runTest) => {
+fixtures.defineTestFixture('createUserDataDir', async ({testOutputDir}, runTest) => {
let counter = 0;
const dirs: string[] = [];
async function createUserDataDir() {
@@ -154,7 +149,7 @@ defineTestFixture('createUserDataDir', async ({testOutputDir}, runTest) => {
await Promise.all(dirs.map(dir => removeFolderAsync(dir).catch(e => {})));
});
-defineTestFixture('launchPersistent', async ({createUserDataDir, defaultBrowserOptions, browserType}, test) => {
+fixtures.defineTestFixture('launchPersistent', async ({createUserDataDir, defaultBrowserOptions, browserType}, test) => {
let context;
async function launchPersistent(options) {
if (context)
diff --git a/test/focus.spec.ts b/test/focus.spec.ts
index 26f920f02f1eb..071d6a8854224 100644
--- a/test/focus.spec.ts
+++ b/test/focus.spec.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
-it('should work', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should work', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async function({page}) {
await page.setContent(``);
expect(await page.evaluate(() => document.activeElement.nodeName)).toBe('BODY');
@@ -78,8 +78,8 @@ it('should traverse focus in all directions', async function({page}) {
expect(await page.evaluate(() => (document.activeElement as HTMLInputElement).value)).toBe('1');
});
-it('should traverse only form elements', (test, parameters) => {
- test.skip(!options.MAC(parameters) || !options.WEBKIT(parameters),
+it('should traverse only form elements', (test, { browserName, platform }) => {
+ test.skip(platform !== 'darwin' || browserName !== 'webkit',
'Chromium and WebKit both have settings for tab traversing all links, but it is only on by default in WebKit.');
}, async function({page}) {
await page.setContent(`
diff --git a/test/frame-evaluate.spec.ts b/test/frame-evaluate.spec.ts
index 584e4772e6b59..fe9da6368633c 100644
--- a/test/frame-evaluate.spec.ts
+++ b/test/frame-evaluate.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame, detachFrame } from './utils';
import type { Frame } from '../src/client/frame';
@@ -44,8 +44,8 @@ function expectContexts(pageImpl, count, isChromium) {
expect(pageImpl._delegate._contextIdToContext.size).toBe(count);
}
-it('should dispose context on navigation', test => {
- test.skip(options.WIRE);
+it('should dispose context on navigation', (test, { wire }) => {
+ test.skip(wire);
}, async ({ page, server, toImpl, isChromium }) => {
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2);
@@ -54,8 +54,8 @@ it('should dispose context on navigation', test => {
expectContexts(toImpl(page), 2, isChromium);
});
-it('should dispose context on cross-origin navigation', (test, parameters) => {
- test.skip(options.WIRE);
+it('should dispose context on cross-origin navigation', (test, { wire }) => {
+ test.skip(wire);
}, async ({ page, server, toImpl, isChromium }) => {
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2);
@@ -132,9 +132,9 @@ it('should be isolated between frames', async ({page, server}) => {
expect(a2).toBe(2);
});
-it('should work in iframes that failed initial navigation', (test, parameters) => {
- test.fail(options.CHROMIUM(parameters));
- test.fixme(options.FIREFOX(parameters));
+it('should work in iframes that failed initial navigation', (test, { browserName }) => {
+ test.fail(browserName === 'chromium');
+ test.fixme(browserName === 'firefox');
}, async ({page}) => {
// - Firefox does not report domcontentloaded for the iframe.
// - Chromium and Firefox report empty url.
@@ -156,8 +156,8 @@ it('should work in iframes that failed initial navigation', (test, parameters) =
expect(await page.frames()[1].$('div')).toBeTruthy();
});
-it('should work in iframes that interrupted initial javascript url navigation', (test, parameters) => {
- test.fixme(options.CHROMIUM(parameters));
+it('should work in iframes that interrupted initial javascript url navigation', (test, { browserName }) => {
+ test.fixme(browserName === 'chromium');
}, async ({page, server}) => {
// Chromium does not report isolated world for the iframe.
await page.goto(server.EMPTY_PAGE);
diff --git a/test/frame-hierarchy.spec.ts b/test/frame-hierarchy.spec.ts
index bdb7b877511a7..2d365a2952f8c 100644
--- a/test/frame-hierarchy.spec.ts
+++ b/test/frame-hierarchy.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame, detachFrame } from './utils';
import type { Frame } from '../index';
@@ -189,8 +189,8 @@ it('should report different frame instance when frame re-attaches', async ({page
expect(frame1).not.toBe(frame2);
});
-it('should refuse to display x-frame-options:deny iframe', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters));
+it('should refuse to display x-frame-options:deny iframe', (test, { browserName }) => {
+ test.fixme(browserName === 'firefox');
}, async ({page, server}) => {
server.setRoute('/x-frame-options-deny.html', async (req, res) => {
res.setHeader('Content-Type', 'text/html');
diff --git a/test/headful.spec.ts b/test/headful.spec.ts
index fdcf91b7c4e8a..74020717b847f 100644
--- a/test/headful.spec.ts
+++ b/test/headful.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should have default url when launching browser', async ({browserType, defaultBrowserOptions, createUserDataDir}) => {
const browserContext = await browserType.launchPersistentContext(await createUserDataDir(), {...defaultBrowserOptions, headless: false });
@@ -23,9 +23,9 @@ it('should have default url when launching browser', async ({browserType, defaul
await browserContext.close();
});
-it('headless should be able to read cookies written by headful', (test, parameters) => {
- test.fail(options.WIN(parameters) && options.CHROMIUM(parameters));
- test.flaky(options.FIREFOX(parameters));
+it('headless should be able to read cookies written by headful', (test, { browserName, platform }) => {
+ test.fail(platform === 'win32' && browserName === 'chromium');
+ test.flaky(browserName === 'firefox');
test.slow();
}, async ({browserType, defaultBrowserOptions, server, createUserDataDir}) => {
// see https://github.com/microsoft/playwright/issues/717
@@ -129,8 +129,8 @@ it('should(not) block third party cookies', async ({browserType, defaultBrowserO
await browser.close();
});
-it('should not override viewport size when passed null', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters));
+it('should not override viewport size when passed null', (test, { browserName }) => {
+ test.fixme(browserName === 'webkit');
}, async function({browserType, defaultBrowserOptions, server}) {
// Our WebKit embedder does not respect window features.
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
diff --git a/test/keyboard.spec.ts b/test/keyboard.spec.ts
index d8209302bd8ca..9c31bb94a7d68 100644
--- a/test/keyboard.spec.ts
+++ b/test/keyboard.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame } from './utils';
it('should type into a textarea', async ({page}) => {
@@ -83,8 +83,8 @@ it('insertText should only emit input event', async ({page, server}) => {
expect(await events.jsonValue()).toEqual(['input']);
});
-it('should report shiftKey', (test, parameters) => {
- test.fail(options.FIREFOX(parameters) && options.MAC(parameters));
+it('should report shiftKey', (test, { browserName, platform }) => {
+ test.fail(browserName === 'firefox' && platform === 'darwin');
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
@@ -342,8 +342,8 @@ it('should be able to prevent selectAll', async ({page, server, isMac}) => {
expect(await page.$eval('textarea', textarea => textarea.value)).toBe('some tex');
});
-it('should support MacOS shortcuts', (test, parameters) => {
- test.skip(!options.MAC(parameters));
+it('should support MacOS shortcuts', (test, { platform }) => {
+ test.skip(platform !== 'darwin');
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = await page.$('textarea');
@@ -384,8 +384,8 @@ it('should work after a cross origin navigation', async ({page, server}) => {
});
// event.keyIdentifier has been removed from all browsers except WebKit
-it('should expose keyIdentifier in webkit', (test, parameters) => {
- test.skip(!options.WEBKIT(parameters));
+it('should expose keyIdentifier in webkit', (test, { browserName }) => {
+ test.skip(browserName !== 'webkit');
}, async ({page}) => {
const lastEvent = await captureLastKeydown(page);
const keyMap = {
diff --git a/test/mouse.spec.ts b/test/mouse.spec.ts
index c0dd44282587e..69b40b519be2f 100644
--- a/test/mouse.spec.ts
+++ b/test/mouse.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, xdescribe, options } from './fixtures';
+import { it, expect, xdescribe } from './fixtures';
function dimensions() {
const rect = document.querySelector('textarea').getBoundingClientRect();
@@ -27,8 +27,8 @@ function dimensions() {
};
}
-it('should click the document', (test, parameters) => {
- test.flaky(options.FIREFOX(parameters) && options.WIN(parameters), 'Occasionally times out on options.FIREFOX on Windows: https://github.com/microsoft/playwright/pull/1911/checks?check_run_id=607149016');
+it('should click the document', (test, { browserName, platform }) => {
+ test.flaky(browserName === 'firefox' && platform === 'win32', 'Occasionally times out on options.FIREFOX on Windows: https://github.com/microsoft/playwright/pull/1911/checks?check_run_id=607149016');
}, async ({page, server}) => {
await page.evaluate(() => {
window['clickPromise'] = new Promise(resolve => {
@@ -165,8 +165,8 @@ it('should tween mouse movement', async ({page, isWebKit}) => {
]);
});
-it('should work with mobile viewports and cross process navigations', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+it('should work with mobile viewports and cross process navigations', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server}) => {
// @see https://crbug.com/929806
const context = await browser.newContext({ viewport: {width: 360, height: 640}, isMobile: true });
diff --git a/test/network-request.spec.ts b/test/network-request.spec.ts
index ac6adb9f6f6ed..8891e43aeba80 100644
--- a/test/network-request.spec.ts
+++ b/test/network-request.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import { attachFrame } from './utils';
it('should work for main frame navigation request', async ({page, server}) => {
@@ -55,8 +55,8 @@ it('should return headers', async ({page, server, isChromium, isFirefox, isWebKi
expect(response.request().headers()['user-agent']).toContain('WebKit');
});
-it('should get the same headers as the server', (test, parameters) => {
- test.fail(options.CHROMIUM(parameters) || options.WEBKIT(parameters), 'Provisional headers differ from those in network stack');
+it('should get the same headers as the server', (test, { browserName }) => {
+ test.fail(browserName === 'chromium' || browserName === 'webkit', 'Provisional headers differ from those in network stack');
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/empty.html');
let serverRequest;
diff --git a/test/page-add-script-tag.spec.ts b/test/page-add-script-tag.spec.ts
index d18211e670dd7..743ad4a437f91 100644
--- a/test/page-add-script-tag.spec.ts
+++ b/test/page-add-script-tag.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import path from 'path';
it('should throw an error if no options are provided', async ({page, server}) => {
@@ -74,8 +74,8 @@ it('should work with a path', async ({page, server}) => {
expect(await page.evaluate(() => window['__injected'])).toBe(42);
});
-it('should include sourceURL when path is provided', (test, parameters) => {
- test.skip(options.WEBKIT(parameters));
+it('should include sourceURL when path is provided', (test, { browserName }) => {
+ test.skip(browserName === 'webkit');
}, async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
diff --git a/test/page-basic.spec.ts b/test/page-basic.spec.ts
index 567021afd94c2..8c8676f47834b 100644
--- a/test/page-basic.spec.ts
+++ b/test/page-basic.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should reject all promises when page is closed', async ({context}) => {
const newPage = await context.newPage();
@@ -252,8 +252,8 @@ it('frame.press should work', async ({page, server}) => {
expect(await frame.evaluate(() => document.querySelector('textarea').value)).toBe('a');
});
-it('frame.focus should work multiple times', (test, parameters) => {
- test.fail(options.FIREFOX(parameters));
+it('frame.focus should work multiple times', (test, { browserName }) => {
+ test.fail(browserName === 'firefox');
}, async ({ context, server }) => {
const page1 = await context.newPage();
const page2 = await context.newPage();
diff --git a/test/page-evaluate.spec.ts b/test/page-evaluate.spec.ts
index a6414401f8af6..3759b3b80660e 100644
--- a/test/page-evaluate.spec.ts
+++ b/test/page-evaluate.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should work', async ({ page, server }) => {
const result = await page.evaluate(() => 7 * 3);
@@ -415,8 +415,8 @@ it('should not throw an error when evaluation does a navigation', async ({ page,
expect(result).toEqual([42]);
});
-it('should not throw an error when evaluation does a synchronous navigation and returns an object', (test, parameters) => {
- test.fixme(options.WEBKIT(parameters));
+it('should not throw an error when evaluation does a synchronous navigation and returns an object', (test, { browserName }) => {
+ test.fixme(browserName === 'webkit');
}, async ({ page, server }) => {
// It is imporant to be on about:blank for sync reload.
const result = await page.evaluate(() => {
@@ -426,7 +426,7 @@ it('should not throw an error when evaluation does a synchronous navigation and
expect(result).toEqual({ a: 42 });
});
-it('should not throw an error when evaluation does a synchronous navigation and returns undefined', async ({ page, server }) => {
+it('should not throw an error when evaluation does a synchronous navigation and returns undefined', async ({ page }) => {
// It is imporant to be on about:blank for sync reload.
const result = await page.evaluate(() => {
window.location.reload();
@@ -435,15 +435,15 @@ it('should not throw an error when evaluation does a synchronous navigation and
expect(result).toBe(undefined);
});
-it('should transfer 100Mb of data from page to node.js', (test, parameters) => {
- test.skip(options.WIRE);
+it('should transfer 100Mb of data from page to node.js', (test, { wire }) => {
+ test.skip(wire);
}, async ({ page }) => {
// This is too slow with wire.
const a = await page.evaluate(() => Array(100 * 1024 * 1024 + 1).join('a'));
expect(a.length).toBe(100 * 1024 * 1024);
});
-it('should throw error with detailed information on exception inside promise ', async ({ page, server }) => {
+it('should throw error with detailed information on exception inside promise ', async ({ page }) => {
let error = null;
await page.evaluate(() => new Promise(() => {
throw new Error('Error in promise');
@@ -482,7 +482,7 @@ it('should work with non-strict expressions', async ({ page, server }) => {
})).toBe(3.14);
});
-it('should respect use strict expression', async ({ page, server }) => {
+it('should respect use strict expression', async ({ page }) => {
const error = await page.evaluate(() => {
'use strict';
// @ts-ignore
@@ -493,11 +493,11 @@ it('should respect use strict expression', async ({ page, server }) => {
expect(error.message).toContain('variableY');
});
-it('should not leak utility script', async function({ page, server }) {
+it('should not leak utility script', async function({ page }) {
expect(await page.evaluate(() => this === window)).toBe(true);
});
-it('should not leak handles', async ({ page, server }) => {
+it('should not leak handles', async ({ page }) => {
const error = await page.evaluate('handles.length').catch(e => e);
expect((error as Error).message).toContain(' handles');
});
@@ -508,7 +508,7 @@ it('should work with CSP', async ({ page, server }) => {
expect(await page.evaluate(() => 2 + 2)).toBe(4);
});
-it('should evaluate exception', async ({ page, server }) => {
+it('should evaluate exception', async ({ page }) => {
const error = await page.evaluate(() => {
return (function functionOnStack() {
return new Error('error message');
@@ -518,7 +518,7 @@ it('should evaluate exception', async ({ page, server }) => {
expect(error).toContain('functionOnStack');
});
-it('should evaluate exception', async ({ page, server }) => {
+it('should evaluate exception', async ({ page }) => {
const error = await page.evaluate(`new Error('error message')`);
expect(error).toContain('Error: error message');
});
@@ -545,12 +545,12 @@ it('should jsonValue() date', async ({ page }) => {
expect(await resultHandle.jsonValue()).toEqual({ date: new Date('2020-05-27T01:31:38.506Z') });
});
-it('should not use toJSON when evaluating', async ({ page, server }) => {
+it('should not use toJSON when evaluating', async ({ page }) => {
const result = await page.evaluate(() => ({ toJSON: () => 'string', data: 'data' }));
expect(result).toEqual({ data: 'data', toJSON: {} });
});
-it('should not use toJSON in jsonValue', async ({ page, server }) => {
+it('should not use toJSON in jsonValue', async ({ page }) => {
const resultHandle = await page.evaluateHandle(() => ({ toJSON: () => 'string', data: 'data' }));
expect(await resultHandle.jsonValue()).toEqual({ data: 'data', toJSON: {} });
});
diff --git a/test/page-event-crash.spec.ts b/test/page-event-crash.spec.ts
index 7e20b3c06b9bc..9625343e1b786 100644
--- a/test/page-event-crash.spec.ts
+++ b/test/page-event-crash.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
function crash(page, toImpl, browserName) {
if (browserName === 'chromium')
@@ -26,9 +26,9 @@ function crash(page, toImpl, browserName) {
toImpl(page)._delegate._session.send('Page.crash', {}).catch(e => {});
}
-describe('', (suite, parameters) => {
- suite.fixme(options.WIRE);
- suite.flaky(options.FIREFOX(parameters) && options.WIN(parameters));
+describe('', (suite, { browserName, platform, wire }) => {
+ suite.fixme(wire);
+ suite.flaky(browserName === 'firefox' && platform === 'win32');
}, () => {
it('should emit crash event when page crashes', async ({page, browserName, toImpl}) => {
await page.setContent(`
This page should crash
`);
@@ -63,9 +63,9 @@ describe('', (suite, parameters) => {
expect(error.message).toContain('Navigation failed because page crashed');
});
- it('should be able to close context when page crashes', (test, parameters) => {
- test.fixme(options.WIRE);
- test.flaky(options.FIREFOX(parameters) && options.WIN(parameters));
+ it('should be able to close context when page crashes', (test, { browserName, platform, wire }) => {
+ test.fixme(wire);
+ test.flaky(browserName === 'firefox' && platform === 'win32');
}, async ({page, browserName, toImpl}) => {
await page.setContent(`
This page should crash
`);
crash(page, toImpl, browserName);
diff --git a/test/page-event-pageerror.spec.ts b/test/page-event-pageerror.spec.ts
index 134d498088e08..a0fb02710349c 100644
--- a/test/page-event-pageerror.spec.ts
+++ b/test/page-event-pageerror.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
it('should fire', async ({page, server, isWebKit}) => {
const [error] = await Promise.all([
@@ -31,8 +31,8 @@ it('should fire', async ({page, server, isWebKit}) => {
expect(error.stack).toBe(stack);
});
-it('should contain sourceURL', (test, parameters) => {
- test.fail(options.WEBKIT(parameters));
+it('should contain sourceURL', (test, { browserName }) => {
+ test.fail(browserName === 'webkit');
}, async ({page, server}) => {
const [error] = await Promise.all([
page.waitForEvent('pageerror'),
@@ -57,8 +57,8 @@ it('should handle odd values', async ({page, isFirefox}) => {
}
});
-it('should handle object', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters));
+it('should handle object', (test, { browserName }) => {
+ test.fixme(browserName === 'firefox');
}, async ({page, isChromium}) => {
// Firefox just does not report this error.
const [error] = await Promise.all([
@@ -68,8 +68,8 @@ it('should handle object', (test, parameters) => {
expect(error.message).toBe(isChromium ? 'Object' : '[object Object]');
});
-it('should handle window', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters));
+it('should handle window', (test, { browserName }) => {
+ test.fixme(browserName === 'firefox');
}, async ({page, isChromium}) => {
// Firefox just does not report this error.
const [error] = await Promise.all([
diff --git a/test/page-fill.spec.ts b/test/page-fill.spec.ts
index 39094616376d6..7253cad1009ed 100644
--- a/test/page-fill.spec.ts
+++ b/test/page-fill.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
async function giveItAChanceToFill(page) {
for (let i = 0; i < 5; i++)
@@ -60,22 +60,22 @@ it('should fill date input after clicking', async ({page, server}) => {
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02');
});
-it('should throw on incorrect date', (test, parameters) => {
- test.skip(options.WEBKIT(parameters));
+it('should throw on incorrect date', (test, { browserName }) => {
+ test.skip(browserName === 'webkit');
}, async ({page}) => {
await page.setContent('');
const error = await page.fill('input', '2020-13-05').catch(e => e);
expect(error.message).toContain('Malformed value');
});
-it('should fill time input', async ({page, server}) => {
+it('should fill time input', async ({page}) => {
await page.setContent('');
await page.fill('input', '13:15');
expect(await page.$eval('input', input => input.value)).toBe('13:15');
});
-it('should throw on incorrect time', (test, parameters) => {
- test.skip(options.WEBKIT(parameters));
+it('should throw on incorrect time', (test, { browserName }) => {
+ test.skip(browserName === 'webkit');
}, async ({page}) => {
await page.setContent('');
const error = await page.fill('input', '25:05').catch(e => e);
@@ -88,8 +88,8 @@ it('should fill datetime-local input', async ({page, server}) => {
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02T05:15');
});
-it('should throw on incorrect datetime-local', (test, parameters) => {
- test.skip(options.WEBKIT(parameters) || options.FIREFOX(parameters));
+it('should throw on incorrect datetime-local', (test, { browserName }) => {
+ test.skip(browserName === 'webkit' || browserName === 'firefox');
}, async ({page, server}) => {
await page.setContent('');
const error = await page.fill('input', 'abc').catch(e => e);
diff --git a/test/page-goto.spec.ts b/test/page-goto.spec.ts
index 78463b605eec8..bc631963866ee 100644
--- a/test/page-goto.spec.ts
+++ b/test/page-goto.spec.ts
@@ -17,7 +17,7 @@
import path from 'path';
import url from 'url';
-import { expect, it, options } from './fixtures';
+import { expect, it } from './fixtures';
import { expectedSSLError } from './utils';
it('should work', async ({page, server}) => {
@@ -25,7 +25,7 @@ it('should work', async ({page, server}) => {
expect(page.url()).toBe(server.EMPTY_PAGE);
});
-it('should work with file URL', async ({page, server}) => {
+it('should work with file URL', async ({page}) => {
const fileurl = url.pathToFileURL(path.join(__dirname, 'assets', 'frames', 'two-frames.html')).href;
await page.goto(fileurl);
expect(page.url().toLowerCase()).toBe(fileurl.toLowerCase());
@@ -360,8 +360,8 @@ it('should not leak listeners during bad navigation', async ({page, server}) =>
expect(warning).toBe(null);
});
-it('should not leak listeners during navigation of 20 pages', test => {
- test.flaky(options.TRACING, 'Flakes on tracing');
+it('should not leak listeners during navigation of 20 pages', (test, parameters) => {
+ test.flaky(parameters.trace, 'Flakes on tracing');
test.slow('We open 20 pages here');
}, async ({page, context, server}) => {
let warning = null;
diff --git a/test/page-history.spec.ts b/test/page-history.spec.ts
index e121af11f7114..38058fad0a100 100644
--- a/test/page-history.spec.ts
+++ b/test/page-history.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import url from 'url';
it('page.goBack should work', async ({page, server}) => {
@@ -52,8 +52,8 @@ it('page.goBack should work with HistoryAPI', async ({page, server}) => {
expect(page.url()).toBe(server.PREFIX + '/first.html');
});
-it('page.goBack should work for file urls', (test, parameters) => {
- test.fail(options.WEBKIT(parameters) && options.MAC(parameters));
+it('page.goBack should work for file urls', (test, { browserName, platform }) => {
+ test.fail(browserName === 'webkit' && platform === 'darwin');
}, async ({page, server, asset}) => {
// WebKit embedder fails to go back/forward to the file url.
const url1 = url.pathToFileURL(asset('empty.html')).href;
diff --git a/test/page-screenshot.spec.ts b/test/page-screenshot.spec.ts
index c0d6089b5de7a..2bf224c732ab0 100644
--- a/test/page-screenshot.spec.ts
+++ b/test/page-screenshot.spec.ts
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
import { verifyViewport } from './utils';
import path from 'path';
import fs from 'fs';
// Firefox headful produces a different image.
-describe('page screenshot', (suite, parameters) => {
- suite.skip(options.FIREFOX(parameters) && !options.HEADLESS);
+describe('page screenshot', (suite, { browserName, headful }) => {
+ suite.skip(browserName === 'firefox' && headful);
}, () => {
it('should work', async ({page, server, golden}) => {
await page.setViewportSize({width: 500, height: 500});
@@ -141,8 +141,8 @@ describe('page screenshot', (suite, parameters) => {
await Promise.all(pages.map(page => page.close()));
});
- it('should allow transparency', (test, parameters) => {
- test.fail(options.FIREFOX(parameters));
+ it('should allow transparency', (test, { browserName }) => {
+ test.fail(browserName === 'firefox');
}, async ({page, golden}) => {
await page.setViewportSize({ width: 50, height: 150 });
await page.setContent(`
@@ -177,8 +177,8 @@ describe('page screenshot', (suite, parameters) => {
expect(screenshot).toMatchImage(golden('screenshot-clip-odd-size.png'));
});
- it('should work with a mobile viewport', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+ it('should work with a mobile viewport', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server, golden}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true });
const page = await context.newPage();
@@ -188,8 +188,8 @@ describe('page screenshot', (suite, parameters) => {
await context.close();
});
- it('should work with a mobile viewport and clip', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+ it('should work with a mobile viewport and clip', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage();
@@ -199,8 +199,8 @@ describe('page screenshot', (suite, parameters) => {
await context.close();
});
- it('should work with a mobile viewport and fullPage', (test, parameters) => {
- test.skip(options.FIREFOX(parameters));
+ it('should work with a mobile viewport and fullPage', (test, { browserName }) => {
+ test.skip(browserName === 'firefox');
}, async ({browser, server, golden}) => {
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
const page = await context.newPage();
@@ -217,9 +217,9 @@ describe('page screenshot', (suite, parameters) => {
expect(screenshot).toMatchImage(golden('screenshot-canvas.png'), { threshold: 0.3 });
});
- it('should work for webgl', (test, parameters) => {
- test.fixme(options.FIREFOX(parameters));
- test.fixme(options.WEBKIT(parameters) && options.LINUX(parameters));
+ it('should work for webgl', (test, { browserName, platform }) => {
+ test.fixme(browserName === 'firefox');
+ test.fixme(browserName === 'webkit' && platform === 'linux');
}, async ({page, server, golden}) => {
await page.setViewportSize({width: 640, height: 480});
await page.goto(server.PREFIX + '/screenshots/webgl.html');
diff --git a/test/pdf.spec.ts b/test/pdf.spec.ts
index cdd64157b5945..dfa8a427635ce 100644
--- a/test/pdf.spec.ts
+++ b/test/pdf.spec.ts
@@ -14,22 +14,22 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import fs from 'fs';
import path from 'path';
-it('should be able to save file', (test, parameters) => {
- test.skip(!(options.HEADLESS && options.CHROMIUM(parameters)), 'Printing to pdf is currently only supported in headless chromium.');
+it('should be able to save file', (test, { browserName, headful }) => {
+ test.skip(headful || browserName !== 'chromium', 'Printing to pdf is currently only supported in headless chromium.');
}, async ({page, testOutputDir}) => {
const outputFile = path.join(testOutputDir, 'output.pdf');
await page.pdf({path: outputFile});
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
});
-it('should only have pdf in chromium', (test, parameters) => {
- test.skip(options.CHROMIUM(parameters));
+it('should only have pdf in chromium', (test, { browserName }) => {
+ test.skip(browserName === 'chromium');
}, async ({page}) => {
expect(page.pdf).toBe(undefined);
});
diff --git a/test/permissions.spec.ts b/test/permissions.spec.ts
index dfc04ff897a8a..c19ad5877c530 100644
--- a/test/permissions.spec.ts
+++ b/test/permissions.spec.ts
@@ -15,14 +15,14 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
function getPermission(page, name) {
return page.evaluate(name => navigator.permissions.query({name}).then(result => result.state), name);
}
-describe('permissions', (suite, parameters) => {
- suite.skip(options.WEBKIT(parameters));
+describe('permissions', (suite, { browserName }) => {
+ suite.skip(browserName === 'webkit');
}, () => {
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)
@@ -101,10 +101,10 @@ describe('permissions', (suite, parameters) => {
expect(await getPermission(page, 'geolocation')).toBe('prompt');
});
- it('should trigger permission onchange', (test, parameters) => {
- test.fail(options.WEBKIT(parameters));
- test.fail(options.CHROMIUM(parameters) && !options.HEADLESS);
- test.flaky(options.FIREFOX(parameters) && options.LINUX(parameters));
+ it('should trigger permission onchange', (test, { browserName, headful, platform }) => {
+ test.fail(browserName === 'webkit');
+ test.fail(browserName === 'chromium' && headful);
+ test.flaky(browserName === 'firefox' && platform === 'linux');
}, async ({page, server, context}) => {
// TODO: flaky
// - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883
@@ -147,10 +147,10 @@ describe('permissions', (suite, parameters) => {
await otherContext.close();
});
- it('should support clipboard read', (test, parameters) => {
- test.fail(options.WEBKIT(parameters));
- test.fail(options.FIREFOX(parameters), 'No such permissions (requires flag) in Firefox');
- test.fixme(options.CHROMIUM(parameters) && !options.HEADLESS);
+ it('should support clipboard read', (test, { browserName, headful }) => {
+ test.fail(browserName === 'webkit');
+ test.fail(browserName === 'firefox', 'No such permissions (requires flag) in Firefox');
+ test.fixme(browserName === 'chromium' && headful);
}, async ({page, server, context}) => {
await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');
diff --git a/test/platform.fixtures.ts b/test/platform.fixtures.ts
index c493e3d485a2b..81263013dea00 100644
--- a/test/platform.fixtures.ts
+++ b/test/platform.fixtures.ts
@@ -31,12 +31,6 @@ export const fixtures = baseFixtures
.declareWorkerFixtures();
const { defineWorkerFixture, defineParameter, generateParametrizedTests } = fixtures;
-export const options = {
- MAC: (parameters: PlatformParameters) => parameters.platform === 'darwin',
- LINUX: (parameters: PlatformParameters) => parameters.platform === 'linux',
- WIN: (parameters: PlatformParameters) => parameters.platform === 'win32',
-};
-
defineParameter('platform', 'Operating system', process.platform as ('win32' | 'linux' | 'darwin'));
generateParametrizedTests(
diff --git a/test/playwright.fixtures.ts b/test/playwright.fixtures.ts
index 5e7fc7e46b1cf..10422a422ccb9 100644
--- a/test/playwright.fixtures.ts
+++ b/test/playwright.fixtures.ts
@@ -24,24 +24,61 @@ import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, Launc
const mkdtempAsync = util.promisify(fs.mkdtemp);
const removeFolderAsync = util.promisify(require('rimraf'));
+
+// Parameter declarations ------------------------------------------------------
+
type PlaywrightParameters = {
- browserName: string;
+ // Browser name, one of 'chromium', 'webkit' and 'firefox', can be specified via
+ // environment BROWSER=webkit or via command line, --browser-name=webkit
+ browserName: 'chromium' | 'firefox' | 'webkit';
+ // Run tests in a headful mode, can be specified via environment HEADFUL=1 or via
+ // command line, --headful. Defaults to false.
+ headful: boolean;
+ // Slows down Playwright operations by the specified amount of milliseconds.
+ // Useful so that you can see what is going on. Defaults to 0.
+ slowMo: number;
+ // Whether to take screenshots on failure, --screenshot-on-failure. Defaults to false.
+ screenshotOnFailure: boolean;
+ // Whether to record the execution trace
+ trace: boolean;
};
+
+// Worker fixture declarations -------------------------------------------------
+// ... these live as long as the worker process.
+
type PlaywrightWorkerFixtures = {
- defaultBrowserOptions: LaunchOptions;
+ // Playwright library.
playwright: typeof import('../index');
+ // Browser type (Chromium / WebKit / Firefox)
browserType: BrowserType;
+ // Default browserType.launch() options.
+ defaultBrowserOptions: LaunchOptions;
+ // Factory for creating a browser with given additional options.
+ browserFactory: (options?: LaunchOptions) => Promise;
+ // Browser instance, shared for the worker.
browser: Browser;
+ // True iff browserName is Chromium
isChromium: boolean;
+ // True iff browserName is Firefox
isFirefox: boolean;
+ // True iff browserName is WebKit
isWebKit: boolean;
};
+
+// Test fixture definitions, those are created for each test ------------------
+
type PlaywrightTestFixtures = {
+ // Default browser.newContext() options.
+ defaultContextOptions: BrowserContextOptions;
+ // Factory for creating a context with given additional options.
+ contextFactory: (options?: BrowserContextOptions) => Promise;
+ // Context instance for test.
context: BrowserContext;
+ // Page instance for test.
page: Page;
- testOutputDir: string;
+ // Temporary directory for this test's artifacts.
tmpDir: string;
};
@@ -50,99 +87,121 @@ export const fixtures = baseFixtures
.declareWorkerFixtures()
.declareTestFixtures();
-const { defineTestFixture, defineWorkerFixture, defineParameter, generateParametrizedTests } = fixtures;
+// Parameter and matrix definitions --------------------------------------------
-export const options = {
- CHROMIUM: (parameters: PlaywrightParameters) => parameters.browserName === 'chromium',
- FIREFOX: (parameters: PlaywrightParameters) => parameters.browserName === 'firefox',
- WEBKIT: (parameters: PlaywrightParameters) => parameters.browserName === 'webkit',
- HEADLESS: !!valueFromEnv('HEADLESS', true),
- SLOW_MO: valueFromEnv('SLOW_MO', 0),
- TRACING: valueFromEnv('TRACING', false),
-};
+fixtures.defineParameter('browserName', 'Browser type name', process.env.BROWSER || 'chromium' as any);
+fixtures.defineParameter('headful', 'Whether to run tests headless or headful', process.env.HEADFUL ? true : false);
+fixtures.defineParameter('screenshotOnFailure', 'Generate screenshot on failure', false);
+fixtures.defineParameter('slowMo', 'Slows down Playwright operations by the specified amount of milliseconds', 0);
+fixtures.defineParameter('trace', 'Whether to record the execution trace', !!process.env.TRACING || false);
+
+// If browser is not specified, we are running tests against all three browsers.
+fixtures.generateParametrizedTests(
+ 'browserName',
+ process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']);
-defineWorkerFixture('defaultBrowserOptions', async ({}, runTest) => {
+
+// Worker fixtures definitions -------------------------------------------------
+
+fixtures.defineWorkerFixture('defaultBrowserOptions', async ({ headful, slowMo }, runTest) => {
await runTest({
handleSIGINT: false,
- slowMo: options.SLOW_MO,
- headless: options.HEADLESS,
+ slowMo,
+ headless: !headful,
artifactsPath: config.outputDir,
});
});
-defineWorkerFixture('playwright', async ({}, test) => {
+fixtures.defineWorkerFixture('playwright', async ({}, runTest) => {
const playwright = require('../index');
- await test(playwright);
+ await runTest(playwright);
});
-defineWorkerFixture('browserType', async ({playwright, browserName}, test) => {
+fixtures.defineWorkerFixture('browserType', async ({playwright, browserName}, runTest) => {
const browserType = playwright[browserName];
- await test(browserType);
+ await runTest(browserType);
});
-defineParameter('browserName', 'Browser type name', '');
-
-generateParametrizedTests(
- 'browserName',
- process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox']);
+fixtures.defineWorkerFixture('isFirefox', async ({browserName}, runTest) => {
+ await runTest(browserName === 'firefox');
+});
-defineWorkerFixture('isChromium', async ({browserName}, test) => {
- await test(browserName === 'chromium');
+fixtures.defineWorkerFixture('isWebKit', async ({browserName}, runTest) => {
+ await runTest(browserName === 'webkit');
});
-defineWorkerFixture('isFirefox', async ({browserName}, test) => {
- await test(browserName === 'firefox');
+fixtures.defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, runTest) => {
+ const browser = await browserType.launch(defaultBrowserOptions);
+ await runTest(browser);
+ await browser.close();
});
-defineWorkerFixture('isWebKit', async ({browserName}, test) => {
- await test(browserName === 'webkit');
+fixtures.defineWorkerFixture('isChromium', async ({browserName}, runTest) => {
+ await runTest(browserName === 'chromium');
});
-defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => {
- const browser = await browserType.launch(defaultBrowserOptions);
- await test(browser);
- if (browser.contexts().length !== 0) {
- console.warn(`\nWARNING: test did not close all created contexts! ${new Error().stack}\n`);
- await Promise.all(browser.contexts().map(context => context.close())).catch(e => void 0);
- }
- await browser.close();
+fixtures.defineWorkerFixture('isFirefox', async ({browserName}, runTest) => {
+ await runTest(browserName === 'firefox');
});
-defineTestFixture('testOutputDir', async ({ testInfo, browserName }, runTest) => {
- const relativePath = path.relative(config.testDir, testInfo.file)
- .replace(/\.spec\.[jt]s/, '')
- .replace(/\.test\.[jt]s/, '');
- const sanitizedTitle = testInfo.title.replace(/[^\w\d]+/g, '_');
- const testOutputDir = path.join(config.outputDir, relativePath, sanitizedTitle, browserName);
- await runTest(testOutputDir);
+fixtures.defineWorkerFixture('isWebKit', async ({browserName}, runTest) => {
+ await runTest(browserName === 'webkit');
});
-defineTestFixture('context', async ({ browser, testOutputDir }, runTest) => {
- const contextOptions: BrowserContextOptions = {
+// Test fixtures definitions ---------------------------------------------------
+
+fixtures.defineTestFixture('defaultContextOptions', async ({ testOutputDir, trace }, runTest) => {
+ await runTest({
relativeArtifactsPath: path.relative(config.outputDir, testOutputDir),
- recordTrace: !!options.TRACING,
- recordVideos: !!options.TRACING,
- };
- const context = await browser.newContext(contextOptions);
+ recordTrace: trace,
+ recordVideos: trace,
+ });
+});
+
+fixtures.defineTestFixture('contextFactory', async ({ browser, defaultContextOptions, testInfo, screenshotOnFailure, testOutputFile }, runTest) => {
+ const contexts: BrowserContext[] = [];
+ async function contextFactory(options: BrowserContextOptions = {}) {
+ const context = await browser.newContext({ ...defaultContextOptions, ...options });
+ contexts.push(context);
+ return context;
+ }
+ await runTest(contextFactory);
+
+ if (screenshotOnFailure && (testInfo.status !== testInfo.expectedStatus)) {
+ let ordinal = 0;
+ for (const context of contexts) {
+ for (const page of context.pages())
+ await page.screenshot({ timeout: 5000, path: await testOutputFile(`test-failed-${++ordinal}.png`) });
+ }
+ }
+ for (const context of contexts)
+ await context.close();
+});
+
+fixtures.defineTestFixture('context', async ({ contextFactory }, runTest) => {
+ const context = await contextFactory();
await runTest(context);
- await context.close();
+ // Context factory is taking care of closing the context,
+ // so that it could capture a screenshot on failure.
});
-defineTestFixture('page', async ({ context, testOutputDir, testInfo }, runTest) => {
- const page = await context.newPage();
- await runTest(page);
- if (testInfo.status === 'failed' || testInfo.status === 'timedOut')
- await page.screenshot({ timeout: 5000, path: path.join(testOutputDir, 'test-failed.png') });
+fixtures.defineTestFixture('page', async ({context}, runTest) => {
+ // Always create page off context so that they matched.
+ await runTest(await context.newPage());
+ // Context fixture is taking care of closing the page.
});
-defineTestFixture('tmpDir', async ({}, test) => {
+fixtures.defineTestFixture('tmpDir', async ({ }, runTest) => {
const tmpDir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
- await test(tmpDir);
- await removeFolderAsync(tmpDir).catch(e => {});
+ await runTest(tmpDir);
+ await removeFolderAsync(tmpDir).catch(e => { });
});
-function valueFromEnv(name, defaultValue) {
- if (!(name in process.env))
- return defaultValue;
- return JSON.parse(process.env[name]);
-}
+fixtures.overrideTestFixture('testOutputDir', async ({ testInfo, browserName }, runTest) => {
+ const relativePath = path.relative(config.testDir, testInfo.file)
+ .replace(/\.spec\.[jt]s/, '')
+ .replace(/\.test\.[jt]s/, '');
+ const sanitizedTitle = testInfo.title.replace(/[^\w\d]+/g, '_');
+ const testOutputDir = path.join(config.outputDir, relativePath, sanitizedTitle, browserName);
+ await runTest(testOutputDir);
+});
diff --git a/test/proxy.spec.ts b/test/proxy.spec.ts
index 826498d946006..c76c28e6e2a08 100644
--- a/test/proxy.spec.ts
+++ b/test/proxy.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import socks from 'socksv5';
@@ -77,8 +77,8 @@ it('should authenticate', async ({browserType, defaultBrowserOptions, server}) =
await browser.close();
});
-it('should exclude patterns', (test, parameters) => {
- test.flaky(options.CHROMIUM(parameters) && !options.HEADLESS, 'Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.');
+it('should exclude patterns', (test, { browserName, headful }) => {
+ test.flaky(browserName === 'chromium' && headful, 'Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.');
}, async ({browserType, defaultBrowserOptions, server}) => {
server.setRoute('/target.html', async (req, res) => {
res.end('Served by the proxy');
@@ -119,8 +119,8 @@ it('should exclude patterns', (test, parameters) => {
await browser.close();
});
-it('should use socks proxy', (test, parameters) => {
- test.flaky(options.MAC(parameters) && options.WEBKIT(parameters), 'Intermittent page.goto: The network connection was lost error on bots');
+it('should use socks proxy', (test, { browserName, platform }) => {
+ test.flaky(platform === 'darwin' && browserName === 'webkit', 'Intermittent page.goto: The network connection was lost error on bots');
}, async ({ browserType, defaultBrowserOptions, testWorkerIndex }) => {
const server = socks.createServer((info, accept, deny) => {
let socket;
diff --git a/test/request-fulfill.spec.ts b/test/request-fulfill.spec.ts
index ed363a7f29fd8..910199dc49eb9 100644
--- a/test/request-fulfill.spec.ts
+++ b/test/request-fulfill.spec.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { it, expect, options } from './fixtures';
+import { it, expect } from './fixtures';
import fs from 'fs';
import path from 'path';
@@ -50,8 +50,8 @@ it('should work with status code 422', async ({page, server}) => {
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
});
-it('should allow mocking binary responses', (test, parameters) => {
- test.skip(options.FIREFOX(parameters) && !options.HEADLESS, '// Firefox headful produces a different image.');
+it('should allow mocking binary responses', (test, { browserName, headful }) => {
+ test.skip(browserName === 'firefox' && headful, '// Firefox headful produces a different image.');
}, async ({page, server, golden}) => {
await page.route('**/*', route => {
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
@@ -70,8 +70,8 @@ it('should allow mocking binary responses', (test, parameters) => {
expect(await img.screenshot()).toMatchImage(golden('mock-binary-response.png'));
});
-it('should allow mocking svg with charset', (test, parameters) => {
- test.skip(options.FIREFOX(parameters) && !options.HEADLESS, '// Firefox headful produces a different image.');
+it('should allow mocking svg with charset', (test, { browserName, headful }) => {
+ test.skip(browserName === 'firefox' && headful, '// Firefox headful produces a different image.');
}, async ({page, server, golden}) => {
// Firefox headful produces a different image.
await page.route('**/*', route => {
diff --git a/test/screencast.spec.ts b/test/screencast.spec.ts
index 1e890f4553676..d2d6d941e0e06 100644
--- a/test/screencast.spec.ts
+++ b/test/screencast.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { options, fixtures as playwrightFixtures, config } from './fixtures';
+import { fixtures as playwrightFixtures, config } from './fixtures';
import type { Page, Browser } from '..';
import fs from 'fs';
@@ -265,9 +265,9 @@ describe('screencast', suite => {
}
});
- it('should capture css transformation', (test, parameters) => {
- test.fail(options.WEBKIT(parameters) && options.WIN(parameters), 'Does not work on WebKit Windows');
- test.fixme(!options.HEADLESS, 'Fails on headful');
+ it('should capture css transformation', (test, { browserName, platform, headful }) => {
+ test.fail(browserName === 'webkit' && platform === 'win32', 'Does not work on WebKit Windows');
+ test.fixme(headful, 'Fails on headful');
}, async ({browser, server, videoPlayer, relativeArtifactsPath, videoDir}) => {
const size = {width: 320, height: 240};
// Set viewport equal to screencast frame size to avoid scaling.
@@ -315,8 +315,8 @@ describe('screencast', suite => {
expect(videoFiles.length).toBe(2);
});
- it('should scale frames down to the requested size ', test => {
- test.fixme(!options.HEADLESS, 'Fails on headful');
+ it('should scale frames down to the requested size ', (test, parameters) => {
+ test.fixme(parameters.headful, 'Fails on headful');
}, async ({browser, videoPlayer, relativeArtifactsPath, videoDir, server}) => {
const context = await browser.newContext({
relativeArtifactsPath,
diff --git a/test/slowmo.spec.ts b/test/slowmo.spec.ts
index 9ebaa4ece3c9b..ca3ace94590bc 100644
--- a/test/slowmo.spec.ts
+++ b/test/slowmo.spec.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { it, expect, describe, options } from './fixtures';
+import { it, expect, describe } from './fixtures';
import { attachFrame } from './utils';
async function checkSlowMo(toImpl, page, task) {
@@ -44,8 +44,8 @@ async function checkPageSlowMo(toImpl, page, task) {
`);
await checkSlowMo(toImpl, page, task);
}
-describe('slowMo', suite => {
- suite.skip(options.WIRE);
+describe('slowMo', (suite, { wire }) => {
+ suite.skip(wire);
}, () => {
it('Page SlowMo $$eval', async ({page, toImpl}) => {
await checkPageSlowMo(toImpl, page, () => page.$$eval('button', () => void 0));