Skip to content

chore: upgrade Vitest to v4 - #497

Merged
AlemTuzlak merged 2 commits into
mainfrom
fix/release-ci-test-timeouts
Aug 12, 2026
Merged

chore: upgrade Vitest to v4#497
AlemTuzlak merged 2 commits into
mainfrom
fix/release-ci-test-timeouts

Conversation

@AlemTuzlak

@AlemTuzlak AlemTuzlak commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Changes

Upgrade Vitest from 3.2.4 to 4.1.10.

The Release test:ci job failed after every @tanstack/devtools test had already passed. Vitest 3 has a hard 60s worker RPC timeout on onTaskUpdate. The workbench suite takes longer than that on a loaded GitHub runner. Raising testTimeout does not change that RPC limit. Vitest 4 removes it.

This PR also keeps the earlier CI load changes:

  • Cap NX_PARALLEL at 3 on Release (same as PR).
  • Raise testTimeout / hookTimeout to 30s on @tanstack/devtools-ui and @tanstack/devtools-a11y.

Vitest 4 migration

  • Replace defineWorkspace / vitest.workspace.js with test.projects in vitest.config.ts.
  • Turn off Solid HMR in tests (hot: process.env.VITEST !== 'true'). Vitest 4's module runner treats /@solid-refresh as file:///@solid-refresh and throws.
  • Construct the React adapter core mock with a class. Vitest 4 calls mocks with new.
  • Use fake timers in @tanstack/devtools-event-client so EventClient reconnect intervals do not leak.
  • Spy on the live mountDevtools export. A file-level vi.mock does not wrap import('./mount-impl') in core.ts.
  • Give console.log spies the real log signature. A bare vi.fn() is also typed as a constructor in Vitest 4.

Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr related checks.

