From b1ce10d1bff063a482ab7f0235730877085ee17b Mon Sep 17 00:00:00 2001 From: soch4n <20456656+soch4n@users.noreply.github.com> Date: Fri, 7 Jun 2024 14:29:54 +0900 Subject: [PATCH 1/3] fix(vue): Correct span name assignment for matched routes in VueRouter --- packages/vue/src/router.ts | 5 +++-- packages/vue/test/router.test.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/vue/src/router.ts b/packages/vue/src/router.ts index ba42c8ba9fb5..b1d7163e48d1 100644 --- a/packages/vue/src/router.ts +++ b/packages/vue/src/router.ts @@ -83,8 +83,9 @@ export function instrumentVueRouter( if (to.name && options.routeLabel !== 'path') { spanName = to.name.toString(); transactionSource = 'custom'; - } else if (to.matched[0] && to.matched[0].path) { - spanName = to.matched[0].path; + } else if (to.matched.length > 0) { + const lastIndex = to.matched.length - 1; + spanName = to.matched[lastIndex].path; transactionSource = 'route'; } diff --git a/packages/vue/test/router.test.ts b/packages/vue/test/router.test.ts index 8ff42d49e2b9..256cecd9b313 100644 --- a/packages/vue/test/router.test.ts +++ b/packages/vue/test/router.test.ts @@ -43,6 +43,18 @@ const testRoutes: Record = { path: '/accounts/4', query: {}, }, + nestedRoute: { + matched: [ + { path: '/' }, + { path: '/categories' }, + { path: '/categories/:categoryId' }, + ], + params: { + categoryId: '1' + }, + path: '/categories/1', + query: {}, + }, namedRoute: { matched: [{ path: '/login' }], name: 'login-screen', @@ -85,6 +97,7 @@ describe('instrumentVueRouter()', () => { it.each([ ['normalRoute1', 'normalRoute2', '/accounts/:accountId', 'route'], + ['normalRoute1', 'nestedRoute', '/categories/:categoryId', 'route'], ['normalRoute2', 'namedRoute', 'login-screen', 'custom'], ['normalRoute2', 'unmatchedRoute', '/e8733846-20ac-488c-9871-a5cbcb647294', 'url'], ])( @@ -122,6 +135,7 @@ describe('instrumentVueRouter()', () => { it.each([ ['initialPageloadRoute', 'normalRoute1', '/books/:bookId/chapter/:chapterId', 'route'], + ['initialPageloadRoute', 'nestedRoute', '/categories/:categoryId', 'route'], ['initialPageloadRoute', 'namedRoute', 'login-screen', 'custom'], ['initialPageloadRoute', 'unmatchedRoute', '/e8733846-20ac-488c-9871-a5cbcb647294', 'url'], ])( From 22028764cfb44513a199fbf00eca68dffae307c4 Mon Sep 17 00:00:00 2001 From: soch4n <20456656+soch4n@users.noreply.github.com> Date: Fri, 7 Jun 2024 19:36:07 +0900 Subject: [PATCH 2/3] style(vue): format --- packages/vue/test/router.test.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/vue/test/router.test.ts b/packages/vue/test/router.test.ts index 256cecd9b313..e835855ebd7a 100644 --- a/packages/vue/test/router.test.ts +++ b/packages/vue/test/router.test.ts @@ -44,13 +44,9 @@ const testRoutes: Record = { query: {}, }, nestedRoute: { - matched: [ - { path: '/' }, - { path: '/categories' }, - { path: '/categories/:categoryId' }, - ], + matched: [{ path: '/' }, { path: '/categories' }, { path: '/categories/:categoryId' }], params: { - categoryId: '1' + categoryId: '1', }, path: '/categories/1', query: {}, From 7be79bed12749ef98aa993467d4593839398b4d4 Mon Sep 17 00:00:00 2001 From: soch4n <20456656+soch4n@users.noreply.github.com> Date: Fri, 7 Jun 2024 19:44:24 +0900 Subject: [PATCH 3/3] run test --- .../vue-3/src/router/index.ts | 9 ++++++ .../vue-3/src/views/CategoryIdView.vue | 3 ++ .../vue-3/tests/performance.test.ts | 29 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 dev-packages/e2e-tests/test-applications/vue-3/src/views/CategoryIdView.vue diff --git a/dev-packages/e2e-tests/test-applications/vue-3/src/router/index.ts b/dev-packages/e2e-tests/test-applications/vue-3/src/router/index.ts index 8c3ac217716f..aac6fb815f43 100644 --- a/dev-packages/e2e-tests/test-applications/vue-3/src/router/index.ts +++ b/dev-packages/e2e-tests/test-applications/vue-3/src/router/index.ts @@ -21,6 +21,15 @@ const router = createRouter({ path: '/users-error/:id', component: () => import('../views/UserIdErrorView.vue'), }, + { + path: '/categories', + children: [ + { + path: ':id', + component: () => import('../views/CategoryIdView.vue'), + }, + ], + }, ], }); diff --git a/dev-packages/e2e-tests/test-applications/vue-3/src/views/CategoryIdView.vue b/dev-packages/e2e-tests/test-applications/vue-3/src/views/CategoryIdView.vue new file mode 100644 index 000000000000..c3b59c9fb7f5 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/vue-3/src/views/CategoryIdView.vue @@ -0,0 +1,3 @@ + diff --git a/dev-packages/e2e-tests/test-applications/vue-3/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/vue-3/tests/performance.test.ts index bdf7b5b8e1fe..d9a594b5abe7 100644 --- a/dev-packages/e2e-tests/test-applications/vue-3/tests/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/vue-3/tests/performance.test.ts @@ -66,6 +66,35 @@ test('sends a navigation transaction with a parameterized URL', async ({ page }) }); }); +test('sends a pageload transaction with a nested route URL', async ({ page }) => { + const transactionPromise = waitForTransaction('vue-3', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + await page.goto(`/categories/123`); + + const rootSpan = await transactionPromise; + + expect(rootSpan).toMatchObject({ + contexts: { + trace: { + data: { + 'sentry.source': 'route', + 'sentry.origin': 'auto.pageload.vue', + 'sentry.op': 'pageload', + 'params.id': '123', + }, + op: 'pageload', + origin: 'auto.pageload.vue', + }, + }, + transaction: '/categories/:id', + transaction_info: { + source: 'route', + }, + }); +}); + test('sends a pageload transaction with a route name as transaction name if available', async ({ page }) => { const transactionPromise = waitForTransaction('vue-3', async transactionEvent => { return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload';