// SPDX-License-Identifier: Apache-2.0 // Record a checkout, keep the evidence, then replay it later without an LLM. // // 1. Record the fixture's checkout form being filled and submitted (every step gets a screenshot). // 2. Save the run report (one self-contained HTML file that opens offline) and JUnit XML for CI. // 3. Turn the recording into a replay script (ranked locators per element), save it as JSON. // 4. Replay the script: no model, no snapshot reading; each step is found again by its locators. // // export WEBPILOT_URL=http://localhost:8931 WEBPILOT_TOKEN=cbu_... // python examples/fixture_site.py & // node record_and_replay.ts # writes checkout-report.html, .xml, .replay.json import { readFileSync, writeFileSync } from "node:fs"; import { WebPilot } from "webpilot-si"; const FIXTURE = process.env["WEBPILOT_FIXTURE"] ?? "http://host.docker.internal:8765"; const wp = new WebPilot(); const tab = await wp.open(`${FIXTURE}/checkout`, { mode: "act" }); try { let rec = await tab.startRecording(); const snap = await tab.snapshot(); await tab.fillForm({ [snap.first("Email").ref]: "ann@example.com", [snap.first("Full name").ref]: "Ann Example" }); await tab.fill(snap.first("Country").ref, "Slovenia"); await tab.click(snap.first("Place order", { role: "button" }).ref); console.log("page says:", (await tab.readText()).trim().split("\n").at(-1)); rec = await wp.recordings.stop(rec.id); console.log(`recording ${rec.id}: ${rec.steps} steps, result ${rec.result ?? "n/a"}`); writeFileSync("checkout-report.html", await wp.recordings.reportHtml(rec.id)); writeFileSync("checkout-report.xml", await wp.recordings.junit(rec.id)); const script = await wp.recordings.script(rec.id, "Checkout"); writeFileSync("checkout.replay.json", JSON.stringify(script, null, 2)); console.log("saved checkout-report.html, checkout-report.xml and checkout.replay.json"); } finally { await tab.close(); } // Later (another day, another process): replay from the saved script. A new act tab opens at its start_url. const saved = JSON.parse(readFileSync("checkout.replay.json", "utf8")) as Record; const run = await wp.replays.run(saved, { mode: "strict" }); // "heal" also tries the weaker locators and partial text console.log(`replay ${run.id}: ${run.status}`); for (const step of run.steps) console.log(` ${String(step.index).padStart(2)} ${step.action.padEnd(9)} ${step.status.padEnd(7)} ${step.duration_ms} ms`); if (run.failure) console.log("failed:", JSON.stringify(run.failure)); await (await wp.tab(run.tab_id)).close();