Understanding Playwright Fixtures

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);
});
Note: Fixtures run inside Playwright’s test lifecycle, so they can themselves use async operations and other fixtures, and they honour test timeouts and cancellation.
Tip: Start by wrapping high-value contexts (such as an authenticated page) in fixtures before abstracting smaller details.
Warning: Avoid putting heavy one-time initialisation in per-test fixtures without considering scope, or test runs may become unnecessarily slow.

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.

🧠 Test Yourself

Why are fixtures important in Playwright Test?