@@ -45,10 +45,9 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes
4545 const navigationTraceId = navigationEvent . contexts ?. trace ?. trace_id ;
4646 expect ( navigationTraceId ) . toMatch ( / ^ [ 0 - 9 a - f ] { 32 } $ / ) ;
4747
48- const [ , errorEvent ] = await Promise . all ( [
49- page . locator ( '#errorBtn' ) . click ( ) ,
50- getFirstSentryEnvelopeRequest < Event > ( page ) ,
51- ] ) ;
48+ const errorEventPromise = getFirstSentryEnvelopeRequest < Event > ( page ) ;
49+ await page . locator ( '#errorBtn' ) . click ( ) ;
50+ const errorEvent = await errorEventPromise ;
5251
5352 const errorTraceId = errorEvent . contexts ?. trace ?. trace_id ;
5453 expect ( errorTraceId ) . toBe ( navigationTraceId ) ;
@@ -80,3 +79,67 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc
8079 const errorTraceId = errorEvent ?. contexts ?. trace ?. trace_id ;
8180 expect ( errorTraceId ) . toBe ( navigationTraceId ) ;
8281} ) ;
82+
83+ sentryTest (
84+ 'outgoing fetch request after navigation has navigation traceId in headers' ,
85+ async ( { getLocalTestPath, page } ) => {
86+ if ( shouldSkipTracingTest ( ) ) {
87+ sentryTest . skip ( ) ;
88+ }
89+
90+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
91+
92+ // ensure navigation transaction is finished
93+ await getFirstSentryEnvelopeRequest < Event > ( page , url ) ;
94+
95+ const navigationEvent = await getFirstSentryEnvelopeRequest < Event > ( page , `${ url } #foo` ) ;
96+ expect ( navigationEvent . contexts ?. trace ?. op ) . toBe ( 'navigation' ) ;
97+
98+ const navigationTraceId = navigationEvent . contexts ?. trace ?. trace_id ;
99+ expect ( navigationTraceId ) . toMatch ( / ^ [ 0 - 9 a - f ] { 32 } $ / ) ;
100+
101+ const requestPromise = page . waitForRequest ( 'http://example.com/*' ) ;
102+ await page . locator ( '#fetchBtn' ) . click ( ) ;
103+ const request = await requestPromise ;
104+ const headers = request . headers ( ) ;
105+
106+ // sampling decision is deferred b/c of no active span at the time of request
107+ expect ( headers [ 'sentry-trace' ] ) . toMatch ( new RegExp ( `^${ navigationTraceId } -[0-9a-f]{16}$` ) ) ;
108+ expect ( headers [ 'baggage' ] ) . toEqual (
109+ `sentry-environment=production,sentry-public_key=public,sentry-trace_id=${ navigationTraceId } ` ,
110+ ) ;
111+ } ,
112+ ) ;
113+
114+ sentryTest (
115+ 'outgoing fetch request during navigation has navigation traceId in headers' ,
116+ async ( { getLocalTestPath, page } ) => {
117+ if ( shouldSkipTracingTest ( ) ) {
118+ sentryTest . skip ( ) ;
119+ }
120+
121+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
122+
123+ // ensure navigation transaction is finished
124+ await getFirstSentryEnvelopeRequest < Event > ( page , url ) ;
125+
126+ const navigationEventPromise = getFirstSentryEnvelopeRequest < Event > ( page ) ;
127+ const requestPromise = page . waitForRequest ( 'http://example.com/*' ) ;
128+ await page . goto ( `${ url } #foo` ) ;
129+ await page . locator ( '#fetchBtn' ) . click ( ) ;
130+ const [ navigationEvent , request ] = await Promise . all ( [ navigationEventPromise , requestPromise ] ) ;
131+
132+ expect ( navigationEvent . contexts ?. trace ?. op ) . toBe ( 'navigation' ) ;
133+
134+ const navigationTraceId = navigationEvent . contexts ?. trace ?. trace_id ;
135+ expect ( navigationTraceId ) . toMatch ( / ^ [ 0 - 9 a - f ] { 32 } $ / ) ;
136+
137+ const headers = request . headers ( ) ;
138+
139+ // sampling decision is propagated from active span sampling decision
140+ expect ( headers [ 'sentry-trace' ] ) . toMatch ( new RegExp ( `^${ navigationTraceId } -[0-9a-f]{16}-1$` ) ) ;
141+ expect ( headers [ 'baggage' ] ) . toEqual (
142+ `sentry-environment=production,sentry-public_key=public,sentry-trace_id=${ navigationTraceId } ,sentry-sample_rate=1,sentry-sampled=true` ,
143+ ) ;
144+ } ,
145+ ) ;
0 commit comments