Evaluation
evaluate() is the fastest way to inspect or compute page state without extra CDP plumbing.
Import and baseline
Section titled “Import and baseline”import { ChromeWebView } from "webotron";
const view = new ChromeWebView({ headless: true });await view.navigate("https://example.com");await view.waitForDocumentReady({ state: "complete", timeoutMs: 15000 });Default behavior: queued mode
Section titled “Default behavior: queued mode”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.
Non-blocking mode
Section titled “Non-blocking mode”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);Practical patterns
Section titled “Practical patterns”Read computed state
Section titled “Read computed state”const state = await view.evaluate<{ path: string; active: number }>(` ({ path: location.pathname, active: document.querySelectorAll('.item.active').length })`);Trigger and verify behavior
Section titled “Trigger and verify behavior”await view.evaluate(` const button = document.querySelector("#refresh"); if (button) button.click();`);
await view.waitForElement(".refresh-complete", { strategy: "observer", timeoutMs: 8000 });Use evaluation with waits
Section titled “Use evaluation with waits”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() ?? "", }; })()`);Error handling
Section titled “Error handling”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.
Best practices
Section titled “Best practices”- 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
waitForDocumentReadyandwaitForElementwithevaluatefor deterministic flows.