1
- import { captureException } from '@sentry/core' ;
1
+ import { captureException , getCurrentHub } from '@sentry/core' ;
2
2
3
3
import {
4
4
DEFAULT_FLUSH_MIN_DELAY ,
5
5
ERROR_CHECKOUT_TIME ,
6
+ MAX_SESSION_LIFE ,
6
7
REPLAY_SESSION_KEY ,
7
8
VISIBILITY_CHANGE_TIMEOUT ,
8
9
WINDOW ,
@@ -264,12 +265,10 @@ describe('Integration | errorSampleRate', () => {
264
265
expect ( replay ) . not . toHaveLastSentReplay ( ) ;
265
266
} ) ;
266
267
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 ( ) => {
268
269
// Idle for 15 minutes
269
270
jest . advanceTimersByTime ( 15 * 60000 ) ;
270
271
271
- // TBD: We are currently deciding that this event will get dropped, but
272
- // this could/should change in the future.
273
272
const TEST_EVENT = {
274
273
data : { name : 'lost event' } ,
275
274
timestamp : BASE_TIMESTAMP ,
@@ -281,15 +280,11 @@ describe('Integration | errorSampleRate', () => {
281
280
jest . runAllTimers ( ) ;
282
281
await new Promise ( process . nextTick ) ;
283
282
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
290
284
291
285
expect ( replay ) . not . toHaveLastSentReplay ( ) ;
292
- expect ( mockRecord . takeFullSnapshot ) . toHaveBeenCalledWith ( true ) ;
286
+ expect ( replay . isEnabled ( ) ) . toBe ( false ) ;
287
+ expect ( mockRecord . takeFullSnapshot ) . not . toHaveBeenCalled ( ) ;
293
288
} ) ;
294
289
295
290
it ( 'has the correct timestamps with deferred root event and last replay update' , async ( ) => {
@@ -375,6 +370,52 @@ describe('Integration | errorSampleRate', () => {
375
370
] ) ,
376
371
} ) ;
377
372
} ) ;
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
+ } ) ;
378
419
} ) ;
379
420
380
421
/**
0 commit comments