@@ -3,7 +3,12 @@ import type * as Sentry from '@sentry/browser';
3
3
import type { EventEnvelopeHeaders } from '@sentry/types' ;
4
4
5
5
import { sentryTest } from '../../../utils/fixtures' ;
6
- import { envelopeRequestParser , shouldSkipTracingTest , waitForTransactionRequest } from '../../../utils/helpers' ;
6
+ import {
7
+ envelopeRequestParser ,
8
+ shouldSkipTracingTest ,
9
+ waitForErrorRequest ,
10
+ waitForTransactionRequest ,
11
+ } from '../../../utils/helpers' ;
7
12
import { getReplaySnapshot , shouldSkipReplayTest , waitForReplayRunning } from '../../../utils/replayHelpers' ;
8
13
9
14
type TestWindow = Window & {
@@ -216,3 +221,67 @@ sentryTest(
216
221
} ) ;
217
222
} ,
218
223
) ;
224
+
225
+ sentryTest ( 'should add replay_id to error DSC while replay is active' , async ( { getLocalTestPath, page } ) => {
226
+ if ( shouldSkipReplayTest ( ) ) {
227
+ sentryTest . skip ( ) ;
228
+ }
229
+
230
+ await page . route ( 'https://dsn.ingest.sentry.io/**/*' , route => {
231
+ return route . fulfill ( {
232
+ status : 200 ,
233
+ contentType : 'application/json' ,
234
+ body : JSON . stringify ( { id : 'test-id' } ) ,
235
+ } ) ;
236
+ } ) ;
237
+
238
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
239
+ await page . goto ( url ) ;
240
+
241
+ const error1Req = waitForErrorRequest ( page , event => event . exception ?. values ?. [ 0 ] . value === 'This is error #1' ) ;
242
+ const error2Req = waitForErrorRequest ( page , event => event . exception ?. values ?. [ 0 ] . value === 'This is error #2' ) ;
243
+
244
+ // We want to wait for the transaction to be done, to ensure we have a consistent test
245
+ const transactionReq = shouldSkipTracingTest ( ) ? Promise . resolve ( ) : waitForTransactionRequest ( page ) ;
246
+
247
+ // Wait for this to be available
248
+ await page . waitForFunction ( '!!window.Replay' ) ;
249
+
250
+ // We have to start replay before we finish the transaction, otherwise the DSC will not be frozen with the Replay ID
251
+ await page . evaluate ( 'window.Replay.start();' ) ;
252
+ await waitForReplayRunning ( page ) ;
253
+ await transactionReq ;
254
+
255
+ await page . evaluate ( 'window._triggerError(1)' ) ;
256
+
257
+ const error1Header = envelopeRequestParser ( await error1Req , 0 ) as EventEnvelopeHeaders ;
258
+ const replay = await getReplaySnapshot ( page ) ;
259
+
260
+ expect ( replay . session ?. id ) . toBeDefined ( ) ;
261
+
262
+ expect ( error1Header . trace ) . toBeDefined ( ) ;
263
+ expect ( error1Header . trace ) . toEqual ( {
264
+ environment : 'production' ,
265
+ sample_rate : '1' ,
266
+ trace_id : expect . any ( String ) ,
267
+ public_key : 'public' ,
268
+ replay_id : replay . session ?. id ,
269
+ sampled : 'true' ,
270
+ } ) ;
271
+
272
+ // Now end replay and trigger another error, it should not have a replay_id in DSC anymore
273
+ await page . evaluate ( 'window.Replay.stop();' ) ;
274
+ await page . waitForFunction ( '!window.Replay.getReplayId();' ) ;
275
+ await page . evaluate ( 'window._triggerError(2)' ) ;
276
+
277
+ const error2Header = envelopeRequestParser ( await error2Req , 0 ) as EventEnvelopeHeaders ;
278
+
279
+ expect ( error2Header . trace ) . toBeDefined ( ) ;
280
+ expect ( error2Header . trace ) . toEqual ( {
281
+ environment : 'production' ,
282
+ sample_rate : '1' ,
283
+ trace_id : expect . any ( String ) ,
284
+ public_key : 'public' ,
285
+ sampled : 'true' ,
286
+ } ) ;
287
+ } ) ;
0 commit comments