@@ -424,6 +424,7 @@ describe('_INTERNAL_captureLog', () => {
424
424
// Simulate behavior: return ID for sampled sessions
425
425
return onlyIfSampled ? 'sampled-replay-id' : 'any-replay-id' ;
426
426
} ) ,
427
+ getRecordingMode : vi . fn ( ( ) => 'session' ) ,
427
428
} ;
428
429
429
430
vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -480,6 +481,7 @@ describe('_INTERNAL_captureLog', () => {
480
481
// Buffer mode should still return ID even with onlyIfSampled=true
481
482
return 'buffer-replay-id' ;
482
483
} ) ,
484
+ getRecordingMode : vi . fn ( ( ) => 'buffer' ) ,
483
485
} ;
484
486
485
487
vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -494,6 +496,10 @@ describe('_INTERNAL_captureLog', () => {
494
496
value : 'buffer-replay-id' ,
495
497
type : 'string' ,
496
498
} ,
499
+ 'sentry._internal.replay_is_buffering' : {
500
+ value : true ,
501
+ type : 'boolean' ,
502
+ } ,
497
503
} ) ;
498
504
} ) ;
499
505
@@ -527,6 +533,7 @@ describe('_INTERNAL_captureLog', () => {
527
533
// Mock replay integration
528
534
const mockReplayIntegration = {
529
535
getReplayId : vi . fn ( ( ) => 'test-replay-id' ) ,
536
+ getRecordingMode : vi . fn ( ( ) => 'session' ) ,
530
537
} ;
531
538
532
539
vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -590,6 +597,196 @@ describe('_INTERNAL_captureLog', () => {
590
597
expect ( logAttributes ) . not . toHaveProperty ( 'sentry.replay_id' ) ;
591
598
} ) ;
592
599
} ) ;
600
+
601
+ it ( 'sets replay_is_buffering attribute when replay is in buffer mode' , ( ) => {
602
+ const options = getDefaultTestClientOptions ( { dsn : PUBLIC_DSN , enableLogs : true } ) ;
603
+ const client = new TestClient ( options ) ;
604
+ const scope = new Scope ( ) ;
605
+ scope . setClient ( client ) ;
606
+
607
+ // Mock replay integration with buffer mode
608
+ const mockReplayIntegration = {
609
+ getReplayId : vi . fn ( ( ) => 'buffer-replay-id' ) ,
610
+ getRecordingMode : vi . fn ( ( ) => 'buffer' ) ,
611
+ } ;
612
+
613
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
614
+
615
+ _INTERNAL_captureLog ( { level : 'info' , message : 'test log with buffered replay' } , scope ) ;
616
+
617
+ expect ( mockReplayIntegration . getReplayId ) . toHaveBeenCalledWith ( true ) ;
618
+ expect ( mockReplayIntegration . getRecordingMode ) . toHaveBeenCalled ( ) ;
619
+
620
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
621
+ expect ( logAttributes ) . toEqual ( {
622
+ 'sentry.replay_id' : {
623
+ value : 'buffer-replay-id' ,
624
+ type : 'string' ,
625
+ } ,
626
+ 'sentry._internal.replay_is_buffering' : {
627
+ value : true ,
628
+ type : 'boolean' ,
629
+ } ,
630
+ } ) ;
631
+ } ) ;
632
+
633
+ it ( 'does not set replay_is_buffering attribute when replay is in session mode' , ( ) => {
634
+ const options = getDefaultTestClientOptions ( { dsn : PUBLIC_DSN , enableLogs : true } ) ;
635
+ const client = new TestClient ( options ) ;
636
+ const scope = new Scope ( ) ;
637
+ scope . setClient ( client ) ;
638
+
639
+ // Mock replay integration with session mode
640
+ const mockReplayIntegration = {
641
+ getReplayId : vi . fn ( ( ) => 'session-replay-id' ) ,
642
+ getRecordingMode : vi . fn ( ( ) => 'session' ) ,
643
+ } ;
644
+
645
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
646
+
647
+ _INTERNAL_captureLog ( { level : 'info' , message : 'test log with session replay' } , scope ) ;
648
+
649
+ expect ( mockReplayIntegration . getReplayId ) . toHaveBeenCalledWith ( true ) ;
650
+ expect ( mockReplayIntegration . getRecordingMode ) . toHaveBeenCalled ( ) ;
651
+
652
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
653
+ expect ( logAttributes ) . toEqual ( {
654
+ 'sentry.replay_id' : {
655
+ value : 'session-replay-id' ,
656
+ type : 'string' ,
657
+ } ,
658
+ } ) ;
659
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry._internal.replay_is_buffering' ) ;
660
+ } ) ;
661
+
662
+ it ( 'does not set replay_is_buffering attribute when replay is undefined mode' , ( ) => {
663
+ const options = getDefaultTestClientOptions ( { dsn : PUBLIC_DSN , enableLogs : true } ) ;
664
+ const client = new TestClient ( options ) ;
665
+ const scope = new Scope ( ) ;
666
+ scope . setClient ( client ) ;
667
+
668
+ // Mock replay integration with undefined mode (replay stopped/disabled)
669
+ const mockReplayIntegration = {
670
+ getReplayId : vi . fn ( ( ) => 'stopped-replay-id' ) ,
671
+ getRecordingMode : vi . fn ( ( ) => undefined ) ,
672
+ } ;
673
+
674
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
675
+
676
+ _INTERNAL_captureLog ( { level : 'info' , message : 'test log with stopped replay' } , scope ) ;
677
+
678
+ expect ( mockReplayIntegration . getReplayId ) . toHaveBeenCalledWith ( true ) ;
679
+ expect ( mockReplayIntegration . getRecordingMode ) . toHaveBeenCalled ( ) ;
680
+
681
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
682
+ expect ( logAttributes ) . toEqual ( {
683
+ 'sentry.replay_id' : {
684
+ value : 'stopped-replay-id' ,
685
+ type : 'string' ,
686
+ } ,
687
+ } ) ;
688
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry._internal.replay_is_buffering' ) ;
689
+ } ) ;
690
+
691
+ it ( 'does not set replay_is_buffering attribute when no replay ID is available' , ( ) => {
692
+ const options = getDefaultTestClientOptions ( { dsn : PUBLIC_DSN , enableLogs : true } ) ;
693
+ const client = new TestClient ( options ) ;
694
+ const scope = new Scope ( ) ;
695
+ scope . setClient ( client ) ;
696
+
697
+ // Mock replay integration that returns no replay ID but has buffer mode
698
+ const mockReplayIntegration = {
699
+ getReplayId : vi . fn ( ( ) => undefined ) ,
700
+ getRecordingMode : vi . fn ( ( ) => 'buffer' ) ,
701
+ } ;
702
+
703
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
704
+
705
+ _INTERNAL_captureLog ( { level : 'info' , message : 'test log with buffer mode but no replay ID' } , scope ) ;
706
+
707
+ expect ( mockReplayIntegration . getReplayId ) . toHaveBeenCalledWith ( true ) ;
708
+ // getRecordingMode should not be called if there's no replay ID
709
+ expect ( mockReplayIntegration . getRecordingMode ) . not . toHaveBeenCalled ( ) ;
710
+
711
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
712
+ expect ( logAttributes ) . toEqual ( { } ) ;
713
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry.replay_id' ) ;
714
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry.internal.replay_is_buffering' ) ;
715
+ } ) ;
716
+
717
+ it ( 'does not set replay_is_buffering attribute when replay integration is missing' , ( ) => {
718
+ const options = getDefaultTestClientOptions ( { dsn : PUBLIC_DSN , enableLogs : true } ) ;
719
+ const client = new TestClient ( options ) ;
720
+ const scope = new Scope ( ) ;
721
+ scope . setClient ( client ) ;
722
+
723
+ // Mock no replay integration found
724
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( undefined ) ;
725
+
726
+ _INTERNAL_captureLog ( { level : 'info' , message : 'test log without replay integration' } , scope ) ;
727
+
728
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
729
+ expect ( logAttributes ) . toEqual ( { } ) ;
730
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry.replay_id' ) ;
731
+ expect ( logAttributes ) . not . toHaveProperty ( 'sentry._internal.replay_is_buffering' ) ;
732
+ } ) ;
733
+
734
+ it ( 'combines replay_is_buffering with other replay attributes' , ( ) => {
735
+ const options = getDefaultTestClientOptions ( {
736
+ dsn : PUBLIC_DSN ,
737
+ enableLogs : true ,
738
+ release : '1.0.0' ,
739
+ environment : 'test' ,
740
+ } ) ;
741
+ const client = new TestClient ( options ) ;
742
+ const scope = new Scope ( ) ;
743
+ scope . setClient ( client ) ;
744
+
745
+ // Mock replay integration with buffer mode
746
+ const mockReplayIntegration = {
747
+ getReplayId : vi . fn ( ( ) => 'buffer-replay-id' ) ,
748
+ getRecordingMode : vi . fn ( ( ) => 'buffer' ) ,
749
+ } ;
750
+
751
+ vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
752
+
753
+ _INTERNAL_captureLog (
754
+ {
755
+ level : 'info' ,
756
+ message : 'test log with buffer replay and other attributes' ,
757
+ attributes : { component : 'auth' , action : 'login' } ,
758
+ } ,
759
+ scope ,
760
+ ) ;
761
+
762
+ const logAttributes = _INTERNAL_getLogBuffer ( client ) ?. [ 0 ] ?. attributes ;
763
+ expect ( logAttributes ) . toEqual ( {
764
+ component : {
765
+ value : 'auth' ,
766
+ type : 'string' ,
767
+ } ,
768
+ action : {
769
+ value : 'login' ,
770
+ type : 'string' ,
771
+ } ,
772
+ 'sentry.release' : {
773
+ value : '1.0.0' ,
774
+ type : 'string' ,
775
+ } ,
776
+ 'sentry.environment' : {
777
+ value : 'test' ,
778
+ type : 'string' ,
779
+ } ,
780
+ 'sentry.replay_id' : {
781
+ value : 'buffer-replay-id' ,
782
+ type : 'string' ,
783
+ } ,
784
+ 'sentry._internal.replay_is_buffering' : {
785
+ value : true ,
786
+ type : 'boolean' ,
787
+ } ,
788
+ } ) ;
789
+ } ) ;
593
790
} ) ;
594
791
595
792
describe ( 'user functionality' , ( ) => {
0 commit comments