@@ -47,6 +47,7 @@ export class Session implements Transport {
4747 private nextId = 1 ;
4848 private pending = new Map < number , Pending > ( ) ;
4949 private activeSessionId : string | undefined ;
50+ private activeTargetId : string | undefined ;
5051 private reattachPromise ?: Promise < void > ;
5152 private enabledDomains = new Map < string , Map < string , unknown > > ( ) ;
5253 private eventListeners : Array < ( method : string , params : unknown , sessionId ?: string ) => void > = [ ] ;
@@ -135,6 +136,7 @@ export class Session implements Transport {
135136 const previous = this . ws ;
136137 this . ws = ws ;
137138 this . activeSessionId = undefined ;
139+ this . activeTargetId = undefined ;
138140 this . enabledDomains . clear ( ) ;
139141 finish ( ) ;
140142 if ( previous && previous !== ws ) {
@@ -148,6 +150,7 @@ export class Session implements Transport {
148150 if ( this . ws === ws ) {
149151 this . ws = undefined ;
150152 this . activeSessionId = undefined ;
153+ this . activeTargetId = undefined ;
151154 this . enabledDomains . clear ( ) ;
152155 }
153156 finish ( new Error ( 'WS closed before open (likely 403 or port closed)' ) ) ;
@@ -170,12 +173,14 @@ export class Session implements Transport {
170173 async use ( targetId : string ) : Promise < string > {
171174 const r = await this . _call ( 'Target.attachToTarget' , { targetId, flatten : true } ) as { sessionId : string } ;
172175 this . activeSessionId = r . sessionId ;
176+ this . activeTargetId = targetId ;
173177 return r . sessionId ;
174178 }
175179
176180 /** Set the active sessionId directly (e.g. one you already attached). */
177181 setActiveSession ( sessionId : string | undefined ) : void {
178182 this . activeSessionId = sessionId ;
183+ this . activeTargetId = undefined ;
179184 }
180185
181186 getActiveSession ( ) : string | undefined {
@@ -228,6 +233,7 @@ export class Session implements Transport {
228233 async _call ( method : string , params : unknown = { } ) : Promise < unknown > {
229234 const browserLevel = isBrowserLevel ( method ) ;
230235 const sentSessionId = browserLevel ? undefined : this . activeSessionId ;
236+ const sentTargetId = browserLevel ? undefined : this . activeTargetId ;
231237 try {
232238 return await this . send ( method , params , sentSessionId ) ;
233239 } catch ( error ) {
@@ -236,7 +242,9 @@ export class Session implements Transport {
236242 // Chrome explicitly rejected the command before executing it, so this is
237243 // safe to retry once. Socket drops are deliberately not retried: Chrome
238244 // may have applied a click or submission before the response was lost.
239- if ( this . activeSessionId === sentSessionId ) await this . reattachFirstPage ( sentSessionId ) ;
245+ if ( this . activeSessionId === sentSessionId ) {
246+ await this . reattachPage ( sentSessionId , sentTargetId ) ;
247+ }
240248 else if ( this . reattachPromise ) await this . reattachPromise ;
241249 if ( ! this . activeSessionId || this . activeSessionId === sentSessionId ) throw error ;
242250 return this . send ( method , params , this . activeSessionId ) ;
@@ -273,10 +281,10 @@ export class Session implements Transport {
273281 } ) ;
274282 }
275283
276- private async reattachFirstPage ( staleSessionId : string ) : Promise < void > {
284+ private async reattachPage ( staleSessionId : string , staleTargetId ? : string ) : Promise < void > {
277285 if ( this . reattachPromise ) return this . reattachPromise ;
278286
279- const attempt = this . attachFirstPage ( staleSessionId ) ;
287+ const attempt = this . attachPage ( staleSessionId , staleTargetId ) ;
280288 this . reattachPromise = attempt ;
281289 try {
282290 await attempt ;
@@ -285,11 +293,15 @@ export class Session implements Transport {
285293 }
286294 }
287295
288- private async attachFirstPage ( staleSessionId : string ) : Promise < void > {
296+ private async attachPage ( staleSessionId : string , staleTargetId ? : string ) : Promise < void > {
289297 const domainsToRestore = [ ...( this . enabledDomains . get ( staleSessionId ) ?. entries ( ) ?? [ ] ) ] ;
290298 const { targetInfos } = await this . domains . Target . getTargets ( { } ) ;
291299 const pages = targetInfos as PageTarget [ ] ;
292- const targetId = pages . find ( isUsablePageTarget ) ?. targetId
300+ const exactTarget = staleTargetId
301+ ? pages . find ( target => target . type === 'page' && target . targetId === staleTargetId )
302+ : undefined ;
303+ const targetId = exactTarget ?. targetId
304+ ?? ( ! staleTargetId ? pages . find ( isUsablePageTarget ) ?. targetId : undefined )
293305 ?? ( await this . domains . Target . createTarget ( { url : 'about:blank' } ) ) . targetId ;
294306 const sessionId = await this . use ( targetId ) ;
295307 await Promise . all (
0 commit comments