@@ -15,6 +15,7 @@ interface MockView {
1515 }
1616 setWindowOpenHandler : ReturnType < typeof vi . fn >
1717 loadURL : ReturnType < typeof vi . fn >
18+ isDestroyed : ReturnType < typeof vi . fn >
1819 setBackgroundThrottling : ReturnType < typeof vi . fn >
1920 capturePage : ReturnType < typeof vi . fn >
2021 }
@@ -166,6 +167,67 @@ describe('browser-agent session', () => {
166167 expect ( removeChildView ) . toHaveBeenCalledWith ( tab . view )
167168 } )
168169
170+ it ( 'clears a stale attachment without touching a destroyed host window' , ( ) => {
171+ const tab = session . ensureTab ( )
172+ session . setPanelBounds ( { x : 100 , y : 50 , width : 800 , height : 600 } )
173+ const staleContent = (
174+ win as unknown as {
175+ contentView : {
176+ removeChildView : ReturnType < typeof vi . fn >
177+ }
178+ }
179+ ) . contentView
180+ staleContent . removeChildView . mockClear ( )
181+ staleContent . removeChildView . mockImplementation ( ( ) => {
182+ throw new Error ( 'Object has been destroyed' )
183+ } )
184+ vi . mocked ( win . isDestroyed ) . mockReturnValue ( true )
185+
186+ const replacement = mainWindowMock ( )
187+ session . initSession (
188+ {
189+ onSessionClosed : vi . fn ( ) ,
190+ onTabCreated : vi . fn ( ) ,
191+ onActiveTabChanged : vi . fn ( ) ,
192+ onTabsChanged : vi . fn ( ) ,
193+ onTabThemeChanged : vi . fn ( ) ,
194+ onDownloadBlocked : vi . fn ( ) ,
195+ } ,
196+ ( ) => replacement
197+ )
198+
199+ expect ( ( ) => session . setPanelBounds ( null ) ) . not . toThrow ( )
200+ expect ( staleContent . removeChildView ) . not . toHaveBeenCalled ( )
201+
202+ session . setPanelBounds ( { x : 100 , y : 50 , width : 800 , height : 600 } )
203+ const replacementContent = (
204+ replacement as unknown as {
205+ contentView : {
206+ addChildView : ReturnType < typeof vi . fn >
207+ }
208+ }
209+ ) . contentView
210+ expect ( replacementContent . addChildView ) . toHaveBeenCalledWith ( tab . view )
211+ } )
212+
213+ it ( 'clears a stale attachment without touching a destroyed child view' , ( ) => {
214+ const tab = session . ensureTab ( )
215+ const view = tab . view as unknown as MockView
216+ session . setPanelBounds ( { x : 100 , y : 50 , width : 800 , height : 600 } )
217+ const content = (
218+ win as unknown as {
219+ contentView : {
220+ removeChildView : ReturnType < typeof vi . fn >
221+ }
222+ }
223+ ) . contentView
224+ content . removeChildView . mockClear ( )
225+ view . webContents . isDestroyed . mockReturnValue ( true )
226+
227+ expect ( ( ) => session . setPanelBounds ( null ) ) . not . toThrow ( )
228+ expect ( content . removeChildView ) . not . toHaveBeenCalled ( )
229+ } )
230+
169231 it ( 'scales panel bounds by the main window zoom factor' , ( ) => {
170232 const winZoomed = mainWindowMock ( )
171233 ; (
0 commit comments