New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@playwright/test

Package Overview
Dependencies
Maintainers
6
Versions
2496
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@playwright/test - npm Package Compare versions

Comparing version 0.1111.0 to 0.1112.0-alpha1

397

out/index.d.ts

@@ -16,181 +16,234 @@ /**

*/
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from 'playwright';
export { expect, config } from 'folio';
declare type PlaywrightParameters = {
browserName: 'chromium' | 'firefox' | 'webkit';
headful: boolean;
platform: 'win32' | 'linux' | 'darwin';
screenshotOnFailure: boolean;
slowMo: number;
video: boolean;
import { Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials } from 'playwright';
import * as folio from 'folio';
/**
* The name of the browser supported by Playwright.
*/
export declare type BrowserName = 'chromium' | 'firefox' | 'webkit';
/**
* Browser channel name. Used to run tests in different browser flavors,
* for example Google Chrome Beta, or Microsoft Edge Stable.
* @see BrowserContextOptions
*/
export declare type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
/**
* Emulates `'prefers-colors-scheme'` media feature,
* supported values are `'light'`, `'dark'`, `'no-preference'`.
* @see BrowserContextOptions
*/
export declare type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
/**
* An object containing additional HTTP headers to be sent with every request. All header values must be strings.
* @see BrowserContextOptions
*/
export declare type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
/**
* Proxy settings available for all tests, or individually per test.
* @see BrowserContextOptions
*/
export declare type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
/**
* Storage state for the test.
* @see BrowserContextOptions
*/
export declare type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
/**
* Options available to configure browser launch.
* - Set options in config:
* ```js
* use: { browserName: 'webkit' }
* ```
* - Set options in test file:
* ```js
* test.use({ browserName: 'webkit' })
* ```
*
* Available as arguments to the test function and all hooks (beforeEach, afterEach, beforeAll, afterAll).
*/
export declare type PlaywrightWorkerOptions = {
/**
* Name of the browser (`chromium`, `firefox`, `webkit`) that runs tests.
*/
browserName: BrowserName;
/**
* Whether to run browser in headless mode. Takes priority over `launchOptions`.
* @see LaunchOptions
*/
headless: boolean | undefined;
/**
* Browser distribution channel. Takes priority over `launchOptions`.
* @see LaunchOptions
*/
channel: BrowserChannel | undefined;
/**
* Options used to launch the browser. Other options above (e.g. `headless`) take priority.
* @see LaunchOptions
*/
launchOptions: LaunchOptions;
};
declare type PlaywrightWorkerFixtures = {
/**
* Options available to configure each test.
* - Set options in config:
* ```js
* use: { video: 'on' }
* ```
* - Set options in test file:
* ```js
* test.use({ video: 'on' })
* ```
*
* Available as arguments to the test function and beforeEach/afterEach hooks.
*/
export declare type PlaywrightTestOptions = {
/**
* Whether to capture a screenshot after each test, off by default.
* - `off`: Do not capture screenshots.
* - `on`: Capture screenshot after each test.
* - `only-on-failure`: Capture screenshot after each test failure.
*/
screenshot: 'off' | 'on' | 'only-on-failure';
/**
* Whether to record video for each test, off by default.
* - `off`: Do not record video.
* - `on`: Record video for each test.
* - `retain-on-failure`: Record video for each test, but remove all videos from successful test runs.
* - `retry-with-video`: Record video only when retrying a test.
*/
video: 'off' | 'on' | 'retain-on-failure' | 'retry-with-video';
/**
* Whether to automatically download all the attachments. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
acceptDownloads: boolean | undefined;
/**
* Toggles bypassing page's Content-Security-Policy. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
bypassCSP: boolean | undefined;
/**
* Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`.
* @see BrowserContextOptions
*/
colorScheme: ColorScheme | undefined;
/**
* Specify device scale factor (can be thought of as dpr). Defaults to `1`.
* @see BrowserContextOptions
*/
deviceScaleFactor: number | undefined;
/**
* An object containing additional HTTP headers to be sent with every request. All header values must be strings.
* @see BrowserContextOptions
*/
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
/**
* Context geolocation. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
geolocation: Geolocation | undefined;
/**
* Specifies if viewport supports touch events. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
hasTouch: boolean | undefined;
/**
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
* @see BrowserContextOptions
*/
httpCredentials: HTTPCredentials | undefined;
/**
* Whether to ignore HTTPS errors during navigation. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
ignoreHTTPSErrors: boolean | undefined;
/**
* Whether the `meta viewport` tag is taken into account and touch events are enabled. Not supported in Firefox.
* @see BrowserContextOptions
*/
isMobile: boolean | undefined;
/**
* Whether or not to enable JavaScript in the context. Defaults to `true`.
* @see BrowserContextOptions
*/
javaScriptEnabled: boolean | undefined;
/**
* User locale, for example `en-GB`, `de-DE`, etc. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
locale: string | undefined;
/**
* Whether to emulate network being offline.
* @see BrowserContextOptions
*/
offline: boolean | undefined;
/**
* A list of permissions to grant to all pages in this context. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
permissions: string[] | undefined;
/**
* Proxy setting used for all pages in the test. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
proxy: Proxy | undefined;
/**
* Populates context with given storage state. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
storageState: StorageState | undefined;
/**
* Changes the timezone of the context. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
timezoneId: string | undefined;
/**
* Specific user agent to use in this context.
* @see BrowserContextOptions
*/
userAgent: string | undefined;
/**
* Viewport used for all pages in the test. Takes priority over `contextOptions`.
* @see BrowserContextOptions
*/
viewport: ViewportSize | undefined;
/**
* Options used to create the context. Other options above (e.g. `viewport`) take priority.
* @see BrowserContextOptions
*/
contextOptions: BrowserContextOptions;
};
/**
* Arguments available to the test function and all hooks (beforeEach, afterEach, beforeAll, afterAll).
*/
export declare type PlaywrightWorkerArgs = {
/**
* The Playwright instance.
*/
playwright: typeof import('playwright');
browserType: BrowserType<Browser>;
browserOptions: LaunchOptions;
/**
* Browser instance, shared between multiple tests.
*/
browser: Browser;
isChromium: boolean;
isFirefox: boolean;
isWebKit: boolean;
isWindows: boolean;
isMac: boolean;
isLinux: boolean;
};
declare type PlaywrightTestFixtures = {
contextOptions: BrowserContextOptions;
contextFactory: (options?: BrowserContextOptions) => Promise<BrowserContext>;
/**
* Arguments available to the test function and beforeEach/afterEach hooks.
*/
export declare type PlaywrightTestArgs = {
/**
* BrowserContext instance, created fresh for each test.
*/
context: BrowserContext;
/**
* Page instance, created fresh for each test.
*/
page: Page;
};
export declare const folio: import("folio").Folio<{
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures, {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures, PlaywrightParameters>;
export declare const it: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
} & {
only: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
skip: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
};
export declare const fit: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
export declare const xit: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
export declare const test: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
} & {
only: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
skip: {
(name: string, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => void | Promise<void>): void;
};
};
export declare const describe: {
(name: string, inner: () => void): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: () => void): void;
} & {
only: {
(name: string, inner: () => void): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: () => void): void;
};
skip: {
(name: string, inner: () => void): void;
(name: string, modifierFn: (modifier: import("folio/out/testModifier").TestModifier, parameters: PlaywrightParameters) => any, inner: () => void): void;
};
};
export declare const beforeEach: (inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => Promise<void>) => void;
export declare const afterEach: (inner: (fixtures: PlaywrightParameters & {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures & {
testInfo: import("folio").TestInfo;
testParametersPathSegment: string;
} & PlaywrightTestFixtures) => Promise<void>) => void;
export declare const beforeAll: (inner: (fixtures: {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures) => Promise<void>) => void;
export declare const afterAll: (inner: (fixtures: {
testWorkerIndex: number;
} & PlaywrightWorkerFixtures) => Promise<void>) => void;
/**
* These tests are executed in Playwright environment that launches the browser
* and provides a fresh page to each test.
*/
export declare const test: folio.TestType<PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
export * from 'folio';
export default test;
export declare type PlaywrightTestProject<TestArgs = {}, WorkerArgs = {}> = folio.Project<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
export declare type PlaywrightTestConfig<TestArgs = {}, WorkerArgs = {}> = folio.Config<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
//# sourceMappingURL=index.d.ts.map

@@ -17,109 +17,154 @@ "use strict";

*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.afterAll = exports.beforeAll = exports.afterEach = exports.beforeEach = exports.describe = exports.test = exports.xit = exports.fit = exports.it = exports.folio = exports.config = exports.expect = void 0;
const folio_1 = require("folio");
var folio_2 = require("folio");
Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return folio_2.expect; } });
Object.defineProperty(exports, "config", { enumerable: true, get: function () { return folio_2.config; } });
// Test timeout for e2e tests is 30 seconds.
folio_1.config.timeout = 30000;
const fixtures = folio_1.folio.extend();
fixtures.browserName.initParameter('Browser type name', (process.env.BROWSER || 'chromium'));
fixtures.headful.initParameter('Whether to run tests headless or headful', process.env.HEADFUL ? true : false);
fixtures.platform.initParameter('Operating system', process.platform);
fixtures.screenshotOnFailure.initParameter('Generate screenshot on failure', false);
fixtures.slowMo.initParameter('Slows down Playwright operations by the specified amount of milliseconds', 0);
fixtures.video.initParameter('Record videos while running tests', false);
fixtures.browserOptions.init(async ({ headful, slowMo }, run) => {
await run({
handleSIGINT: false,
slowMo,
headless: !headful,
});
}, { scope: 'worker' });
fixtures.playwright.init(async ({}, run) => {
const playwright = require('playwright');
await run(playwright);
}, { scope: 'worker' });
fixtures.browserType.init(async ({ playwright, browserName }, run) => {
const browserType = playwright[browserName];
await run(browserType);
}, { scope: 'worker' });
fixtures.browser.init(async ({ browserType, browserOptions }, run) => {
const browser = await browserType.launch(browserOptions);
await run(browser);
await browser.close();
}, { scope: 'worker' });
fixtures.isChromium.init(async ({ browserName }, run) => {
await run(browserName === 'chromium');
}, { scope: 'worker' });
fixtures.isFirefox.init(async ({ browserName }, run) => {
await run(browserName === 'firefox');
}, { scope: 'worker' });
fixtures.isWebKit.init(async ({ browserName }, run) => {
await run(browserName === 'webkit');
}, { scope: 'worker' });
fixtures.isWindows.init(async ({ platform }, run) => {
await run(platform === 'win32');
}, { scope: 'worker' });
fixtures.isMac.init(async ({ platform }, run) => {
await run(platform === 'darwin');
}, { scope: 'worker' });
fixtures.isLinux.init(async ({ platform }, run) => {
await run(platform === 'linux');
}, { scope: 'worker' });
fixtures.contextOptions.init(async ({ video, testInfo }, run) => {
if (video) {
await run({
videosPath: testInfo.outputPath(''),
});
}
else {
await run({});
}
});
fixtures.contextFactory.init(async ({ browser, contextOptions, testInfo, screenshotOnFailure }, run) => {
const contexts = [];
async function contextFactory(options = {}) {
const context = await browser.newContext({ ...contextOptions, ...options });
contexts.push(context);
return context;
}
await run(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: testInfo.outputPath(`test-failed-${++ordinal}.png`) });
exports.test = void 0;
const folio = __importStar(require("folio"));
const fs = __importStar(require("fs"));
const util = __importStar(require("util"));
const headedOption = folio.registerCLIOption('headed', 'Run tests in headed browsers (default: headless)', { type: 'boolean' });
/**
* These tests are executed in Playwright environment that launches the browser
* and provides a fresh page to each test.
*/
exports.test = folio.test.extend({
browserName: ['chromium', { scope: 'worker' }],
playwright: [require('playwright'), { scope: 'worker' }],
headless: [undefined, { scope: 'worker' }],
channel: [undefined, { scope: 'worker' }],
launchOptions: [{}, { scope: 'worker' }],
browser: [async ({ playwright, browserName, headless, channel, launchOptions }, use) => {
const options = {
handleSIGINT: false,
...launchOptions,
};
if (headless !== undefined)
options.headless = headless;
if (channel !== undefined)
options.channel = channel;
if (headedOption.value)
options.headless = false;
const browser = await playwright[browserName].launch(options);
await use(browser);
await browser.close();
}, { scope: 'worker' }],
screenshot: 'off',
video: 'off',
acceptDownloads: undefined,
bypassCSP: undefined,
colorScheme: undefined,
deviceScaleFactor: undefined,
extraHTTPHeaders: undefined,
geolocation: undefined,
hasTouch: undefined,
httpCredentials: undefined,
ignoreHTTPSErrors: undefined,
isMobile: undefined,
javaScriptEnabled: undefined,
locale: undefined,
offline: undefined,
permissions: undefined,
proxy: undefined,
storageState: undefined,
timezoneId: undefined,
userAgent: undefined,
viewport: undefined,
contextOptions: {},
context: async ({ browserName, browser, screenshot, video, acceptDownloads, bypassCSP, colorScheme, deviceScaleFactor, extraHTTPHeaders, hasTouch, geolocation, httpCredentials, ignoreHTTPSErrors, isMobile, javaScriptEnabled, locale, offline, permissions, proxy, storageState, viewport, timezoneId, userAgent, contextOptions }, use, testInfo) => {
testInfo.snapshotPathSegment = browserName + '-' + process.platform;
if (process.env.PWDEBUG)
testInfo.setTimeout(0);
const recordVideo = video === 'on' || video === 'retain-on-failure' ||
(video === 'retry-with-video' && !!testInfo.retry);
const options = {
recordVideo: recordVideo ? { dir: testInfo.outputPath('') } : undefined,
...contextOptions,
};
if (acceptDownloads !== undefined)
options.acceptDownloads = acceptDownloads;
if (bypassCSP !== undefined)
options.bypassCSP = bypassCSP;
if (colorScheme !== undefined)
options.colorScheme = colorScheme;
if (deviceScaleFactor !== undefined)
options.deviceScaleFactor = deviceScaleFactor;
if (extraHTTPHeaders !== undefined)
options.extraHTTPHeaders = extraHTTPHeaders;
if (geolocation !== undefined)
options.geolocation = geolocation;
if (hasTouch !== undefined)
options.hasTouch = hasTouch;
if (httpCredentials !== undefined)
options.httpCredentials = httpCredentials;
if (ignoreHTTPSErrors !== undefined)
options.ignoreHTTPSErrors = ignoreHTTPSErrors;
if (isMobile !== undefined)
options.isMobile = isMobile;
if (javaScriptEnabled !== undefined)
options.javaScriptEnabled = javaScriptEnabled;
if (locale !== undefined)
options.locale = locale;
if (offline !== undefined)
options.offline = offline;
if (permissions !== undefined)
options.permissions = permissions;
if (proxy !== undefined)
options.proxy = proxy;
if (storageState !== undefined)
options.storageState = storageState;
if (timezoneId !== undefined)
options.timezoneId = timezoneId;
if (userAgent !== undefined)
options.userAgent = userAgent;
if (viewport !== undefined)
options.viewport = viewport;
const context = await browser.newContext(options);
const allPages = [];
context.on('page', page => allPages.push(page));
await use(context);
const testFailed = testInfo.status !== testInfo.expectedStatus;
if (screenshot === 'on' || (screenshot === 'only-on-failure' && testFailed)) {
await Promise.all(allPages.map((page, index) => {
const screenshotPath = testInfo.outputPath(`test-${testFailed ? 'failed' : 'finished'}-${++index}.png`);
return page.screenshot({ timeout: 5000, path: screenshotPath }).catch(e => { });
}));
}
}
for (const context of contexts)
await context.close();
const deleteVideos = video === 'retain-on-failure' && !testFailed;
if (deleteVideos) {
await Promise.all(allPages.map(async (page) => {
const video = page.video();
if (!video)
return;
const videoPath = await video.path();
await util.promisify(fs.unlink)(videoPath).catch(e => { });
}));
}
},
page: async ({ context }, use) => {
await use(await context.newPage());
},
});
fixtures.context.init(async ({ contextFactory }, run) => {
const context = await contextFactory();
await run(context);
// Context factory is taking care of closing the context,
// so that it could capture a screenshot on failure.
});
fixtures.page.init(async ({ context }, run) => {
// Always create page off context so that they matched.
await run(await context.newPage());
// Context fixture is taking care of closing the page.
});
fixtures.testParametersPathSegment.override(async ({ browserName, platform }, run) => {
await run(browserName + '-' + platform);
});
exports.folio = fixtures.build();
exports.it = exports.folio.it;
exports.fit = exports.folio.fit;
exports.xit = exports.folio.xit;
exports.test = exports.folio.test;
exports.describe = exports.folio.describe;
exports.beforeEach = exports.folio.beforeEach;
exports.afterEach = exports.folio.afterEach;
exports.beforeAll = exports.folio.beforeAll;
exports.afterAll = exports.folio.afterAll;
// If browser is not specified, we are running tests against all three browsers.
exports.folio.generateParametrizedTests('browserName', process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox']);
__exportStar(require("folio"), exports);
exports.default = exports.test;
//# sourceMappingURL=index.js.map
{
"name": "@playwright/test",
"version": "0.1111.0",
"version": "0.1112.0-alpha1",
"license": "Apache-2.0",

@@ -16,4 +16,4 @@ "author": {

"prepare": "npm run build",
"prepublishOnly": "rm tsconfig.tsbuildinfo && rm -rf out && npm run build",
"test": "folio test/"
"prepublishOnly": "rm -rf out && npm run build",
"test": "folio -c test/"
},

@@ -24,3 +24,3 @@ "repository": "github:Microsoft/playwright-test",

"dependencies": {
"folio": "=0.3.18",
"folio": "=0.4.0-alpha17",
"playwright": "=1.11.1",

@@ -27,0 +27,0 @@ "rimraf": "^3.0.2"

@@ -5,3 +5,3 @@ # ⚠️ This project is not ready for production. Stay tuned! ⚠️

Zero config cross-browser end-to-end testing for web apps. Browser automation with [Playwright](https://playwright.dev), Jest-like assertions and built-in support for TypeScript.
Cross-browser end-to-end testing for web apps. Browser automation with [Playwright](https://playwright.dev), Jest-like assertions and built-in support for TypeScript.

@@ -13,3 +13,5 @@ Playwright test runner is **available in preview** and minor breaking changes could happen. We welcome your feedback to shape this towards 1.0.

- [Write a test](#write-a-test)
- [Run the test](#run-the-test)
- [Tests and assertions syntax](#tests-and-assertions-syntax)
- [Write a configuration file](#write-a-configuration-file)
- [Run the test suite](#run-the-test-suite)
- [Examples](#examples)

@@ -21,4 +23,3 @@ - [Multiple pages](#multiple-pages)

- [Configuration](#configuration)
- [Modify context options](#modify-context-options)
- [Modify launch options](#modify-launch-options)
- [Modify options](#modify-options)
- [Skip tests with annotations](#skip-tests-with-annotations)

@@ -37,8 +38,8 @@ - [Export JUnit report](#export-junit-report)

Create `foo.spec.ts` to define your test. The test function uses the [`page`][page] argument for browser automation.
Create `tests/foo.spec.ts` to define your test. The test function uses the [`page`][page] argument for browser automation.
```js
import { it, expect } from "@playwright/test";
```ts
import { test, expect } from "@playwright/test";
it("is a basic test with the page", async ({ page }) => {
test("is a basic test with the page", async ({ page }) => {
await page.goto("https://playwright.dev/");

@@ -50,58 +51,107 @@ const name = await page.innerText(".navbar__title");

#### Default arguments
The test runner provides browser primitives as arguments to your test functions. Test functions can use one or more of these arguments.
- `page`: Instance of [Page][page]. Each test gets a new isolated page to run the test.
- `context`: Instance of [BrowserContext][browser-context]. Each test gets a new isolated context to run the test. The `page` object belongs to this context.
- `contextOptions`: Default options passed to context creation. Learn [how to modify them](#modify-context-options).
- `browser`: Instance of [Browser][browser]. Browsers are shared across tests to optimize resources. Each worker process gets a browser instance.
- `browserOptions`: Default options passed to browser/launch creation.
- `context`: Instance of [BrowserContext][browser-context]. Each test gets a new isolated context to run the test. The `page` object belongs to this context. Learn [how to configure](#modify-options) context creation.
- `browser`: Instance of [Browser][browser]. Browsers are shared across tests to optimize resources. Learn [how to configure](#modify-options) browser launch.
- `browserName`: The name of the browser currently running the test. Either `chromium`, `firefox` or `webkit`.
#### Specs and assertions
You can now run the test using the underlying [Folio] command line:
- Use `it` and `describe` to write test functions. Run a single test with `it.only` and skip a test with `it.skip`.
- For assertions, use the [`expect` API](https://jestjs.io/docs/en/expect).
```sh
# Assuming that test files are in the tests directory.
npx folio -c tests
```
### Tests and assertions syntax
- Use `test` to write test functions. Run a single test with `test.only` and skip a test with `test.skip`.
- Use `test.describe` to group related tests together.
- Use `test.beforeAll` and `test.afterAll` hooks to set up and tear down resources shared between tests.
- Use `test.beforeEach` and `test.afterEach` hooks to set up and tear down resources for each test individually.
- For assertions, use the [`expect` API](https://jestjs.io/docs/expect).
```js
const { it, describe } = require("@playwright/test");
const { test, expect } = require("@playwright/test");
describe("feature foo", () => {
it("is working correctly", async ({ page }) => {
// Test function
test.describe("feature foo", () => {
test.beforeEach(async ({ page }) => {
// Go to the starting url before each test.
await page.goto("https://my.start.url/feature-foo");
});
test("is working correctly", async ({ page }) => {
// Assertions use the expect API.
expect(page.url()).toBe("https://my.start.url/feature-foo");
});
});
```
### Run the test
### Write a configuration file
Tests can be run on single or multiple browsers and with flags to generate screenshot on test failures.
Create `config.ts` to configure your tests: specify browser launch options, run tests in multiple browsers and much more. Here is an example configuration that runs every test in Chromium, Firefox and WebKit.
```ts
import { PlaywrightTestProject } from "@playwright/test";
const projects: PlaywrightTestProject[] = [
{
name: 'chromium',
use: {
browserName: 'chromium',
headless: true,
viewport: { width: 1280, height: 720 },
},
},
{
name: 'webkit',
use: {
browserName: 'webkit',
headless: true,
viewport: { width: 1280, height: 720 },
},
},
{
name: 'firefox',
use: {
browserName: 'firefox',
headless: true,
viewport: { width: 1280, height: 720 },
},
}
];
module.exports = {
timeout: 30000, // Each test is given 30 seconds.
projects,
};
```
### Run the test suite
Tests can be run in single or multiple browsers, in parallel or sequentially.
```sh
# Run all tests across Chromium, Firefox and WebKit
npx folio
$ npx folio --config=config.ts
# Run tests on a single browser
npx folio --param browserName=chromium
$ npx folio --config=config.ts --project=chromium
# Run all tests in headful mode
npx folio --param headful
# Run tests in parallel
$ npx folio --config=config.ts --workers=5
# Run tests with slowMo (slows down Playwright operations by n milliseconds)
npx folio --param slowMo=100
# Run tests sequentially
$ npx folio --config=config.ts --workers=1
# Save screenshots on failure in test-results directory
npx folio --param screenshotOnFailure
# Retry failing tests
$ npx folio --config=config.ts --retries=2
# Record videos
npx folio --param video
# Retry test failures
npx folio --retries 3
# See all options
npx folio --help
$ npx folio --help
```
Test runner CLI can be customized with [Folio parameters][folio-parameters].
Refer to the [command line documentation][folio-cli] for all options.

@@ -115,3 +165,3 @@ #### Configure NPM scripts

"scripts": {
"test": "npx folio --param screenshotOnFailure"
"test": "npx folio --config=config.ts"
}

@@ -130,5 +180,5 @@ }

```js
import { it } from "@playwright/test";
import { test } from "@playwright/test";
it("tests on multiple web pages", async ({ context }) => {
test("tests on multiple web pages", async ({ context }) => {
const pageFoo = await context.newPage();

@@ -142,20 +192,44 @@ const pageBar = await context.newPage();

The `contextOptions` fixture defines default options used for context creation. This fixture can be overriden to configure mobile emulation in the default `context`.
`use` section in the configuration file can be used to configure mobile emulation in the default `context`.
```js
import { folio } from "@playwright/test";
import { devices } from "playwright";
```diff
// config.ts
import { PlaywrightTestProject } from "@playwright/test";
+ import { devices } from "playwright";
const fixtures = folio.extend();
fixtures.contextOptions.override(async ({ contextOptions }, runTest) => {
await runTest({
...contextOptions,
...devices["iPhone 11"]
});
});
const { it, describe, extend } = fixtures.build();
const projects: PlaywrightTestProject[] = [
{
name: 'chromium',
use: {
browserName: 'chromium',
headless: true,
- viewport: { width: 1280, height: 720 },
+ ...devices["Pixel 2"],
},
},
it("uses mobile emulation", async ({ context }) => {
// Test function
});
{
name: 'webkit',
use: {
browserName: 'webkit',
headless: true,
- viewport: { width: 1280, height: 720 },
+ ...devices["iPhone 11"],
},
},
{
name: 'firefox',
use: {
browserName: 'firefox',
headless: true,
viewport: { width: 1280, height: 720 },
},
}
];
module.exports = {
timeout: 30000, // Each test is given 30 seconds.
projects,
};
```

@@ -165,31 +239,19 @@

Define a custom argument that mocks networks call for a browser context.
Define a custom route that mocks network calls for a browser context.
```js
// In fixtures.ts
import { folio as base } from "@playwright/test";
import { BrowserContext } from "playwright";
// In foo.spec.ts
import { test, expect } from "@playwright/test";
// Extend base fixtures with a new test-level fixture
const fixtures = base.extend<{ mockedContext: BrowserContext }>();
fixtures.mockedContext.init(async ({ context }, runTest) => {
// Modify existing `context` fixture to add a route
context.route(/.css/, route => route.abort());
// Pass fixture to test functions
runTest(context);
test.beforeEach(async ({ context }) => {
// Block any css requests for each test in this file.
await context.route(/.css/, route => route.abort());
});
export folio = fixtures.build();
```
test("loads page without css", async ({ page }) => {
// Alternatively, block any png requests just for this test.
await page.route(/.png/, route => route.abort());
```js
// In foo.spec.ts
import { folio } from "./fixtures";
const { it, expect } = folio;
it("loads pages without css requests", async ({ mockedContext }) => {
const page = await mockedContext.newPage();
// Test function code.
await page.goto("https://stackoverflow.com");
// Test function code
});

@@ -203,8 +265,8 @@ ```

```js
import { it, expect } from "@playwright/test";
import { test, expect } from "@playwright/test";
it("compares page screenshot", async ({ page, browserName }) => {
test("compares page screenshot", async ({ page }) => {
await page.goto("https://stackoverflow.com");
const screenshot = await page.screenshot();
expect(screenshot).toMatchSnapshot(`test-${browserName}.png`, { threshold: 0.2 });
expect(screenshot).toMatchSnapshot(`test.png`, { threshold: 0.2 });
});

@@ -224,144 +286,102 @@ ```

### Modify context options
### Modify options
You can modify the built-in fixtures. This example modifies the default `contextOptions` with a custom viewport size.
You can modify browser launch options, context creation options and testing options either globally in the configuration file, or locally in the test file.
**Step 1**: Create a new file (say `test/fixtures.ts`) which contains our modifications.
Playwright test runner is based on the [Folio] framework, so it supports any configuration available in Folio, and adds a lot of Playwright-specific options.
```ts
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
#### Globally in the configuration file
const builder = baseFolio.extend();
You can specify different options for each browser using projects in the configuration file. Below is an example that changes some global testing options, and Chromium browser configuration.
// Fixture modifications go here
const folio = builder.build();
```
**Step 2**: Override the existing `contextOptions` fixture to configure viewport size and HTTPS error handling.
```diff
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
+ import { BrowserContextOptions } from "playwright";
// config.ts
import { PlaywrightTestProject } from "@playwright/test";
const builder = baseFolio.extend();
const projects: PlaywrightTestProject[] = [
{
name: 'chromium',
use: {
browserName: 'chromium',
- headless: true,
- viewport: { width: 1280, height: 720 },
+
+ // Launch options:
+ headless: false,
+ slowMo: 50,
+
+ // Context options:
+ viewport: { width: 800, height: 600 },
+ ignoreHTTPSErrors: true,
+
+ // Testing options:
+ video: 'retain-on-failure', },
},
+ builder.contextOptions.override(async ({ contextOptions }, runTest) => {
+ const modifiedOptions: BrowserContextOptions = {
+ ...contextOptions, // default options
+ viewport: { width: 1440, height: 900 },
+ ignoreHTTPSErrors: true
+ }
+ await runTest(modifiedOptions);
+ });
{
name: 'webkit',
use: {
browserName: 'webkit',
headless: true,
viewport: { width: 1280, height: 720 },
},
},
const folio = builder.build();
```
**Step 3**: Export `it` and other helpers from the modified fixtures. In your test files, import the modified fixture.
```diff
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
import { BrowserContextOptions } from "playwright";
const builder = baseFolio.extend();
builder.contextOptions.override(async ({ contextOptions }, runTest) => {
const modifiedOptions: BrowserContextOptions = {
...contextOptions, // default options
viewport: { width: 1440, height: 900 }
ignoreHTTPSErrors: true
{
name: 'firefox',
use: {
browserName: 'firefox',
headless: true,
viewport: { width: 1280, height: 720 },
},
}
await runTest(modifiedOptions);
});
];
const folio = builder.build();
+ export const it = folio.it;
+ export const expect = folio.expect;
module.exports = {
- timeout: 30000, // Each test is given 30 seconds.
+ timeout: 90000, // Each test is given 90 seconds.
+ retries: 2, // Failing tests will be retried at most two times.
projects,
};
```
```ts
// test/index.spec.ts
import { it, expect } from "./fixtures";
#### Locally in the test file
// Test functions go here
it("should have modified viewport", async ({ context }) => {
// ...
});
```
With `test.use()` you can override some options for a file, or a `describe` block.
### Modify launch options
You can modify the built-in fixtures. This example modifies the default `browserOptions` with a slowMo.
**Step 1**: Create a new file (say `test/fixtures.ts`) which contains our modifications.
```ts
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
// my.spec.ts
import { test, expect } from "@playwright/test";
const builder = baseFolio.extend();
// Run tests in this file with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
// Fixture modifications go here
const folio = builder.build();
test('my test', async ({ page }) => {
// Test code goes here.
});
```
**Step 2**: Override the existing `browserOptions` fixture to configure the slowMo.
#### Available options
```diff
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
+ import { LaunchOptions } from "playwright";
See the full list of launch options in [`browserType.launch()`](https://playwright.dev/docs/api/class-browsertype#browsertypelaunchoptions) documentation.
const builder = baseFolio.extend();
See the full list of context options in [`browser.newContext()`](https://playwright.dev/docs/api/class-browser#browsernewcontextoptions) documentation.
+ builder.browserOptions.override(async ({ browserOptions }, runTest) => {
+ const modifiedOptions: LaunchOptions = {
+ ...browserOptions, // Default options
+ slowMo: 50,
+ }
+ await runTest(modifiedOptions);
+ });
Available testing options:
- `screenshot: 'off' | 'on' | 'only-on-failure'` - Whether to capture a screenshot after each test, off by default.
- `off` - Do not capture screenshots.
- `on` - Capture screenshot after each test.
- `only-on-failure` - Capture screenshot after each test failure.
- `video: 'off' | 'on' | 'retain-on-failure' | 'retry-with-video'` - Whether to record video for each test, off by default.
- `off` - Do not record video.
- `on` - Record video for each test.
- `retain-on-failure` - Record video for each test, but remove all videos from successful test runs.
- `retry-with-video` - Record video only when retrying a test.
const folio = builder.build();
```
Most notable testing options from [Folio documentation][folio]:
- `retries: number` - Each failing test will be retried up to the certain number of times.
- `testDir: string` - Directory where test runner should search for test files.
- `timeout: number` - Timeout in milliseconds for each test.
- `workers: number` - The maximum number of worker processes to run in parallel.
**Step 3**: Export `it` and other helpers from the modified fixtures. In your test files, import the modified fixture.
```diff
// test/fixtures.ts
import { folio as baseFolio } from "@playwright/test";
import { LaunchOptions } from "playwright";
const builder = baseFolio.extend();
builder.browserOptions.override(async ({ browserOptions }, runTest) => {
const modifiedOptions: LaunchOptions = {
...browserOptions, // default
slowMo: 50,
}
await runTest(modifiedOptions);
});
const folio = builder.build();
+ export const it = folio.it;
+ export const expect = folio.expect;
```
```ts
// test/index.spec.ts
import { it, expect } from "./fixtures";
// Test functions go here
it("should have the slow mo", async ({ context }) => {
// ...
});
```
### Skip tests with annotations

@@ -372,5 +392,4 @@

```js
it("should be skipped on firefox", (test, { browserName }) => {
test.skip(browserName === "firefox", "optional description for the skip")
}, async ({ page, browserName }) => {
test("should be skipped on firefox", async ({ page, browserName }) => {
test.skip(browserName === "firefox", "optional description for the skip");
// Test function

@@ -384,18 +403,45 @@ });

```sh
# Specify output file as an environment variable
# Linux/macOS
export FOLIO_JUNIT_OUTPUT_NAME=junit.xml
# Windows
set FOLIO_JUNIT_OUTPUT_NAME=junit.xml
```diff
// config.ts
import { PlaywrightTestProject } from "@playwright/test";
# Use junit and CLI reporters
npx folio --reporter=junit,line
const projects: PlaywrightTestProject[] = [
{
name: 'chromium',
use: {
browserName: 'chromium',
headless: true,
viewport: { width: 1280, height: 720 },
},
},
# See all supported reporters
npx folio --help
{
name: 'webkit',
use: {
browserName: 'webkit',
headless: true,
viewport: { width: 1280, height: 720 },
},
},
{
name: 'firefox',
use: {
browserName: 'firefox',
headless: true,
viewport: { width: 1280, height: 720 },
},
}
];
module.exports = {
timeout: 30000, // Each test is given 30 seconds.
+ reporter: [
+ 'list', // Terminal output
+ { name: 'junit', outputFile: 'report.xml' }, // And junit report
+ ],
projects,
};
```
[browser-opts]: https://playwright.dev/docs/api/class-browsertype#browsertypelaunchoptions
[context-opts]: https://playwright.dev/docs/api/class-browser#browsernewcontextoptions
[multi-page]: https://playwright.dev/docs/multi-pages

@@ -405,3 +451,4 @@ [browser]: https://playwright.dev/docs/api/class-browser

[page]: https://playwright.dev/docs/api/class-page
[folio]: https://github.com/microsoft/folio
[folio-annotations]: https://github.com/microsoft/folio#annotations
[folio-parameters]: https://github.com/microsoft/folio#parameters
[folio-cli]: https://github.com/microsoft/folio#command-line
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc