Fixtures are one of Playwright Testβs most powerful features. They provide a structured way to share setup, teardown and context objects across tests without resorting to global state or ad hoc helpers. For advanced QA work, understanding fixtures is essential for building scalable, maintainable test suites.
What Fixtures Are in Playwright Test
In Playwright, fixtures are async functions that prepare and provide values to tests, such as authenticated pages, API clients or test data. The built-in page, browser and context objects are themselves fixtures, and you can define your own on top.
// example-fixture.spec.ts
import { test as base, expect } from '@playwright/test';
// Extend the base test with a custom fixture.
type MyFixtures = {
demoUserEmail: string;
};
const test = base.extend({
demoUserEmail: async ({}, use) => {
// In a real project you might fetch this from config or create it via API.
await use('user@example.com');
},
});
-test('uses a custom fixture value', async ({ page, demoUserEmail }) => {
+test('uses a custom fixture value', async ({ page, demoUserEmail }) => {
await page.goto('https://demo.myshop.com/login');
await page.getByRole('textbox', { name: 'Email' }).fill(demoUserEmail);
await expect(page.getByRole('textbox', { name: 'Email' })).toHaveValue(demoUserEmail);
});
Thinking in terms of fixtures encourages you to model the resources tests depend on explicitly, which improves readability and control compared to hidden globals or manual setup blocks.
Common Mistakes
Mistake 1 β Ignoring fixtures and using only helper functions
This misses lifecycle integration.
β Wrong: Creating global helper functions that open pages or log in outside the test runnerβs control.
β Correct: Use fixtures so setup and teardown are visible to Playwright and can be managed per test or per worker.
Mistake 2 β Overcomplicating fixtures from day one
This creates accidental complexity.
β Wrong: Designing a deep, nested fixture hierarchy before you have real test cases.
β Correct: Start with a few simple fixtures and refactor as patterns emerge.