How to Wait for Specific Browser Events in ego-lite: A Complete Guide

To wait for specific browser events in ego-lite, use the waitForBrowserEvent function from src/browser-runtime.ts for low-level CDP events, or use specialized helpers like waitForRequest, waitForResponse, and waitForSelector from src/driver/waits.ts for common automation patterns.

Waiting for specific browser events in citrolabs/ego-lite ensures your automation scripts synchronize correctly with page navigation, network requests, and DOM mutations. The library implements a two-tiered waiting architecture: a low-level primitive that listens to Chrome DevTools Protocol (CDP) events directly, and a suite of high-level helpers that handle common scenarios with automatic timeout management based on values stored in src/state.ts.

Core Event-Waiting Architecture

ego-lite structures its waiting capabilities across two primary files. The foundation resides in src/browser-runtime.ts, which exports waitForBrowserEvent. This function registers a one-time promise that resolves when an incoming CDP event satisfies your predicate function, or rejects after the default timeout period.

Built atop this primitive, src/driver/waits.ts provides domain-specific wrappers that abstract away protocol details:

  • waitForRequest and waitForResponse – Monitor network activity using URL strings, globs, RegExp patterns, or synchronous predicates.
  • waitForLoadState – Pause execution until the page reaches load, domcontentloaded, or networkidle states.
  • waitForSelector – Poll the DOM until an element matching a CSS selector appears (optionally checking visibility).
  • waitForNetworkIdle – Wait for a configurable period of network inactivity.

Using the Low-Level waitForBrowserEvent Helper

For CDP events not covered by high-level helpers—such as console messages, dialog openings, or custom Page events—call waitForBrowserEvent directly. The helper accepts a predicate function that inspects the event object (containing method, params, sessionId, etc.) and returns true when the desired event occurs.

The function signature resolves with the full event payload, allowing you to extract any fields from the CDP response.

Example: Waiting for Page Navigation

// Wait until the browser emits a "Page.frameNavigated" event.
const navEvent = await waitForBrowserEvent(
  (e) => e.method === "Page.frameNavigated",
  5000   // optional timeout in ms
);
console.log('Navigated to:', navEvent.params?.url);

Example: Listening for Console Messages

const consoleMsg = await waitForBrowserEvent(
  (e) => e.method === 'Runtime.consoleAPICalled' &&
        e.params?.type === 'log' &&
        e.params?.args?.some(arg => arg.value?.includes('Ready')),
  8000
);
console.log('Console logged "Ready":', consoleMsg);

High-Level Wait Helpers for Common Scenarios

When working with network activity or DOM elements, the specialized helpers in src/driver/waits.ts provide type-safe, ergonomic alternatives to manual predicate construction.

Waiting for Network Requests and Responses

Use waitForRequest to pause execution until a matching request initiates, or waitForResponse to wait until a response completes. Both accept URL patterns, glob strings, regular expressions, or predicate functions.

// Wait for any request whose URL ends with ".png".
const request = await waitForRequest('**/*.png');
console.log('PNG request URL:', request.url());

// Wait for a 200 OK response using a predicate.
const response = await waitForResponse((resp) => resp.status() === 200);
console.log('Successful response URL:', response.url());

Waiting for Page Load States

The waitForLoadState helper monitors page lifecycle events. Valid states include "load" (default), "domcontentloaded", and "networkidle".

const idle = await waitForLoadState('networkidle', { idleMs: 500 });
if (idle) console.log('Network is idle');

Waiting for DOM Elements

Use waitForSelector to poll for element existence or visibility. The optional state parameter accepts "visible", "hidden", or "detached".

const found = await waitForSelector('#submit-button', { state: 'visible' });
if (found) console.log('Submit button is ready');

Waiting for Network Idle

The waitForNetworkIdle helper specifically monitors network activity, resolving when no requests have occurred for a specified duration (defaulting to the global timeout configuration).

Configuration and Timeout Behavior

All wait helpers in ego-lite respect a default timeout value stored in the global state object defined in src/state.ts (state.defaultTimeout). When calling any wait function, you can override this default by passing a timeout value in milliseconds as the final argument, as demonstrated in the waitForBrowserEvent examples above.

If the specified event does not occur within the timeout window, the promise rejects with a timeout error, enabling you to handle stalled page loads or missing elements gracefully.

Summary

  • waitForBrowserEvent in src/browser-runtime.ts provides the low-level mechanism for listening to any CDP event using custom predicates.
  • High-level helpers in src/driver/waits.ts (waitForRequest, waitForResponse, waitForLoadState, waitForSelector) abstract common waiting scenarios with built-in polling and timeout logic.
  • All helpers resolve with event payloads or element handles, allowing immediate access to event data or DOM interaction.
  • Default timeouts are managed centrally in src/state.ts but can be overridden per-call.
  • These functions are injected into the script execution scope, allowing direct invocation without explicit imports.

Frequently Asked Questions

How does waitForBrowserEvent work internally?

According to the src/browser-runtime.ts source, waitForBrowserEvent registers a transient event listener on the CDP transport that checks each incoming event against your predicate function. Once the predicate returns true, the listener removes itself and resolves the promise with the full event object. If the predicate never returns true before the timeout expires, the promise rejects.

What is the default timeout for wait helpers in ego-lite?

The default timeout is retrieved from state.defaultTimeout as defined in src/state.ts. This global configuration applies to all wait helpers including waitForBrowserEvent, waitForSelector, and network-related waits. You can override this value for individual calls by passing a millisecond value as the final argument to any wait function.

Can I wait for custom CDP events not covered by high-level helpers?

Yes. For any CDP event not handled by waitForRequest, waitForResponse, or waitForSelector, call waitForBrowserEvent directly from src/browser-runtime.ts. Pass a predicate function that inspects the event's method and params properties to identify your target event, such as Page.javascriptDialogOpening for alert dialogs or Runtime.exceptionThrown for uncaught exceptions.

How do I handle multiple concurrent browser events?

While waitForBrowserEvent and its high-level counterparts wait for a single event occurrence, you can issue multiple wait calls concurrently using Promise.all() or similar patterns. For example, you can simultaneously wait for a network response and a DOM element to appear, proceeding only when both conditions are satisfied.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →