11import { relativeNow , type Duration , type RelativeTime } from '@datadog/browser-core'
22import type { Clock } from '@datadog/browser-core/test'
33import { mockClock , registerCleanupTask } from '@datadog/browser-core/test'
4+ import type { RumNotRestoredReasons } from '../../../browser/performanceObservable'
45import { mockDocumentReadyState , mockRumConfiguration } from '../../../../test'
56import type { NavigationTimings , RelevantNavigationTiming } from './trackNavigationTimings'
67import { trackNavigationTimings } from './trackNavigationTimings'
@@ -21,6 +22,15 @@ const FAKE_INCOMPLETE_NAVIGATION_ENTRY: RelevantNavigationTiming = {
2122 responseStart : 0 as RelativeTime ,
2223}
2324
25+ const FAKE_NOT_RESTORED_REASONS : RumNotRestoredReasons = {
26+ children : [ ] ,
27+ id : null ,
28+ name : null ,
29+ reasons : [ { reason : 'unload-listener' } ] ,
30+ src : null ,
31+ url : 'https://example.com/' ,
32+ }
33+
2434describe ( 'trackNavigationTimings' , ( ) => {
2535 let navigationTimingsCallback : jasmine . Spy < ( timings : NavigationTimings ) => void >
2636 let stop : ( ) => void
@@ -46,6 +56,7 @@ describe('trackNavigationTimings', () => {
4656 domContentLoaded : 345 as Duration ,
4757 domInteractive : 234 as Duration ,
4858 loadEvent : 567 as Duration ,
59+ notRestoredReasons : undefined ,
4960 } )
5061 } )
5162
@@ -91,4 +102,77 @@ describe('trackNavigationTimings', () => {
91102
92103 expect ( navigationTimingsCallback ) . not . toHaveBeenCalled ( )
93104 } )
105+
106+ it ( 'includes notRestoredReasons when present' , ( ) => {
107+ ; ( { stop } = trackNavigationTimings ( mockRumConfiguration ( ) , navigationTimingsCallback , ( ) => ( {
108+ ...FAKE_NAVIGATION_ENTRY ,
109+ notRestoredReasons : FAKE_NOT_RESTORED_REASONS ,
110+ } ) ) )
111+
112+ clock . tick ( 0 )
113+
114+ expect ( navigationTimingsCallback ) . toHaveBeenCalledOnceWith ( {
115+ firstByte : 123 as Duration ,
116+ domComplete : 456 as Duration ,
117+ domContentLoaded : 345 as Duration ,
118+ domInteractive : 234 as Duration ,
119+ loadEvent : 567 as Duration ,
120+ notRestoredReasons : FAKE_NOT_RESTORED_REASONS ,
121+ } )
122+ } )
123+
124+ it ( 'handles null notRestoredReasons' , ( ) => {
125+ ; ( { stop } = trackNavigationTimings ( mockRumConfiguration ( ) , navigationTimingsCallback , ( ) => ( {
126+ ...FAKE_NAVIGATION_ENTRY ,
127+ notRestoredReasons : null ,
128+ } ) ) )
129+
130+ clock . tick ( 0 )
131+
132+ expect ( navigationTimingsCallback ) . toHaveBeenCalledOnceWith ( {
133+ firstByte : 123 as Duration ,
134+ domComplete : 456 as Duration ,
135+ domContentLoaded : 345 as Duration ,
136+ domInteractive : 234 as Duration ,
137+ loadEvent : 567 as Duration ,
138+ notRestoredReasons : null ,
139+ } )
140+ } )
141+
142+ it ( 'handles notRestoredReasons with nested iframes' , ( ) => {
143+ const complexNotRestoredReasons : RumNotRestoredReasons = {
144+ children : [
145+ {
146+ children : [ ] ,
147+ id : 'iframe-1' ,
148+ name : 'myFrame' ,
149+ reasons : null ,
150+ src : './frame.html' ,
151+ url : 'https://example.com/frame.html' ,
152+ } ,
153+ {
154+ children : [ ] ,
155+ id : 'iframe-2' ,
156+ name : 'anotherFrame' ,
157+ reasons : [ { reason : 'response-cache-control-no-store' } ] ,
158+ src : './another.html' ,
159+ url : 'https://example.com/another.html' ,
160+ } ,
161+ ] ,
162+ id : null ,
163+ name : null ,
164+ reasons : [ ] ,
165+ src : null ,
166+ url : 'https://example.com/' ,
167+ }
168+
169+ ; ( { stop } = trackNavigationTimings ( mockRumConfiguration ( ) , navigationTimingsCallback , ( ) => ( {
170+ ...FAKE_NAVIGATION_ENTRY ,
171+ notRestoredReasons : complexNotRestoredReasons ,
172+ } ) ) )
173+
174+ clock . tick ( 0 )
175+
176+ expect ( navigationTimingsCallback . calls . mostRecent ( ) . args [ 0 ] . notRestoredReasons ) . toEqual ( complexNotRestoredReasons )
177+ } )
94178} )
0 commit comments