Saturday, May 3, 2025

Working with browser context using hooks in playwright

Learn to work with browser context in Playwright using hooks. Our expert insights and practical tips will elevate your automation testing skills. Playwright is a powerful Node.js-based automation framework that enables developers and testers to write fast, reliable end-to-end tests. One of its core features is the ability to manage browser contexts, which are like separate browser profiles, each with its own cookies, local storage, and session data.

When running multiple tests, it’s important to understand how to use browser contexts with test hooks to ensure your tests are either isolated (no shared state) or shared (reuse sessions like a logged-in state). In this post, we’ll explore both patterns using Playwright's built-in test runner.

Working with browser context using hooks in playwright


What is a Browser Context?

A browser context in Playwright is an isolated environment within a browser instance. Each context can have multiple pages (tabs), but the contexts themselves don’t share cookies, storage, or cache.

This is useful for:

  1. Running tests in parallel without interference.
  2. Reusing a logged-in session across tests.
  3. Simulating multiple users in the same test suite.


Using Hooks to Control Browser Context

Playwright Test provides lifecycle hooks like beforeAll, beforeEach, afterAll, and afterEach to set up and tear down browser contexts and pages.

Depending on your test strategy, you can either:

  1. Use a fresh context per test for complete test isolation.
  2. Use a shared context across multiple tests when state needs to persist.

1. Fresh Context Per Test (Best for Isolation)

This is the most robust approach for test independence. Each test starts with a new browser context and page.


Benefits:

  1. Each test is isolated.
  2. No shared cookies or session state.
  3. Best for reliability and parallel execution.
import { test, expect, BrowserContext, Page } from '@playwright/test';

let context: BrowserContext;
let page: Page;

test.beforeEach(async ({ browser }) => {
  context = await browser.newContext();     // Create a fresh context
  page = await context.newPage();           // Open a new page
});

test.afterEach(async () => {
  await context.close();                    // Clean up context after test
});

test('Test A - Visit example.com', async () => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example Domain/);
});

test('Test B - Visit Playwright site', async () => {
  await page.goto('https://playwright.dev');
  await expect(page).toHaveTitle(/Playwright/);
});

2. Shared Context Across Tests (Best for Logged-in Flows)

Sometimes, it’s useful to share state across tests—for example, when tests depend on a logged-in session. You can use beforeAll to set up the context once and reuse it.


Benefits:

  1. Login is done once, speeding up the test suite.
  2. Useful for workflows where tests depend on persistent state.

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

let context: BrowserContext;
let page: Page;

test.beforeAll(async ({ browser }) => {
  context = await browser.newContext();
  page = await context.newPage();

  // Perform login once
  await page.goto('https://example.com/login');
  await page.fill('#username', 'user');
  await page.fill('#password', 'password');
  await page.click('button[type="submit"]');

  // Wait for redirect or user dashboard
  await page.waitForURL('**/dashboard');
});

test.afterAll(async () => {
  await context.close();  // Close the shared context
});

test('Test A - Access dashboard', async () => {
  await page.goto('https://example.com/dashboard');
  await expect(page.locator('#welcome')).toBeVisible();
});

test('Test B - Access settings', async () => {
  await page.goto('https://example.com/settings');
  await expect(page.locator('#settings')).toBeVisible();
});


Another example to use browser context in playwright. In this example, a new browser context and page are created before each test using the beforeEach hook, and the context is closed after each test using the afterEach hook. The beforeAll and afterAll hooks manage the browser instance for the entire suite.

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

describe('Browser Context Management', () => {
  let browser;
  let context;
  let page;

  beforeAll(async () => {
    browser = await chromium.launch();
  });

  afterAll(async () => {
    await browser.close();
  });

  beforeEach(async () => {
    context = await browser.newContext();
    page = await context.newPage();
  });

  afterEach(async () => {
    await context.close();
  });

  test('Test 1', async () => {
    await page.goto('https://example.com');
    // Test logic
  });

  test('Test 2', async () => {
     await page.goto('https://example.com');
    // Test logic
  });
});


Using browser context with Playwright hooks gives you fine-grained control over how your tests interact with the browser environment. Whether you need isolated environments or a shared session for logged-in users, browser contexts are your tool of choice.



No comments:

Post a Comment