@@ -92,6 +92,42 @@ export class FrameContextManager {
9292 }
9393
9494 removeFrame ( frameId : string ) : void {
95+ // 1. Clean execution contexts
96+ const contextId = this . frameExecutionContexts . get ( frameId ) ;
97+ if ( contextId !== undefined ) {
98+ this . executionContextToFrame . delete ( contextId ) ;
99+ this . frameExecutionContexts . delete ( frameId ) ;
100+ }
101+
102+ const waiters = this . executionContextWaiters . get ( frameId ) ;
103+ if ( waiters ) {
104+ for ( const waiter of waiters ) {
105+ if ( waiter . timeoutId ) clearTimeout ( waiter . timeoutId ) ;
106+ waiter . resolve ( undefined ) ;
107+ }
108+ this . executionContextWaiters . delete ( frameId ) ;
109+ }
110+
111+ // 2. Clean session listeners - only for OOPIF frames with dedicated sessions
112+ // Same-origin frames share the root session, so we must not remove shared listeners
113+ const isOOPIF = this . oopifFrameIds . has ( frameId ) ;
114+ if ( isOOPIF ) {
115+ const session = this . sessions . get ( frameId ) ;
116+ if ( session ) {
117+ const listeners = this . sessionListeners . get ( session ) ;
118+ if ( listeners ) {
119+ for ( const { event, handler } of listeners ) {
120+ session . off ?.( event , handler ) ;
121+ }
122+ this . sessionListeners . delete ( session ) ;
123+ }
124+ }
125+ }
126+
127+ // 3. Clean OOPIF set
128+ this . oopifFrameIds . delete ( frameId ) ;
129+
130+ // 4. Remove from graph and sessions
95131 this . graph . removeFrame ( frameId ) ;
96132 this . sessions . delete ( frameId ) ;
97133 }
@@ -388,7 +424,11 @@ export class FrameContextManager {
388424 this . log (
389425 `[FrameContext] Frame ${ frame . url ( ) } is detached, removing cached record`
390426 ) ;
427+ const frameId = cachedRecord . frameId ;
391428 this . removeCachedPlaywrightFrame ( frame ) ;
429+ if ( frameId ) {
430+ this . removeFrame ( frameId ) ;
431+ }
392432 return null ;
393433 }
394434 cachedRecord . url = frame . url ( ) ;
@@ -439,6 +479,7 @@ export class FrameContextManager {
439479 } ;
440480 const detachHandler = ( ) : void => {
441481 this . removeCachedPlaywrightFrame ( frame ) ;
482+ this . removeFrame ( frameId ) ;
442483 oopifSession ?. off ?.( "Detached" , detachHandler ) ;
443484 } ;
444485 record . detachHandler = detachHandler ;
0 commit comments