Full Workflow
This guide combines navigation, waiting, evaluation, observability, and capture into one repeatable script.
Workflow visualization
Section titled “Workflow visualization”flowchart TD A[Create ChromeWebView] --> B[Start observability plugins] B --> C[Navigate + waitForDocumentReady] C --> D[waitForElement critical UI] D --> E[evaluate page state] E --> F[Perform input actions] F --> G[Capture screenshot] G --> H[Collect logs and stop plugins] H --> I[Close view]End-to-end example
Section titled “End-to-end example”import { mkdirSync } from "node:fs";import { join } from "node:path";import { ChromeWebView } from "webotron";import { startConsoleMonitor } from "webotron/plugins/console-monitor";import { createErrorPlugin } from "webotron/plugins/error";
const outDir = join(process.cwd(), "output", "full-workflow");mkdirSync(outDir, { recursive: true });
const view = new ChromeWebView({ headless: false, windowSize: { width: 1440, height: 900 },});
const consoleEvents: string[] = [];
const consoleMonitor = await startConsoleMonitor(view, { onEntry(entry) { const line = `[console:${entry.level}] ${entry.message}`; consoleEvents.push(line); console.log(line); },});
const errorPlugin = createErrorPlugin({ target: view, onException(exception) { console.error("[runtime-exception]", exception); },});
await errorPlugin.enable();
try { await view.navigate("https://example.com"); await view.waitForDocumentReady({ state: "complete", timeoutMs: 15000 });
await view.waitForElement("h1", { strategy: "observer", observerMode: "shared", sharedObserverTtlMs: 10000, timeoutMs: 8000, });
const page = await view.evaluate<{ title: string; href: string }>(` ({ title: document.title, href: location.href, }) `);
console.log("Page snapshot", page);
await view.scroll(0, 300); await view.press("Tab");
const screenshotBase64 = await view.captureViewport({ format: "png", encoding: "base64", });
console.log("Captured screenshot bytes (base64 length)", String(screenshotBase64).length);
console.log("Captured screenshot bytes", String(screenshotBase64).length);} finally { await consoleMonitor.stop(); await errorPlugin.disable(); await view.close();}Why this pattern works
Section titled “Why this pattern works”- Initializes observability before navigation to capture early failures.
- Uses readiness waits (
waitForDocumentReady,waitForElement) instead of fixed delays. - Uses
evaluateto snapshot state at deterministic checkpoints. - Produces visual artifacts (screenshots) for debugging and regressions.
- Cleans up plugins and browser instance in a
finallyblock.
Variants
Section titled “Variants”- CI mode: set
headless: trueand persist logs/artifacts per test case. - Fast smoke mode: reduce timeouts and skip optional capture steps.
- Deep diagnostics mode: combine this flow with debugger plugin breakpoints.