Demo, all content is generated
Question

Vitest: ReferenceError: document is not defined on my first component test

Solved · 175 views · asked by imani_w · edited

Trying to add tests for the first time. Cursor installed vitest and wrote this:

import { render, screen } from "@testing-library/react";
import { PriceTag } from "@/components/price-tag";

test("shows euro price", () => {
  render(<PriceTag cents={1250} />);
  expect(screen.getByText("€12.50")).toBeInTheDocument();
});
ReferenceError: document is not defined

Then Cursor added import { JSDOM } from "jsdom" to the test and made a fake document by hand, which feels very wrong.

What I’ve tried

Asked Cursor to fix it (the JSDOM thing), googled the error, found configs for Jest that don't apply.

Comment
Can you share the vitest config Cursor made? dmitri_v · edited

2 answers

Marked as helpful by the asker
dev_ana · edited

Vitest runs in Node by default, which has no DOM. Tell it to use jsdom for everything, remove the hand-made JSDOM:

npm i -D jsdom @testing-library/jest-dom @vitejs/plugin-react vite-tsconfig-paths
// vitest.config.mts
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [tsconfigPaths(), react()],
  test: { environment: "jsdom", setupFiles: ["./vitest.setup.ts"] },
});
// vitest.setup.ts
import "@testing-library/jest-dom/vitest";

The setup file is what makes toBeInTheDocument exist. tsconfigPaths makes the @/ import work.

One heads-up: async server components can't be rendered like this. Test those with Playwright.

Comment
Green! First test ever that passes for the right reason. imani_w · edited
Nice. Now write one that fails on purpose to see it catch something. dev_ana · edited
The /vitest suffix on the jest-dom import is the part everybody misses, good call. femi_o · edited
dmitri_v · edited

If you only need the DOM in some files, you can also put // @vitest-environment jsdom at the top of that test file instead of setting it globally. Keeps your pure logic tests fast.

Comment