@@ -20,8 +20,9 @@ import {
20
20
UI_LOAD ,
21
21
} from '../../../src/js/tracing' ;
22
22
import {
23
+ _captureAppStart ,
23
24
_clearRootComponentCreationTimestampMs ,
24
- _setAppStartEndTimestampMs ,
25
+ _setAppStartEndData ,
25
26
_setRootComponentCreationTimestampMs ,
26
27
appStartIntegration ,
27
28
setRootComponentCreationTimestampMs ,
@@ -788,6 +789,169 @@ describe('App Start Integration', () => {
788
789
} ) ;
789
790
} ) ;
790
791
792
+ describe ( 'Frame Data Integration' , ( ) => {
793
+ it ( 'attaches frame data to standalone cold app start span' , async ( ) => {
794
+ const mockEndFrames = {
795
+ totalFrames : 150 ,
796
+ slowFrames : 5 ,
797
+ frozenFrames : 2 ,
798
+ } ;
799
+
800
+ mockFunction ( NATIVE . fetchNativeFrames ) . mockResolvedValue ( mockEndFrames ) ;
801
+
802
+ mockAppStart ( { cold : true } ) ;
803
+
804
+ const actualEvent = await captureStandAloneAppStart ( ) ;
805
+
806
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Cold App Start' ) ;
807
+
808
+ expect ( appStartSpan ) . toBeDefined ( ) ;
809
+ expect ( appStartSpan ! . data ) . toEqual (
810
+ expect . objectContaining ( {
811
+ 'frames.total' : 150 ,
812
+ 'frames.slow' : 5 ,
813
+ 'frames.frozen' : 2 ,
814
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_COLD_OP ,
815
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
816
+ } ) ,
817
+ ) ;
818
+ } ) ;
819
+
820
+ it ( 'attaches frame data to standalone warm app start span' , async ( ) => {
821
+ const mockEndFrames = {
822
+ totalFrames : 200 ,
823
+ slowFrames : 8 ,
824
+ frozenFrames : 1 ,
825
+ } ;
826
+
827
+ mockFunction ( NATIVE . fetchNativeFrames ) . mockResolvedValue ( mockEndFrames ) ;
828
+
829
+ mockAppStart ( { cold : false } ) ;
830
+
831
+ const actualEvent = await captureStandAloneAppStart ( ) ;
832
+
833
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Warm App Start' ) ;
834
+
835
+ expect ( appStartSpan ) . toBeDefined ( ) ;
836
+ expect ( appStartSpan ! . data ) . toEqual (
837
+ expect . objectContaining ( {
838
+ 'frames.total' : 200 ,
839
+ 'frames.slow' : 8 ,
840
+ 'frames.frozen' : 1 ,
841
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_WARM_OP ,
842
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
843
+ } ) ,
844
+ ) ;
845
+ } ) ;
846
+
847
+ it ( 'attaches frame data to attached cold app start span' , async ( ) => {
848
+ const mockEndFrames = {
849
+ totalFrames : 120 ,
850
+ slowFrames : 3 ,
851
+ frozenFrames : 0 ,
852
+ } ;
853
+
854
+ mockFunction ( NATIVE . fetchNativeFrames ) . mockResolvedValue ( mockEndFrames ) ;
855
+
856
+ mockAppStart ( { cold : true } ) ;
857
+
858
+ await _captureAppStart ( { isManual : false } ) ;
859
+
860
+ const actualEvent = await processEvent ( getMinimalTransactionEvent ( ) ) ;
861
+
862
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Cold App Start' ) ;
863
+
864
+ expect ( appStartSpan ) . toBeDefined ( ) ;
865
+ expect ( appStartSpan ! . data ) . toEqual (
866
+ expect . objectContaining ( {
867
+ 'frames.total' : 120 ,
868
+ 'frames.slow' : 3 ,
869
+ 'frames.frozen' : 0 ,
870
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_COLD_OP ,
871
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
872
+ } ) ,
873
+ ) ;
874
+ } ) ;
875
+
876
+ it ( 'attaches frame data to attached warm app start span' , async ( ) => {
877
+ const mockEndFrames = {
878
+ totalFrames : 180 ,
879
+ slowFrames : 12 ,
880
+ frozenFrames : 3 ,
881
+ } ;
882
+
883
+ mockFunction ( NATIVE . fetchNativeFrames ) . mockResolvedValue ( mockEndFrames ) ;
884
+
885
+ mockAppStart ( { cold : false } ) ;
886
+
887
+ await _captureAppStart ( { isManual : false } ) ;
888
+
889
+ const actualEvent = await processEvent ( getMinimalTransactionEvent ( ) ) ;
890
+
891
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Warm App Start' ) ;
892
+
893
+ expect ( appStartSpan ) . toBeDefined ( ) ;
894
+ expect ( appStartSpan ! . data ) . toEqual (
895
+ expect . objectContaining ( {
896
+ 'frames.total' : 180 ,
897
+ 'frames.slow' : 12 ,
898
+ 'frames.frozen' : 3 ,
899
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_WARM_OP ,
900
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
901
+ } ) ,
902
+ ) ;
903
+ } ) ;
904
+
905
+ it ( 'does not attach frame data when native frames are not available' , async ( ) => {
906
+ mockFunction ( NATIVE . fetchNativeFrames ) . mockRejectedValue ( new Error ( 'Native frames not available' ) ) ;
907
+
908
+ mockAppStart ( { cold : true } ) ;
909
+
910
+ const actualEvent = await captureStandAloneAppStart ( ) ;
911
+
912
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Cold App Start' ) ;
913
+
914
+ expect ( appStartSpan ) . toBeDefined ( ) ;
915
+ expect ( appStartSpan ! . data ) . toEqual (
916
+ expect . objectContaining ( {
917
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_COLD_OP ,
918
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
919
+ } ) ,
920
+ ) ;
921
+
922
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.total' ) ;
923
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.slow' ) ;
924
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.frozen' ) ;
925
+ } ) ;
926
+
927
+ it ( 'does not attach frame data when NATIVE is not enabled' , async ( ) => {
928
+ const originalEnableNative = NATIVE . enableNative ;
929
+ ( NATIVE as any ) . enableNative = false ;
930
+
931
+ try {
932
+ mockAppStart ( { cold : true } ) ;
933
+
934
+ const actualEvent = await captureStandAloneAppStart ( ) ;
935
+
936
+ const appStartSpan = actualEvent ! . spans ! . find ( ( { description } ) => description === 'Cold App Start' ) ;
937
+
938
+ expect ( appStartSpan ) . toBeDefined ( ) ;
939
+ expect ( appStartSpan ! . data ) . toEqual (
940
+ expect . objectContaining ( {
941
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : APP_START_COLD_OP ,
942
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : SPAN_ORIGIN_AUTO_APP_START ,
943
+ } ) ,
944
+ ) ;
945
+
946
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.total' ) ;
947
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.slow' ) ;
948
+ expect ( appStartSpan ! . data ) . not . toHaveProperty ( 'frames.frozen' ) ;
949
+ } finally {
950
+ ( NATIVE as any ) . enableNative = originalEnableNative ;
951
+ }
952
+ } ) ;
953
+ } ) ;
954
+
791
955
function setupIntegration ( ) {
792
956
const client = new TestClient ( getDefaultTestClientOptions ( ) ) ;
793
957
const integration = appStartIntegration ( ) ;
@@ -1095,7 +1259,10 @@ function mockAppStart({
1095
1259
: [ ] ,
1096
1260
} ;
1097
1261
1098
- _setAppStartEndTimestampMs ( appStartEndTimestampMs || timeOriginMilliseconds ) ;
1262
+ _setAppStartEndData ( {
1263
+ timestampMs : appStartEndTimestampMs || timeOriginMilliseconds ,
1264
+ endFrames : null ,
1265
+ } ) ;
1099
1266
mockFunction ( getTimeOriginMilliseconds ) . mockReturnValue ( timeOriginMilliseconds ) ;
1100
1267
mockFunction ( NATIVE . fetchNativeAppStart ) . mockResolvedValue ( mockAppStartResponse ) ;
1101
1268
@@ -1112,7 +1279,10 @@ function mockTooLongAppStart() {
1112
1279
spans : [ ] ,
1113
1280
} ;
1114
1281
1115
- _setAppStartEndTimestampMs ( timeOriginMilliseconds ) ;
1282
+ _setAppStartEndData ( {
1283
+ timestampMs : timeOriginMilliseconds ,
1284
+ endFrames : null ,
1285
+ } ) ;
1116
1286
mockFunction ( getTimeOriginMilliseconds ) . mockReturnValue ( timeOriginMilliseconds ) ;
1117
1287
mockFunction ( NATIVE . fetchNativeAppStart ) . mockResolvedValue ( mockAppStartResponse ) ;
1118
1288
@@ -1134,7 +1304,10 @@ function mockTooOldAppStart() {
1134
1304
1135
1305
// App start finish timestamp
1136
1306
// App start length is 5 seconds
1137
- _setAppStartEndTimestampMs ( appStartEndTimestampMilliseconds ) ;
1307
+ _setAppStartEndData ( {
1308
+ timestampMs : appStartEndTimestampMilliseconds ,
1309
+ endFrames : null ,
1310
+ } ) ;
1138
1311
mockFunction ( getTimeOriginMilliseconds ) . mockReturnValue ( timeOriginMilliseconds - 64000 ) ;
1139
1312
mockFunction ( NATIVE . fetchNativeAppStart ) . mockResolvedValue ( mockAppStartResponse ) ;
1140
1313
// Transaction start timestamp
0 commit comments