# 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 & python examples/python/record_and_replay.py # writes checkout-report.html, .xml, .replay.json """ from __future__ import annotations import json import os from webpilot import WebPilot FIXTURE = os.environ.get("WEBPILOT_FIXTURE", "http://host.docker.internal:8765") with WebPilot() as wp: tab = wp.open(f"{FIXTURE}/checkout", mode="act") try: rec = tab.start_recording() snap = tab.snapshot() tab.fill_form({snap.first("Email").ref: "ann@example.com", snap.first("Full name").ref: "Ann Example"}) tab.fill(snap.first("Country").ref, "Slovenia") tab.click(snap.first("Place order", role="button").ref) print("page says:", tab.read_text().strip().splitlines()[-1]) rec = wp.recordings.stop(rec.id) print(f"recording {rec.id}: {rec.steps} steps, result {rec.result or 'n/a'}") with open("checkout-report.html", "w", encoding="utf-8") as f: f.write(wp.recordings.report_html(rec.id)) with open("checkout-report.xml", "w", encoding="utf-8") as f: f.write(wp.recordings.junit(rec.id)) script = wp.recordings.script(rec.id, name="Checkout") with open("checkout.replay.json", "w", encoding="utf-8") as f: json.dump(script.to_dict(), f, indent=2) print("saved checkout-report.html, checkout-report.xml and checkout.replay.json") finally: tab.close() # Later (another day, another process): replay from the saved script. A new act tab opens at its start_url. with open("checkout.replay.json", encoding="utf-8") as f: saved = json.load(f) run = wp.replays.run(saved, mode="strict") # "heal" also tries the weaker locators and partial text print(f"replay {run.id}: {run.status}") for step in run.steps: print(f" {step.index:>2} {step.action:<9} {step.status:<7} {step.duration_ms} ms") if run.failure: print("failed:", run.failure.to_dict()) wp.tab(run.tab_id).close()