DEV Community

RamaMallika Kadali
RamaMallika Kadali

Posted on

Day 4: Advanced Playwright Features – Tracing, Fixtures, and Parallel Execution

In Day 3, we mastered the core Playwright test syntax and commonly used functions. Now, it's time to explore advanced capabilities that help scale and stabilize your test suite in real-world scenarios. Today we’ll dive into Tracing, Fixtures, and Parallel Execution, which elevate your Playwright framework to enterprise-grade.

Tracing in Playwright
Playwright’s built-in tracing capability helps you record test executions and debug failures with ease. It provides an interactive HTML view of test actions, DOM snapshots, console logs, and network requests.

Enabling Tracing
Tracing can be enabled via the test configuration or manually in your test.

ts

// Setup inside test
test('trace example', async ({ page, context, browserName }, testInfo) => {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto('https://example.com');
await context.tracing.stop({ path: trace-${browserName}.zip });
});

Tip: Use npx playwright show-trace trace.zip to open the trace viewer.

When to Use Tracing:
Debug flaky or failing tests

Review execution flow in CI/CD

Validate element interaction timing and network calls

Using Fixtures for Custom Test Contexts
Fixtures are the backbone of test reusability and modularity in Playwright Test. They allow you to create custom test environments with shared setup and teardown logic.

Example: Custom Fixture for Logged-In State
ts

// In fixtures.ts
import { test as base } from '@playwright/test';

export const test = base.extend({
loggedInPage: async ({ page }, use) => {
await page.goto('/login');
await page.fill('#username', 'testuser');
await page.fill('#password', 'securepass');
await page.click('button[type="submit"]');
await use(page);
},
});

Usage in Tests
ts

test('Access dashboard', async ({ loggedInPage }) => {
await loggedInPage.goto('/dashboard');
await expect(loggedInPage.locator('h1')).toContainText('Dashboard');
});

Reuse this fixture across multiple tests requiring authentication or precondition setup.

Running Tests in Parallel
Playwright is built to support high-performance parallel test execution out of the box. This drastically reduces execution time for large test suites.

Enable Parallel Execution
By default, Playwright runs tests in parallel based on CPU cores. You can control parallelism using the workers setting in playwright.config.ts.

ts

export default defineConfig({
workers: 4, // number of parallel workers
});

Parallel at File and Describe Level
Each test file runs in its own worker by default.

Use test.describe.parallel() to run tests concurrently within a single file.

ts

test.describe.parallel('UI Element Checks', () => {
test('Check Header', async ({ page }) => {
await page.goto('/');
await expect(page.locator('header')).toBeVisible();
});

test('Check Footer', async ({ page }) => {
await page.goto('/');
await expect(page.locator('footer')).toBeVisible();
});
});

Cleanups and Hooks
Use hooks for setup/teardown logic to avoid repetitive code.

Common Hooks
ts

test.beforeEach(async ({ page }) => {
await page.goto('/');
});

test.afterEach(async ({ page }) => {
await page.screenshot({ path: 'test-results/final.png' });
});

Organize hooks globally or per test file based on your suite design.

Summary
By incorporating advanced features of Playwright, you can:

Use Tracing to debug test flows visually and interactively

Create Fixtures to maintain clean and reusable test logic

Maximize speed with Parallel Execution for faster feedback

Leverage Hooks to enforce consistent setup and teardown patterns

Top comments (0)