diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts index 329ac33b7880..796d34d7623a 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts @@ -27,6 +27,8 @@ test.describe('client-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'browser' }); + + expect(errorEvent.transaction).toEqual('/client-error'); }); test('captures universal load error', async ({ page }) => { @@ -52,5 +54,6 @@ test.describe('client-side errors', () => { ); expect(errorEvent.tags).toMatchObject({ runtime: 'browser' }); + expect(errorEvent.transaction).toEqual('/universal-load-error'); }); }); diff --git a/packages/sveltekit/src/client/browserTracingIntegration.ts b/packages/sveltekit/src/client/browserTracingIntegration.ts index 716223a17c5c..d2a266e2cbea 100644 --- a/packages/sveltekit/src/client/browserTracingIntegration.ts +++ b/packages/sveltekit/src/client/browserTracingIntegration.ts @@ -3,6 +3,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } fr import { WINDOW, browserTracingIntegration as originalBrowserTracingIntegration, + getCurrentScope, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan, startInactiveSpan, @@ -65,6 +66,7 @@ function _instrumentPageload(client: Client): void { if (routeId) { pageloadSpan.updateName(routeId); pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); + getCurrentScope().setTransactionName(routeId); } }); } diff --git a/packages/sveltekit/test/client/browserTracingIntegration.test.ts b/packages/sveltekit/test/client/browserTracingIntegration.test.ts index 315985433e66..cdbe093e201b 100644 --- a/packages/sveltekit/test/client/browserTracingIntegration.test.ts +++ b/packages/sveltekit/test/client/browserTracingIntegration.test.ts @@ -40,7 +40,6 @@ describe('browserTracingIntegration', () => { ...txnCtx, updateName: vi.fn(), setAttribute: vi.fn(), - setTag: vi.fn(), }; return createdRootSpan; }); @@ -52,7 +51,6 @@ describe('browserTracingIntegration', () => { ...txnCtx, updateName: vi.fn(), setAttribute: vi.fn(), - setTag: vi.fn(), }; return createdRootSpan; }); @@ -138,6 +136,29 @@ describe('browserTracingIntegration', () => { expect(startBrowserTracingPageLoadSpanSpy).toHaveBeenCalledTimes(0); }); + it("updates the current scope's transactionName once it's resolved during pageload", () => { + const scopeSetTransactionNameSpy = vi.fn(); + + // @ts-expect-error - only returning a partial scope here, that's fine + vi.spyOn(SentrySvelte, 'getCurrentScope').mockImplementation(() => { + return { + setTransactionName: scopeSetTransactionNameSpy, + }; + }); + + const integration = browserTracingIntegration(); + // @ts-expect-error - the fakeClient doesn't satisfy Client but that's fine + integration.afterAllSetup(fakeClient); + + // We emit an update to the `page` store to simulate the SvelteKit router lifecycle + // @ts-expect-error - page is a writable but the types say it's just readable + page.set({ route: { id: 'testRoute/:id' } }); + + // This should update the transaction name with the parameterized route: + expect(scopeSetTransactionNameSpy).toHaveBeenCalledTimes(3); + expect(scopeSetTransactionNameSpy).toHaveBeenLastCalledWith('testRoute/:id'); + }); + it("doesn't start a navigation span when `instrumentNavigation` is false", () => { const integration = browserTracingIntegration({ instrumentNavigation: false, @@ -185,7 +206,6 @@ describe('browserTracingIntegration', () => { }, }); - // eslint-disable-next-line deprecation/deprecation expect(startInactiveSpanSpy).toHaveBeenCalledWith({ op: 'ui.sveltekit.routing', name: 'SvelteKit Route Change', @@ -248,7 +268,6 @@ describe('browserTracingIntegration', () => { }, }); - // eslint-disable-next-line deprecation/deprecation expect(startInactiveSpanSpy).toHaveBeenCalledWith({ op: 'ui.sveltekit.routing', name: 'SvelteKit Route Change',