In this example we will explore how to use global beforeEach and afterEach implementation using playwright automatic fixtures. Playwright’s test fixtures are a powerful feature for sharing setup and logic across tests, promoting code reuse and maintainability. With custom fixtures, you can share code across multiple tests, resulting in a test base that is easier to expand and easier to maintain.
Playwright automatic fixtures
Follow the below steps to step up auto fixtures in playwright.- Define a fixture in a separate file (e.g., fixtures.ts).
- Use test.extend to create a new test type with your fixture.
- Within the fixture function, use async ({}, use) => { ... } to define setup and teardown logic.
- The use function is where the test execution happens.
- Automatic fixtures are declared with the auto: true option.
NOTE : This auto fixture will execute for each tests present in playwright spec files. In this example we are tracing start and end time of execution but we can leverage this functionality for multiple purpose based on requirement.
fixtures.ts
import { test as base } from "@playwright/test"; type MyFixtures = { timeLogger: void, }; export const test = base.extend<MyFixtures>({ timeLogger: [ async ({}, use, testInfo) => { const startTime = new Date().toISOString(); console.log(`[${testInfo.title}] Started`); test.info().annotations.push({ type: "Start", description: startTime, }); await use(); const endTime = new Date().toISOString(); console.log(`[${testInfo.title}] Ended`); test.info().annotations.push({ type: "End", description: endTime, }); }, { auto: true }, ], };
Use the Fixture in Tests:
- Import the extended test object from your fixture file.
- Tests will automatically use the timeLogger fixture due to auto: true.
import { test } from './fixtures'; import { expect } from '@playwright/test'; test('my test', async ({ page }) => { await page.goto('https://example.com'); expect(await page.title()).toBe('Example Domain'); }); test('another test', async ({ page }) => { await page.goto('https://example.com'); expect(await page.title()).toBe('Example Domain'); });
Output :
In this report, we can see the start and end time in annotation section.
Also we can use this auto fixture to track error in playwright script.
import { test as base } from "@playwright/test"; export const test = base.extend<{ exceptionLogger: void; timeLogger: void; }>({ page: async ({ page }, use) => { await use(page); }, exceptionLogger: [ async ({ page }, use) => { // before test const errors: Error[] = []; page.on("pageerror", (error) => errors.push(error)); await use(); // after test if (errors.length > 0) { await test.info().attach("frontend-exceptions", { body: errors .map((error) => `${error.message}\n${error.stack}`) .join("\n-----\n"), }); throw new Error("Something went wrong in JS land"); } }, { auto: true }, ], }); export { expect } from "@playwright/test";
Output :
Complete code :
import { test as base } from "@playwright/test"; export const test = base.extend<{ exceptionLogger: void; timeLogger: void; }>({ page: async ({ page }, use) => { await use(page); }, timeLogger: [ async ({}, use) => { // before test test.info().annotations.push({ type: "Start", description: new Date().toISOString(), }); await use(); // after test test.info().annotations.push({ type: "End", description: new Date().toISOString(), }); }, { auto: true }, ], exceptionLogger: [ async ({ page }, use) => { // before test const errors: Error[] = []; page.on("pageerror", (error) => errors.push(error)); await use(); // after test if (errors.length > 0) { await test.info().attach("frontend-exceptions", { body: errors .map((error) => `${error.message}\n${error.stack}`) .join("\n-----\n"), }); throw new Error("Something went wrong in JS land"); } }, { auto: true }, ], }); export { expect } from "@playwright/test";
This is all about playwright automatic fixtures.
No comments:
Post a Comment