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/test
Create 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 }) => {
await page.goto("https://playwright.dev/");
const name = await page.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. Thepage
object 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
it
anddescribe
to write test functions. Run a single test withit.only
and skip a test withit.skip
. - For assertions, use the
expect
API.
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 --help
Test 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 }) => {
const pageFoo = await context.newPage();
const pageBar = await context.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";
const fixtures = folio.extend();
fixtures.contextOptions.override(async ({ contextOptions }, runTest) => {
await runTest({
...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.ts
import { folio as base } from "@playwright/test";
import { BrowserContext } from "playwright";
// 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);
});
export folio = fixtures.build();
// 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();
await page.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 }) => {
await page.goto("https://stackoverflow.com");
const screenshot = await page.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-snapshots
You 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.ts
import { folio as baseFolio } from "@playwright/test";
const builder = baseFolio.extend();
// Fixture modifications go here
const folio = 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.ts
import { it, expect } from "./fixtures";
// Test functions go here
it("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/macOS
export FOLIO_JUNIT_OUTPUT_NAME=junit.xml
# Windows
set FOLIO_JUNIT_OUTPUT_NAME=junit.xml
# Use junit and CLI reporters
npx folio --reporter=junit,line
# See all supported reporters
npx folio --help