Vitest: ReferenceError: document is not defined
Vitest runs in Node by default, where there is no DOM. The component test needs a browser like environment declared, either for the whole project or per file. Unlike Jest, Vitest does not bundle jsdom, so the package has to be installed as well as configured.
Quick fix
Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.
# jsdom is a separate install
npm i -D jsdom # or happy-dom, which is faster and less complete
// vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: { environment: "jsdom", globals: true, setupFiles: ["./vitest.setup.ts"] }
});
// Per file, when most of the suite is pure Node
// @vitest-environment jsdom
// Only some directories need a DOM
test: {
environmentMatchGlobs: [["src/components/**", "jsdom"], ["src/server/**", "node"]]
}
# Confirm which environment a file ran in
npx vitest run --reporter=verbose src/components/Button.test.tsx
How to diagnose Testing errors
Test errors divide into infrastructure problems (the framework cannot find or load your tests, fixtures or modules) and flakiness, which is the more expensive category. End-to-end timeouts are almost always a race between the test and the application, and the durable fix is to wait for a condition (an element, a network response, a state change) rather than for a duration.
If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.
- Run a single failing test in isolation. If it passes alone but fails in the suite, you have shared state or test ordering dependence.
- For Cypress and Playwright timeouts, use the trace viewer or video to see what the page actually showed. The element usually exists but is covered, detached, or not yet interactive.
- Replace fixed waits with condition-based waits.
waitForSelectorand auto-retrying assertions eliminate an entire class of flakiness. - For collection and module-resolution errors, check the framework's rootDir/testPaths configuration and the presence of
__init__.pyorconftest.pywhere the framework expects it. - Review snapshot diffs rather than updating them reflexively. A changed snapshot is sometimes a real regression.
Tools worth reaching for
playwright show-tracepytest -x -vv --tb=longjest --runInBandcypress opentest retry analytics
Authoritative references
Primary documentation for this error, worth reading before applying any fix in production.
Related Testing errors
- Cypress: Cypress detected a cross origin errorThe test navigated to a different origin. Cypress runs in the same browser context as the…
- Cypress: Timed out retrying - Expected to find elementCypress could not find the specified element within the default timeout. The element may not…
- Jest: Cannot find moduleJest cannot resolve an import during test execution. Usually caused by missing…
- Jest: Exceeded timeout of 5000 ms for a testThe test returned a promise that never settled within the limit. A slow network call is the…
- Jest: Snapshot does not match stored snapshotThe component output has changed since the snapshot was last recorded. This may be an…
- Jest: SyntaxError: Cannot use import statement outside a moduleJest ran a file containing ES module syntax through a CommonJS pipeline. Either the transform…
- Jest: You are trying to import a file after the Jest environment has been torn downAsynchronous work outlived the test that started it. When Jest tears down the environment, a…
- Jest: Your test suite must contain at least one test.A file matched the test pattern but declared no test. Helper files living beside the tests…
Browse other categories
- HTTP 494xx client errors, 5xx server errors, redirects, headers and protocol problems.
- JavaScript 42npm resolution, async pitfalls, hydration, memory limits and runtime type…
- Database 41Connections, deadlocks, constraints, replication and memory limits.
- AI 35Rate limits, context windows, GPU memory and model-serving failures.
- Network 35Refused connections, timeouts, resets, MTU problems and port exhaustion.
- Python 35Imports, virtual environments, encoding, concurrency and dependency conflicts.
- Kubernetes 34CrashLoopBackOff, ImagePullBackOff, OOMKilled, RBAC, scheduling and storage.
- Docker 27Daemon connectivity, disk space, image pulls, ports and architecture mismatches.
- System 26Disk space, systemd units, file descriptors, OOM killer and scheduled jobs.
- Cloud 25IAM permissions, quotas, service limits and credential failures.
- Security 25JWT validation, CSRF, OAuth grants, SELinux, SSH host keys and CSP.
- TLS 24Untrusted authorities, expiry, hostname mismatch, chains and cipher negotiation.
Something missing or wrong?
This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.