Fixtures in Playwright
By Aishwarya Lakshmi, Community Contributor - November 5, 2024
Playwright provides various features to help optimize code. One such feature is Fixtures. In general terms, Fixtures give a definitive, reliable, and constant context for the tests.
This article will give a comprehensive overview of Fixtures in Playwright.
- What are Fixtures in Playwright?
- Why are Playwright Fixtures important?
- Built-in Fixtures
- Custom Fixtures
What are Fixtures in Playwright?
Playwright Fixtures pertain to the concept of Test Fixtures.
A test fixture is a fixed state of a set of objects used as a base for running tests. It sets up the system for testing by yielding the initialization code, such as loading up a database with defined parameters from a site before running the test.
Why are Playwright Fixtures important?
Playwright Fixtures help you to reuse the code in different test cases. It is easier to encapsulate the function and its parameters in an individual block and call it whenever needed.
There are two kinds of Playwright Fixtures:
- Built-in Fixtures
- Custom Fixtures
Built-in Fixtures
Playwright’s built-in fixtures offer core elements like browser instances, contexts, and pages, ensuring that the browser is properly set up and reset for each test, while maintaining isolation between tests.
Here is an example of built-in fixture in Playwright:
import { test, expect } from '@playwright/test'; test(login test', async ({ page }) => { await page.goto("https://www.bstackdemo.com/"); // ... });
From the above example, Playwright will set up the page as a fixture and run it before every test execution. It will then tear it down after the execution is terminated. Here,page is a fixture that provides a Page object to the test.
In Playwright, there are a few other predefined fixtures.
Here is an overview of the built-in fixtures:
Fixture | Type | Description |
---|---|---|
page | Page | Separate page for a test run |
context | BrowserContext | Separate context for a test run. Page fixture is adherent to BrowserContext |
browser | Browser | Browsers are used across different tests. |
browserName | string | Name of the browser that is currently been initiated to run the test. For example, Chromium, Firefox, Webkit |
request | APIRequestContext | Separate APIRequestContext instance for the test run |
Custom Fixtures
Custom fixtures in Playwright allow users to define their own reusable setup and teardown logic tailored to their specific test needs.
You can create custom fixtures using the test.extend() method. This allows for additional setup specific to your tests.
Here is an example of Custom Fixtures in Playwright:
import {test as basic} from '@playwright/test'; type MyFixture = { login: any; } export const test = basic.extend<MyFixture> ({ login : async({}, use) =>{ const login = "Login into the application"; console.log("Before fixture execution"); await use(login); console.log("After fixture"); } }) test('test with fixture', async({login}) =>{ console.log("Inside test"); console.log(login); })
To create a fixture, start by importing the test from the Playwright test module. In this case, it is imported as basic.
import {test as basic} from '@playwright/test';
Next, define a type that specifies the structure for all the fixtures. In this example, a fixture MyFixture is created with a type any:
type MyFixture = { login : any; }
Then, extend the basic test using the extend method, providing the previously created type MyFixture.
Inside the extend method, define the fixture by using an object where the key is the fixture name (e.g., login) and the value is an anonymous function. This function takes use as its second parameter.
export const test = basic.extend<MyFixture> ({ login : async({}, use) =>{ const login = "Login into the application"; console.log("Before fixture execution"); await use(login); console.log("After fixture"); } })
With the fixture created, it can now be used in the test case. The fixture login is passed inside the async function, and a log statement is printed.
test('test with fixture', async({login}) =>{ console.log("Inside test"); console.log(login); })
The output below will be produced once the test is executed.
When to use Playwright Fixtures?
Playwright Fixtures are especially useful when:
- Repeating test setups across multiple test cases.
- Needing to establish consistent conditions (e.g., logins, API states) for various tests.
- Simplifying teardown processes after test execution.
Steps to Implement Fixtures in Playwright
Creating a Playwright fixture is straightforward and significantly aids in reusing functions.
Below are the detailed steps for implementing them.
Creation of Custom fixture in a test file
To create a new fixture file loginFixture.ts for a custom fixture, first import the Playwright test as baseTest.
import { test as baseTest } from '@playwright/test'; // Define custom fixture const test = baseTest.extend<{loggedInPage: any;}>({ loggedInPage: async ({ page }, use) => { // Go to the login page await page.goto('https://www.bstackdemo.com/signin'); // Replace with login URL // Fill in login details await page.locator('id=username').click(); // click on the username field await page.locator('#react-select-2-option-0-0').click(); // click the first option await page.locator('id=password').click(); // click on the password field await page.locator('#react-select-3-option-0-0').click(); // click the first option await page.click('button[type="submit"]'); // Make the logged-in page available for tests await use(page); } }); export { test };
A variable test will be defined at this stage by extending the base test. Inside the extend method, the loggedInPage fixture will be used as the key, with an anonymous function as the value, where use will serve as the second parameter.
const test = baseTest.extend<{loggedInPage: any;}>({ loggedInPage: async ({ page }, use) => { // }
The next block features a simple test that navigates to https://www.bstackdemo.com/signin, selects the username and password, and logs into the application.
// Go to the login page await page.goto('https://www.bstackdemo.com/signin'); // Replace with your login URL // Fill in login details await page.locator('id=username').click(); // click on the username field await page.locator('#react-select-2-option-0-0').click(); // click the first option await page.locator('id=password').click(); // click on the password field await page.locator('#react-select-3-option-0-0').click(); // click the first option await page.click('button[type="submit"]'); // Wait for navigation to complete after login await page.waitForNavigation();
This line will make the page available for all the tests.
await use(page);
Using Fixtures in the spec file
A new spec file named login.spec.ts will be created, with a reference to loggedInPage. Since this page is already logged in, it enables testing of other application functionalities without the need to repeat the login process.
import { test } from '../fixtures/loginFixture'; test('should navigate to the dashboard after login', async ({ loggedInPage }) => { // Now we're logged in, so we can go to the dashboard await loggedInPage.goto('https://www.bstackdemo.com/'); });
Best Practices of Using Fixtures in Playwright
Here are some best practices when using Playwright fixtures.
Test on real devices
- Playwright fixtures are useful in creating and defining reusable and consistent steps for a process flow, such as Login, authentication, and API mocking.
- BrowserStack allows access to real device cloud platform with over 3500+ different device, browsers, and OS combinations and browsers, ensuring that Playwright Fixtures run in real user conditions rather than virtual environments.
- This helps early identification of device-oriented bugs.
For example, login fixtures can be used to automate all devices and browsers in a single instance, ensuring that the login functionality operates efficiently.
Cross-Browser and Cross-Platform Support
- BrowserStack enables the execution of Playwright tests across various devices, browsers, and operating system combinations.
- Adapting Playwright fixtures ensures that test steps remain flexible and reusable across different combinations.
- This allows for the same test steps to be executed in multiple browsers, including Chrome, Firefox, Safari, and Edge, across various versions.
CI/CD Integration
- BrowserStack integrates flawlessly with CI/CD tools such as GitHub Actions, Jenkins, and CircleCI. The tests can be run in a clean and isolated environment by configuring Playwright Fixtures.
- Automating the Playwright tests on BrowserStack after every build will help ensure the application is validated and tested in real-world scenarios.
For example: Automating the tests with BrowserStack through parallel testing in GitHub Actions will make sure that on every deployment, the test cases are run across real device.
How BrowserStack Automate Can Enhance Playwright Tests
BrowserStack Automate offers various functionalities for running the tests on multiple devices and parallelism.
Here are a few advantages of using BrowserStack Automate in Playwright tests:
- Reduce the time taken for execution – Parallel execution allows to run multiple test cases in parallel. With BrowserStack Automate, many number of tests can be run in parallel across different devices and browsers.
- Cross Browser and Cross device execution – BrowserStack Automate helps to run multiple tests simultaneously across various devices and OS combinations, thus giving the leverage of efficiency in testing the application.
- Scalability – BrowserStack is scalable to many devices and can spin up as many browser combinations as possible with the any additional maintenance.
- Cost efficient – BrowserStack Automate is cost-effective in the longer term in case of maintenance of the tests.
- CI/CD Integration – Tests can be integrated in the CI/CD process through BrowserStack, which is optimal for continuous testing and integration.
Useful Playwright Resources
- Playwright Automation Framework
- Playwright Java Tutorial
- Playwright Python tutorial
- Playwright Debugging
- End to End Testing using Playwright
- Visual Regression Testing Using Playwright
- Mastering End-to-End Testing with Playwright and Docker
- Page Object Model in Playwright
- Scroll to Element in Playwright
- Understanding Playwright Assertions
- Cross Browser Testing using Playwright
- Playwright Selectors
- Playwright and Cucumber Automation
Tool Comparisons: