Skip to content

[Bug]: globalSetup is skipped for browser-only runs and races with browser start in mixed runs #1194

@fi3ework

Description

@fi3ework

Version

System:
  OS: macOS 15.0.1
  CPU: (14) arm64 Apple M3 Max
  Shell: 5.9 - /bin/zsh
Browsers:
  Chrome: 147.0.7727.101
  Safari: 18.0.1
npmPackages:
  @rstest/core: 0.9.8

Details

globalSetup is documented as a global hook that runs once before the test run and is awaited before workers start executing. In browser mode this contract is not honored today, in two distinct ways:

1. Browser-only runs never execute globalSetup.

In packages/core/src/core/runTests.ts (around L64–L76), when hasBrowserProjects && !hasNodeProjects, the code calls runBrowserModeTests(...) and returns without ever invoking runGlobalSetup. For a browser-only project, any globalSetup file configured by the user is silently ignored — including startup steps like starting a backend, seeding a DB, or configuring env vars.

2. Mixed (browser + node) runs start browser tests before globalSetup has run.

In the same file, browser execution is kicked off at L194 (browserResultPromise = runBrowserModeTests(...)), while runGlobalSetup is invoked inside the per-node-project loop at L357–L368. Browser workers therefore start before globalSetup resolves, which breaks any ordering assumption users have (e.g., “my server is up before any test runs”).

As a side note, even once these two timing issues are addressed, process.env mutations made inside globalSetup are not forwarded to browser workers — packages/browser/src/hostController.ts (around L790–L803) only forwards project.normalizedConfig.env (the user's static test.env config) when constructing browser runtime config. Whether to bridge process.env into browser workers is a separate design question; this issue is strictly about scheduling.

Reproduce link

No external repro — the behavior is directly visible in web-infra-dev/rstest at the referenced source lines above.

Reproduce Steps

  1. Create a project that uses @rstest/browser with a single browser project and configure globalSetup: ['./global-setup.ts'].
  2. In global-setup.ts, console.log('[globalSetup] start') synchronously and return a teardown that logs [globalSetup] teardown.
  3. Run rstest.
  4. Observe that [globalSetup] start is never printed; browser tests run directly.
  5. For the mixed case, add a second node project to the same run. Observe that browser tests begin before [globalSetup] start is printed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions