From aaffb1e90df57d3dc1d86a128cef3779bfc096f7 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 25 Sep 2025 17:37:00 +0200 Subject: [PATCH 1/4] more tests --- .../react-create-hash-router/package.json | 3 +- .../react-create-hash-router/src/index.tsx | 26 +++ .../src/pages/Group.tsx | 7 + .../src/pages/Index.tsx | 15 ++ .../src/pages/Post.tsx | 13 ++ .../src/pages/PostFeatured.tsx | 7 + .../src/pages/PostIndex.tsx | 7 + .../src/pages/PostRelated.tsx | 7 + .../tests/transactions.test.ts | 216 +++++++++++++++++- 9 files changed, 297 insertions(+), 4 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Group.tsx create mode 100644 dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Post.tsx create mode 100644 dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostFeatured.tsx create mode 100644 dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostIndex.tsx create mode 100644 dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostRelated.tsx diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json index 3dea78b20080..991b2de59e04 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json @@ -15,6 +15,7 @@ }, "scripts": { "build": "react-scripts build", + "dev": "react-scripts start", "start": "serve -s build", "test": "playwright test", "clean": "npx rimraf node_modules pnpm-lock.yaml", @@ -48,4 +49,4 @@ "volta": { "extends": "../../package.json" } -} +} \ No newline at end of file diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx index 2ad9490ccd57..f8612e225eb7 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx @@ -11,6 +11,11 @@ import { } from 'react-router-dom'; import Index from './pages/Index'; import User from './pages/User'; +import Group from './pages/Group'; +import Post from './pages/Post'; +import PostFeatured from './pages/PostFeatured'; +import PostRelated from './pages/PostRelated'; +import PostIndex from './pages/PostIndex'; const replay = Sentry.replayIntegration(); @@ -52,8 +57,29 @@ const router = sentryCreateHashRouter([ path: '/user/:id', element: , }, + { + path: '/group/:group/:user?', + element: , + }, + { + path: '/v2/post/:post', + element: , + children: [ + { index: true, element: }, + { + path: 'featured', + element: , + }, + { + path: '/v2/post/:post/related', + element: , + }, + ], + }, ]); +console.log(router.routes); + const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render(); diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Group.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Group.tsx new file mode 100644 index 000000000000..9dd9ac110898 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Group.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const Group = () => { + return

Group page

; +}; + +export default Group; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx index 1000dd53df27..ac877db7b812 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx @@ -15,6 +15,21 @@ const Index = () => { navigate + + Post 1 + + + Post 1 featured + + + Post 1 related + + + Group 1 + + + Group 1 user 5 + ); }; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Post.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Post.tsx new file mode 100644 index 000000000000..9b844b17ff68 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Post.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { Outlet } from 'react-router-dom'; + +const Post = () => { + return ( + <> +

Post V2 page

+ + + ); +}; + +export default Post; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostFeatured.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostFeatured.tsx new file mode 100644 index 000000000000..0446fa0ec6ad --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostFeatured.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const PostFeatured = () => { + return

Post featured page

; +}; + +export default PostFeatured; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostIndex.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostIndex.tsx new file mode 100644 index 000000000000..ad3efaa9216a --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostIndex.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const PostIndex = () => { + return

Post index page

; +}; + +export default PostIndex; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostRelated.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostRelated.tsx new file mode 100644 index 000000000000..ff8d05f6f6f9 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/PostRelated.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const PostRelated = () => { + return

Post related page

; +}; + +export default PostRelated; diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts index 920506838080..bfc07adcc4eb 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts @@ -14,9 +14,9 @@ test('Captures a pageload transaction', async ({ page }) => { deviceMemory: expect.any(String), effectiveConnectionType: expect.any(String), hardwareConcurrency: expect.any(String), - 'lcp.element': 'body > div#root > input#exception-button[type="button"]', - 'lcp.id': 'exception-button', - 'lcp.size': 1650, + 'lcp.element': expect.any(String), + 'lcp.id': expect.any(String), + 'lcp.size': expect.any(Number), 'sentry.idle_span_finish_reason': 'idleTimeout', 'sentry.op': 'pageload', 'sentry.origin': 'auto.pageload.react.reactrouter_v6', @@ -150,3 +150,213 @@ test('Captures a navigation transaction', async ({ page }) => { expect(transactionEvent.spans).toEqual([]); }); + +test('Captures a parameterized path pageload transaction', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/v2/post/1'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path pageload transaction for nested route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/v2/post/1/featured'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post/featured', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path pageload transaction for nested route with absolute path', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/v2/post/1/related'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post/related', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path navigation transaction', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-post-1'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path navigation transaction for nested route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-post-1-featured'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post/featured', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path navigation transaction for nested route with absolute path', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-post-1-related'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v2/post/:post/related', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path pageload transaction for group route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/group/1'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/group/:group/:user?', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path navigation transaction for group route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-group-1'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/group/:group/:user?', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path pageload transaction for nested group route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/group/1/5'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/group/:group/:user?', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Captures a parameterized path navigation transaction for nested group route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-group-1-user-5'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/group/:group/:user?', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); From 2a684f5df088ea5ba7652be4b8f63e8fa184b125 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 25 Sep 2025 17:43:01 +0200 Subject: [PATCH 2/4] format --- .../test-applications/react-create-hash-router/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json index 991b2de59e04..0e108f6fa56e 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json @@ -49,4 +49,4 @@ "volta": { "extends": "../../package.json" } -} \ No newline at end of file +} From cec648edf3cc19bf759553994025f923d5778316 Mon Sep 17 00:00:00 2001 From: s1gr1d Date: Tue, 21 Oct 2025 15:34:09 +0200 Subject: [PATCH 3/4] add test case for deely nested route --- .../react-create-hash-router/src/index.tsx | 24 +++++++---- .../src/pages/Index.tsx | 3 ++ .../tests/transactions.test.ts | 42 +++++++++++++++++++ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx index f8612e225eb7..a88e8acf06fb 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx @@ -62,20 +62,26 @@ const router = sentryCreateHashRouter([ element: , }, { - path: '/v2/post/:post', - element: , + path: '/v1/post/:post', + element:
, children: [ - { index: true, element: }, - { - path: 'featured', - element: , - }, + { path: 'featured', element:
}, + { path: '/v1/post/:post/related', element:
}, { - path: '/v2/post/:post/related', - element: , + element:
More Nested Children
, + children: [{ path: 'edit', element:
Edit Post
}], }, ], }, + { + path: '/v2/post/:post', + element:
, + children: [ + { index: true, element:
}, + { path: 'featured', element:
}, + { path: '/v2/post/:post/related', element:
}, + ], + }, ]); console.log(router.routes); diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx index ac877db7b812..20a2ab60fa21 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/pages/Index.tsx @@ -18,6 +18,9 @@ const Index = () => { Post 1 + + Edit Post 1 + Post 1 featured diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts index bfc07adcc4eb..36e6d0c18ee2 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts @@ -191,6 +191,26 @@ test('Captures a parameterized path pageload transaction for nested route', asyn ); }); +test('Captures a parameterized path pageload transaction for deeply nested route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'pageload'; + }); + + await page.goto('/#/v1/post/1/edit'); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v1/post/:post/edit', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + test('Captures a parameterized path pageload transaction for nested route with absolute path', async ({ page }) => { const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { return event.contexts?.trace?.op === 'pageload'; @@ -255,6 +275,28 @@ test('Captures a parameterized path navigation transaction for nested route', as ); }); +test('Captures a parameterized path navigation transaction for deeply nested route', async ({ page }) => { + const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { + return event.contexts?.trace?.op === 'navigation'; + }); + + await page.goto('/'); + const linkElement = page.locator('id=navigation-post-1-edit'); + await linkElement.click(); + + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: '/v1/post/:post/edit', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + test('Captures a parameterized path navigation transaction for nested route with absolute path', async ({ page }) => { const transactionEventPromise = waitForTransaction('react-create-hash-router', event => { return event.contexts?.trace?.op === 'navigation'; From 8cd26a2ec2de16f3da56bd3b2ea64c00429212cc Mon Sep 17 00:00:00 2001 From: s1gr1d Date: Thu, 23 Oct 2025 16:03:40 +0200 Subject: [PATCH 4/4] fix CI errors --- .../test-applications/react-create-hash-router/package.json | 2 +- .../react-create-hash-router/src/index.tsx | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json index 0e108f6fa56e..afe9486eeebf 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/package.json @@ -11,7 +11,7 @@ "react-dom": "18.2.0", "react-router-dom": "^6.4.1", "react-scripts": "5.0.1", - "typescript": "~5.0.0" + "typescript": "~4.9.5" }, "scripts": { "build": "react-scripts build", diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx index a88e8acf06fb..86de5f20378d 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/src/index.tsx @@ -12,10 +12,6 @@ import { import Index from './pages/Index'; import User from './pages/User'; import Group from './pages/Group'; -import Post from './pages/Post'; -import PostFeatured from './pages/PostFeatured'; -import PostRelated from './pages/PostRelated'; -import PostIndex from './pages/PostIndex'; const replay = Sentry.replayIntegration(); @@ -84,8 +80,6 @@ const router = sentryCreateHashRouter([ }, ]); -console.log(router.routes); - const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render();