Playwright fixtures turn repeated test setup into named values that a spec can request from the test callback. A custom fixture is useful when several specs need the same helper object, prepared data, or page wrapper without copying setup and teardown code into every file.
The fixture is defined by extending the base Playwright Test object and exporting that extended test from a project-local module. The fixture function prepares the value, calls await use(value) to hand it to the test, and runs cleanup after the test body finishes.
Use a test-scoped fixture for state that must be fresh for each test. Reserve worker-scoped fixtures for expensive shared state such as accounts or servers, and keep the first custom fixture small enough that setup and teardown can be seen clearly before the pattern is reused across a suite.
Related: How to install Playwright with npm
Related: How to run specific Playwright tests
import { test as base, expect } from '@playwright/test';
type TodoStore = {
items: string[];
add(item: string): void;
clear(): void;
};
export const test = base.extend<{ todoStore: TodoStore }>({
todoStore: async ({}, use, testInfo) => {
const items: string[] = [];
const todoStore: TodoStore = {
items,
add(item: string) {
items.push(item);
},
clear() {
items.splice(0, items.length);
},
};
console.log('setup ' + testInfo.title);
await use(todoStore);
todoStore.clear();
console.log('teardown ' + testInfo.title);
},
});
export { expect };
The testInfo argument is optional, but it gives the fixture access to the running test title and output paths. The two console.log() calls make the lifecycle visible while the fixture pattern is being checked.
import { test, expect } from '../fixtures/todo-fixture';
test('uses a todo fixture', async ({ todoStore }) => {
todoStore.add('write fixture');
expect(todoStore.items).toEqual(['write fixture']);
});
Specs that import test from fixtures/todo-fixture.ts can request todoStore in the test callback. Specs that import directly from @playwright/test do not receive this custom fixture.
$ npx playwright test tests/todo-fixture.spec.ts --reporter=line Running 1 test using 1 worker [1/1] tests/todo-fixture.spec.ts:3:5 › uses a todo fixture setup uses a todo fixture teardown uses a todo fixture 1 passed (755ms)
The setup log appears before the test assertion, the teardown log appears after await use(todoStore) returns, and the passing summary confirms the imported fixture value was available to the spec.