Locally:

  • nx run-many -t test:lib --exclude=examples/** — 16 packages green, including @tanstack/devtools 323/323 (workbench 44 tests, no onTaskUpdate timeout).
  • nx run-many -t test:types --exclude=examples/** — green.
  • knip and sherif — only pre-existing warnings.

Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes

    • Improved test reliability by disabling Solid HMR during Vitest runs.
    • Increased test and hook timeouts to support slower CI environments.
    • Replaced timing-based tests with deterministic fake timers.
  • Chores

    • Upgraded Vitest to version 4.1.10.
    • Improved release task parallelism for more stable builds.
    • Updated Vitest project configuration and TypeScript settings.

@AlemTuzlak
AlemTuzlak requested a review from a team as a code owner August 11, 2026 13:03
Release runs nx run-many across every package at nx.json parallel: 5.
That oversubscribes GitHub-hosted runners and flakes two test:lib jobs:

- @tanstack/devtools-ui: default 5s timeout on Solid + goober mounts
- @tanstack/devtools: vitest worker RPC stall (onTaskUpdate)

PR already caps NX_PARALLEL at 3 (#478). Apply the same cap to Release,
and raise the 30s test/hook timeouts on the remaining heavy UI packages.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The project migrates to Vitest 4, adds package-specific test projects, disables Solid HMR during tests, updates affected test mocks and timers, and limits Nx release parallelism to 3.

Changes

Vitest 4 migration and test execution

Layer / File(s) Summary
Vitest configuration and dependency migration
vitest.config.ts, vitest.workspace.js, tsconfig.json, package.json, packages/angular-devtools/package.json, examples/react/*/package.json
The repository adds four Vitest test projects, replaces the workspace configuration, updates TypeScript inclusion, and upgrades Vitest to ^4.1.10.
Solid test runtime configuration
packages/*/vite.config*.ts
Solid HMR is disabled during Vitest runs and remains enabled otherwise. The devtools-a11y and devtools-ui configurations set test and hook timeouts to 30 seconds.
Vitest 4 test adaptations
packages/devtools/tests/index.test.ts, packages/devtools-vite/tests/index.test.ts, packages/event-bus-client/tests/index.test.ts, packages/react-devtools/tests/devtools.test.tsx
Tests use live-module spies, typed console callbacks, constructable mocks, and fake timers.
Release parallelism limit
.github/workflows/release.yml
The release workflow sets NX_PARALLEL to 3 and documents runner resource constraints.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the primary change: upgrading Vitest to version 4.
Description check ✅ Passed The description covers the changes, motivation, testing, checklist, and release impact required by the repository template.
✨ 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 fix/release-ci-test-timeouts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Aug 11, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 8dbdde6

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 4m 10s View ↗
nx run-many --target=test:e2e --parallel=1 --pr... ✅ Succeeded 1m 8s View ↗
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 44s View ↗

☁️ Nx Cloud last updated this comment at 2026-08-11 13:57:31 UTC

@pkg-pr-new

pkg-pr-new Bot commented Aug 11, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-devtools

npm i https://pkg.pr.new/@tanstack/angular-devtools@497

@tanstack/devtools

npm i https://pkg.pr.new/@tanstack/devtools@497

@tanstack/devtools-a11y

npm i https://pkg.pr.new/@tanstack/devtools-a11y@497

@tanstack/devtools-bundler-core

npm i https://pkg.pr.new/@tanstack/devtools-bundler-core@497

@tanstack/devtools-client

npm i https://pkg.pr.new/@tanstack/devtools-client@497

@tanstack/devtools-rspack

npm i https://pkg.pr.new/@tanstack/devtools-rspack@497

@tanstack/devtools-ui

npm i https://pkg.pr.new/@tanstack/devtools-ui@497

@tanstack/devtools-utils

npm i https://pkg.pr.new/@tanstack/devtools-utils@497

@tanstack/devtools-vite

npm i https://pkg.pr.new/@tanstack/devtools-vite@497

@tanstack/devtools-event-bus

npm i https://pkg.pr.new/@tanstack/devtools-event-bus@497

@tanstack/devtools-event-client

npm i https://pkg.pr.new/@tanstack/devtools-event-client@497

@tanstack/preact-devtools

npm i https://pkg.pr.new/@tanstack/preact-devtools@497

@tanstack/react-devtools

npm i https://pkg.pr.new/@tanstack/react-devtools@497

@tanstack/solid-devtools

npm i https://pkg.pr.new/@tanstack/solid-devtools@497

@tanstack/svelte-devtools

npm i https://pkg.pr.new/@tanstack/svelte-devtools@497

@tanstack/vue-devtools

npm i https://pkg.pr.new/@tanstack/vue-devtools@497

commit: 8dbdde6

@AlemTuzlak AlemTuzlak changed the title ci: stop Release test:lib flakes from runner overload chore: upgrade Vitest to v4 Aug 11, 2026
Bump vitest from 3.2.4 to 4.1.10. Vitest 4 replaces the 60s
onTaskUpdate RPC timeout that failed Release after every
@tanstack/devtools test had already passed.

Migrate defineWorkspace to test.projects. Turn off Solid HMR in
tests so the module runner does not load /@solid-refresh. Update
mocks and timers that Vitest 4 types or isolates differently.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/event-bus-client/tests/index.test.ts`:
- Around line 12-24: Update the test setup around bus.start and afterEach to
track every disposer returned by client.on, onAll, and onAllPluginEvents, then
invoke all stored disposers before clearing timers. Ensure the disposer
collection is reset per test so EventClient subscriptions do not leak between
tests.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6da7bdcb-1056-46f6-ac3d-a6cdddc4588e

📥 Commits

Reviewing files that changed from the base of the PR and between 3f5bc41 and 8dbdde6.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • examples/react/bundling-repro/package.json
  • examples/react/start/package.json
  • package.json
  • packages/angular-devtools/package.json
  • packages/devtools-a11y/vite.config.ts
  • packages/devtools-ui/vite.config.ts
  • packages/devtools-utils/vite.config.solid-class.ts
  • packages/devtools-utils/vite.config.solid.ts
  • packages/devtools-vite/tests/index.test.ts
  • packages/devtools/tests/index.test.ts
  • packages/devtools/vite.config.ts
  • packages/event-bus-client/tests/index.test.ts
  • packages/react-devtools/tests/devtools.test.tsx
  • packages/solid-devtools/vite.config.ts
  • tsconfig.json
  • vitest.config.ts
  • vitest.workspace.js
💤 Files with no reviewable changes (1)
  • vitest.workspace.js

Comment on lines +12 to +24
// EventClient starts reconnect intervals and has no public stop.
// Fake timers so each test owns those intervals and leftover
// `tanstack-connect` events do not leak into the next test.
vi.useFakeTimers()
bus = new ClientEventBus()
bus.start()
})

afterEach(() => {
// Clean up after each test
bus.stop()
vi.clearAllTimers()
vi.useRealTimers()
vi.restoreAllMocks()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file='packages/event-bus-client/tests/index.test.ts'

rg -n -C 3 \
  'new EventClient|\.on(All|AllPluginEvents)?\(|cleanup\(\)|afterEach|bus\.stop|clearAllTimers' \
  "$file"

Repository: TanStack/devtools

Length of output: 9723


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- test structure and teardown ---'
cat -n packages/event-bus-client/tests/index.test.ts | sed -n '1,540p'

printf '%s\n' '--- EventClient subscription implementation ---'
fd -i 'plugin.ts' packages/event-bus-client
rg -n -C 6 'class EventClient|onAllPluginEvents|onAll\(|on\(' packages/event-bus-client/src packages/event-bus-client/tests

Repository: TanStack/devtools

Length of output: 43631


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- EventClient listener registration and disposal ---'
cat -n packages/event-bus-client/src/plugin.ts | sed -n '40,315p'

printf '%s\n' '--- ClientEventBus event lifecycle ---'
rg -n -C 8 'tanstack-connect|tanstack-connect-success|tanstack-devtools-global|tanstack-dispatch-event|addEventListener|removeEventListener' packages/event-bus-client packages/event-bus/src packages --glob '*.ts' --glob '*.tsx' | sed -n '1,260p'

printf '%s\n' '--- Subscription calls and disposer usage by test line ---'
python3 - <<'PY'
import re
from pathlib import Path

path = Path('packages/event-bus-client/tests/index.test.ts')
lines = path.read_text().splitlines()

for i, line in enumerate(lines, 1):
    if re.search(r'\.on(?:AllPluginEvents|All)?\s*\(', line):
        print(f'{i}: {line.strip()}')
        window = '\n'.join(lines[i-1:min(i+8, len(lines))])
        if re.search(r'\b(?:cleanup|off|dispose)\s*\(\)', window):
            print('  disposer call found nearby')
        else:
            print('  no disposer call found nearby')
PY

Repository: TanStack/devtools

Length of output: 31325


Clean up all EventClient subscriptions between tests.

Several calls to client.on(...), onAll(...), and onAllPluginEvents(...) discard their disposer. These listeners remain on window after afterEach, so later tests can invoke earlier handlers. Store and call each disposer before timer cleanup.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/event-bus-client/tests/index.test.ts` around lines 12 - 24, Update
the test setup around bus.start and afterEach to track every disposer returned
by client.on, onAll, and onAllPluginEvents, then invoke all stored disposers
before clearing timers. Ensure the disposer collection is reset per test so
EventClient subscriptions do not leak between tests.

@AlemTuzlak
AlemTuzlak merged commit 5380540 into main Aug 12, 2026
11 checks passed
@AlemTuzlak
AlemTuzlak deleted the fix/release-ci-test-timeouts branch August 12, 2026 14:20
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.

2 participants