Playwright Test Fixtures
A hotel room arrives fully prepared with clean towels, working lights, and made beds before a guest ever checks in. A fixture prepares a test the same way, handing over a ready-to-use resource before the actual test steps even begin.
How a Fixture Supplies a Test
Fixture Definition (the recipe)
|
v
Playwright Prepares the Resource
|
v
Test Receives It Automatically as a Parameter
The Built-In Page Fixture
test('checks homepage title', async ({ page }) => {
await page.goto('https://example.com');
});The page object seen in every test is itself a fixture. Playwright creates a brand new browser page automatically before each test starts, and closes it automatically afterward.
Why Custom Fixtures Help
Many tests share the exact same starting requirement, such as being logged in already. Writing a custom fixture handles that shared requirement once, instead of repeating the same setup lines inside every test file.
Creating a Custom Fixture
const base = require('@playwright/test');
const test = base.test.extend({
loggedInPage: async ({ page }, use) => {
await page.goto('https://example.com/login');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password').fill('secret123');
await page.getByRole('button', { name: 'Log In' }).click();
await use(page);
},
});
module.exports = { test };This fixture performs the login steps once, then hands over the already logged-in page to any test requesting it through the use function.
Using the Custom Fixture in a Test
const { test } = require('./fixtures');
const { expect } = require('@playwright/test');
test('view dashboard after login', async ({ loggedInPage }) => {
await expect(loggedInPage.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});This test skips writing any login steps at all, since the fixture already delivered a ready, logged-in page.
A Fixture That Provides Test Data
const test = base.test.extend({
testUser: async ({}, use) => {
const user = { name: 'Jane Doe', email: `jane${Date.now()}@example.com` };
await use(user);
},
});This fixture generates a unique email address for every test run, avoiding conflicts when a website does not allow duplicate account registrations.
A Real-World Example
A banking website test suite needs an authenticated user for almost every test, such as checking balances or transferring funds. A single loggedInPage fixture removes login code from fifty separate test files, keeping every one of them shorter and easier to read.
Quick Practice Task
Identify a setup step repeated across several of your tests. Convert that step into a custom fixture and update one test to use it.
Key Takeaways
- Fixtures supply ready-made resources directly to a test.
- The built-in page fixture creates and closes a browser page automatically.
- Custom fixtures remove repeated setup code across many tests.
- Fixtures can also generate unique test data, such as random emails.
