Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Playwright Test fixtures package setup, a resource’s availability during a test, and cleanup in one reusable unit. A test asks for a fixture by naming it in its parameters; Playwright initializes the required fixtures, supplies their values, and runs their teardown at the appropriate lifecycle boundary. Fixtures make setup easier to reuse and reason about, but isolation still depends on choosing the right scope and managing shared state deliberately.

How Playwright Test fixtures work

The built-in page fixture is a familiar example: a test requests it and receives a page it can use. Custom fixtures follow the same pattern. They can provide a page object, test data, an authenticated context, or another resource the test needs. Playwright initializes non-automatic fixtures on demand, so unused fixtures are not set up.

Declare custom fixtures by extending a base test object with test.extend(). In TypeScript, fixture types can make the values available to tests type-safe. Keep each fixture focused on one resource or behavior so its use in a test communicates what the test depends on. See the Playwright fixtures guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to create a custom fixture with setup and cleanup

The fixture function performs setup before await use(value) and cleanup after it. The value passed to use is what the requesting test receives.

import { test as base, expect } from '@playwright/test';

class TodoPage {
  constructor(readonly page) {}

  async open() {
    await this.page.goto('/');
  }
}

type Fixtures = {
  todoPage: TodoPage;
};

export const test = base.extend<Fixtures>({
  todoPage: async ({ page }, use) => {
    const todoPage = new TodoPage(page);
    await todoPage.open();
    await use(todoPage);
    // Remove any test data created by this fixture here.
  },
});

export { expect };

Tests import the extended test object and request the fixture by name:

import { test, expect } from './fixtures';

test('shows the todo page', async ({ todoPage }) => {
  await expect(todoPage.page).toHaveURL(//$/);
});

The example opens the application before passing the page object to the test. If the fixture creates data, place matching cleanup after use. Make cleanup specific to what the fixture created; teardown cannot be assumed to succeed if setup was interrupted or an external service is unavailable. A fixture centralizes lifecycle code, but it does not remove the need to handle failures and external state carefully.

Choosing test scope or worker scope

Custom fixtures are test-scoped by default. A test-scoped fixture is initialized for each test that needs it and torn down after that test. A worker-scoped fixture is initialized for a worker process and torn down when that worker shuts down. Choose based on the resource’s intended lifetime and whether tests mutate it.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Scope Lifecycle Good fit Trade-off to manage
Test Set up for a test that requests it; torn down after that test. Mutable state that should not leak between tests. Repeated setup may cost more when initialization is expensive.
Worker Set up once for a worker process; torn down when that worker shuts down. An expensive resource intentionally reused within one worker, such as a service or account reserved for that worker. Tests can observe one another’s changes unless shared state is reset or otherwise isolated.

Playwright’s browser setup illustrates two different lifetimes: the browser is shared by tests running in a worker, while each test receives its own isolated browser context and page. A custom worker fixture can also create an account using workerInfo.workerIndex, with a test-scoped fixture authenticating a page for each test. That is a pattern to adapt, not a guarantee that an application supports concurrent account creation. The fixtures API reference describes the built-in fixture behavior.

How fixture dependencies determine setup and teardown order

A fixture can request another fixture in its own parameters. If fixture A depends on fixture B, Playwright sets up B before A and tears down A before B. Put the provider or lower-level resource in the dependency position, then build the higher-level helper on top of it. This makes the resource chain explicit and keeps cleanup in the reverse order of setup.

When to use automatic fixtures

Set auto: true when work should run for every test or worker at the fixture’s configured scope, even when tests do not name the fixture. This can suit genuinely cross-cutting diagnostics. Otherwise, prefer an explicit fixture request: hidden setup can make it harder to tell why a test is doing extra work.

Automatic worker fixtures run before beforeAll; automatic test fixtures run before test and beforeEach work. Ordinary fixtures initialize when a relevant hook or test needs them. Test-scoped teardown follows the test’s hooks, and worker-scoped teardown occurs at worker shutdown. A failing test or worker restart can affect which setup and teardown events you observe, so do not assume one worker-wide setup event for an entire suite. The fixtures guide explains execution order.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fixture timeouts and slow setup

Fixture setup and teardown generally count toward the test timeout. A slow initializer can therefore time out a test even when its assertions and browser interactions are quick. Playwright allows an individual fixture to have its own timeout. Worker-scoped fixtures also have a timeout, defaulting to the test timeout, which can be configured. When diagnosing a timeout, separate fixture startup or cleanup time from the time spent in the test body. See Playwright’s timeout documentation.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Using built-in fixtures and overrides

The core built-in fixtures include browser, context, page, and request. Use them when their lifecycle suits the test: for example, request supplies an isolated API request context for a test, while the context and page are isolated per test.

An override can wrap an existing fixture as a dependency or replace its behavior. For example, a custom page fixture might reuse the existing page and navigate to the application’s base URL. An authentication setup might instead override storageState to supply a different state. These are distinct choices: one adds behavior around an existing resource, while the other changes the state the browser context uses. For shared authentication setup, Playwright documents placing a storageState override in a fixture module and importing that module’s test object; see the authentication guide.

Fixtures or project dependencies for prerequisites?

Use fixtures when a resource belongs to an individual test or worker. Use project dependencies when setup is a prerequisite for an entire test project or workflow. A setup project can run before dependent projects, and teardown can be attached to that setup project. Project dependencies express ordering and can run multiple dependency projects in parallel; they are not a substitute for per-test cleanup. See Playwright project dependencies and its global setup and teardown documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Composing fixtures and keeping reports useful

As a suite grows, mergeTests can combine fixtures from separate modules—for example, database helpers and accessibility helpers—while retaining separate ownership. Playwright shows custom fixtures as steps in UI mode, Trace Viewer, reports, and error output by default. Use a custom title to make a fixture’s report label clearer. The box option hides a fixture from visible steps; box: 'self' hides the fixture entry while leaving nested work visible. Box uninteresting plumbing, not meaningful diagnostic steps that would help locate a failure. These composition and reporting options are documented in the fixtures guide.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.