Playwright Test Isolation and Browser Context

This chapter introduces Playwright's test isolation mechanism and the concept of Browser Context, which is key design for ensuring stable and reliable tests.


What is Test Isolation

Test isolation means each test case runs in acompletely independentenvironment and do not affect each other.

In Playwright, each test automatically gets an independent `BrowserContext`Browser Context(browser context).


What is Browser Context

A Browser Context is equivalent to abrand-new browser profile。

Creating a Context is like opening a brand-new browser window, with its own Cookie, localStorage, and sessionStorage, but with extremely low overhead (millisecond-level).

ConceptAnalogyDescription
Browser (browser instance)Opens a browser programHigh overhead; generally created only once for the entire test run
Browser Context (browser context)An independent profile in the browserLow overhead; one per test
Page (tab)A tab in the browserOpens pages in the Context

The `page` in each testpageandcontextis brand new, so if one test modifies localStorage or Cookie, it won't affect other tests.


What Context Isolates

The following content is completely isolated between each Browser Context:

Isolation ItemDescription
CookiesEach Context has independent Cookie storage
localStorageLocal storage is completely isolated
sessionStorageSession storage is completely isolated
IndexedDBBrowser database isolation
CacheHTTP cache isolation

Example

// Test A sets a Cookie
test('Test A', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Set the Cookie (takes effect only in the current Context)
  await page.context().addCookies([{
    name: 'example_session',
    value: 'abc123',
    domain: 'www.example.com',
    path: '/',
  }]);

  // Subsequent operations use this Cookie
});

// Test B receives a brand-new Context, without the Cookie set by Test A
test('Test B', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // context().cookies() returns an empty array
  const cookies = await page.context().cookies();
  console.log(cookies); // []
});

Using the context fixture

Besides `page`page, the test function can also access thecontext`context` fixture for Context-level operations.

Example

test('Using the context fixture', async ({ context, page }) => {
  // Set permissions at the Context level
  await context.grantPermissions(['geolocation']);
  await context.setGeolocation({ latitude: 39.9, longitude: 116.4 });

  // Intercept network traffic at the Context level
  await context.route('**/*.{png,jpg,jpeg}', route => route.abort());

  // page is in the same context and inherits the above settings
  await page.goto('https://www.example.com/');
});

Multi-Context Scenarios

When you need to simulate multiple independent users in the same test, you can manually create Contexts.

Example

test('Two users operate independently', async ({ browser }) => {
  // Create independent Contexts for the two users
  const userAContext = await browser.newContext();
  const userBContext = await browser.newContext();

  // The two users' pages are completely isolated
  const pageA = await userAContext.newPage();
  const pageB = await userBContext.newPage();

  await pageA.goto('https://www.example.com/login');
  await pageB.goto('https://www.example.com/login');

  // User A logs in
  await pageA.getByLabel('Username').fill('user_a');
  await pageA.getByLabel('Password').fill('password_a');
  await pageA.getByRole('button', { name: 'Login' }).click();

  // User B logs in (each has an independent Cookie/Session, without affecting each other)
  await pageB.getByLabel('Username').fill('user_b');
  await pageB.getByLabel('Password').fill('password_b');
  await pageB.getByRole('button', { name: 'Login' }).click();

  // Cleanup
  await userAContext.close();
  await userBContext.close();
});

Benefits of Test Isolation

1. Reproducibility

Each test starts from the same initial state and produces consistent results regardless of execution order.

2. Prevents Cascading Failures

Test A failing will not cause Test B to fail; each test can be debugged independently.

3. Supports Parallel Execution

Because the tests are completely independent, Playwright can safely run them in parallel across multiple workers.

Test isolation is Playwright's default behavior; eachtest()`test` automatically gets an independentpageandcontext`BrowserContext`, without requiring any extra configuration.

Other Extensions