@@ -27,6 +27,7 @@ const FORM_FIXTURE = `<!doctype html><title>form</title>
2727type Bridge = typeof globalThis & {
2828 simDesktop : SimDesktopApi
2929 pageDialog ?: BrowserPageDialog | null
30+ boundsTimer ?: number
3031}
3132
3233/**
@@ -79,7 +80,7 @@ test('page dialogs wait for the user on their page and stay automatic for the ag
7980 response . end (
8081 ! isSite
8182 ? SHELL_FIXTURE
82- : path === '/form'
83+ : path === '/form' || path === '/agent'
8384 ? FORM_FIXTURE
8485 : '<!doctype html><title>next</title>'
8586 )
@@ -117,7 +118,7 @@ test('page dialogs wait for the user on their page and stay automatic for the ag
117118 scope
118119 )
119120 updateBounds ( )
120- window . setInterval ( updateBounds , 200 )
121+ bridge . boundsTimer = window . setInterval ( updateBounds , 200 )
121122 bridge . pageDialog = null
122123 api . onPageState ( ( state ) => {
123124 bridge . pageDialog = state . dialog ?? null
@@ -260,6 +261,53 @@ test('page dialogs wait for the user on their page and stay automatic for the ag
260261 await expect . poll ( pageUrl ) . toBe ( `${ site } /next` )
261262 expect ( await pageDialog ( ) ) . toBeNull ( )
262263 } )
264+ /** Opens a page-initiated confirm (no user gesture) on the tab at `path`. */
265+ const confirmFromPage = ( path : string ) =>
266+ shellApp . evaluate ( ( { webContents } , url ) => {
267+ const contents = webContents . getAllWebContents ( ) . find ( ( c ) => c . getURL ( ) === url )
268+ if ( ! contents ) throw new Error ( `No page at ${ url } ` )
269+ void contents . executeJavaScript (
270+ "setTimeout(() => { document.title = 'confirm:' + confirm('Continue?') })"
271+ )
272+ } , `${ site } ${ path } ` )
273+ const titleAt = ( path : string ) =>
274+ shellApp . evaluate (
275+ ( { webContents } , url ) =>
276+ webContents
277+ . getAllWebContents ( )
278+ . find ( ( c ) => c . getURL ( ) === url )
279+ ?. getTitle ( ) ?? null ,
280+ `${ site } ${ path } `
281+ )
282+
283+ await check (
284+ "a dialog on the agent's page stays automatic until the user takes it" ,
285+ async ( ) => {
286+ await execute ( 'browser_open_tab' , { url : `${ site } /agent` } )
287+ const tabs = await shell . evaluate (
288+ async ( scope ) =>
289+ ( await ( globalThis as Bridge ) . simDesktop . browserAgent . activateScope ( scope ) ) . tabs ,
290+ SCOPE
291+ )
292+ const agentTabId = tabs . find ( ( tab ) => tab . url === `${ site } /agent` ) ?. tabId
293+ // The resource strip mirrors the agent's tab on screen without the user claiming it.
294+ await panelAction ( { action : 'switch-tab' , tabId : agentTabId , claim : false } )
295+ await confirmFromPage ( '/agent' )
296+ await expect . poll ( ( ) => titleAt ( '/agent' ) ) . toBe ( 'confirm:false' )
297+ expect ( await pageDialog ( ) ) . toBeNull ( )
298+ }
299+ )
300+
301+ await check ( 'a dialog while the browser is off screen stays automatic' , async ( ) => {
302+ await shell . evaluate ( ( scope ) => {
303+ const bridge = globalThis as Bridge
304+ window . clearInterval ( bridge . boundsTimer )
305+ bridge . simDesktop . browserAgent . setPanelBounds ( null , null , scope )
306+ } , SCOPE )
307+ await confirmFromPage ( '/agent' )
308+ await expect . poll ( ( ) => titleAt ( '/agent' ) ) . toBe ( 'confirm:false' )
309+ expect ( await pageDialog ( ) ) . toBeNull ( )
310+ } )
263311 passed = true
264312 } finally {
265313 mkdirSync ( dirname ( reportPath ) , { recursive : true } )
0 commit comments