Skip to content

Commit 3d3328e

Browse files
Lms24cursoragent
andauthored
feat(angular): Set url attributes on pageload and navigation spans (#21985)
Adjusts the Angular routing instrumentation to set `url.template` and update `url.full` and `url.path` when resolving routes. We not only have to set `template` (which we can only do in the framework/router-specific instrumentation). We also have to ensure we set `full` and `path` again because in the default integration (#21952), we set it to early based on the window location path. So therefore, we update it again in the router instrumentation and re-set the raw URL (but the resolved one). ref #21921 --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent d86b168 commit 3d3328e

10 files changed

Lines changed: 372 additions & 19 deletions

File tree

dev-packages/e2e-tests/test-applications/angular-17/tests/performance.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ test('sends a pageload transaction with a parameterized URL', async ({ page }) =
1717
trace: {
1818
op: 'pageload',
1919
origin: 'auto.pageload.angular',
20+
data: {
21+
'sentry.origin': 'auto.pageload.angular',
22+
'sentry.source': 'route',
23+
'url.template': '/home/',
24+
'url.path': '/home',
25+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
26+
},
2027
},
2128
},
2229
transaction: '/home/',
@@ -46,6 +53,14 @@ test('sends a navigation transaction with a parameterized URL', async ({ page })
4653
contexts: {
4754
trace: {
4855
op: 'navigation',
56+
origin: 'auto.navigation.angular',
57+
data: {
58+
'sentry.origin': 'auto.navigation.angular',
59+
'sentry.source': 'route',
60+
'url.template': '/users/:id/',
61+
'url.path': '/users/123',
62+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
63+
},
4964
},
5065
},
5166
transaction: '/users/:id/',
@@ -78,6 +93,13 @@ test('sends a navigation transaction even if the pageload span is still active',
7893
trace: {
7994
op: 'pageload',
8095
origin: 'auto.pageload.angular',
96+
data: {
97+
'sentry.origin': 'auto.pageload.angular',
98+
'sentry.source': 'route',
99+
'url.template': '/home/',
100+
'url.path': '/home',
101+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
102+
},
81103
},
82104
},
83105
transaction: '/home/',
@@ -91,6 +113,13 @@ test('sends a navigation transaction even if the pageload span is still active',
91113
trace: {
92114
op: 'navigation',
93115
origin: 'auto.navigation.angular',
116+
data: {
117+
'sentry.origin': 'auto.navigation.angular',
118+
'sentry.source': 'route',
119+
'url.template': '/users/:id/',
120+
'url.path': '/users/123',
121+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
122+
},
94123
},
95124
},
96125
transaction: '/users/:id/',
@@ -115,6 +144,13 @@ test('groups redirects within one navigation root span', async ({ page }) => {
115144
trace: {
116145
op: 'navigation',
117146
origin: 'auto.navigation.angular',
147+
data: {
148+
'sentry.origin': 'auto.navigation.angular',
149+
'sentry.source': 'route',
150+
'url.template': '/users/:id/',
151+
'url.path': '/users/456',
152+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/456$/),
153+
},
118154
},
119155
},
120156
transaction: '/users/:id/',
@@ -145,6 +181,13 @@ test.describe('finish routing span', () => {
145181
trace: {
146182
op: 'navigation',
147183
origin: 'auto.navigation.angular',
184+
data: {
185+
'sentry.origin': 'auto.navigation.angular',
186+
'sentry.source': 'url',
187+
'url.path': '/cancel',
188+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/cancel$/),
189+
// url.template is not set because the navigation was cancelled before Angular fully resolved the route
190+
},
148191
},
149192
},
150193
transaction: '/cancel',
@@ -176,6 +219,13 @@ test.describe('finish routing span', () => {
176219
trace: {
177220
op: 'navigation',
178221
origin: 'auto.navigation.angular',
222+
data: {
223+
'sentry.origin': 'auto.navigation.angular',
224+
'sentry.source': 'url',
225+
'url.path': '/non-existent',
226+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/non-existent$/),
227+
// url.template is not set because the navigation failed before Angular fully resolved the route
228+
},
179229
},
180230
},
181231
transaction: nonExistentRoute,

dev-packages/e2e-tests/test-applications/angular-18/tests/performance.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ test('sends a pageload transaction with a parameterized URL', async ({ page }) =
1717
trace: {
1818
op: 'pageload',
1919
origin: 'auto.pageload.angular',
20+
data: {
21+
'sentry.origin': 'auto.pageload.angular',
22+
'sentry.source': 'route',
23+
'url.template': '/home/',
24+
'url.path': '/home',
25+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
26+
},
2027
},
2128
},
2229
transaction: '/home/',
@@ -46,6 +53,14 @@ test('sends a navigation transaction with a parameterized URL', async ({ page })
4653
contexts: {
4754
trace: {
4855
op: 'navigation',
56+
origin: 'auto.navigation.angular',
57+
data: {
58+
'sentry.origin': 'auto.navigation.angular',
59+
'sentry.source': 'route',
60+
'url.template': '/users/:id/',
61+
'url.path': '/users/123',
62+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
63+
},
4964
},
5065
},
5166
transaction: '/users/:id/',
@@ -78,6 +93,13 @@ test('sends a navigation transaction even if the pageload span is still active',
7893
trace: {
7994
op: 'pageload',
8095
origin: 'auto.pageload.angular',
96+
data: {
97+
'sentry.origin': 'auto.pageload.angular',
98+
'sentry.source': 'route',
99+
'url.template': '/home/',
100+
'url.path': '/home',
101+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
102+
},
81103
},
82104
},
83105
transaction: '/home/',
@@ -91,6 +113,13 @@ test('sends a navigation transaction even if the pageload span is still active',
91113
trace: {
92114
op: 'navigation',
93115
origin: 'auto.navigation.angular',
116+
data: {
117+
'sentry.origin': 'auto.navigation.angular',
118+
'sentry.source': 'route',
119+
'url.template': '/users/:id/',
120+
'url.path': '/users/123',
121+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
122+
},
94123
},
95124
},
96125
transaction: '/users/:id/',
@@ -115,6 +144,13 @@ test('groups redirects within one navigation root span', async ({ page }) => {
115144
trace: {
116145
op: 'navigation',
117146
origin: 'auto.navigation.angular',
147+
data: {
148+
'sentry.origin': 'auto.navigation.angular',
149+
'sentry.source': 'route',
150+
'url.template': '/users/:id/',
151+
'url.path': '/users/456',
152+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/456$/),
153+
},
118154
},
119155
},
120156
transaction: '/users/:id/',
@@ -145,6 +181,13 @@ test.describe('finish routing span', () => {
145181
trace: {
146182
op: 'navigation',
147183
origin: 'auto.navigation.angular',
184+
data: {
185+
'sentry.origin': 'auto.navigation.angular',
186+
'sentry.source': 'url',
187+
'url.path': '/cancel',
188+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/cancel$/),
189+
// url.template is not set because the navigation was cancelled before Angular fully resolved the route
190+
},
148191
},
149192
},
150193
transaction: '/cancel',
@@ -176,6 +219,13 @@ test.describe('finish routing span', () => {
176219
trace: {
177220
op: 'navigation',
178221
origin: 'auto.navigation.angular',
222+
data: {
223+
'sentry.origin': 'auto.navigation.angular',
224+
'sentry.source': 'url',
225+
'url.path': '/non-existent',
226+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/non-existent$/),
227+
// url.template is not set because the navigation failed before Angular fully resolved the route
228+
},
179229
},
180230
},
181231
transaction: nonExistentRoute,

dev-packages/e2e-tests/test-applications/angular-19/tests/performance.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ test('sends a pageload transaction with a parameterized URL', async ({ page }) =
1717
trace: {
1818
op: 'pageload',
1919
origin: 'auto.pageload.angular',
20+
data: {
21+
'sentry.origin': 'auto.pageload.angular',
22+
'sentry.source': 'route',
23+
'url.template': '/home/',
24+
'url.path': '/home',
25+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
26+
},
2027
},
2128
},
2229
transaction: '/home/',
@@ -46,6 +53,14 @@ test('sends a navigation transaction with a parameterized URL', async ({ page })
4653
contexts: {
4754
trace: {
4855
op: 'navigation',
56+
origin: 'auto.navigation.angular',
57+
data: {
58+
'sentry.origin': 'auto.navigation.angular',
59+
'sentry.source': 'route',
60+
'url.template': '/users/:id/',
61+
'url.path': '/users/123',
62+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
63+
},
4964
},
5065
},
5166
transaction: '/users/:id/',
@@ -78,6 +93,13 @@ test('sends a navigation transaction even if the pageload span is still active',
7893
trace: {
7994
op: 'pageload',
8095
origin: 'auto.pageload.angular',
96+
data: {
97+
'sentry.origin': 'auto.pageload.angular',
98+
'sentry.source': 'route',
99+
'url.template': '/home/',
100+
'url.path': '/home',
101+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
102+
},
81103
},
82104
},
83105
transaction: '/home/',
@@ -91,6 +113,13 @@ test('sends a navigation transaction even if the pageload span is still active',
91113
trace: {
92114
op: 'navigation',
93115
origin: 'auto.navigation.angular',
116+
data: {
117+
'sentry.origin': 'auto.navigation.angular',
118+
'sentry.source': 'route',
119+
'url.template': '/users/:id/',
120+
'url.path': '/users/123',
121+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
122+
},
94123
},
95124
},
96125
transaction: '/users/:id/',
@@ -115,6 +144,13 @@ test('groups redirects within one navigation root span', async ({ page }) => {
115144
trace: {
116145
op: 'navigation',
117146
origin: 'auto.navigation.angular',
147+
data: {
148+
'sentry.origin': 'auto.navigation.angular',
149+
'sentry.source': 'route',
150+
'url.template': '/users/:id/',
151+
'url.path': '/users/456',
152+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/456$/),
153+
},
118154
},
119155
},
120156
transaction: '/users/:id/',
@@ -145,6 +181,13 @@ test.describe('finish routing span', () => {
145181
trace: {
146182
op: 'navigation',
147183
origin: 'auto.navigation.angular',
184+
data: {
185+
'sentry.origin': 'auto.navigation.angular',
186+
'sentry.source': 'url',
187+
'url.path': '/cancel',
188+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/cancel$/),
189+
// url.template is not set because the navigation was cancelled before Angular fully resolved the route
190+
},
148191
},
149192
},
150193
transaction: '/cancel',
@@ -176,6 +219,13 @@ test.describe('finish routing span', () => {
176219
trace: {
177220
op: 'navigation',
178221
origin: 'auto.navigation.angular',
222+
data: {
223+
'sentry.origin': 'auto.navigation.angular',
224+
'sentry.source': 'url',
225+
'url.path': '/non-existent',
226+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/non-existent$/),
227+
// url.template is not set because the navigation failed before Angular fully resolved the route
228+
},
179229
},
180230
},
181231
transaction: nonExistentRoute,

dev-packages/e2e-tests/test-applications/angular-20/tests/performance.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ test('sends a pageload transaction with a parameterized URL', async ({ page }) =
1717
trace: {
1818
op: 'pageload',
1919
origin: 'auto.pageload.angular',
20+
data: {
21+
'sentry.origin': 'auto.pageload.angular',
22+
'sentry.source': 'route',
23+
'url.template': '/home/',
24+
'url.path': '/home',
25+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
26+
},
2027
},
2128
},
2229
transaction: '/home/',
@@ -46,6 +53,14 @@ test('sends a navigation transaction with a parameterized URL', async ({ page })
4653
contexts: {
4754
trace: {
4855
op: 'navigation',
56+
origin: 'auto.navigation.angular',
57+
data: {
58+
'sentry.origin': 'auto.navigation.angular',
59+
'sentry.source': 'route',
60+
'url.template': '/users/:id/',
61+
'url.path': '/users/123',
62+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
63+
},
4964
},
5065
},
5166
transaction: '/users/:id/',
@@ -78,6 +93,13 @@ test('sends a navigation transaction even if the pageload span is still active',
7893
trace: {
7994
op: 'pageload',
8095
origin: 'auto.pageload.angular',
96+
data: {
97+
'sentry.origin': 'auto.pageload.angular',
98+
'sentry.source': 'route',
99+
'url.template': '/home/',
100+
'url.path': '/home',
101+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/home$/),
102+
},
81103
},
82104
},
83105
transaction: '/home/',
@@ -91,6 +113,13 @@ test('sends a navigation transaction even if the pageload span is still active',
91113
trace: {
92114
op: 'navigation',
93115
origin: 'auto.navigation.angular',
116+
data: {
117+
'sentry.origin': 'auto.navigation.angular',
118+
'sentry.source': 'route',
119+
'url.template': '/users/:id/',
120+
'url.path': '/users/123',
121+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/123$/),
122+
},
94123
},
95124
},
96125
transaction: '/users/:id/',
@@ -115,6 +144,13 @@ test('groups redirects within one navigation root span', async ({ page }) => {
115144
trace: {
116145
op: 'navigation',
117146
origin: 'auto.navigation.angular',
147+
data: {
148+
'sentry.origin': 'auto.navigation.angular',
149+
'sentry.source': 'route',
150+
'url.template': '/users/:id/',
151+
'url.path': '/users/456',
152+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/456$/),
153+
},
118154
},
119155
},
120156
transaction: '/users/:id/',
@@ -145,6 +181,13 @@ test.describe('finish routing span', () => {
145181
trace: {
146182
op: 'navigation',
147183
origin: 'auto.navigation.angular',
184+
data: {
185+
'sentry.origin': 'auto.navigation.angular',
186+
'sentry.source': 'url',
187+
'url.path': '/cancel',
188+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/cancel$/),
189+
// url.template is not set because the navigation was cancelled before Angular fully resolved the route
190+
},
148191
},
149192
},
150193
transaction: '/cancel',
@@ -176,6 +219,13 @@ test.describe('finish routing span', () => {
176219
trace: {
177220
op: 'navigation',
178221
origin: 'auto.navigation.angular',
222+
data: {
223+
'sentry.origin': 'auto.navigation.angular',
224+
'sentry.source': 'url',
225+
'url.path': '/non-existent',
226+
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/non-existent$/),
227+
// url.template is not set because the navigation failed before Angular fully resolved the route
228+
},
179229
},
180230
},
181231
transaction: nonExistentRoute,

0 commit comments

Comments
 (0)