Skip to content

Migrate frontend tests from node:test to Vitest#291

Merged
hackerwins merged 1 commit into
mainfrom
chore/frontend-vitest-migration
May 24, 2026
Merged

Migrate frontend tests from node:test to Vitest#291
hackerwins merged 1 commit into
mainfrom
chore/frontend-vitest-migration

Conversation

@hackerwins

@hackerwins hackerwins commented May 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

The frontend package was the only one running tests on
node --experimental-strip-types with a bespoke resolve-hooks.mjs loader
that resolved workspace deps to stale dist/ (preferring built output,
with hand-written virtual stubs). Because strip-types is not a transpiler
(it can't handle TS parameter properties, directory imports, or antlr CJS
interop), the runtime test channel could not resolve @wafflebase/* to
source — so a src edit was invisible to pnpm frontend test until a
rebuild, producing the recurring stale-dist/ "missing export" failures.

This migrates the frontend to Vitest, like slides/docs/sheets:

  • Vitest reuses the existing vite.config.ts — its resolve.alias already
    points @wafflebase/{sheets,docs,slides} at src/index.ts, and its React
    plugin + antlr assert-shim + jsdom handle JSX/CJS/DOM. So workspace deps
    now resolve to source with no rebuild, killing the stale-dist/
    runtime false-failure class.
  • resolve-hooks.mjs + register-hooks.mjs (250+ lines, incl. virtual
    stubs) are deleted; net change is −100ish lines.
  • 42 .test.ts files converted node:test/assertvitest/expect
    via a throwaway jscodeshift codemod (~1,100 assertions; mock.fnvi.fn,
    leading comments preserved). The .integration.ts lane (separate
    tsx --test glob) is untouched.
  • Scripts: testvitest --run, test:watchvitest; adds
    vitest/jsdom/@vitest/coverage-v8 devDeps.

Design + constraints: docs/design/cross-package-source-resolution.md
(added in a sibling PR).

Test plan

  • pnpm frontend test — 399 passed / 0 failed (parity with the
    node:test baseline; skip count differs only by runner convention)
  • pnpm frontend lint clean (--max-warnings 0)
  • pnpm verify:fast exit 0
  • Spot-check: a symbol added only to slides/src (absent from dist)
    is visible to pnpm frontend test with no rebuild — the case that
    failed under dist-first resolution
  • CI green

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Migrated frontend test suite from Node's built-in test runner to Vitest for improved test execution and faster development feedback.
  • Chores

    • Updated test dependencies to include Vitest and jsdom environment configuration.
    • Simplified test infrastructure by removing custom module resolution hooks and leveraging existing Vite configuration.

Frontend was the only package on node --experimental-strip-types with a
custom resolve-hooks.mjs loader that resolved workspace deps to stale
dist/. strip-types is not a transpiler, so the runtime test channel could
not resolve workspace packages to source (parameter properties, directory
imports, antlr CJS interop all broke). slides/docs/sheets already run on
Vitest.

Vitest reuses frontend's existing vite.config.ts — its aliases already
point @wafflebase/* at src/index.ts, and its react plugin + antlr assert
shim + jsdom handle JSX/CJS/DOM. So a workspace src edit is now visible to
pnpm frontend test with no rebuild, killing the stale-dist runtime
false-failure class, and resolve-hooks.mjs + register-hooks.mjs (incl.
hand-written virtual stubs) are deleted.

Test bodies were converted with a throwaway jscodeshift codemod
(assert.*->expect, node:test->vitest, mock.fn->vi.fn, mock call-args
indexing, leading-comment preservation) across 42 .test.ts files;
.integration.ts (separate tsx lane) untouched. Parity: 399 passed / 0
failed (skip-count differs by runner convention). verify:fast green.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR replaces the Node.js built-in test runner with Vitest across the entire frontend test suite. It reconfigures Vite to enable jsdom testing, removes 250 lines of custom ESM resolve/load hooks, updates helper documentation to reflect the new test isolation approach, and migrates ~50 test files from node:assert to Vitest expect matchers using a semi-automated codemod.

Changes

Frontend test runner migration

Layer / File(s) Summary
Vitest configuration and dependency setup
packages/frontend/vite.config.ts, packages/frontend/package.json
Imports defineConfig from vitest/config and adds a test block configuring jsdom environment, test file discovery, and globals. Dependencies add vitest, @vitest/coverage-v8, and jsdom; test script switches from node --experimental-strip-types to direct vitest --run.
Remove custom ESM resolve/load hooks
packages/frontend/tests/resolve-hooks.mjs, packages/frontend/tests/register-hooks.mjs
Deletes the 250-line resolve-hooks.mjs file that provided custom resolution for workspace packages and JSX stubbing for .tsx modules. Empties register-hooks.mjs by removing the hook registration call. Vitest will use Vite's existing aliasing instead.
Update source code documentation
packages/frontend/src/app/slides/shape-picker-helpers.ts, theme-panel-helpers.ts, themed-color-picker-helpers.ts, themed-font-picker-helpers.ts, packages/frontend/src/hooks/use-pointer-swipe.ts
Clarifies in module comments that helper logic lives in non-TSX files to enable unit testing in isolation, replacing prior explanation of JSX-stub loader involvement.
Migrate API and docs tests
packages/frontend/tests/api/http-error.test.ts, single-flight.test.ts, tests/app/docs/*, tests/app/documents/tab-name.test.ts
Converts all assertions from node:assert to Vitest expect matchers across 10 test files covering HTTP error handling, caching, document store operations, comment threading, and merge/split scenarios.
Migrate slides and toolbar tests
packages/frontend/tests/app/slides/*, tests/app/slides/toolbar/*
Converts assertions in 20+ test files from Node assert to Vitest expect, including mock function setup via vi.fn instead of mock.fn, for shape/line picker, image insertion/replacement, theme panel, color/font pickers, and toolbar section logic.
Migrate spreadsheet and concurrency tests
packages/frontend/tests/app/spreadsheet/*
Converts 10 test files' assertions from node:assert to Vitest expect, covering chart utilities, comment concurrency scenarios, worksheet structure operations, and cell editing under concurrent Yorkie clients.
Migrate component and utility tests
packages/frontend/tests/components/comments/*, packages/frontend/tests/hooks/use-pointer-swipe.test.ts, packages/frontend/tests/lib/utils.test.ts
Converts 5 test files' assertions to Vitest style, covering comment store threading, subscription lifecycle, gesture DOM event handling, and utility function validation.
Document migration task completion
docs/tasks/README.md, docs/tasks/active/20260524-frontend-vitest-migration-todo.md, docs/tasks/active/20260524-frontend-vitest-migration-lessons.md
Adds active task entry and detailed migration documentation recording rationale (stale dist/ via custom loader), completion phases, verification results (399 passed, 0 failed), and codemod patterns observed during the Node → Vitest transition.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • wafflebase/wafflebase#190: Both PRs update or remove the custom packages/frontend/tests/resolve-hooks.mjs file, but this PR deletes it as part of the Vitest migration while the related PR added workspace resolution support to it.
  • wafflebase/wafflebase#208: Both PRs update the active task index in docs/tasks/README.md to reflect newly completed migration/work items.
  • wafflebase/wafflebase#29: Both PRs modify the frontend test resolver hook infrastructure in packages/frontend/tests/, though this PR removes it entirely while the related PR tweaks its fallback logic.

Poem

🐰 From Node's strict assertions to Vitest's sweet expect,

The test suite hops forward, no JSX stubs in sight,

No custom hooks, no loader tricks—just Vite's familiar light,

399 tests pass, the migration's perfect.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/frontend-vitest-migration

@github-actions

github-actions Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Verification: verify:self

Result: ✅ PASS in 240.0s

Lane Status Duration
sheets:build ✅ pass 13.5s
docs:build ✅ pass 12.8s
slides:build ✅ pass 14.3s
verify:fast ✅ pass 152.1s
frontend:build ✅ pass 18.7s
verify:frontend:chunks ✅ pass 0.3s
backend:build ✅ pass 5.1s
cli:build ✅ pass 2.2s
verify:entropy ✅ pass 20.9s

Verification: verify:integration

Result: ✅ PASS

@codecov

codecov Bot commented May 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@hackerwins
hackerwins merged commit 4d8dfeb into main May 24, 2026
4 checks passed
@hackerwins
hackerwins deleted the chore/frontend-vitest-migration branch May 24, 2026 13:48
hackerwins added a commit that referenced this pull request May 24, 2026
Both tasks' work has landed on main: the Vitest migration merged as #291,
and the @wafflebase/tokens deploy fixes (publish-ghpage.yml build:all +
Dockerfile tokens build) are present on main, absorbed into #292. Their
only open todo items were trailing 'open PR / code review' process steps,
now ticked, so pnpm tasks:archive moves both to archive/2026/05 and
regenerates the index.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@hackerwins hackerwins mentioned this pull request May 24, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant