perf(tests): skip jest-dom in node-environment test files - #6088
Conversation
`vitest.setup.ts` loaded `@testing-library/jest-dom/vitest` unconditionally, so all 1,219 test files paid for it. jest-dom only registers DOM matchers (`toBeInTheDocument`, `toBeVisible`, ...), which are useless without a document — and 985 of those files declare `@vitest-environment node`. Guarding the import on `typeof document !== 'undefined'` loads it for exactly the files that can use it. All 7 files that actually call a jest-dom matcher are explicitly `@vitest-environment jsdom`, so none loses anything; verified by running them. Measured locally, same machine, full suite: baseline Duration 179.47s (setup 367.13s aggregate) guarded Duration 165.78s (setup 252.72s aggregate) 7.6% off the suite, 31% off aggregate setup time. On a node-only subset (50 files, n=3 each) it is 21%: 2.75s -> 2.16s median. Identical results either way: 1225 files / 16184 tests pass, plus one failure that reproduces on unmodified staging (cloud-review-tools.test.ts cannot find `rg` from its spawned python3 locally; CI installs ripgrep explicitly and it passes there). Also fixes two pieces of CI documentation that claimed more than the code does — the same class of thing #6076 cleaned up: - The step was named "Run tests with coverage" but runs `bun run test` = `vitest run`, with no `--coverage` anywhere. - The Codecov upload reads `apps/sim/coverage`, which nothing generates (vitest.config.ts declares no coverage provider). It uploads nothing and still reports success in ~1s because `fail_ci_if_error: false`. Annotated rather than deleted, since whether to enable coverage or drop the step is a call for the team, not a side effect of a perf change.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryLow Risk Overview CI docs in Reviewed by Cursor Bugbot for commit 264dcef. Configure here. |
Greptile SummaryConditionally loads jest-dom only when a DOM
Confidence Score: 5/5Safe to merge; no blocking defects in the guarded jest-dom load or the CI annotation-only workflow edits. Default environment is node, matcher-using tests are jsdom-annotated so the document guard still loads jest-dom there, Vitest 4 setupFiles support the top-level await pattern, and the workflow change does not alter run commands or referenced step contracts.
|
| Filename | Overview |
|---|---|
| apps/sim/vitest.setup.ts | Skips jest-dom registration in the default node environment; jsdom tests still load matchers when document is present. |
| .github/workflows/test-build.yml | Cosmetic step rename and dead-path Codecov comments; test command and Codecov action inputs unchanged. |
Reviews (1): Last reviewed commit: "perf(tests): skip jest-dom in node-envir..." | Re-trigger Greptile
Summary
Lint and Testis now the CI critical path (184s vs Build App's 147s after #6080), and 143s of that 184s is the test suite. This takes ~8% off it.vitest.setup.tsloaded@testing-library/jest-dom/vitestunconditionally, so all 1,219 test files paid for it. jest-dom only registers DOM matchers (toBeInTheDocument,toBeVisible, …), which are useless without a document — and 985 of those files declare@vitest-environment node.Where the time actually goes
From the CI run's own vitest summary (aggregate across workers, so it exceeds wall clock):
Actual test execution is 55s. The rest is per-file overhead — and
setupis the part a global setup file controls.Measured, same machine, full suite
7.6% off the suite, 31% off aggregate setup. On a node-only subset (50 files, n=3 each) it's 21% — 2.75s → 2.16s median.
Nothing loses a matcher
All 7 files that actually call a jest-dom matcher are explicitly
@vitest-environment jsdom, sotypeof document !== 'undefined'is true for exactly those. Verified by running them: 4 files / 7 tests pass.Full suite is identical either way — 1225 files / 16184 tests pass. The one failure (
cloud-review-tools.test.ts) reproduces on unmodified staging: its spawnedpython3can't findrgon macOS. CI installs ripgrep explicitly and it passes there.Two CI docs that claimed more than the code does
Same class as #6076, found while tracing this:
bun run test=vitest run, with no--coverageanywhere.apps/sim/coverage, which nothing generates —vitest.config.tsdeclares no coverage provider. It uploads nothing and still reports success in ~1s becausefail_ci_if_error: false. So its green tick has never meant coverage was published.I annotated rather than deleted the Codecov step:
@vitest/coverage-v8is installed, so enabling coverage is possible, but instrumentation costs test time and nothing gates on the result. That's a call for you, not a side effect of a perf change — happy to either wire it up or drop the step.Not addressed here
importis the real monster — 686s aggregate vs 55s of actual tests. That's module graph cost per test file, the same root cause as the tool registry being 68–78% of every route's graph.vitest.setup.tsalready globally mocks@/blocks/registry; doing the same for@/tools/registrycould be large, but it would silently change behaviour for any test that needs real tools, across 1,219 files. Needs its own measured, scoped change.Type of Change
Testing
Full suite run both ways on the same machine (numbers above); the 7 jest-dom-dependent files run explicitly;
actionlintclean;biomeclean.