Skip to content

test: use onTestFinished for cleanup - #8025

Open
Sheraff wants to merge 1 commit into
mainfrom
test/use-on-test-finished-cleanup
Open

test: use onTestFinished for cleanup#8025
Sheraff wants to merge 1 commit into
mainfrom
test/use-on-test-finished-cleanup

Conversation

@Sheraff

@Sheraff Sheraff commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • replace cleanup-only try/finally blocks and shared teardown registries with onTestFinished
  • colocate cleanup for subscriptions, timers, roots, mocks, globals, and pending operations with the tests that own them
  • retain shared framework cleanup and operation-scoped finalizers where teardown timing is behaviorally significant

Testing

  • pnpm nx affected --target=test:unit
  • pnpm nx affected --target=test:types
  • pnpm nx affected --target=test:eslint

Summary by CodeRabbit

  • Tests
    • Improved test isolation and cleanup across routing, hydration, streaming, navigation, and generator test suites.
    • Cleanup now runs automatically after each test, including restoration of timers, mocks, subscriptions, DOM state, temporary files, and environment settings.
    • Preserved existing assertions and tested behavior while reducing shared test state and manual teardown.

@nx-cloud

nx-cloud Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit bc1e0fd

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 10m 48s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 2m 11s View ↗

☁️ Nx Cloud last updated this comment at 2026-08-10 07:07:00 UTC

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

No changeset entries found. Merging this PR will not cause a version bump for any packages.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request updates test cleanup across React, Solid, Vue, router-core, and tooling packages. Shared hooks, cleanup arrays, and manual teardown move to Vitest onTestFinished callbacks. Test assertions and production code remain unchanged.

Changes

Per-test cleanup migration

