Skip to content

Replace JS dialog stubs with CDP-level dismiss_dialog()#2

Closed
MagMueller wants to merge 3 commits intomainfrom
cdp-dialog-handling
Closed

Replace JS dialog stubs with CDP-level dismiss_dialog()#2
MagMueller wants to merge 3 commits intomainfrom
cdp-dialog-handling

Conversation

@MagMueller
Copy link
Copy Markdown
Contributor

@MagMueller MagMueller commented Apr 17, 2026

Summary

  • dismiss_dialog(accept=True) replaces capture_dialogs()/dialogs() — uses Page.handleJavaScriptDialog via CDP, works on all dialog types (alert, confirm, prompt, beforeunload) even when the JS thread is frozen
  • goto() auto-clears window.onbeforeunload before navigating, preventing the most common source of stuck automation
  • Updated SKILL.md gotcha to reflect the new approach

Why

The JS-level stubs had three failure modes we hit in production:

  1. beforeunload dialogs aren't interceptable via JS stubs
  2. Stubs are wiped on page navigation — if you forget to re-call capture_dialogs(), the next alert() freezes the session
  3. When JS is already frozen (dialog already showing), you can't call any JS to recover

CDP's Page.handleJavaScriptDialog operates at the browser level and handles all three cases.

Test plan

  • Verified dismiss_dialog() dismisses beforeunload dialogs on TikTok Studio
  • Verified goto() navigates cleanly without triggering beforeunload blocking
  • Verified dismiss_dialog() returns the dialog message from CDP events

🤖 Generated with Claude Code


Summary by cubic

Replaced JS-based dialog handling with a CDP-level dismiss_dialog() and updated goto() to auto-dismiss beforeunload via CDP, avoiding JS injection and antibot flags. Kept capture_dialogs() for proactive flows.

  • New Features
    • Added dismiss_dialog(accept=True) using Page.handleJavaScriptDialog; works for alert, confirm, prompt, and beforeunload, returns {type, message, url}, can be called after the dialog appears, and is antibot-safe.
    • Retained capture_dialogs()/dialogs() with clearer docs: use for known flows to auto-approve or swallow multiple alerts; note this injects JS and can be detected. Use dismiss_dialog() for beforeunload, frozen pages, or unexpected dialogs.
    • goto() now navigates first, then auto-dismisses any beforeunload dialog via CDP (no page JS touched, undetectable). SKILL.md updated to document this tradeoff.

Written for commit 7ee18cd. Summary will update on new commits.

MagMueller and others added 2 commits April 17, 2026 13:01
capture_dialogs()/dialogs() required calling before the dialog
fired, couldn't handle beforeunload, and broke when the JS thread
was frozen. dismiss_dialog() uses Page.handleJavaScriptDialog via
CDP which works on all dialog types even when JS is blocked.

Also makes goto() auto-clear window.onbeforeunload to prevent the
most common source of stuck automation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
They solve different problems: capture_dialogs() is proactive
(auto-approve confirms, swallow multiple alerts without blocking),
dismiss_dialog() is reactive (beforeunload, frozen pages, unexpected
dialogs). Updated docstrings to clarify when to use each.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="helpers.py">

<violation number="1" location="helpers.py:277">
P2: `capture_dialogs()` prompt stub drops valid falsy default values by using `d||''`; use a null/undefined check so `0`/`false` are preserved.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread helpers.py
Call BEFORE the action that triggers the dialog; read with dialogs().
Good for known flows with multiple alerts or confirm() calls that should auto-approve.
For beforeunload or already-frozen pages, use dismiss_dialog() instead."""
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||'';}")
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: capture_dialogs() prompt stub drops valid falsy default values by using d||''; use a null/undefined check so 0/false are preserved.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At helpers.py, line 277:

<comment>`capture_dialogs()` prompt stub drops valid falsy default values by using `d||''`; use a null/undefined check so `0`/`false` are preserved.</comment>

<file context>
@@ -267,6 +269,18 @@ def dismiss_dialog(accept=True):
+    Call BEFORE the action that triggers the dialog; read with dialogs().
+    Good for known flows with multiple alerts or confirm() calls that should auto-approve.
+    For beforeunload or already-frozen pages, use dismiss_dialog() instead."""
+    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||'';}")
+
+def dialogs():
</file context>
Suggested change
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||'';}")
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==null?'':String(d);}")
Fix with Cubic

- goto(): no longer injects JS to clear onbeforeunload. Instead,
  navigates first then auto-dismisses any beforeunload dialog via
  CDP. Zero page JS touched, undetectable by antibot.
- dismiss_dialog(): now returns {type, message, url} so the agent
  can read what the dialog says and decide how to respond.
- SKILL.md: document antibot tradeoff between capture_dialogs()
  (JS injection, detectable) vs dismiss_dialog() (CDP-level, safe).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant