This page covers @playwright/test, the integrated test runner that ships as part of the Playwright monorepo. It describes the configuration model, the fixture system, the test execution pipeline, and the built-in assertion library. Taken together these components provide a complete end-to-end testing solution built on top of the core browser automation described in Core API.
For information about the individual reporters that consume test results, see Reporting System. For information about the interactive developer tools (UI Mode, Trace Viewer, Inspector), see Developer Tools. For component testing built on top of this framework, see Component Testing.
@playwright/test is packaged in packages/playwright. Its public surface is exported from packages/playwright/src/index.ts and its TypeScript type definitions are generated into packages/playwright/types/test.d.ts
The two primary exports are:
| Export | Description |
|---|---|
test | A TestType instance pre-loaded with all Playwright browser fixtures |
expect | The assertion library, exported from packages/playwright/src/matchers/expect |
Additional utilities exported: defineConfig, mergeTests, mergeExpects, _baseTest (a fixture-free base TestType).
Configuration is expressed as a TypeScript or JavaScript file (conventionally playwright.config.ts) that default-exports a TestConfig object wrapped in defineConfig().
Diagram: Configuration Object Hierarchy
TestConfig contains global defaults. Each entry in projects is a TestProject that can override most of those defaults. At runtime, both are resolved to their Full* equivalents (FullConfig, FullProject) which are the types exposed to test code and reporters.
Key TestConfig fields:
| Field | Type | Default |
|---|---|---|
testDir | string | directory of config file |
testMatch | string | RegExp | Array | **/*.@(spec|test).?(c|m)[jt]s?(x) |
timeout | number | 30 000 ms |
retries | number | 0 |
workers | number | string | ½ logical CPUs |
fullyParallel | boolean | false |
reporter | string | ReporterDescription[] | 'list' (or 'dot' in CI) |
use | UseOptions | {} |
projects | Project[] | [] |
globalSetup / globalTeardown | string | string[] | undefined |
webServer | TestConfigWebServer | TestConfigWebServer[] | undefined |
shard | { total, current } | null |
expect | assertion config object | {} |
Key TestProject fields (all also available at top-level TestConfig as defaults):
| Field | Purpose |
|---|---|
name | Project identifier shown in reports |
dependencies | Projects that must complete first |
teardown | Project to run after this one and its dependents finish |
grep / grepInvert | Regex filter applied to test titles |
ignoreSnapshots | Skip snapshot assertions for this project |
snapshotPathTemplate | Token-based template for snapshot file paths |
workers | Worker limit per project |
Sources: packages/playwright/types/test.d.ts104-735 docs/src/test-api/class-testconfig.md docs/src/test-api/class-testproject.md
defineConfig is a passthrough helper that provides TypeScript type inference for the configuration object. It also accepts multiple configs for composition:
defineConfig(baseConfig, ...overrides)
Sources: utils/generate_types/overrides-test.d.ts541-546
Fixtures are the primary mechanism for setting up test state. They use dependency injection: each test or fixture declares the fixtures it needs by name, and the framework resolves and instantiates them in dependency order.
| Scope | Instantiated per | Shared across |
|---|---|---|
'worker' | Worker process | All tests in the same worker |
'test' | Test | Nothing |
Worker-scoped fixtures are created once when a worker starts and torn down when it exits. Test-scoped fixtures are created before each test's body and torn down after.
Fixtures are defined using the Fixtures<T, W, PT, PW> type and registered with test.extend(). The type parameters are: T (new test-scope fixtures), W (new worker-scope fixtures), PT (parent test fixtures), PW (parent worker fixtures).
A fixture function receives an object of already-resolved dependencies, a use callback (which receives the fixture value), and either TestInfo or WorkerInfo. The fixture code before use() is setup; code after is teardown.
<FileRef file-url="https://github.com/microsoft/playwright/blob/54e92be7/packages/playwright/types/test.d.ts#L202-L210" min=202 max=210 file-path="packages/playwright/types/test.d.ts">Hii</FileRef> — Fixtures<T,W,PT,PW> type definition
Options (option: true) are fixtures whose values can be overridden via use: in TestProject/TestConfig. Auto fixtures (auto: true) are instantiated automatically without being declared as dependencies.
Sources: packages/playwright/types/test.d.ts198-210 utils/generate_types/overrides-test.d.ts198-210
@playwright/test ships with two groups of built-in fixtures defined in packages/playwright/src/index.ts
Diagram: Built-in Fixture Dependency Graph
Sources: packages/playwright/src/index.ts71-155
Worker-scope fixtures (PlaywrightWorkerArgs + PlaywrightWorkerOptions):
| Fixture | Scope | Description |
|---|---|---|
playwright | worker | The playwright-core module instance |
browser | worker | Launched or connected Browser |
browserName | worker option | 'chromium' / 'firefox' / 'webkit' |
headless | worker option | Whether to run headless |
channel | worker option | Browser channel (e.g. 'chrome') |
launchOptions | worker option | Extra BrowserType.launch() options |
connectOptions | worker option | BrowserType.connect() options |
screenshot | worker option | Screenshot-on-failure mode |
video | worker option | Video recording mode |
trace | worker option | Trace recording mode |
Test-scope fixtures (PlaywrightTestArgs + PlaywrightTestOptions):
| Fixture | Scope | Description |
|---|---|---|
context | test | Isolated BrowserContext |
page | test | Page from the context |
request | test | APIRequestContext |
baseURL | test option | Base URL for navigations |
viewport | test option | Default viewport size |
storageState | test option | Pre-loaded storage state |
locale / timezoneId | test option | Browser locale/timezone |
actionTimeout / navigationTimeout | test option | Per-action timeouts |
testIdAttribute | test option | Attribute used by getByTestId() |
Sources: utils/generate_types/overrides-test.d.ts253-328 packages/playwright/src/index.ts56-69
FixtureRunner (in packages/playwright/src/worker/fixtureRunner.ts) is the runtime engine for fixture management within a worker. It maintains a map of active fixture instances by scope and fixture name. Key responsibilities:
PoolBuilder).teardownScope('test', ...) and teardownScope('worker', ...) in reverse-registration order.Sources: packages/playwright/src/worker/fixtureRunner.ts
The test runner is split across a runner process (orchestrator) and worker processes (executors). Communication between them uses Node.js IPC with serialized message payloads.
Diagram: Test Runner Component Map
Sources: packages/playwright/src/runner/dispatcher.ts packages/playwright/src/worker/workerMain.ts packages/playwright/src/worker/testInfo.ts
All messages between runner and worker are defined in packages/playwright/src/common/ipc.ts Key payload types:
| Payload | Direction | Purpose |
|---|---|---|
WorkerInitParams | Runner → Worker | Config, project, worker index |
RunPayload | Runner → Worker | Test group to execute |
StepBeginPayload | Worker → Runner | Step started |
StepEndPayload | Worker → Runner | Step finished (with optional error) |
AttachmentPayload | Worker → Runner | File/buffer attachment |
TestEndPayload | Worker → Runner | Single test result |
TeardownErrorsPayload | Worker → Runner | Fatal errors during cleanup |
TestPausedPayload | Worker → Runner | page.pause() called |
ResumePayload | Runner → Worker | Response to pause |
Sources: packages/playwright/src/common/ipc.ts
WorkerMain (extends ProcessRunner) is the top-level class in the worker process. It:
WorkerInitParams and loads project config.RunPayload containing a test group (list of TestCases).TestInfoImpl, calls FixtureRunner to set up fixtures, runs the test body, then tears down fixtures.StepBeginPayload / StepEndPayload back to the runner.unhandledRejection and uncaughtException by failing the current test.Sources: packages/playwright/src/worker/workerMain.ts40-104
TestInfoImpl implements the public TestInfo interface and is passed as the second argument to every test function and hook.
Key members:
| Member | Type | Purpose |
|---|---|---|
_timeoutManager | TimeoutManager | Deadline tracking per runnable |
_tracing | TestTracing | Trace file management |
_steps | TestStepInternal[] | Step tree for this test |
status | TestStatus | Final status (passed, failed, etc.) |
errors | TestInfoErrorImpl[] | Accumulated errors |
attachments | array | Files/buffers to attach to the report |
outputDir | string | Per-test unique output directory |
snapshotDir | string | Snapshot directory for this test file |
retry | number | 0-based retry index |
project | FullProject | Resolved project config |
_addStep() creates a TestStepInternal and immediately dispatches StepBeginPayload. The returned step's complete() method dispatches StepEndPayload. Steps form a tree; the current step context is tracked via AsyncLocalStorage zones.
Test modifiers (skip, fixme, fail, slow) are implemented in _modifier() by manipulating expectedStatus and optionally throwing TestSkipError.
Sources: packages/playwright/src/worker/testInfo.ts36-249
TimeoutManager (packages/playwright/src/worker/timeoutManager.ts) tracks deadlines for different "runnables" (test body, fixture setup/teardown, hooks). It supports multiple timeout slots with different durations. test.slow() multiplies the current timeout by 3 by calling TimeoutManager.slow().
Dispatcher (packages/playwright/src/runner/dispatcher.ts) manages the pool of WorkerHost processes. It:
WorkerHost processes when needed.test.fail() unhandled error is detected).Sources: packages/playwright/src/runner/dispatcher.ts
The TestType<TestArgs, WorkerArgs> interface (packages/playwright/types/test.d.ts105-196) is the type of the exported test object. Key methods:
| Method | Purpose |
|---|---|
test(title, body) | Declare a test |
test(title, details, body) | Declare a test with tags/annotations |
test.describe(title, callback) | Group tests |
test.describe.serial(...) | Group where tests run sequentially in one worker |
test.describe.parallel(...) | Group with per-test parallelism forced on |
test.describe.configure(options) | Set mode, retries, timeout for a group |
test.only / test.skip / test.fixme / test.fail | Test modifiers |
test.slow() | Multiply current timeout by 3 |
test.setTimeout(ms) | Override timeout for current test |
test.beforeEach / test.afterEach | Per-test hooks |
test.beforeAll / test.afterAll | Per-worker hooks |
test.use(fixtures) | Override fixture options for a file or describe block |
test.extend(fixtures) | Create a new TestType with additional fixtures |
test.step(title, body) | Create a named step visible in reports and traces |
test.info() | Return the current TestInfo |
Sources: utils/generate_types/overrides-test.d.ts105-196 docs/src/test-api/class-test.md
@playwright/test exports expect, which is an instance of the Expect<ExtendedMatchers> type. Unlike plain Jest-style expect, Playwright's expect is web-first: assertions targeting Locator, Page, or APIResponse objects automatically retry until the condition is met or the timeout expires.
| Variant | Description |
|---|---|
expect(value) | Standard hard assertion — throws on failure |
expect.soft(value) | Soft assertion — records failure but continues test |
expect.poll(fn) | Polls a function until a non-web assertion passes |
expect(fn).toPass() | Retries a callback until all its assertions pass |
expect.configure(opts) | Returns a new expect with different default timeout/message |
expect.extend(matchers) | Adds custom matchers |
Sources: utils/generate_types/overrides-test.d.ts505-517
Diagram: Assertion Type Dispatch
Sources: utils/generate_types/overrides-test.d.ts416-421
Targets Locator objects; all methods are async and retry-capable. Defined in docs/src/api/class-locatorassertions.md
Selected matchers:
| Matcher | What it checks |
|---|---|
toBeVisible() | Element is attached and visible |
toBeHidden() | Element is not visible or absent |
toBeEnabled() / toBeDisabled() | Interactive state |
toBeChecked() | Checkbox / radio state |
toHaveText(str) | Text content matches |
toContainText(str) | Text content contains substring |
toHaveAttribute(name, value) | HTML attribute value |
toHaveValue(val) | Input/select value |
toHaveCount(n) | Number of matching elements |
toHaveCSS(prop, val) | Computed CSS property |
toBeFocused() | Element has focus |
toBeInViewport() | Element intersects viewport |
toMatchAriaSnapshot(yaml) | ARIA accessibility tree snapshot |
Targets Page objects. Defined in docs/src/api/class-pageassertions.md
| Matcher | What it checks |
|---|---|
toHaveURL(url) | Current page URL |
toHaveTitle(title) | Page <title> content |
toHaveScreenshot(name) | Visual pixel comparison |
Targets APIResponse objects.
| Matcher | What it checks |
|---|---|
toBeOK() | Status code is 2xx |
Standard value assertions (toBe, toEqual, toContain, toMatchObject, etc.) plus toMatchSnapshot() for arbitrary value snapshots.
Sources: utils/generate_types/overrides-test.d.ts354-420 docs/src/api/class-locatorassertions.md docs/src/api/class-pageassertions.md
Both toHaveScreenshot() and toMatchSnapshot() write reference files on first run and compare against them on subsequent runs. The file path for each snapshot is controlled by the snapshotPathTemplate token system. Supported tokens include {testDir}, {testFilePath}, {testName}, {projectName}, {platform}, {arg}, {ext}.
Snapshot comparison thresholds (threshold, maxDiffPixels, maxDiffPixelRatio) are configurable in TestConfig.expect.toHaveScreenshot and TestConfig.expect.toMatchSnapshot.
Sources: packages/playwright/types/test.d.ts190-278 docs/src/test-api/class-testconfig.md71-109
The _setupArtifacts auto-fixture in packages/playwright/src/index.ts248-344 wires Playwright's ClientInstrumentation callbacks to the active TestInfoImpl. This is what causes:
screenshot is not 'off'..zip files to be written according to the trace mode (on, off, retain-on-failure, on-first-retry, on-all-retries, retain-on-first-failure).video mode is active.The ArtifactsRecorder class (also in index.ts) tracks all open BrowserContext and APIRequestContext instances created during a test and handles artifact finalization after the test body and all fixtures have completed.
Sources: packages/playwright/src/index.ts248-344
| API | Purpose |
|---|---|
test.extend(fixtures) | Add or override fixtures, returning a new TestType |
mergeTests(...tests) | Combine multiple TestType instances (merges fixture sets) |
expect.extend(matchers) | Add custom assertion matchers |
mergeExpects(...expects) | Combine multiple extended expect instances |
test.use(options) | Override fixture options for a file or describe block |
Sources: utils/generate_types/overrides-test.d.ts194-196 utils/generate_types/overrides-test.d.ts548-563
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.