Zero config cross-browser end-to-end testing for web apps. Browser automation with Playwright, Jest-like assertions and built-in support for TypeScript.
Playwright test runner is available in preview and minor breaking changes could happen. We welcome your feedback to shape this towards 1.0.
npm i -D @playwright/testCreate foo.spec.ts to define your test. The test function uses the page argument for browser automation.
import{it,expect}from"@playwright/test";it("is a basic test with the page",async({ page })=>{awaitpage.goto("https://playwright.dev/");constname=awaitpage.innerText(".home-navigation");expect(name).toBe("🎭 Playwright");});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. Each test gets a new isolated page to run the test.context: Instance of BrowserContext. Each test gets a new isolated context to run the test. Thepageobject belongs to this context.contextOptions: Default options passed to context creation. Learn how to modify them.
browser: Instance of Browser. Browsers are shared across tests to optimize resources. Each worker process gets a browser instance.browserOptions: Default options passed to browser creation.
- Use
itanddescribeto write test functions. Run a single test withit.onlyand skip a test withit.skip. - For assertions, use the
expectAPI.
const{ it, describe }=require("@playwright/test");describe("feature foo",()=>{it("is working correctly",async({ page })=>{// Test function});});Tests can be run on single or multiple browsers and with flags to generate screenshot on test failures.
# Run all tests across Chromium, Firefox and WebKit
npx folio
# Run tests on a single browser
npx folio --param browserName=chromium
# Run all tests in headful mode
npx folio --param headful
# Run tests with slowMo (slows down Playwright operations by n milliseconds)
npx folio --param slowMo=100
# Save screenshots on failure in test-results directory
npx folio --param screenshotOnFailure
# Record videos
npx folio --param video
# Retry test failures
npx folio --retries 3
# See all options
npx folio --helpTest runner CLI can be customized with Folio parameters.
Save the run command as an NPM script.
{
"scripts": {
"test": "npx folio --param screenshotOnFailure"
}
}The default context argument is a BrowserContext. Browser contexts are isolated execution environments that can host multiple pages. See multi-page scenarios for more examples.
import{it}from"@playwright/test";it("tests on multiple web pages",async({ context })=>{constpageFoo=awaitcontext.newPage();constpageBar=awaitcontext.newPage();// Test function});The contextOptions fixture defines default options used for context creation. This fixture can be overriden to configure mobile emulation in the default context.
import{folio}from"@playwright/test";import{devices}from"playwright";constfixtures=folio.extend();fixtures.contextOptions.override(async({ contextOptions },runTest)=>{awaitrunTest({
...contextOptions,
...devices["iPhone 11"]});});const{ it, describe, extend }=fixtures.build();it("uses mobile emulation",async({ context })=>{// Test function});Define a custom argument that mocks networks call for a browser context.
// In fixtures.tsimport{folioasbase}from"@playwright/test";import{BrowserContext}from"playwright";// Extend base fixtures with a new test-level fixtureconstfixtures=base.extend<{mockedContext: BrowserContext}>();fixtures.mockedContext.init(async({ context },runTest)=>{// Modify existing `context` fixture to add a routecontext.route(/.css/,route=>route.abort());// Pass fixture to test functionsrunTest(context);});exportfolio=fixtures.build();// In foo.spec.tsimport{folio}from"./fixtures";const{ it, expect }=folio;it("loads pages without css requests",async({ mockedContext })=>{constpage=awaitmockedContext.newPage();awaitpage.goto("https://stackoverflow.com");// Test function code});The expect API supports visual comparisons with toMatchSnapshot. This uses the pixelmatch library, and you can pass threshold as an option.
import{it,expect}from"@playwright/test";it("compares page screenshot",async({ page, browserName })=>{awaitpage.goto("https://stackoverflow.com");constscreenshot=awaitpage.screenshot();expect(screenshot).toMatchSnapshot(`test-${browserName}.png`,{threshold: 0.2});});On first execution, this will generate golden snapshots. Subsequent runs will compare against the golden snapshots. To update golden snapshots with new actuals, run with the --update-snapshots flag.
# Update golden snapshots when they differ from actual
npx folio --update-snapshotsYou can modify the built-in fixtures. This example modifies the default contextOptions with a custom viewport size.
Step 1: Create a new file (say test/fixtures.ts) which contains our modifications.
// test/fixtures.tsimport{folioasbaseFolio}from"@playwright/test";constbuilder=baseFolio.extend();// Fixture modifications go hereconstfolio=builder.build();Step 2: Override the existing contextOptions fixture to configure viewport size and HTTPS error handling.
// 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+ }+ await runTest(modifiedOptions);+ });
const folio = builder.build();Step 3: Export it and other helpers from the modified fixtures. In your test files, import the modified fixture.
// 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
viewport: { width: 1440, height: 900 }
}
await runTest(modifiedOptions);
});
const folio = builder.build();
+ export const it = folio.it;+ export const expect = folio.expect;// test/index.spec.tsimport{it,expect}from"./fixtures";// Test functions go hereit("should have modified viewport",async({ context })=>{// ...});The Playwright test runner can annotate tests to skip under certain parameters. This is enabled by Folio annotations.
it("should be skipped on firefox",(test,{ browserName })=>{test.skip(browserName==="firefox","optional description for the skip")},async({ page, browserName })=>{// Test function});The Playwright test runner supports various reporters, including exporting as a JUnit compatible XML file.
# Specify output file as an environment variable# Linux/macOSexport FOLIO_JUNIT_OUTPUT_NAME=junit.xml
# Windowsset FOLIO_JUNIT_OUTPUT_NAME=junit.xml
# Use junit and CLI reporters
npx folio --reporter=junit,line
# See all supported reporters
npx folio --help