Skip to content

Evaluation

evaluate() is the fastest way to inspect or compute page state without extra CDP plumbing.

import { ChromeWebView } from "webotron";
const view = new ChromeWebView({ headless: true });
await view.navigate("https://example.com");
await view.waitForDocumentReady({ state: "complete", timeoutMs: 15000 });

By default, evaluation uses mode: "queued", which serializes concurrent calls.

const title = await view.evaluate<string>("document.title");
const ready = await view.evaluate<string>("document.readyState");

Use queued mode when evaluations may interact with shared mutable page state.

Use mode: "non-blocking" only when a call is independent and you do not want it to wait behind queued evaluations.

const metricsPromise = view.evaluate<{ nodes: number }>(
"({ nodes: document.querySelectorAll('*').length })",
{ mode: "non-blocking" },
);
const primaryResultPromise = view.evaluate<string>("document.title");
const [metrics, title] = await Promise.all([metricsPromise, primaryResultPromise]);
console.log(metrics.nodes, title);
const state = await view.evaluate<{ path: string; active: number }>(`
({
path: location.pathname,
active: document.querySelectorAll('.item.active').length
})
`);
await view.evaluate(`
const button = document.querySelector("#refresh");
if (button) button.click();
`);
await view.waitForElement(".refresh-complete", { strategy: "observer", timeoutMs: 8000 });
await view.waitForElement("#profile", { strategy: "observer", timeoutMs: 10000 });
const profile = await view.evaluate<{ name: string; email: string }>(`
(() => {
const root = document.querySelector('#profile');
return {
name: root?.querySelector('[data-field="name"]')?.textContent?.trim() ?? "",
email: root?.querySelector('[data-field="email"]')?.textContent?.trim() ?? "",
};
})()
`);
try {
const value = await view.evaluate<number>("window.__appVersion.major");
console.log(value);
} catch (error) {
console.error("Evaluation failed", error);
}

Pair this with the Debugging and Observability guide when tracking runtime script failures.

  • Keep evaluation snippets focused and short.
  • Return plain serializable data when possible.
  • Prefer queued mode unless non-blocking execution is explicitly needed.
  • Avoid large DOM traversals in tight loops.
  • Combine waitForDocumentReady and waitForElement with evaluate for deterministic flows.