How to Use waitForFunction for Custom Polling Conditions in ego-browser
waitForFunction is a low-level helper that repeatedly evaluates JavaScript in the page context until it returns a truthy value or a timeout expires.
In the citrolabs/ego-lite repository, waitForFunction provides agents with a flexible mechanism to pause execution until custom conditions—such as DOM state changes, variable availability, or data loading—are met. This guide explains how to implement custom polling logic using the function exported from src/helpers.ts and implemented in src/driver/waits.ts.
Understanding the waitForFunction Architecture
The waitForFunction utility is implemented inside src/driver/waits.ts, where it constructs a Chrome DevTools Protocol (CDP) expression and manages the polling lifecycle. It is re-exported through src/helpers.ts to make it available for import in agent scripts.
According to the source code in src/helpers.ts, the function signature is:
waitForFunction(pageFunction, argOrOptions?, options?) // → Promise<unknown|false>
The helper relies on src/state.ts for timing utilities (state.sleep, state.now, and default timeout values) and src/cdp-eval.ts to dispatch Runtime.evaluate calls to the browser.
How the Polling Loop Works
The internal polling mechanism follows a tight evaluation cycle defined in src/driver/waits.ts. When you invoke waitForFunction, the utility:
- Builds a CDP
Runtime.evaluateexpression usingbuildWaitForFunctionExpression, wrapping your supplied function or string for execution in the page context. - Sends the expression via
cdp("Runtime.evaluate", …)and reads the result usingruntimeValue. - Resolves the promise immediately if the returned value is truthy.
- Otherwise, sleeps for the configured
pollingduration usingstate.sleep(polling)and repeats until the deadline (state.now() + timeout) is reached.
This loop continues until the condition is satisfied or the timeout expires, at which point it returns false.
Function Signature and Options
The waitForFunction method accepts flexible arguments to accommodate both simple and complex polling scenarios:
pageFunction: A function or string expression to evaluate in the browser context. Must return a truthy value to indicate success.argOrOptions: Either an argument to pass intopageFunction(ifpageFunctionaccepts parameters) or an options object if no argument is needed.options: An object configuring the wait behavior:timeout(number): Maximum time to wait in milliseconds. Defaults tostate.defaultTimeout.polling(number): Interval between evaluations in milliseconds. Defaults to100ms.
Practical Code Examples
Waiting for Page Variables
Poll until a global JavaScript variable becomes available and truthy:
// Wait until the page sets window.isReady to true
const result = await waitForFunction(() => window.isReady);
console.log('Ready?', !!result);
Polling with Function Arguments
Pass dynamic data into the evaluated function to check for specific content:
// Wait until a specific element's text equals the target string
const target = 'Done';
const result = await waitForFunction(
(t) => document.querySelector('#status')?.textContent?.trim() === t,
target, // argument passed to the function
{ timeout: 5000, polling: 200 } // custom options
);
if (result) console.log('Status reached:', target);
Using String Expressions
Supply a string expression instead of a function for simpler conditions:
// Equivalent to the previous example, but with a string expression
await waitForFunction(
"document.querySelector('#status')?.textContent?.trim() === 'Done'",
{ timeout: 5000, polling: 200 }
);
Extracting Data from the Page
Use waitForFunction to retrieve computed values once elements are present:
// Retrieve the number of rows in a table once the table is present
const rowCount = await waitForFunction(() => {
const table = document.querySelector('#myTable');
return table ? table.rows.length : false;
});
console.log('Rows:', rowCount);
Summary
waitForFunctionis the primary mechanism in ego-browser for implementing custom polling conditions against page state.- The implementation resides in
src/driver/waits.tsand is exposed viasrc/helpers.ts, utilizing CDPRuntime.evaluatefor execution. - The polling loop checks conditions every 100 ms by default, configurable via the
pollingoption, and respects atimeoutdeadline. - You can pass arguments to page functions, use string expressions, and extract return values directly from the browser context.
Frequently Asked Questions
What is the default polling interval for waitForFunction?
The default polling interval is 100 milliseconds. You can override this by providing a polling value in the options object, as implemented in the polling loop within src/driver/waits.ts.
How does waitForFunction handle timeouts?
If the evaluated condition does not return a truthy value before the timeout duration elapses (defaulting to state.defaultTimeout), the function resolves to false. The deadline is calculated as state.now() + timeout and checked during each iteration of the polling loop.
Can I pass multiple arguments to the page function?
The current signature supports a single argument via the argOrOptions parameter. For multiple values, wrap them in an array or object and destructure them inside your page function.
What is the difference between waitForFunction and waitForSelector?
waitForSelector waits for a specific DOM element to appear, while waitForFunction evaluates arbitrary JavaScript expressions. Use waitForFunction when you need to check complex conditions like text content, variable state, or computed properties that go beyond element presence.
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 →