1- import { captureException } from '@sentry/core' ;
1+ import { captureException , getCurrentHub } from '@sentry/core' ;
22
33import { REPLAY_SESSION_KEY , VISIBILITY_CHANGE_TIMEOUT , WINDOW } from '../../src/constants' ;
44import { addEvent } from '../../src/util/addEvent' ;
55import { ReplayContainer } from './../../src/replay' ;
66import { PerformanceEntryResource } from './../fixtures/performanceEntry/resource' ;
77import { BASE_TIMESTAMP , RecordMock } from './../index' ;
88import { resetSdkMock } from './../mocks/resetSdkMock' ;
9- import { DomHandler , MockTransportSend } from './../types' ;
9+ import { DomHandler } from './../types' ;
1010import { useFakeTimers } from './../utils/use-fake-timers' ;
1111
1212useFakeTimers ( ) ;
@@ -19,11 +19,11 @@ async function advanceTimers(time: number) {
1919describe ( 'Replay (errorSampleRate)' , ( ) => {
2020 let replay : ReplayContainer ;
2121 let mockRecord : RecordMock ;
22- let mockTransportSend : MockTransportSend ;
22+
2323 let domHandler : DomHandler ;
2424
2525 beforeEach ( async ( ) => {
26- ( { mockRecord, mockTransportSend , domHandler, replay } = await resetSdkMock ( {
26+ ( { mockRecord, domHandler, replay } = await resetSdkMock ( {
2727 replayOptions : {
2828 stickySession : true ,
2929 } ,
@@ -86,9 +86,6 @@ describe('Replay (errorSampleRate)', () => {
8686 ] ) ,
8787 } ) ;
8888
89- mockTransportSend . mockClear ( ) ;
90- expect ( replay ) . not . toHaveSentReplay ( ) ;
91-
9289 jest . runAllTimers ( ) ;
9390 await new Promise ( process . nextTick ) ;
9491 jest . runAllTimers ( ) ;
@@ -310,63 +307,6 @@ describe('Replay (errorSampleRate)', () => {
310307 } ) ;
311308 } ) ;
312309
313- /**
314- * This is testing a case that should only happen with error-only sessions.
315- * Previously we had assumed that loading a session from session storage meant
316- * that the session was not new. However, this is not the case with error-only
317- * sampling since we can load a saved session that did not have an error (and
318- * thus no replay was created).
319- */
320- it ( 'sends a replay after loading the session multiple times' , async ( ) => {
321- // Pretend that a session is already saved before loading replay
322- WINDOW . sessionStorage . setItem (
323- REPLAY_SESSION_KEY ,
324- `{"segmentId":0,"id":"fd09adfc4117477abc8de643e5a5798a","sampled":"error","started":${ BASE_TIMESTAMP } ,"lastActivity":${ BASE_TIMESTAMP } }` ,
325- ) ;
326- ( { mockRecord, mockTransportSend, replay } = await resetSdkMock ( {
327- replayOptions : {
328- stickySession : true ,
329- } ,
330- } ) ) ;
331- replay . start ( ) ;
332-
333- jest . runAllTimers ( ) ;
334-
335- await new Promise ( process . nextTick ) ;
336- const TEST_EVENT = { data : { } , timestamp : BASE_TIMESTAMP , type : 3 } ;
337- mockRecord . _emitter ( TEST_EVENT ) ;
338-
339- expect ( replay ) . not . toHaveSentReplay ( ) ;
340-
341- captureException ( new Error ( 'testing' ) ) ;
342- jest . runAllTimers ( ) ;
343- await new Promise ( process . nextTick ) ;
344-
345- expect ( replay ) . toHaveSentReplay ( {
346- events : JSON . stringify ( [ { data : { isCheckout : true } , timestamp : BASE_TIMESTAMP , type : 2 } , TEST_EVENT ] ) ,
347- } ) ;
348-
349- mockTransportSend . mockClear ( ) ;
350- expect ( replay ) . not . toHaveSentReplay ( ) ;
351-
352- jest . runAllTimers ( ) ;
353- await new Promise ( process . nextTick ) ;
354- jest . runAllTimers ( ) ;
355- await new Promise ( process . nextTick ) ;
356-
357- // New checkout when we call `startRecording` again after uploading segment
358- // after an error occurs
359- expect ( replay ) . toHaveSentReplay ( {
360- events : JSON . stringify ( [
361- {
362- data : { isCheckout : true } ,
363- timestamp : BASE_TIMESTAMP + 10000 + 20 ,
364- type : 2 ,
365- } ,
366- ] ) ,
367- } ) ;
368- } ) ;
369-
370310 it ( 'has correct timestamps when error occurs much later than initial pageload/checkout' , async ( ) => {
371311 const ELAPSED = 60000 ;
372312 const TEST_EVENT = { data : { } , timestamp : BASE_TIMESTAMP , type : 3 } ;
@@ -415,3 +355,67 @@ describe('Replay (errorSampleRate)', () => {
415355 } ) ;
416356 } ) ;
417357} ) ;
358+
359+ /**
360+ * This is testing a case that should only happen with error-only sessions.
361+ * Previously we had assumed that loading a session from session storage meant
362+ * that the session was not new. However, this is not the case with error-only
363+ * sampling since we can load a saved session that did not have an error (and
364+ * thus no replay was created).
365+ */
366+ it ( 'sends a replay after loading the session multiple times' , async ( ) => {
367+ // Pretend that a session is already saved before loading replay
368+ WINDOW . sessionStorage . setItem (
369+ REPLAY_SESSION_KEY ,
370+ `{"segmentId":0,"id":"fd09adfc4117477abc8de643e5a5798a","sampled":"error","started":${ BASE_TIMESTAMP } ,"lastActivity":${ BASE_TIMESTAMP } }` ,
371+ ) ;
372+ const { mockRecord, replay } = await resetSdkMock ( {
373+ replayOptions : {
374+ stickySession : true ,
375+ } ,
376+ autoStart : false ,
377+ } ) ;
378+
379+ const fn = getCurrentHub ( ) ?. getClient ( ) ?. getTransport ( ) ?. send ;
380+ const mockTransportSend = fn
381+ ? ( jest . spyOn ( getCurrentHub ( ) . getClient ( ) ! . getTransport ( ) ! , 'send' ) as jest . MockedFunction < any > )
382+ : jest . fn ( ) ;
383+
384+ replay . start ( ) ;
385+
386+ jest . runAllTimers ( ) ;
387+
388+ await new Promise ( process . nextTick ) ;
389+ const TEST_EVENT = { data : { } , timestamp : BASE_TIMESTAMP , type : 3 } ;
390+ mockRecord . _emitter ( TEST_EVENT ) ;
391+
392+ expect ( replay ) . not . toHaveSentReplay ( ) ;
393+
394+ captureException ( new Error ( 'testing' ) ) ;
395+ jest . runAllTimers ( ) ;
396+ await new Promise ( process . nextTick ) ;
397+
398+ expect ( replay ) . toHaveSentReplay ( {
399+ events : JSON . stringify ( [ { data : { isCheckout : true } , timestamp : BASE_TIMESTAMP , type : 2 } , TEST_EVENT ] ) ,
400+ } ) ;
401+
402+ mockTransportSend . mockClear ( ) ;
403+ expect ( replay ) . not . toHaveSentReplay ( ) ;
404+
405+ jest . runAllTimers ( ) ;
406+ await new Promise ( process . nextTick ) ;
407+ jest . runAllTimers ( ) ;
408+ await new Promise ( process . nextTick ) ;
409+
410+ // New checkout when we call `startRecording` again after uploading segment
411+ // after an error occurs
412+ expect ( replay ) . toHaveSentReplay ( {
413+ events : JSON . stringify ( [
414+ {
415+ data : { isCheckout : true } ,
416+ timestamp : BASE_TIMESTAMP + 10000 + 20 ,
417+ type : 2 ,
418+ } ,
419+ ] ) ,
420+ } ) ;
421+ } ) ;
0 commit comments