Skip to content

Full Workflow

This guide combines navigation, waiting, evaluation, observability, and capture into one repeatable script.

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]
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();
}
  • Initializes observability before navigation to capture early failures.
  • Uses readiness waits (waitForDocumentReady, waitForElement) instead of fixed delays.
  • Uses evaluate to snapshot state at deterministic checkpoints.
  • Produces visual artifacts (screenshots) for debugging and regressions.
  • Cleans up plugins and browser instance in a finally block.
  • CI mode: set headless: true and 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.