1- import { captureException } from '@sentry/core' ;
1+ import { captureException , getCurrentHub } from '@sentry/core' ;
22
33import {
44 DEFAULT_FLUSH_MIN_DELAY ,
55 ERROR_CHECKOUT_TIME ,
6+ MAX_SESSION_LIFE ,
67 REPLAY_SESSION_KEY ,
78 VISIBILITY_CHANGE_TIMEOUT ,
89 WINDOW ,
@@ -264,12 +265,10 @@ describe('Integration | errorSampleRate', () => {
264265 expect ( replay ) . not . toHaveLastSentReplay ( ) ;
265266 } ) ;
266267
267- it ( 'does not upload if user has been idle for more than 15 minutes and comes back to move their mouse' , async ( ) => {
268+ it ( 'stops replay if user has been idle for more than 15 minutes and comes back to move their mouse' , async ( ) => {
268269 // Idle for 15 minutes
269270 jest . advanceTimersByTime ( 15 * 60000 ) ;
270271
271- // TBD: We are currently deciding that this event will get dropped, but
272- // this could/should change in the future.
273272 const TEST_EVENT = {
274273 data : { name : 'lost event' } ,
275274 timestamp : BASE_TIMESTAMP ,
@@ -281,15 +280,11 @@ describe('Integration | errorSampleRate', () => {
281280 jest . runAllTimers ( ) ;
282281 await new Promise ( process . nextTick ) ;
283282
284- // Instead of recording the above event, a full snapshot will occur.
285- //
286- // TODO: We could potentially figure out a way to save the last session,
287- // and produce a checkout based on a previous checkout + updates, and then
288- // replay the event on top. Or maybe replay the event on top of a refresh
289- // snapshot.
283+ // We stop recording after 15 minutes of inactivity in error mode
290284
291285 expect ( replay ) . not . toHaveLastSentReplay ( ) ;
292- expect ( mockRecord . takeFullSnapshot ) . toHaveBeenCalledWith ( true ) ;
286+ expect ( replay . isEnabled ( ) ) . toBe ( false ) ;
287+ expect ( mockRecord . takeFullSnapshot ) . not . toHaveBeenCalled ( ) ;
293288 } ) ;
294289
295290 it ( 'has the correct timestamps with deferred root event and last replay update' , async ( ) => {
@@ -375,6 +370,52 @@ describe('Integration | errorSampleRate', () => {
375370 ] ) ,
376371 } ) ;
377372 } ) ;
373+
374+ it ( 'stops replay when session expires' , async ( ) => {
375+ jest . setSystemTime ( BASE_TIMESTAMP ) ;
376+
377+ const TEST_EVENT = { data : { } , timestamp : BASE_TIMESTAMP , type : 3 } ;
378+ mockRecord . _emitter ( TEST_EVENT ) ;
379+
380+ expect ( mockRecord . takeFullSnapshot ) . not . toHaveBeenCalled ( ) ;
381+ expect ( replay ) . not . toHaveLastSentReplay ( ) ;
382+
383+ jest . runAllTimers ( ) ;
384+ await new Promise ( process . nextTick ) ;
385+
386+ captureException ( new Error ( 'testing' ) ) ;
387+
388+ jest . advanceTimersByTime ( DEFAULT_FLUSH_MIN_DELAY ) ;
389+ await new Promise ( process . nextTick ) ;
390+
391+ expect ( replay ) . toHaveLastSentReplay ( ) ;
392+
393+ // Wait a bit, shortly before session expires
394+ jest . advanceTimersByTime ( MAX_SESSION_LIFE - 1000 ) ;
395+ await new Promise ( process . nextTick ) ;
396+
397+ mockRecord . _emitter ( TEST_EVENT ) ;
398+ replay . triggerUserActivity ( ) ;
399+
400+ expect ( replay ) . toHaveLastSentReplay ( ) ;
401+
402+ // Now wait after session expires - should stop recording
403+ mockRecord . takeFullSnapshot . mockClear ( ) ;
404+ ( getCurrentHub ( ) . getClient ( ) ! . getTransport ( ) ! . send as unknown as jest . SpyInstance < any > ) . mockClear ( ) ;
405+
406+ jest . advanceTimersByTime ( 10_000 ) ;
407+ await new Promise ( process . nextTick ) ;
408+
409+ mockRecord . _emitter ( TEST_EVENT ) ;
410+ replay . triggerUserActivity ( ) ;
411+
412+ jest . advanceTimersByTime ( DEFAULT_FLUSH_MIN_DELAY ) ;
413+ await new Promise ( process . nextTick ) ;
414+
415+ expect ( replay ) . not . toHaveLastSentReplay ( ) ;
416+ expect ( mockRecord . takeFullSnapshot ) . toHaveBeenCalledTimes ( 0 ) ;
417+ expect ( replay . isEnabled ( ) ) . toBe ( false ) ;
418+ } ) ;
378419} ) ;
379420
380421/**
0 commit comments