Agents rarely know to check for open alert/confirm/prompt/beforeunload
dialogs — they freeze the JS thread, so page_info()'s Runtime.evaluate
returns a stale or misleading viewport dict while the page is blocked.
Track the latest unhandled Page.javascriptDialogOpening in the daemon
(cleared on Page.javascriptDialogClosed) and, when one is open, return
{dialog: {type, message, ...}} from page_info() instead of the usual
viewport dict. The dialogs skill now points agents at this signal.
2.3 KiB
Dialogs
Browser dialogs (alert, confirm, prompt, beforeunload) freeze the JS thread. Two approaches depending on timing.
Detection
page_info() auto-surfaces any open dialog: if one is pending it returns {"dialog": {"type", "message", ...}} instead of the usual viewport dict (because the page's JS is frozen anyway). So if you call page_info() after an action and see a dialog key, handle it before doing anything else.
Reactive: dismiss via CDP (preferred)
Works even when JS is frozen. Handles all dialog types including beforeunload.
# Dismiss and read the message
cdp("Page.handleJavaScriptDialog", accept=True) # accept / click OK
cdp("Page.handleJavaScriptDialog", accept=False) # cancel / click Cancel
# Read what the dialog said (from buffered CDP events)
events = drain_events()
for e in events:
if e["method"] == "Page.javascriptDialogOpening":
print(e["params"]["type"]) # "alert", "confirm", "prompt", "beforeunload"
print(e["params"]["message"]) # the dialog text
Undetectable by antibot — no JS injected into the page.
Proactive: stub via JS
Prevents dialogs from ever appearing. Good when you expect multiple alert()/confirm() calls in sequence.
js("""
window.__dialogs__=[];
window.alert=m=>window.__dialogs__.push(String(m));
window.confirm=m=>{window.__dialogs__.push(String(m));return true;};
window.prompt=(m,d)=>{window.__dialogs__.push(String(m));return d||'';};
""")
# ... do actions that trigger dialogs ...
msgs = js("window.__dialogs__||[]")
Tradeoffs:
- Stubs are lost on page navigation -- must re-run the snippet
confirm()always returnstrue(auto-approves)- Detectable by antibot (
window.alert.toString()reveals non-native code) - Does NOT handle
beforeunload
beforeunload specifically
Fires when navigating away from a page with unsaved changes (forms, editors, upload pages). The page freezes until the user clicks Leave/Stay.
# Option A: dismiss after navigating (CDP-level, safe)
goto("https://new-url.com")
try:
cdp("Page.handleJavaScriptDialog", accept=True) # click "Leave"
except:
pass # no dialog — normal
# Option B: prevent before navigating (JS injection, detectable)
js("window.onbeforeunload=null")
goto("https://new-url.com")