How to Manage Page Dialogs (Alerts, Prompts, Confirms) in Ego-Browser
Ego-Browser exposes JavaScript dialogs through the pendingDialog() helper and pageInfo() API, allowing you to accept or dismiss them via Chrome DevTools Protocol commands.
Managing page dialogs like alerts and prompts in ego-browser requires interacting with the Chrome DevTools Protocol (CDP) to detect and respond to JavaScript dialog events. The citrolabs/ego-lite runtime tracks these dialogs in a per-session map and provides helper functions to inspect their state. This guide explains how to detect, inspect, and handle alert, confirm, and prompt dialogs using the library's core APIs.
How Ego-Browser Tracks JavaScript Dialogs
The runtime listens for CDP events to maintain dialog state. When a page triggers alert(), confirm(), prompt(), or beforeunload, Chrome emits the Page.javascriptDialogOpening event.
In browser-runtime.ts, this event updates an internal pendingDialogs map that stores the dialog payload for the active session. The runtime automatically removes the entry when the Page.javascriptDialogClosed event fires, ensuring you don't need to manually clean up state after handling a dialog.
The pendingDialog() function exported from browser-runtime.ts exposes the current dialog object, if any, to your automation code.
Detecting Dialogs with pageInfo() and pendingDialog()
To check whether a dialog is blocking the page, use either the high-level pageInfo() helper or the direct pendingDialog() accessor.
The pageInfo() function defined in driver/nav.ts returns a dialog object alongside page metadata when a dialog is present. Alternatively, import pendingDialog() from browser-runtime.ts to access the raw dialog state directly.
A dialog object contains the following fields:
- type – The dialog variant:
alert,confirm,prompt, orbeforeunload - message – The string message displayed to the user
- defaultPrompt – For
promptdialogs only, the default input text
Accepting or Dismissiving Dialogs via CDP
Once detected, interact with the dialog using the CDP method Page.handleJavaScriptDialog. Import the cdp() helper from cdp-eval.ts to send commands to the browser.
The payload requires an accept boolean:
- Set
accept: trueto click "OK" or confirm the action - Set
accept: falseto dismiss or cancel the dialog
For prompt dialogs, include a promptText string containing the value to enter into the input field.
import { cdp } from "ego-browser/src/cdp-eval.js";
// Accept an alert or confirm
await cdp("Page.handleJavaScriptDialog", { accept: true });
// Dismiss a confirm dialog (click Cancel)
await cdp("Page.handleJavaScriptDialog", { accept: false });
// Answer a prompt dialog
await cdp("Page.handleJavaScriptDialog", {
accept: true,
promptText: "my custom answer"
});
Complete Code Examples
Accepting an Alert Dialog
Detect an alert using pageInfo() and accept it to continue page execution:
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pageInfo } from "ego-browser/src/driver/nav.js";
async function acceptCurrentDialog() {
const info = await pageInfo();
if ("dialog" in info) {
await cdp("Page.handleJavaScriptDialog", { accept: true });
console.log("Dialog accepted");
} else {
console.log("No dialog present");
}
}
Dismissing a Confirmation and Capturing Its Message
Use pendingDialog() to inspect the message before dismissing:
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pendingDialog } from "ego-browser/src/browser-runtime.js";
async function dismissConfirmAndLog() {
const dialog = pendingDialog();
if (dialog && dialog.type === "confirm") {
console.log("Confirm message:", dialog.message);
await cdp("Page.handleJavaScriptDialog", { accept: false });
}
}
Responding to a Prompt with Custom Text
Check for type: "prompt" and supply the promptText parameter:
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pendingDialog } from "ego-browser/src/browser-runtime.js";
async function answerPrompt() {
const dlg = pendingDialog();
if (dlg && dlg.type === "prompt") {
await cdp("Page.handleJavaScriptDialog", {
accept: true,
promptText: "my custom answer"
});
}
}
Handling Dialogs in Automation Workflows
The screenshot helper in driver/observe.ts demonstrates defensive dialog handling. The screenshot() function checks pendingDialog() before capturing; if a dialog is present, it switches to a "raw" screenshot mode to avoid clipping the overlay.
This pattern ensures your automation remains robust when unexpected alerts appear during visual regression testing or page observation tasks.
Summary
- Track dialogs using the
Page.javascriptDialogOpeningevent handled internally inbrowser-runtime.ts - Detect state by calling
pageInfo()fromdriver/nav.tsorpendingDialog()frombrowser-runtime.ts - Interact via
cdp("Page.handleJavaScriptDialog", { accept: boolean, promptText?: string })imported fromcdp-eval.ts - Automatic cleanup occurs when the runtime receives
Page.javascriptDialogClosed, so manual state management is unnecessary
Frequently Asked Questions
How do I detect if a dialog is currently open?
Call await pageInfo() and check if the returned object contains a dialog key, or import pendingDialog() from browser-runtime.ts to get the dialog object directly. Both methods return null or undefined when no dialog is active.
Can I handle beforeunload dialogs using the same API?
Yes. The type field in the dialog object includes beforeunload alongside alert, confirm, and prompt. Use the same Page.handleJavaScriptDialog CDP command to accept or dismiss beforeunload confirmations.
What happens if I don't handle the dialog?
If ignored, the dialog remains pending and blocks page execution. The pendingDialogs map in browser-runtime.ts retains the entry until the dialog is dismissed via CDP or the page context is destroyed.
How do I capture the message text from a confirmation dialog?
Access the message property on the object returned by pendingDialog() or pageInfo(). This field contains the exact string passed to the JavaScript confirm() or alert() call.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →