Playwright · Reliable end-to-end tests

How does Playwright isolate tests and where does isolation break?

Hardtest isolationcontextsshared stateUpdated Oct 2026
Quiz this track

Short answer

Each test gets a fresh browser context, so cookies, storage and pages do not leak. Isolation breaks when tests share external state such as a database row, a file or a server session.

Playwright's default isolation is strong at the browser layer. The page and context fixtures are per test, so one test cannot see another test's cookies, localStorage or open tabs. That removes a large class of order-dependent failures.

What is isolated by default

  • Browser context, including cookies and localStorage
  • Pages, popups and dialogs opened by the test
  • Network routes registered on that context
  • Test-scoped fixture instances
  • In-flight requests, which are closed with the context
ts
test.describe.configure({ mode: "serial" });

test("creates an order", async ({ page }) => {
  await page.goto("/orders/new");
  await page.getByRole("button", { name: "Create" }).click();
});

test("updates the order", async ({ page }) => {
  await page.goto("/orders");
  await page.getByRole("button", { name: "Edit" }).click();
});
Serial mode makes tests depend on order and is a warning sign, not a default isolation strategy.

Isolation breaks outside the browser. If both tests use the same account, truncate the same table or write the same file, they can interfere even with separate contexts. Serial mode hides the symptom by forcing order, but it also skips later tests when one fails and prevents parallelism.

ts
test("shows the invoice", async ({ page, request }) => {
  const created = await request.post("/api/invoices", {
    data: { total: 120 },
  });
  const invoice = await created.json();

  await page.goto("/invoices/" + invoice.id);
  await expect(page.getByText("120")).toBeVisible();

  await request.delete("/api/invoices/" + invoice.id);
});
Creating and deleting unique data keeps tests independent even when they share a backend.
Use test.afterEach or a fixture for cleanup that must run even on failure. A cleanup line at the end of a test body is skipped when an assertion throws.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What does serial mode change about isolation?
  2. 2Why does a fresh context not isolate a shared database?
  3. 3How do you clean up data when a test fails midway?
  4. 4When is serial mode legitimate?

Say it in the interview

Playwright isolates the browser layer by giving each test a fresh context, so cookies, storage and pages do not leak. Isolation still breaks if tests share backend state like the same account or database row, so I create unique data and clean it up in a fixture or afterEach. Serial mode forces order and hides the real dependency; I only use it when the flow genuinely cannot be split. Cleanup must be automatic, because a failing test will not reach code at the end of its body.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Playwright mock interview and get scored feedback on depth, clarity and confidence.