Sitelet https://github.com/vitejs/devtools/issues/585
Skip to content

Vitest UI launcher shows Vitest 5's "requires authentication" page instead of the UI #585

Description

@zahidzorbaz

Describe the bug

With Vitest 5, clicking Start Vitest UI in the Vite+ group starts the server, the dock swaps to the iframe, and the iframe shows only this text instead of the Vitest UI:

Vitest UI requires authentication. Open the URL with the token printed in the terminal, e.g. http://localhost:51204/__vitest__/?token=...

Since Vitest 5 (vitest-dev/vitest#10583), /__vitest__/ answers 403 unless the request carries ?token=<api token> (which sets a vitest-ui-token cookie and redirects 302 to the clean URL) or already has that cookie. The token is printed by Vitest as UI started at http://localhost:<port>/__vitest__/?token=… and is stored in %LOCALAPPDATA%/vitest/.vitest-secret-token (or node_modules/.vitest/).

The launcher never obtains that token:

  • The iframe URL is built as http://localhost:${port}/__vitest__/ with no token (plugin.ts#L117) and returned from onReady as-is (#L133-L137).
  • waitForServer() treats any status below 500 as ready (#L192-L205), so the 403 counts as "ready" and the auth page is embedded. Accepting 403 is fine for "is the port up", but the embedded URL then can never succeed.

Possible fix: take the authenticated URL from the UI started at … line of the session's stdout (via session.getChildProcess()), use it as the iframe URL, and have the readiness probe request that URL and accept only 2xx/3xx. A fallback could read the token file, but that path is a Vitest internal.

Unverified, possibly related (not tested in a browser): the cookie is SameSite=Strict and the launcher hard-codes the localhost host. If DevTools is opened on http://127.0.0.1:<vite port>, the localhost iframe is cross-site, so the browser may not store or send the cookie even when the token is present. Building the iframe URL on the same hostname as the DevTools page would avoid that.

Related: stopping this launcher on Windows leaves the vitest process running, see devframes/devframe#402.

Reproduction

Inline steps below — needs a local Vitest 5 UI (no hosted repro possible).

  1. Any Vite 8 project with vitest@5, @vitest/ui@5, @vitejs/devtools@0.7.5 and @vitejs/devtools-vitest@0.7.5, devtools: true in the Vite config. Upstream's own pnpm -C packages/core run play should show the same, since the workspace uses vitest ^5.0.1.
  2. Run vite, open DevTools, Vite+ group → Vitest → Start Vitest UI.
  3. The iframe shows the "Vitest UI requires authentication" page.

The HTTP side without a browser (empty folder with one test file and an empty vitest.config.js; vitest 5.0.0 + @vitest/ui 5.0.0 installed):

// probe.mjs — same spawn args and probe as the launcher
import { spawn } from 'node:child_process'
const port = 43217
const cp = spawn(process.execPath, ['node_modules/vitest/vitest.mjs', '--ui', '--no-open', '--watch', '--api.port', String(port)], { stdio: 'pipe' })
let out = ''
cp.stdout.on('data', d => { out += d })
let res
for (let i = 0; i < 100 && !res; i++)
  res = await fetch(`http://localhost:${port}/__vitest__/`, { redirect: 'manual' }).catch(() => new Promise(r => setTimeout(r, 300)))
console.log('bare URL ->', res.status, (await res.text()).slice(0, 60), '| launcher accepts:', res.status < 500)
await new Promise(r => setTimeout(r, 1500))
const url = out.replace(/\x1B\[[0-9;]*m/g, '').match(/UI started at (\S+)/)[1]
const r2 = await fetch(url, { redirect: 'manual' })
console.log('token URL ->', r2.status, r2.headers.get('location'), r2.headers.get('set-cookie')?.split(';').slice(1).join(';'))
cp.kill()

Output:

bare URL -> 403 Vitest UI requires authentication. Open the URL with the | launcher accepts: true
token URL -> 302 /__vitest__/  Path=/__vitest__/; HttpOnly; SameSite=Strict

Expected: the dock iframe shows the Vitest UI.
Actual: the dock iframe shows Vitest's 403 "requires authentication" page, and the launcher reports the server as ready.

System Info

OS: Windows 11 Pro 10.0.26200 (x64)
Node: 24.21.0
pnpm: 12.5.1
Browser: Chrome
@vitejs/devtools / @vitejs/devtools-kit / @vitejs/devtools-vitest: 0.7.5 (also upstream main ad2d6df)
devframe / @devframes/hub: 1.0.0
vite: 8.3.0
vitest / @vitest/ui: 5.0.0

Used Package Manager

pnpm

Validations

  • Follow our Code of Conduct
  • Read the Contributing Guide.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Check that this is a concrete bug. For Q&A, please open a GitHub Discussion instead.
  • The provided reproduction is a minimal reproducible of the bug.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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