Playwright

Lesson 12 of 17

Lesson ยท 25 min

Fixtures

Setup that a test asks for

You know one fixture already: page. A test asks for it in its first argument, and Playwright makes a new page for each test and closes it at the end. The test does not make the page, and it does not clean up.

A fixture is a value that Playwright prepares for a test, and removes after the test. You can write your own. Then a test can ask for "a login page that is open", or "a page where the user is signed in", in the same way.

Write a fixture

Use test.extend. It makes a new test that has your fixtures, in addition to the standard ones.

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

const test = base.extend({
  loginPage: async ({ page }, use) => {
    const loginPage = new LoginPage(page);
    await loginPage.open();
    await use(loginPage);
  },
});

Read the fixture from the top.

  • loginPage is the name. A test that lists loginPage in its arguments gets this fixture.
  • { page } is what the fixture needs. A fixture can ask for other fixtures.
  • The setup is the code before use.
  • await use(loginPage) hands the value to the test. The test runs at this point.
  • The code after use runs when the test is done, also when it failed. Use it for cleanup, for example to delete data that the test made.

A test uses the fixture like this:

test('signs in', async ({ loginPage }) => {
  await loginPage.signIn('ada@example.com', 'correct-horse-battery');
});

Playwright makes a fixture only when a test asks for it. A test that does not list loginPage does not run its setup.

Fixtures and hooks

A beforeEach hook runs for every test in its group. A fixture runs only for the tests that ask for it, and it can give a value back. Fixtures also run their cleanup in the right order, even when a test fails. For most setup, a fixture is a better choice than a hook.

In a real project

In a real project you write your fixtures in a file of their own, for example fixtures.js, and you export test and expect. Every test file imports them from there:

// fixtures.js
export const test = base.extend({ /* ... */ });
export { expect } from '@playwright/test';

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

In this lesson all the code is in one file, so you do not need export.

Your turn

Write two fixtures and three tests.

Tasks

3 to do

  1. Task 1, not checked yet. Make a constant test with base.extend. Add a fixture named loginPage. It makes a LoginPage, opens the sign-in page, and gives the object to the test with await use(...). Then write a test named signs in that asks for { loginPage }. It signs in as ada@example.com with correct-horse-battery and checks the heading Welcome, Ada.

  2. Task 2, not checked yet. Add a second fixture named account. It uses loginPage and page. It signs in as Ada, waits until the heading Welcome, Ada is visible, and gives page to the test. Write a test named shows who is signed in that uses account, and checks that the page shows the email ada@example.com.

  3. Task 3, not checked yet. Write a test named signs out that uses the account fixture. Click the button Sign out. Check that the address is /login.

Task 1 of 3

Make a constant test with base.extend. Add a fixture named loginPage. It makes a LoginPage, opens the sign-in page, and gives the object to the test with await use(...). Then write a test named signs in that asks for { loginPage }. It signs in as ada@example.com with correct-horse-battery and checks the heading Welcome, Ada.

All tasks

example.spec.js

Ctrl+Enter runs your tests. Ctrl+Shift+Enter checks it. Press Esc, then Tab, to leave the editor.

Practice browser

The sample app is ready

The results of your tests show here. Press Run tests to watch them run in the practice browser.