microsoft/playwright · error · Error

The page has closed

Error message

The page has closed

What it means

Thrown inside the expectScreenshot polling loop when the Page becomes closed mid-wait. The screenshot matcher retries until the image stabilizes, and each iteration re-checks page liveness; a closed page cannot produce further screenshots, so the loop aborts with this message rather than timing out.

Source

Thrown at packages/playwright-core/src/server/page.ts:754

      const areEqualScreenshots = (actual: Buffer | undefined, expected: Buffer | undefined, previous: Buffer | undefined) => {
        const comparatorResult = actual && expected ? comparator(actual, expected, options) : undefined;
        if (comparatorResult !== undefined && !!comparatorResult === !!options.isNot)
          return true;
        if (comparatorResult)
          intermediateResult = { errorMessage: comparatorResult.errorMessage, diff: comparatorResult.diff, actual, previous };
        return false;
      };
      let actual: Buffer | undefined;
      let previous: Buffer | undefined;
      const pollIntervals = [0, 100, 250, 500];
      if (options.expected)
        progress.log(`  verifying given screenshot expectation`);
      else
        progress.log(`  generating new stable screenshot expectation`);
      let isFirstIteration = true;
      while (true) {
        if (this.isClosed())
          throw new Error('The page has closed');
        const screenshotTimeout = pollIntervals.shift() ?? 1000;
        if (screenshotTimeout)
          progress.log(`waiting ${screenshotTimeout}ms before taking screenshot`);
        previous = actual;
        actual = await rafrafScreenshot(progress, screenshotTimeout).catch(e => {
          if (this.mainFrame().isNonRetriableError(e))
            throw e;
          progress.log(`failed to take screenshot - ` + e.message);
          return undefined;
        });
        if (!actual)
          continue;
        // Compare against expectation for the first iteration.
        const expectation = options.expected && isFirstIteration ? options.expected : previous;
        if (areEqualScreenshots(actual, expectation, previous))
          break;
        if (intermediateResult)
          progress.log(intermediateResult.errorMessage);

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Ensure no concurrent code path closes the page while the screenshot assertion is in flight; await the assertion before calling page.close().
  2. Increase the page/script timeout or reduce page load so the assertion completes before any teardown.
  3. Wrap the assertion and treat a 'page closed' error as a signal to re-create the page, or use a scoped fixture that owns the page lifetime.

Example fix

// before
const assert = expect(page).toHaveScreenshot('x.png');
await page.close(); // races with the assertion
await assert;
// after
await expect(page).toHaveScreenshot('x.png');
await page.close();
Defensive patterns

Strategy: try-catch

Validate before calling

if (page.isClosed()) throw new Error('page already closed; skip screenshot assertion');

Try / catch

try {
  await expect(page).toHaveScreenshot('home.png');
} catch (e) {
  if (/page has closed/i.test(e.message)) {
    // page died mid-assertion: recreate or skip rather than retry blindly
    throw new Error('Screenshot assertion aborted: page closed unexpectedly');
  }
  throw e;
}

Prevention

When it happens

Trigger: The page (or its browser) is closed, crashes, or navigates to a destroy trigger while expect(page).toHaveScreenshot() is polling; page.close() called from another async branch during the assertion; the web app calls window.close(); the browser process is killed by the OS.

Common situations: A test that closes the page in a finally block racing with a still-running screenshot assertion; an app that self-closes (popup, OAuth flow); resource exhaustion or OOM killing the browser during a heavy screenshot comparison.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/9de994b9b279b166. Report an issue: GitHub.