@@ -38,12 +38,14 @@ export class PageCollector<T> {
3838 collector : ( item : T ) => void ,
3939 ) => ListenerMap < PageEvents > ;
4040 #listeners = new WeakMap < Page , ListenerMap > ( ) ;
41+ #maxNavigationSaved = 3 ;
42+
4143 /**
42- * The Array in this map should only be set once
43- * As we use the reference to it .
44- * Use methods that manipulate the array in place .
44+ * This maps a Page to a list of navigations with a sub-list
45+ * of all collected resources .
46+ * The newer navigations come first .
4547 */
46- protected storage = new WeakMap < Page , Array < WithSymbolId < T > > > ( ) ;
48+ protected storage = new WeakMap < Page , Array < Array < WithSymbolId < T > > > > ( ) ;
4749
4850 constructor (
4951 browser : Browser ,
@@ -85,20 +87,23 @@ export class PageCollector<T> {
8587 }
8688
8789 const idGenerator = createIdGenerator ( ) ;
88- const stored : Array < WithSymbolId < T > > = [ ] ;
89- this . storage . set ( page , stored ) ;
90+ const storedLists : Array < Array < WithSymbolId < T > > > = [ [ ] ] ;
91+ this . storage . set ( page , storedLists ) ;
9092
9193 const listeners = this . #listenersInitializer( value => {
9294 const withId = value as WithSymbolId < T > ;
9395 withId [ stableIdSymbol ] = idGenerator ( ) ;
94- stored . push ( withId ) ;
96+
97+ const navigations = this . storage . get ( page ) ?? [ [ ] ] ;
98+ navigations [ 0 ] . push ( withId ) ;
9599 } ) ;
100+
96101 listeners [ 'framenavigated' ] = ( frame : Frame ) => {
97- // Only reset the storage on main frame navigation
102+ // Only split the storage on main frame navigation
98103 if ( frame !== page . mainFrame ( ) ) {
99104 return ;
100105 }
101- this . cleanupAfterNavigation ( page ) ;
106+ this . splitAfterNavigation ( page ) ;
102107 } ;
103108
104109 for ( const [ name , listener ] of Object . entries ( listeners ) ) {
@@ -108,12 +113,14 @@ export class PageCollector<T> {
108113 this . #listeners. set ( page , listeners ) ;
109114 }
110115
111- protected cleanupAfterNavigation ( page : Page ) {
112- const collection = this . storage . get ( page ) ;
113- if ( collection ) {
114- // Keep the reference alive
115- collection . length = 0 ;
116+ protected splitAfterNavigation ( page : Page ) {
117+ const navigations = this . storage . get ( page ) ;
118+ if ( ! navigations ) {
119+ return ;
116120 }
121+ // Add the latest navigation first
122+ navigations . unshift ( [ ] ) ;
123+ navigations . splice ( this . #maxNavigationSaved) ;
117124 }
118125
119126 #cleanupPageDestroyed( page : Page ) {
@@ -127,22 +134,28 @@ export class PageCollector<T> {
127134 }
128135
129136 getData ( page : Page ) : T [ ] {
130- return this . storage . get ( page ) ?? [ ] ;
137+ const navigations = this . storage . get ( page ) ;
138+ if ( ! navigations ) {
139+ return [ ] ;
140+ }
141+ return navigations [ 0 ] ;
131142 }
132143
133144 getIdForResource ( resource : WithSymbolId < T > ) : number {
134145 return resource [ stableIdSymbol ] ?? - 1 ;
135146 }
136147
137148 getById ( page : Page , stableId : number ) : T {
138- const data = this . storage . get ( page ) ;
139- if ( ! data || ! data . length ) {
149+ const navigations = this . storage . get ( page ) ;
150+ if ( ! navigations ) {
140151 throw new Error ( 'No requests found for selected page' ) ;
141152 }
142153
143- for ( const collected of data ) {
144- if ( collected [ stableIdSymbol ] === stableId ) {
145- return collected ;
154+ for ( const navigation of navigations ) {
155+ for ( const collected of navigation ) {
156+ if ( collected [ stableIdSymbol ] === stableId ) {
157+ return collected ;
158+ }
146159 }
147160 }
148161
@@ -151,19 +164,39 @@ export class PageCollector<T> {
151164}
152165
153166export class NetworkCollector extends PageCollector < HTTPRequest > {
154- override cleanupAfterNavigation ( page : Page ) {
155- const requests = this . storage . get ( page ) ?? [ ] ;
156- if ( ! requests ) {
167+ constructor ( browser : Browser ) {
168+ super ( browser , collect => {
169+ return {
170+ request : req => {
171+ collect ( req ) ;
172+ } ,
173+ } as ListenerMap ;
174+ } ) ;
175+ }
176+ override splitAfterNavigation ( page : Page ) {
177+ const navigations = this . storage . get ( page ) ?? [ ] ;
178+ if ( ! navigations ) {
157179 return ;
158180 }
181+
182+ const requests = navigations [ 0 ] ;
183+
159184 const lastRequestIdx = requests . findLastIndex ( request => {
160185 return request . frame ( ) === page . mainFrame ( )
161186 ? request . isNavigationRequest ( )
162187 : false ;
163188 } ) ;
189+
164190 // Keep all requests since the last navigation request including that
165191 // navigation request itself.
166192 // Keep the reference
167- requests . splice ( 0 , Math . max ( lastRequestIdx , 0 ) ) ;
193+ if ( lastRequestIdx ) {
194+ const fromCurrentNavigation = requests . splice (
195+ Math . min ( lastRequestIdx , 0 ) ,
196+ ) ;
197+ navigations . unshift ( fromCurrentNavigation ) ;
198+ } else {
199+ navigations . unshift ( [ ] ) ;
200+ }
168201 }
169202}
0 commit comments