Skip to content

Vitest browser mode

Tests that run in a browser (Vitest’s browser mode) are reported like tests that run in Node: the same keys, statuses, attempts and probara.* helpers. The reporter still runs in Vitest’s Node process, and the browser hands it what each test recorded. A few things work differently, and a few do not work yet: each one warns, and none fails a test.

  1. Install the provider of your Vitest version, at the same version as vitest, with playwright, then Playwright’s Chromium (npx playwright install chromium):

    VitestProvider packageprovider in test.browser
    3.2@vitest/browser'playwright'
    4.0, 4.1 and 5@vitest/browser-playwrightplaywright(), imported from @vitest/browser-playwright
  2. Turn browser mode on in test.browser, next to the reporter, registered as for Node (get started):

    Key of test.browserValue
    enabledtrue
    providerthe value of the table above
    instances[{ browser: 'chromium' }]
  3. Run the tests as usual (npx vitest run). Nothing else goes in the config: the reporter adds the browser setup file of your Vitest version to each browser project.

The reporter is tested in headless Chromium with Vitest 3.2.7, 4.0.18, 4.1.11 and 5.0.2, each with its provider at the same version.

FeatureIn a browser
ResultsThe keys, statuses and attempts of a Node run: a test that moves between Node and the browser keeps its case
Retries and repeatsEvery attempt is a result
The probara.* helpersThe same import and the same calls: titles, comments, parameters, tags, links, steps, files
captureOutputThe browser’s console reaches Vitest, and each attempt gets its stdout.log and stderr.log
Failure screenshotsAttached to the failed attempts; attachScreenshots: false leaves them out

A step nests under another only when it starts in the synchronous part of the other’s body: a browser has no async context to follow, so a step started after an await is not that step’s child (probara.step()).

  • Await it. The browser hands the file or the body to Vitest’s Node side, which copies it after the call returns. A copy that ends after its test ended is not attached, with one warning in Vitest’s output that names the file and the test, and ends Await probara.attach() before the test ends.

  • A body (a string, a Uint8Array) is sent as in Node.

  • A path is read by Vitest’s Node side, and only where Vite serves files, by the same rules as the project’s own Vite:

    The pathWhat happens
    RelativeResolved against the project’s root (Vite’s root), not the directory vitest runs in
    Inside the folders of server.fs.allow (by default, the project’s workspace root)Copied
    A file Vite denies: .env files, certificates and .git, by defaultRefused
    Listed in the project’s own server.fs.denyRefused. That list replaces Vite’s defaults: list .env* and *.{crt,pem} in it again
    A symlink in the project that points outside the folders Vite servesRefused: Vite judges the file the link points to

    A refused file is copied nowhere, and the test goes on. One warning names it: probara.attach() did not attach "<name>": Vite does not serve "<file>" (server.fs.allow or server.fs.deny).

  • Old Vite versions. The reporter asks the Vite that the project’s Vitest runs with. Vite 5.0 to 5.3 have only an older file check, which then decides, with one notice per vitest process: Vite <version> has no isFileLoadingAllowed (it arrived in 5.4): the browser attach follows its isFileServingAllowed. When Vite cannot be found from the project, a path is refused: Vite's file rules are not reachable from this run, so "<file>" is not served.

  • The command it uses. probara.attach() calls a browser command the reporter adds to each browser project, probaraAttach; a command of yours with that name is replaced.

FeatureWhat happens
runCasesOnlyNot applied to a browser project: its tests all run and are reported, with one warning, runCasesOnly does not apply in browser mode yet: the tests of project "<name>" run and are reported
probara.* calls of a test.concurrent testDropped, with one warning in Vitest’s output, probara.<helper>() is dropped in a concurrent test: ...: a browser cannot tell which of the concurrent tests made a call, and a call is never given to another test
The console output of a test.concurrent testLeft out, with one warning, as in Node (console output)

Write the tests that call the helpers as sequential tests (test, not test.concurrent), or run them in Node, where each concurrent test keeps its own calls. Every browser-mode warning, and what to do about it, is in troubleshooting.

Related: Steps and attachments · Differences from the Jest API · Upgrading · Source: browser-mode.md