--- title: "Test a website" description: "Sweep a list of pages in a real browser for load failures, broken links and console errors, and get a screenshot of each." --- The `website-qa-sweep` template visits the pages you list in an isolated Chromium session, screenshots each one, and reports pages that failed to load, broken links and console errors. It is **read only**: it clicks nothing that changes anything, and its preset grants no write capability at all. That makes it the safest Worker to start with, and the one worth pointing at production. ## Create and publish ```bash curl -fsS -X POST "$WS/workers" \ -H "Authorization: Bearer $OBOL_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "site-sweep", "display_name": "Site sweep", "agent_passport_id": "agt_release", "template_id": "website-qa-sweep", "environment_classes": ["browser"], "permission_preset": "read_only", "execution_mode": "balanced" }' ``` ```ts const worker = await obol.workers.findBySlug("site-sweep"); await obol.workers.publishDraft(worker.id); ``` ## Run it ```ts const started = await obol.workers.run("site-sweep", { inputs: { pages: [ "https://www.example.test/", "https://www.example.test/pricing", "https://www.example.test/docs", ], check_links: true, }, }); ``` The template's default allowlist covers Obol's own demo storefront only. Point it at your own site by widening the Worker's `allowed_domains` — a reviewed edit to the draft, published as v2. A page outside the allowlist fails the run with `network_destination_denied` rather than being fetched quietly. ## What you get back A result object with `pages_checked`, `all_pages_loaded`, a per-page array and an `issues` array; one `screenshot` artifact per page; and one `report` artifact summarising the sweep. The run is complete when those validate, not when the model says so. ```ts const view = await obol.workers.getRun(runId); for (const id of view.run.output.artifact_ids) { const artifact = await obol.workers.getArtifact(runId, id); artifact.kind; // "screenshot" | "report" artifact.download_allowed; // an access decision, not a URL artifact.demo; // labelled everywhere it appears } ``` `getArtifact` returns metadata and an access decision — never bytes and never a storage location a caller could reach on its own. `provenance` records who observed the artifact and what the observation is worth: a screenshot of a page is evidence that the page rendered that way for this environment at that moment, and it is not a claim about anything a vendor did. ## Try it against Obol's demo site first `website-qa-sweep` supports demo runs. Its sample input sweeps three pages on Obol's demo storefront, one of which returns a 500 on purpose, so a first run has something real to report. ```bash curl -sS -X POST "$WS/worker-demo-runs" \ -H "Authorization: Bearer $OBOL_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"template_id": "website-qa-sweep"}' ``` No OAuth, no card, and never billed. The run and every artifact it produces are labelled a demo wherever they appear. You do not have to publish a Worker first: if your workspace has none for this template, the route seeds one from the reviewed template, so the demo still runs a pinned revision without you doing the create, read, digest and publish sequence first. ## Watching pages for change instead `competitor-page-watch` is the same shape with a different question: it captures the pages you list, compares them against the last capture, and reports what changed, with `ignore_selectors` for the parts that always move. Also read only, also demo-supported. As of 2026-09-10 a run does not complete end to end. The orchestration service has an image and Compose services now, but the joins that would let it accept a run are still being built, so a start is refused at the hand-off. See [Overview](/workers/overview).