nuxt / nuxt/test-utils

`goto({ waitUntil: "hydration" })` times out on Firefox — `window.useNuxtApp?.().isHydrating` never resolves

Open
#1,671 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

pending triage
Dominant language
TypeScript
Stars
437
Forks
120
Avg merge
22h 52m
Merged PRs (30d)
23

Description

Environment
  • Operating System: Windows 11 Enterprise (10.0.26100)
  • Node Version: v20.20.0
  • Nuxt Version: 4.4.2
  • CLI Version: 3.34.0
  • Nitro Version: 2.13.3
  • Package Manager: npm@11.10.1
  • Builder: vite
  • @nuxt/test-utils Version: 4.0.0
  • @playwright/test Version: 1.59.1
  • Vue Version: 3.5.32
Reproduction

Minimal repro using the test-utils example app:

  1. Clone the https://stackblitz.com/github/nuxt/test-utils/tree/main/examples/app-vitest or any Nuxt app with Playwright E2E tests
  2. Add a Firefox project to playwright.config.ts:
projects: [
  { name: "chromium", use: { ...devices["Desktop Chrome"] } },
  { name: "firefox", use: { ...devices["Desktop Firefox"] } },
]
  1. Write a test using goto with waitUntil: "hydration":
import { expect, test } from "@nuxt/test-utils/playwright";

test("page loads", async ({ page, goto }) => {
  await goto("/", { waitUntil: "hydration" });
  await expect(page.locator("body")).toBeVisible();
});
  1. Run: npx playwright test
  2. Chromium passes. Firefox times out at goto().
Describe the bug

When using goto(url, { waitUntil: "hydration" }) with Playwright's Firefox project, the call never resolves and the test times out. The page loads fully — Playwright's page snapshot confirms the entire DOM is rendered, auth works, routing completes — but the hydration detection never fires.

The root cause is in https://github.com/nuxt/test-utils/blob/main/src/e2e/browser.ts#L69:

await page.waitForFunction(() => window.useNuxtApp?.().isHydrating === false)

In Firefox, this waitForFunction call never resolves. Either window.useNuxtApp is not exposed to the page's global scope in Firefox, or isHydrating never transitions from true to false.

This affects 100% of tests that use waitUntil: "hydration" (or waitUntil: "route"), making Firefox E2E testing impossible with @nuxt/test-utils.

Chromium: passes
WebKit: passes
Firefox: 0% pass rate (all timeout)

Additional context
  • The app renders and functions correctly in Firefox — this is purely a test-utils detection issue, not a browser compatibility problem.
  • Tested with a production Nuxt 4.4.2 app (55 E2E specs). Chromium and WebKit both pass 100%. Firefox fails 100%, all at the waitForHydration call.
  • The waitUntil: "route" option (line 72, same file) likely has the same issue since it also relies on window.useNuxtApp?.().
  • Playwright version 1.59.1 with Firefox 148.0.2.
Logs
Error: page.goto: Test timeout of 30000ms exceeded.

Call log:
  - navigating to "https://example.com/", waiting until "load"
    at goto (node_modules/@nuxt/test-utils/dist/playwright.mjs:46:35)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/e2e/browser.ts at the waitForFunction call around line 69, then inspect the related waitUntil: "route" handling around line 72. Reproduce the example app with Chromium, Firefox, and WebKit using the provided Playwright configuration. Done means hydration and route waits resolve in Firefox without breaking the existing browser projects.

Written by the indexing model from the issue text.

Assessment

Tech stack
nuxt, playwright, typescript
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.