Layer / File(s) Summary
React Router and hydration cleanup
packages/react-router/tests/*, packages/react-start-client/src/tests/*
Tests register cleanup for mocks, timers, subscriptions, hydration roots, containers, globals, and SSR state with onTestFinished.
Router-core resource cleanup
packages/router-core/tests/*
Tests replace shared teardown and try/finally blocks with test-scoped cleanup for promises, streams, timers, spies, subscriptions, and environment state.
Tooling and query cleanup
packages/router-devtools-core/tests/*, packages/router-generator/tests/*, packages/router-plugin/tests/*, packages/router-ssr-query-core/tests/*, packages/start-*/tests/*
Tests scope generated-file, module, platform, environment, observer, query-client, and temporary-server cleanup to each test.
Solid Router cleanup
packages/solid-router/tests/*
Tests register history destruction, subscription disposal, spy restoration, timer restoration, DOM cleanup, and controlled-promise settlement per test.
Vue Router cleanup
packages/vue-router/tests/*, packages/vue-start-client/src/*
Tests scope browser-history, SSR head, subscription, mock, timer, DOM, and pending-operation cleanup to test completion.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: replacing shared test cleanup with Vitest's onTestFinished.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/use-on-test-finished-cleanup

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.

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

This pull request does not affect bundle size in any measured scenario.

@pkg-pr-new

pkg-pr-new Bot commented Aug 10, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8025

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@8025

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8025

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8025

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@8025

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@8025

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@8025

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8025

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8025

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8025

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8025

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@8025

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@8025

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@8025

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@8025

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@8025

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@8025

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@8025

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@8025

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@8025

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@8025

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@8025

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8025

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8025

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8025

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8025

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8025

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8025

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8025

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@8025

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8025

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8025

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8025

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@8025

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@8025

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8025

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8025

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8025

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8025

commit: bc1e0fd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/react-router/tests/preloaded-mount-resolution.test.tsx (1)

30-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the any cast with a typed global.

globalThis as any disables type checking for IS_REACT_ACT_ENVIRONMENT. Define an intersection type or a global declaration for this property and use that typed value in disableActEnvironment.

As per coding guidelines, TypeScript changes must use strict mode with extensive type safety.

Proposed type-safe change
+type ReactActGlobal = typeof globalThis & {
+  IS_REACT_ACT_ENVIRONMENT?: boolean
+}
+
 const disableActEnvironment = () => {
-  const prevActEnv = (globalThis as any).IS_REACT_ACT_ENVIRONMENT
-  ;(globalThis as any).IS_REACT_ACT_ENVIRONMENT = false
+  const actGlobal = globalThis as ReactActGlobal
+  const prevActEnv = actGlobal.IS_REACT_ACT_ENVIRONMENT
+  actGlobal.IS_REACT_ACT_ENVIRONMENT = false
   onTestFinished(() => {
-    ;(globalThis as any).IS_REACT_ACT_ENVIRONMENT = prevActEnv
+    actGlobal.IS_REACT_ACT_ENVIRONMENT = prevActEnv
   })
 }
🤖 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/react-router/tests/preloaded-mount-resolution.test.tsx` around lines
30 - 35, Update disableActEnvironment to access IS_REACT_ACT_ENVIRONMENT through
a typed global declaration or intersection type instead of casting globalThis to
any. Preserve the existing save, disable, and onTestFinished restoration
behavior while ensuring the property is fully type-checked under strict
TypeScript settings.

Source: Coding guidelines

🤖 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/router-devtools-core/tests/cache-replacement.test.ts`:
- Around line 27-33: Move the IntersectionObserver cleanup registration out of
the shared beforeEach in observe(...) within
packages/start-client-core/tests/hydration-visible.test.ts#L55-L57 and into each
test body so onTestFinished runs only during tests. The beforeAll hook in
packages/router-devtools-core/tests/cache-replacement.test.ts#L19-L27 requires
no change.

In `@packages/solid-router/tests/same-route-pending-blank.test.tsx`:
- Around line 39-42: Update the cleanup block in the test teardown so
vi.useRealTimers() runs even when cleanup() throws: wrap cleanup() in an inner
try/finally and place timer restoration in that finally, preserving the existing
outer teardown behavior.

---

Nitpick comments:
In `@packages/react-router/tests/preloaded-mount-resolution.test.tsx`:
- Around line 30-35: Update disableActEnvironment to access
IS_REACT_ACT_ENVIRONMENT through a typed global declaration or intersection type
instead of casting globalThis to any. Preserve the existing save, disable, and
onTestFinished restoration behavior while ensuring the property is fully
type-checked under strict TypeScript settings.
🪄 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: c876ebcb-7a84-4473-9f24-3e4aff31e0f2

📥 Commits

Reviewing files that changed from the base of the PR and between af8dcb8 and bc1e0fd.

📒 Files selected for processing (91)
  • packages/react-router/tests/ClientOnly.test.tsx
  • packages/react-router/tests/Matches.test.tsx
  • packages/react-router/tests/Scripts.test.tsx
  • packages/react-router/tests/component-preload-retry-pending-min.test.tsx
  • packages/react-router/tests/component-preload-retry.test.tsx
  • packages/react-router/tests/errorComponent.test.tsx
  • packages/react-router/tests/hydration-capped-boundary-pending.test.tsx
  • packages/react-router/tests/hydration-terminal-lane.test.tsx
  • packages/react-router/tests/issue-7635-error-head-after-navigation.test.tsx
  • packages/react-router/tests/issue-7638-invalidate-transition-error.test.tsx
  • packages/react-router/tests/link.test.tsx
  • packages/react-router/tests/on-rendered-same-href-state.test.tsx
  • packages/react-router/tests/preloaded-mount-resolution.test.tsx
  • packages/react-router/tests/public-presentation-lane-contract.test.tsx
  • packages/react-router/tests/react-render-owner-contract.test.tsx
  • packages/react-router/tests/redirect.test.tsx
  • packages/react-router/tests/renderRouterToStream.test.tsx
  • packages/react-router/tests/root-pending-min.test.tsx
  • packages/react-router/tests/router-client-stream-cleanup.test.tsx
  • packages/react-router/tests/router.test.tsx
  • packages/react-router/tests/transitioner-listener-errors.test.tsx
  • packages/react-router/tests/transitioner-remount.test.tsx
  • packages/react-router/tests/transitioner-render-ack.test.tsx
  • packages/react-router/tests/useMatch.test.tsx
  • packages/react-router/tests/useNavigate.test.tsx
  • packages/react-start-client/src/tests/Hydrate.test.tsx
  • packages/react-start-client/src/tests/hydrateStart.test.ts
  • packages/router-core/tests/background-assets-stale.test.ts
  • packages/router-core/tests/blocked-navigation-current-load.test.ts
  • packages/router-core/tests/boundary-component-chunk.test.ts
  • packages/router-core/tests/build-location.test.ts
  • packages/router-core/tests/client-lane-adversarial.test.ts
  • packages/router-core/tests/error-boundary-cache-generation.test.ts
  • packages/router-core/tests/hmr-refresh-lifecycle.test.ts
  • packages/router-core/tests/hydration-asset-context-order.test.ts
  • packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts
  • packages/router-core/tests/masked-location-state-commit.test.ts
  • packages/router-core/tests/preload-adoption.test.ts
  • packages/router-core/tests/preload-beforeload-reuse.test.ts
  • packages/router-core/tests/preload-public-cache-behavior.test.ts
  • packages/router-core/tests/public-client-loading-contract.test.ts
  • packages/router-core/tests/public-preload-lane-contract.test.ts
  • packages/router-core/tests/same-destination-navigation-join.test.ts
  • packages/router-core/tests/scroll-restoration.test.ts
  • packages/router-core/tests/searchParams.test.ts
  • packages/router-core/tests/server-async-headers-decorative-hang.test.ts
  • packages/router-core/tests/ssr-server-cleanup.test.ts
  • packages/router-core/tests/stay-match-abort.test.ts
  • packages/router-core/tests/transformStreamWithRouter.test.ts
  • packages/router-core/tests/utils.test.ts
  • packages/router-devtools-core/tests/cache-replacement.test.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/utils.test.ts
  • packages/router-generator/tests/validate-route-params.test.ts
  • packages/router-plugin/tests/router-plugin-context.test.ts
  • packages/router-ssr-query-core/tests/index.test.ts
  • packages/solid-router/tests/Scripts.test.tsx
  • packages/solid-router/tests/Transitioner.test.tsx
  • packages/solid-router/tests/component-preload-retry.test.tsx
  • packages/solid-router/tests/createLazyRoute.test.tsx
  • packages/solid-router/tests/errorComponent.test.tsx
  • packages/solid-router/tests/issue-7986-retained-pending.test.tsx
  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/loaders.test.tsx
  • packages/solid-router/tests/pending-fallback-promise-replacement.test.tsx
  • packages/solid-router/tests/redirect.test.tsx
  • packages/solid-router/tests/renderRouterToStream.test.tsx
  • packages/solid-router/tests/router-client-stream-cleanup.test.tsx
  • packages/solid-router/tests/router.test.tsx
  • packages/solid-router/tests/same-route-pending-blank.test.tsx
  • packages/solid-router/tests/server/Transitioner.test.tsx
  • packages/solid-router/tests/transitioner-remount.test.tsx
  • packages/solid-router/tests/useMatch.test.tsx
  • packages/solid-start-client/src/tests/hydrateStart.test.ts
  • packages/start-client-core/tests/hydration-visible.test.ts
  • packages/start-plugin-core/tests/rsbuild/post-build.test.ts
  • packages/start-plugin-core/tests/utils.test.ts
  • packages/start-server-core/tests/early-hints.test.ts
  • packages/vue-router/tests/Scripts.test.tsx
  • packages/vue-router/tests/errorComponent.test.tsx
  • packages/vue-router/tests/hydration-capped-boundary-pending.test.tsx
  • packages/vue-router/tests/issue-7986-retained-pending.test.tsx
  • packages/vue-router/tests/link.test.tsx
  • packages/vue-router/tests/pending-fallback-promise-replacement.test.tsx
  • packages/vue-router/tests/renderRouterToStream.test.tsx
  • packages/vue-router/tests/router.test.tsx
  • packages/vue-router/tests/transitioner-idle-after-render.test.tsx
  • packages/vue-router/tests/transitioner-remount-rendered.test.tsx
  • packages/vue-router/tests/transitioner-remount.test.tsx
  • packages/vue-router/tests/useMatch.test.tsx
  • packages/vue-start-client/src/hydrateStart.test.ts

Comment on lines +27 to +33
onTestFinished(() => {
document.body.innerHTML = ''
try {
window.localStorage.clear()
} catch {}
vi.useRealTimers()
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

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

rg -n -C 5 'before(All|Each)|onTestFinished' \
  packages/router-devtools-core/tests/cache-replacement.test.ts \
  packages/start-client-core/tests/hydration-visible.test.ts

fd -HI '^package\.json$' . -E node_modules -x \
  rg -n '"vitest"' {}

Repository: TanStack/router

Length of output: 7708


🌐 Web query:

Vitest onTestFinished API call outside test body beforeAll beforeEach throws

💡 Result:

Yes, calling the onTestFinished API outside of a test body, including within beforeAll or beforeEach hooks, will throw an error [1][2][3]. Vitest explicitly designs onTestFinished to be used during the execution of a test to clean up state created specifically within that test's body [1][4][2]. When running hooks like beforeAll or beforeEach, Vitest specifically disables the onTestFinished (and onTestFailed) functions to prevent them from being invoked in an invalid scope, resulting in the error: Cannot call "onTestFinished" inside a test hook [5][3]. To perform cleanup within hooks, you should use the standard lifecycle patterns provided by Vitest: 1. For beforeEach: You can return a cleanup function directly from your beforeEach hook [6][7]. Vitest will automatically execute this function after each test [6]. 2. For beforeAll: Similarly, you can return a cleanup function from a beforeAll hook, which Vitest will execute after all tests in the suite have completed [6]. If you need to register cleanup logic dynamically based on resources created inside a test, keep using onTestFinished inside the test body itself [1][2][7]. If you are working with concurrent tests, ensure you use the onTestFinished method provided directly by the test context [8][1][2].

Citations:


🌐 Web query:

Vitest beforeAll hook can call onTestFinished inside it

💡 Result:

No, you cannot call onTestFinished inside a beforeAll hook [1][2]. In Vitest, onTestFinished is designed to be used during the execution of a test (or within beforeEach/afterEach hooks that run in the context of a test) to register cleanup logic that runs after that specific test completes [3][4][5]. The beforeAll hook, by contrast, runs once before the entire suite starts [3][5]. Because it operates outside the context of any individual test, Vitest explicitly disables and throws an error if you attempt to call onTestFinished within beforeAll (or other suite-level hooks) [1][2]. If you need to perform cleanup for the entire suite, you should use the afterAll hook instead [3][5].

Citations:


🏁 Script executed:

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

printf '%s\n' '--- cache-replacement.test.ts relevant section ---'
sed -n '1,100p' packages/router-devtools-core/tests/cache-replacement.test.ts | cat -n

printf '%s\n' '--- hydration-visible.test.ts relevant section ---'
sed -n '38,110p' packages/start-client-core/tests/hydration-visible.test.ts | cat -n

Repository: TanStack/router

Length of output: 6291


🏁 Script executed:

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

node - <<'JS'
const vitestDocsLink = 'https://vitest.dev/api/hooks.html'
const vitestErrorsLink = 'https://errors.standardbeagle.com/vitest-dev/vitest/cannot-call-ontestfinished-inside-a-test-hook/'
const packages = {
  'packages/router-devtools-core/tests/cache-replacement.test.ts': { onTestFinishedOutsideTestBody: true, vitestVersionFromRootPackageJson: require('./package.json').devDependencies.vitest },
  'packages/router-devtools-core/tests/cache-replacement.test.ts': { onTestFinishedInsideBeforeAllComment: false },
  'packages/start-client-core/tests/hydration-visible.test.ts': { onTestFinishedOutsideTestBodyInBeforeEach: true, vitestVersionFromStartPackageJson: require('./packages/start-client-core/package.json').devDependencies.vitest },
}
Object.entries(packages).forEach(([file, info]) => {
  console.log(file, JSON.stringify(info))
})
console.log(vitestDocsLink)
console.log(vitestErrorsLink)
JS

Repository: TanStack/router

Length of output: 505


Register onTestFinished only from test bodies.

Vitest throws when onTestFinished runs outside a test body, including from suite-level or shared setup hooks. This can fail affected tests before assertions run.

  • packages/router-devtools-core/tests/cache-replacement.test.ts#L19-L27: The beforeAll warmup hook currently does not register onTestFinished; no change is needed here.
  • packages/start-client-core/tests/hydration-visible.test.ts#L49-L69: Move the IntersectionObserver cleanup registration into each test body, including via observe(...) which calls onTestFinished, instead of from the shared beforeEach.
🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 27-27: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation

(dom-content-modification)

📍 Affects 2 files
  • packages/router-devtools-core/tests/cache-replacement.test.ts#L27-L33 (this comment)
  • packages/start-client-core/tests/hydration-visible.test.ts#L55-L57
🤖 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/router-devtools-core/tests/cache-replacement.test.ts` around lines
27 - 33, Move the IntersectionObserver cleanup registration out of the shared
beforeEach in observe(...) within
packages/start-client-core/tests/hydration-visible.test.ts#L55-L57 and into each
test body so onTestFinished runs only during tests. The beforeAll hook in
packages/router-devtools-core/tests/cache-replacement.test.ts#L19-L27 requires
no change.

Comment on lines +39 to +42
} finally {
cleanup()
vi.useRealTimers()
}

Copy link
Copy Markdown
Contributor

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

Restore real timers when DOM cleanup fails.

If cleanup() throws, execution skips vi.useRealTimers(). A failed unmount can leave fake timers enabled for later tests and cause cascading failures. Put vi.useRealTimers() in an inner finally.

Proposed fix
     } finally {
-      cleanup()
-      vi.useRealTimers()
+      try {
+        cleanup()
+      } finally {
+        vi.useRealTimers()
+      }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} finally {
cleanup()
vi.useRealTimers()
}
} finally {
try {
cleanup()
} finally {
vi.useRealTimers()
}
}
🤖 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/solid-router/tests/same-route-pending-blank.test.tsx` around lines
39 - 42, Update the cleanup block in the test teardown so vi.useRealTimers()
runs even when cleanup() throws: wrap cleanup() in an inner try/finally and
place timer restoration in that finally, preserving the existing outer teardown
behavior.

@codspeed-hq

codspeed-hq Bot commented Aug 10, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 30.59%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
❌ 3 regressed benchmarks
✅ 175 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory mem server error-paths not-found (vue) 329.9 KB 2,061.9 KB -84%
Memory mem server request-churn (react) 488.2 KB 833.3 KB -41.41%
Memory mem server error-paths redirect (solid) 288.7 KB 345.4 KB -16.44%
Memory mem server error-paths not-found (solid) 661.7 KB 411.8 KB +60.68%
Memory mem client unique-location-churn (solid) 436.9 KB 341.4 KB +27.99%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing test/use-on-test-finished-cleanup (bc1e0fd) with main (af8dcb8)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment