@@ -27,6 +27,7 @@ vi.mock('@sentry/core', async () => {
2727
2828vi . mock ( '@sentry/browser' , ( ) => ( {
2929 startBrowserTracingNavigationSpan : vi . fn ( ) . mockReturnValue ( { setStatus : vi . fn ( ) } ) ,
30+ getAbsoluteUrl : vi . fn ( ( urlOrPath : string ) => urlOrPath ) ,
3031} ) ) ;
3132
3233describe ( 'createSentryClientInstrumentation' , ( ) => {
@@ -92,15 +93,19 @@ describe('createSentryClientInstrumentation', () => {
9293 to : '/about' ,
9394 } ) ;
9495
95- expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith ( mockClient , {
96- name : '/about' ,
97- attributes : expect . objectContaining ( {
98- 'sentry.source' : 'url' ,
99- 'sentry.op' : 'navigation' ,
100- 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
101- 'navigation.type' : 'router.navigate' ,
102- } ) ,
103- } ) ;
96+ expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith (
97+ mockClient ,
98+ {
99+ name : '/about' ,
100+ attributes : expect . objectContaining ( {
101+ 'sentry.source' : 'url' ,
102+ 'sentry.op' : 'navigation' ,
103+ 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
104+ 'navigation.type' : 'router.navigate' ,
105+ } ) ,
106+ } ,
107+ { url : '/about' } ,
108+ ) ;
104109 expect ( mockCallNavigate ) . toHaveBeenCalled ( ) ;
105110 } ) ;
106111
@@ -123,15 +128,20 @@ describe('createSentryClientInstrumentation', () => {
123128 to : { pathname : '/items/123' , search : '?foo=bar' } ,
124129 } ) ;
125130
126- expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith ( mockClient , {
127- name : '/items/123' ,
128- attributes : expect . objectContaining ( {
129- 'sentry.source' : 'url' ,
130- 'sentry.op' : 'navigation' ,
131- 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
132- 'navigation.type' : 'router.navigate' ,
133- } ) ,
134- } ) ;
131+ expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith (
132+ mockClient ,
133+ {
134+ name : '/items/123' ,
135+ attributes : expect . objectContaining ( {
136+ 'sentry.source' : 'url' ,
137+ 'sentry.op' : 'navigation' ,
138+ 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
139+ 'navigation.type' : 'router.navigate' ,
140+ } ) ,
141+ } ,
142+ // the destination URL keeps the query string, even though the span name doesn't
143+ { url : '/items/123?foo=bar' } ,
144+ ) ;
135145 expect ( mockCallNavigate ) . toHaveBeenCalled ( ) ;
136146 } ) ;
137147
@@ -374,15 +384,19 @@ describe('createSentryClientInstrumentation', () => {
374384
375385 await hooks . navigate ( mockCallNavigate , { currentUrl : '/current-page' , to } ) ;
376386
377- expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith ( mockClient , {
378- name : '/current-page' ,
379- attributes : expect . objectContaining ( {
380- 'sentry.source' : 'url' ,
381- 'sentry.op' : 'navigation' ,
382- 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
383- 'navigation.type' : expectedType ,
384- } ) ,
385- } ) ;
387+ expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith (
388+ mockClient ,
389+ {
390+ name : '/current-page' ,
391+ attributes : expect . objectContaining ( {
392+ 'sentry.source' : 'url' ,
393+ 'sentry.op' : 'navigation' ,
394+ 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
395+ 'navigation.type' : expectedType ,
396+ } ) ,
397+ } ,
398+ { url : '/current-page' } ,
399+ ) ;
386400 expect ( mockNavigationSpan . updateName ) . toHaveBeenCalledWith ( destination ) ;
387401 } ,
388402 ) ;
@@ -608,15 +622,19 @@ describe('createSentryClientInstrumentation', () => {
608622
609623 popstateHandler ! ( ) ;
610624
611- expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith ( mockClient , {
612- name : '/current-page' ,
613- attributes : expect . objectContaining ( {
614- 'sentry.source' : 'url' ,
615- 'sentry.op' : 'navigation' ,
616- 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
617- 'navigation.type' : 'browser.popstate' ,
618- } ) ,
619- } ) ;
625+ expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith (
626+ mockClient ,
627+ {
628+ name : '/current-page' ,
629+ attributes : expect . objectContaining ( {
630+ 'sentry.source' : 'url' ,
631+ 'sentry.op' : 'navigation' ,
632+ 'sentry.origin' : 'auto.navigation.react_router.instrumentation_api' ,
633+ 'navigation.type' : 'browser.popstate' ,
634+ } ) ,
635+ } ,
636+ { url : '/current-page' } ,
637+ ) ;
620638 } ) ;
621639
622640 it ( 'should not create span on popstate when no client is available' , ( ) => {
@@ -671,12 +689,16 @@ describe('createSentryClientInstrumentation', () => {
671689 // Direct popstate without navigate(-1) - simulates browser back button click
672690 popstateHandler ! ( ) ;
673691
674- expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith ( mockClient , {
675- name : '/current-page' ,
676- attributes : expect . objectContaining ( {
677- 'navigation.type' : 'browser.popstate' ,
678- } ) ,
679- } ) ;
692+ expect ( browser . startBrowserTracingNavigationSpan ) . toHaveBeenCalledWith (
693+ mockClient ,
694+ {
695+ name : '/current-page' ,
696+ attributes : expect . objectContaining ( {
697+ 'navigation.type' : 'browser.popstate' ,
698+ } ) ,
699+ } ,
700+ { url : '/current-page' } ,
701+ ) ;
680702 } ) ;
681703 } ) ;
682704} ) ;
@@ -762,7 +784,7 @@ describe('navigation root parameterization', () => {
762784 } ) ;
763785
764786 it ( 'renames the active navigation/pageload root span with the route pattern from the loader hook' , async ( ) => {
765- const mockRootSpan = { setAttribute : vi . fn ( ) } ;
787+ const mockRootSpan = { setAttributes : vi . fn ( ) } ;
766788 ( core . getActiveSpan as any ) . mockReturnValue ( { } ) ;
767789 ( core . getRootSpan as any ) . mockReturnValue ( mockRootSpan ) ;
768790 ( core . spanToJSON as any ) . mockReturnValue ( { op : 'navigation' } ) ;
@@ -780,11 +802,11 @@ describe('navigation root parameterization', () => {
780802 } ) ;
781803
782804 expect ( core . updateSpanName ) . toHaveBeenCalledWith ( mockRootSpan , '/users/:id' ) ;
783- expect ( mockRootSpan . setAttribute ) . toHaveBeenCalledWith ( 'sentry.source' , 'route' ) ;
805+ expect ( mockRootSpan . setAttributes ) . toHaveBeenCalledWith ( { 'sentry.source' : 'route' , 'url.template' : '/users/:id' } ) ;
784806 } ) ;
785807
786808 it ( 'does not rename the root span when the route has no pattern' , async ( ) => {
787- const mockRootSpan = { setAttribute : vi . fn ( ) } ;
809+ const mockRootSpan = { setAttributes : vi . fn ( ) } ;
788810 ( core . getActiveSpan as any ) . mockReturnValue ( { } ) ;
789811 ( core . getRootSpan as any ) . mockReturnValue ( mockRootSpan ) ;
790812 ( core . spanToJSON as any ) . mockReturnValue ( { op : 'navigation' } ) ;
0 commit comments