@@ -424,6 +424,7 @@ describe('_INTERNAL_captureLog', () => {
424424 // Simulate behavior: return ID for sampled sessions
425425 return onlyIfSampled ? 'sampled-replay-id' : 'any-replay-id' ;
426426 } ) ,
427+ getRecordingMode : vi . fn ( ( ) => 'session' ) ,
427428 } ;
428429
429430 vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -480,6 +481,7 @@ describe('_INTERNAL_captureLog', () => {
480481 // Buffer mode should still return ID even with onlyIfSampled=true
481482 return 'buffer-replay-id' ;
482483 } ) ,
484+ getRecordingMode : vi . fn ( ( ) => 'buffer' ) ,
483485 } ;
484486
485487 vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -494,6 +496,10 @@ describe('_INTERNAL_captureLog', () => {
494496 value : 'buffer-replay-id' ,
495497 type : 'string' ,
496498 } ,
499+ 'sentry._internal.replay_is_buffering' : {
500+ value : true ,
501+ type : 'boolean' ,
502+ } ,
497503 } ) ;
498504 } ) ;
499505
@@ -527,6 +533,7 @@ describe('_INTERNAL_captureLog', () => {
527533 // Mock replay integration
528534 const mockReplayIntegration = {
529535 getReplayId : vi . fn ( ( ) => 'test-replay-id' ) ,
536+ getRecordingMode : vi . fn ( ( ) => 'session' ) ,
530537 } ;
531538
532539 vi . spyOn ( client , 'getIntegrationByName' ) . mockReturnValue ( mockReplayIntegration as any ) ;
@@ -590,6 +597,196 @@ describe('_INTERNAL_captureLog', () => {
590597 expect ( logAttributes ) . not . toHaveProperty ( 'sentry.replay_id' ) ;
591598 } ) ;
592599 } ) ;
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+ } ) ;
593790 } ) ;
594791
595792 describe ( 'user functionality' , ( ) => {
0 commit comments