Skip to content

perf(playwright): keep the browser alive across test files in the same worker #1656

Description

@9aoy

Problem

@rstest/playwright@0.11.5 closes its cached browser after the browser fixture has been idle for 1 second (BROWSER_IDLE_CLOSE_DELAY = 1000).

For E2E suites that start or rebuild a dev server in beforeAll, the gap between files is often longer than one second. The idle timer then closes the browser before the next file requests the fixture, so Chrome is relaunched for almost every test file.

This differs from @playwright/test, which normally keeps one browser process alive for the lifetime of a worker and creates an isolated context/page per test.

Reproduction

Rspress is migrating its E2E suite in web-infra-dev/rspress#3569.

With five representative files and one worker:

DEBUG='pw:browser*' CI=1 rstest run \
  --config rstest.e2e.config.mts \
  --pool.maxWorkers 1 \
  e2e/fixtures/title-number/index.test.ts \
  e2e/fixtures/custom-icon/index.test.ts \
  e2e/fixtures/custom-home-footer/index.test.ts \
  e2e/fixtures/theme-css/index.test.ts \
  e2e/fixtures/heading-title/index.test.ts

The debug output contains five separate pw:browser <launching> events: one browser launch per file. The equivalent native Playwright run launches one browser per worker.

On the full Rspress CI suite (70 files / 221 tests), the latest Rstest run took 6m24s while the Rstest build phase was only 180ms. Repeated Chrome startup appears to account for much of the remaining runtime difference from native Playwright.

Suggested behavior

Prefer keeping the cached browser alive until worker shutdown, while continuing to create and close a fresh browser context for each test.

If an unconditional worker-lifetime cache is undesirable, exposing a Playwright option such as one of the following would let integration suites choose the lifecycle explicitly:

{
  browserIdleTimeout: Infinity,
  // or
  reuseBrowser: true,
}

A configurable idle timeout would also be sufficient, provided the browser is still reliably closed during worker teardown and failure/debug paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions