Skip to content

Conversation

@birkskyum
Copy link
Member

@birkskyum birkskyum commented Nov 3, 2025

this better handles the async navigation transitions

Summary by CodeRabbit

  • Tests
    • Improved reliability for router test suites by converting immediate assertions to awaited, retry-enabled checks; added asynchronous waits around post-navigation assertions, deferred element lookups until after relevant navigations, and ensured active-link state is observed only after navigation completes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Walkthrough

Tests in react-router and solid-router were updated to synchronize with navigation by adding waitFor usage, moving some element lookups, and wrapping assertions that depend on router state changes.

Changes

Cohort / File(s) Summary
React Router — Link Test
packages/react-router/tests/link.test.tsx
Wraps the active-class assertion in a waitFor after clicking the link to wait for navigation-driven DOM updates.
Solid Router — Link Test
packages/solid-router/tests/link.test.tsx
Wraps the active-class assertion in a waitFor after clicking the link to wait for navigation-driven DOM updates.
React Router — Optional Path Params Tests
packages/react-router/tests/optional-path-params.test.tsx
Adds waitFor import; defers certain element lookups and wraps pathname assertions in waitFor blocks to await router state updates after clicks.
Solid Router — Optional Path Params Tests
packages/solid-router/tests/optional-path-params.test.tsx
Moves some element retrievals and wraps post-click pathname assertions in waitFor blocks to ensure navigation completion before checks.

Sequence Diagram(s)

sequenceDiagram
  participant Test as Test Code
  participant DOM as Browser DOM
  participant Router as Router

  Test->>DOM: find link/button
  Test->>DOM: click link/button
  note right of DOM `#DFF7DF`: click initiates navigation
  DOM->>Router: navigation request
  Router->>Router: update location (async)
  Router->>DOM: render updated route (async)
  alt Wait for update
    Test->>Test: waitFor(assertion)
    Test->>DOM: query for active class / pathname
    DOM-->>Test: element reflects new state
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Repetitive, localized changes confined to test files.
  • Spot-check:
    • Correct import of waitFor where added.
    • That moved element lookups occur at intended times (before/after clicks).
    • No accidental changes to production code or test semantics beyond synchronization.

Possibly related PRs

Suggested reviewers

  • schiller-manuel
  • brenelz

Poem

🐰 I waited by the testing tree,
Clicked a link and hopped with glee,
Paths resolved and classes shone,
Assertions found their cozy home,
Hooray — tests now rest easy 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding waitFor assertions to handle asynchronous navigation in router tests for both react-router and solid-router packages.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test(router)--add-waitFor-for-page-navigation

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 and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Nov 3, 2025

View your CI Pipeline Execution ↗ for commit f99dc18

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

☁️ Nx Cloud last updated this comment at 2025-11-03 18:32:49 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 3, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5741

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5741

@tanstack/eslint-plugin-router

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

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5741

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5741

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5741

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5741

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5741

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5741

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5741

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5741

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5741

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5741

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5741

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5741

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5741

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5741

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5741

commit: f99dc18

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/react-router/tests/link.test.tsx (1)

363-365: LGTM! Test synchronization correctly handles async navigation.

The waitFor wrapper properly ensures the router state update completes before asserting the active class. This aligns with the PR's objective to improve test reliability for asynchronous navigation.

Optional: Consider whether the subsequent assertions (lines 367-409) that check link states after navigation might benefit from being included in this waitFor block or having their own synchronization checks. The current implementation likely works because the first waitFor provides sufficient delay, but explicitly grouping related assertions could make the test's intent clearer and more robust:

 await waitFor(() => {
   expect(indexFooBarLink).toHaveClass('active')
+  
+  expect(indexExactLink).toHaveClass('inactive')
+  expect(indexExactLink).not.toHaveClass('active')
+  // ... other related assertions
 })

However, this is purely a robustness suggestion and not required if the current implementation is stable.

packages/solid-router/tests/link.test.tsx (1)

396-399: Good use of waitFor to de-flake async navigation assertion.

Optional: also assert the location/search within the same waitFor, or re-query the link post‑navigation to avoid a potentially stale element reference.

packages/react-router/tests/optional-path-params.test.tsx (1)

650-665: Synchronizing via waitFor and deferring queries looks solid.

Optional: prefer DOM signals over internal state for assertions, e.g., await screen.findByRole('heading', { name: 'Posts' }) and/or expect(window.location.pathname) inside waitFor, to reduce coupling to router internals.

