From 475c6d6d9f9b0fb1b6b5f442634430236d49d514 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2025 11:56:23 +0200 Subject: [PATCH 1/3] Add unit test for reproducing #4245 --- packages/react-router/tests/loaders.test.tsx | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/packages/react-router/tests/loaders.test.tsx b/packages/react-router/tests/loaders.test.tsx index 85a9dc15f9..8f2fe13e07 100644 --- a/packages/react-router/tests/loaders.test.tsx +++ b/packages/react-router/tests/loaders.test.tsx @@ -27,6 +27,7 @@ afterEach(() => { }) const WAIT_TIME = 100 +const LOADER_WAIT_TIME = 1000 describe('loaders are being called', () => { configure({ reactStrictMode: true }) @@ -325,3 +326,68 @@ test('throw error from beforeLoad when navigating to route', async () => { const indexElement = await screen.findByText('fooErrorComponent') expect(indexElement).toBeInTheDocument() }) + +test('reproducer #4245', async () => { + const rootRoute = createRootRoute({}) + + const indexRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/', + loader: async () => { + await sleep(LOADER_WAIT_TIME) + return 'index' + }, + component: () => { + const data = indexRoute.useLoaderData() + return ( +
+ foo + {data} +
+ ) + }, + }) + + const fooRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/foo', + component: () => index, + }) + + const routeTree = rootRoute.addChildren([indexRoute, fooRoute]) + const router = createRouter({ routeTree }) + + render() + + // We wait for the initial loader to complete + const fooLink = await screen.findByRole('link', { name: 'foo' }, { timeout: LOADER_WAIT_TIME + WAIT_TIME }) + expect(fooLink).toBeInTheDocument() + + // We navigate to the foo route + fireEvent.click(fooLink) + + // We immediately see the content of the foo route + const indexLink = await screen.findByRole('link', { name: 'index' }, { timeout: WAIT_TIME }) + expect(indexLink).toBeInTheDocument() + + // We navigate to the index route + fireEvent.click(indexLink) + + // We immediately see the content of the index route because the stale data is still available + const fooLink2 = await screen.findByRole('link', { name: 'foo' }, { timeout: WAIT_TIME }) + expect(fooLink2).toBeInTheDocument() + + // We navigate to the foo route again + fireEvent.click(fooLink2) + + // We immediately see the content of the foo route + const indexLink2 = await screen.findByRole('link', { name: 'index' }, { timeout: WAIT_TIME }) + expect(indexLink2).toBeInTheDocument() + + // We navigate to the index route again + fireEvent.click(indexLink2) + + // We now should see the content of the index route immediately because the stale data is still available + const fooLink3 = await screen.findByRole('link', { name: 'foo' }, { timeout: WAIT_TIME }) + expect(fooLink3).toBeInTheDocument() +}) \ No newline at end of file From a68bf5ba40372820aea6a40a74c8751b4533153c Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2025 12:19:57 +0200 Subject: [PATCH 2/3] Wait for router to load before starting to test --- packages/react-router/tests/loaders.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-router/tests/loaders.test.tsx b/packages/react-router/tests/loaders.test.tsx index 8f2fe13e07..3c65a6d5d7 100644 --- a/packages/react-router/tests/loaders.test.tsx +++ b/packages/react-router/tests/loaders.test.tsx @@ -359,6 +359,8 @@ test('reproducer #4245', async () => { render() + await router.load() + // We wait for the initial loader to complete const fooLink = await screen.findByRole('link', { name: 'foo' }, { timeout: LOADER_WAIT_TIME + WAIT_TIME }) expect(fooLink).toBeInTheDocument() From b6d6cd21f5496e3a97c4956d090d20e30c295cb6 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 24 May 2025 10:21:32 +0000 Subject: [PATCH 3/3] ci: apply automated fixes --- packages/react-router/tests/loaders.test.tsx | 32 ++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/react-router/tests/loaders.test.tsx b/packages/react-router/tests/loaders.test.tsx index 3c65a6d5d7..cd4e2638d4 100644 --- a/packages/react-router/tests/loaders.test.tsx +++ b/packages/react-router/tests/loaders.test.tsx @@ -362,34 +362,54 @@ test('reproducer #4245', async () => { await router.load() // We wait for the initial loader to complete - const fooLink = await screen.findByRole('link', { name: 'foo' }, { timeout: LOADER_WAIT_TIME + WAIT_TIME }) + const fooLink = await screen.findByRole( + 'link', + { name: 'foo' }, + { timeout: LOADER_WAIT_TIME + WAIT_TIME }, + ) expect(fooLink).toBeInTheDocument() // We navigate to the foo route fireEvent.click(fooLink) // We immediately see the content of the foo route - const indexLink = await screen.findByRole('link', { name: 'index' }, { timeout: WAIT_TIME }) + const indexLink = await screen.findByRole( + 'link', + { name: 'index' }, + { timeout: WAIT_TIME }, + ) expect(indexLink).toBeInTheDocument() // We navigate to the index route fireEvent.click(indexLink) // We immediately see the content of the index route because the stale data is still available - const fooLink2 = await screen.findByRole('link', { name: 'foo' }, { timeout: WAIT_TIME }) + const fooLink2 = await screen.findByRole( + 'link', + { name: 'foo' }, + { timeout: WAIT_TIME }, + ) expect(fooLink2).toBeInTheDocument() // We navigate to the foo route again fireEvent.click(fooLink2) // We immediately see the content of the foo route - const indexLink2 = await screen.findByRole('link', { name: 'index' }, { timeout: WAIT_TIME }) + const indexLink2 = await screen.findByRole( + 'link', + { name: 'index' }, + { timeout: WAIT_TIME }, + ) expect(indexLink2).toBeInTheDocument() // We navigate to the index route again fireEvent.click(indexLink2) // We now should see the content of the index route immediately because the stale data is still available - const fooLink3 = await screen.findByRole('link', { name: 'foo' }, { timeout: WAIT_TIME }) + const fooLink3 = await screen.findByRole( + 'link', + { name: 'foo' }, + { timeout: WAIT_TIME }, + ) expect(fooLink3).toBeInTheDocument() -}) \ No newline at end of file +})