Q17 of 42 · Playwright
Walk me through how you'd test a feature with multiple browser contexts.
Short answer
Short answer: Create independent contexts via `browser.newContext()` — each has its own cookies, storage, and cache, simulating different users. Each context spawns its own `page`. Both pages can interact with the same app simultaneously, asserting on cross-user behaviour like real-time updates or permission boundaries.
Detail
Multiple browser contexts is a Playwright capability that's genuinely impossible in Cypress — and the right tool for testing collaborative features, real-time updates, and permission boundaries.
The pattern:
test('two users see the same chat in real time', async ({ browser }) => {
const aliceContext = await browser.newContext({ storageState: 'auth-alice.json' });
const bobContext = await browser.newContext({ storageState: 'auth-bob.json' });
const alice = await aliceContext.newPage();
const bob = await bobContext.newPage();
await alice.goto('/chat/room-1');
await bob.goto('/chat/room-1');
await alice.getByTestId('input').fill('Hello, Bob!');
await alice.getByTestId('input').press('Enter');
// Bob's page receives the message
await expect(bob.getByTestId('messages')).toContainText('Hello, Bob!');
await aliceContext.close();
await bobContext.close();
});
Use cases:
- Real-time messaging / collaboration — does a comment by user A appear in user B's view?
- Permission boundaries — does action by user A invalidate user B's session as expected?
- Multi-tenant isolation — does data created in tenant A stay invisible in tenant B?
- Concurrent editing — does optimistic locking work when two users edit the same document?
Watch-outs:
- Cleanup. Always
context.close()in a teardown — un-closed contexts leak memory across tests. - Worker scope. Multi-context tests can't share contexts across tests via worker fixtures unless you build that explicitly.
- Storage state. Pre-built
auth-{role}.jsonfiles speed up setup; otherwise log in twice per test. - Independence. Cookies, localStorage, sessionStorage are isolated per context. The same browser process backs them, but they don't share state.
A senior nuance: multi-context tests are slower and more complex than single-user tests. Reserve them for features where multi-user behaviour is the actual contract under test, not as a default pattern.