DEV Community

Styrow.dev
Styrow.dev

Posted on Originally published at styrow.dev

Managing Highly Concurrent, State-Dependent Playwright Sessions

πŸ”₯ Playwright Load Test Nightmare: Silent State Pollution?
Imagine thousands of concurrent e-commerce journeys, where a single test failure poisons your CI/CD. Here’s how to guarantee state isolation and cleanup.

πŸ“Œ Problem Statement
Large-scale Playwright E2E load tests for stateful processes (login, cart, checkout) on distributed CI/CD face critical issues.
❌ Failed tests leave dirty backend state (logged-in users, partial carts) and browser state (cookies).
β€’ This pollutes subsequent tests, causing flaky, inexplicable failures.
β€’ Goal: Achieve absolute isolation and guaranteed cleanup efficiently, without full browser relaunch per test.

πŸ’‘ Solution & Code Walkthrough
Leverage Playwright's BrowserContext for isolation and robust test hooks for setup/teardown.

βœ… Absolute Isolation:
β€’ BrowserContext: Provides an Incognito-like session, isolating cookies, local storage, etc. Crucial for concurrency.
β€’ Create a new BrowserContext for each test.beforeEach.

βœ… Guaranteed Cleanup:
β€’ test.beforeEach & test.afterEach: Essential hooks for state management.
β€’ Browser State: context.close() in afterEach tears down the isolated session.
β€’ Backend State: Make API calls (e.g., DELETE /api/user/{id}) via Playwright's request context in afterEach for data cleanup. This is paramount.

import { test, expect, BrowserContext, request } from '@playwright/test';

test.describe('Concurrent Playwright Isolation', () => {
  let context: BrowserContext;
  let userId: string; // Example: tracks user for backend cleanup

  test.beforeEach(async ({ browser }) => {
    context = await browser.newContext(); // New, pristine session
    const page = await context.newPage();
    // Setup: e.g., register new user, store userId, login
    // userId = (await request.post('/api/register')).data.id;
    await page.goto('https://ecommerce.com/login'); 
    await expect(page.locator('#dashboard')).toBeVisible();
  });

  test.afterEach(async () => {
    await context.close(); // Close isolated browser context
    // Cleanup: e.g., delete user from backend
    // await request.delete(`/api/user/${userId}`); 
  });

  test('should complete full e-commerce journey', async () => {
    const page = await context.newPage(); // Use isolated context
    await page.goto('https://ecommerce.com/products');
    // ... intricate add-to-cart, checkout steps ...
    await expect(page.locator('.order-confirmation')).toBeVisible();
  });
});
Enter fullscreen mode Exit fullscreen mode

βœ… Efficiency: Creating new BrowserContext instances is far more efficient than launching a full browser (browser.launch()) per test, as browser fixture provides one instance per worker.

πŸ”‘ Key Takeaways
β€’ BrowserContext is your isolation powerhouse.
β€’ test.beforeEach/afterEach are critical for pristine setup/cleanup.
β€’ Backend API calls in afterEach are vital for comprehensive state reset.
β€’ Prioritize BrowserContext over full browser launches for speed.

❓ Quick Summary Q&A
Q: Why not just browser.launch() per test?
A: Too slow. browser.newContext() reuses an existing browser instance, offering speed and isolation.

Q: How do I clean backend data effectively?
A: Use Playwright's request context to make targeted API calls (e.g., DELETE, POST /clear-state) in test.afterEach.

TAGS: playwright, typescript, e2e testing, load testing, test automation, CI/CD, software testing, test architecture
────────────────────────────────────────
Level up your test automation skills!
Download our app for exclusive tutorials and daily interview challenges:
────────────────────────────────────────

πŸ“² 𝐅𝐑𝐄𝐄 πŒπŽππˆπ‹π„ 𝐀𝐏𝐏 β€” πŸ”πŸŽπŸŽ+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
Practice real-world interview scenarios offline on the free QA Automation & SDET Prep app:

πŸ€– 𝐆𝐨𝐨𝐠π₯𝐞 𝐏π₯𝐚𝐲 (𝐀𝐧𝐝𝐫𝐨𝐒𝐝):
https://play.google.com/store/apps/details?id=com.app.seleniuminterviewquestions&referrer=utm_source%3Ddevto%26utm_medium%3Darticle%26utm_campaign%3Dselenium_20260905

🍎 𝐀𝐩𝐩 π’π­π¨π«πž (π’πŽπ’):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20260905&mt=8

────────────────────────────────────────
────────────────────────────────────────

Top comments (0)