packages/solid-router/tests/optional-path-params.test.tsx (1)

651-665: Nice stabilization with waitFor and deferred lookups.

Optional: assert via UI (e.g., heading present) and/or window.location.pathname inside waitFor to avoid relying on router.state directly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbd3e2 and 4cf5f50.

📒 Files selected for processing (4)
  • packages/react-router/tests/link.test.tsx (1 hunks)
  • packages/react-router/tests/optional-path-params.test.tsx (2 hunks)
  • packages/solid-router/tests/link.test.tsx (1 hunks)
  • packages/solid-router/tests/optional-path-params.test.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/link.test.tsx
packages/{react-router,solid-router}/**

📄 CodeRabbit inference engine (AGENTS.md)

Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/

Files:

  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/link.test.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to packages/{react-router,solid-router}/** : Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/optional-path-params.test.tsx
📚 Learning: 2025-09-23T17:36:12.598Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to packages/{react-router,solid-router}/** : Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/

Applied to files:

  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/optional-path-params.test.tsx
  • packages/react-router/tests/optional-path-params.test.tsx
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.

Applied to files:

  • packages/solid-router/tests/optional-path-params.test.tsx
📚 Learning: 2025-10-09T12:59:02.129Z
Learnt from: hokkyss
Repo: TanStack/router PR: 5418
File: e2e/react-start/custom-identifier-prefix/src/styles/app.css:19-21
Timestamp: 2025-10-09T12:59:02.129Z
Learning: In e2e test directories (paths containing `e2e/`), accessibility concerns like outline suppression patterns are less critical since the code is for testing purposes, not production use.

Applied to files:

  • packages/solid-router/tests/optional-path-params.test.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (2)
packages/react-router/tests/optional-path-params.test.tsx (1)

2-9: Importing waitFor is correct for the new async assertions.

packages/solid-router/tests/optional-path-params.test.tsx (1)

718-735: Good pattern: re-query element after navigation and wrap assertions in waitFor.

This reduces stale node issues and flakiness. No changes needed.

@birkskyum birkskyum added this to the catch up solid to react milestone Nov 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/react-router/tests/optional-path-params.test.tsx (1)

649-664: Good use of waitFor for async navigation assertions.

The waitFor wrapper correctly handles asynchronous router state updates after navigation, preventing potential race conditions in the test.

Optional: Remove unnecessary await on fireEvent.click().

The fireEvent.click() method is synchronous and returns void, so awaiting it has no effect. Consider this refactor:

-      await fireEvent.click(navigateAll)
+      fireEvent.click(navigateAll)
       await waitFor(() => {
         expect(router.state.location.pathname).toBe('/posts')
       })
 
       const navigateTech = await screen.findByTestId('navigate-tech')
-      await fireEvent.click(navigateTech)
+      fireEvent.click(navigateTech)
       await waitFor(() => {
         expect(router.state.location.pathname).toBe('/posts/tech')
       })
 
       const navigateSpecific = await screen.findByTestId('navigate-specific')
-      await fireEvent.click(navigateSpecific)
+      fireEvent.click(navigateSpecific)
       await waitFor(() => {
         expect(router.state.location.pathname).toBe('/posts/tech/hello-world')
       })

Optional: Consider applying this pattern to other tests.

For consistency, other tests in this file that assert router.state.location.pathname after navigation (lines 511, 533, 721, 728) could benefit from the same waitFor wrapper to ensure robustness against timing variations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fa4a2e and f99dc18.

📒 Files selected for processing (1)
  • packages/react-router/tests/optional-path-params.test.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • packages/react-router/tests/optional-path-params.test.tsx
packages/{react-router,solid-router}/**

📄 CodeRabbit inference engine (AGENTS.md)

Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/

Files:

  • packages/react-router/tests/optional-path-params.test.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to packages/{react-router,solid-router}/** : Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/react-router/tests/optional-path-params.test.tsx
📚 Learning: 2025-09-23T17:36:12.598Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to packages/{react-router,solid-router}/** : Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/

Applied to files:

  • packages/react-router/tests/optional-path-params.test.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (1)
packages/react-router/tests/optional-path-params.test.tsx (1)

2-9: LGTM! Proper import for async test assertions.

The addition of waitFor to the imports is correct and necessary for handling asynchronous router navigation state updates in the test below.

@birkskyum birkskyum merged commit 470f9b6 into main Nov 3, 2025
6 checks passed
@birkskyum birkskyum deleted the test(router)--add-waitFor-for-page-navigation branch November 3, 2025 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants