Zero config cross-browser end-to-end testing for web apps. Browser automation with Playwright, Jest-like assertions and support for TypeScript.
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.
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
# Save screenshots on failure in test-results directory
npx folio --param screenshotOnFailure
# Record videos
npx folio --param video
# See all options
npx folio --help
Test runner CLI can be customized with test 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
});