TaskProof turns a browser task spec into inspectable proof.
Give it a target URL and a JSON or YAML spec. TaskProof runs the flow in Playwright, captures screenshots and DOM after every step, records console errors and failed network activity, evaluates assertions, and emits:
- a machine-readable evidence bundle
- a self-contained static HTML report
- a deterministic rerun command and script
- a zipped archive of the full run
Most browser automation tells you whether a run passed. TaskProof is built to show you what actually happened.
It stays intentionally narrow:
- local-first
- no auth
- no database
- no cloud service
- no paid API
- one clear CLI path
- one strong static report
The repo is set up so the product story is visible immediately:
apps/demo-app: polished bundled target app used for CI and local evaluationdemo/specs: committed task specs against the demo app, including an intentional regression catchexamples/sample-report/README.md: committed real proof bundle with explanationexamples/sample-report/bundle.json: machine-readable source-of-truth evidenceexamples/sample-report/logs/console-events.json: captured console failuresexamples/sample-report/logs/network-events.json: captured failed requests
The canonical sample is deliberate: the spec passes because the UI handles the failing sync path gracefully, while TaskProof still surfaces the failed request and console errors that caused it.
npm install
npx playwright install chromium
npm run demo:evalThen open ./artifacts/demo-eval/report/index.html from disk.
Useful next commands:
npm run demo:app
npm run taskproof -- --help
npm run validate
npm run showcase:refreshnpm run demo:app: runs the bundled demo target onhttp://127.0.0.1:43173npm run validate: runs lint, typecheck, tests, e2e, and buildnpm run showcase:refresh: rebuilds the sample report and README assets
Direct example against the bundled demo:
npm run taskproof -- run \
--url http://127.0.0.1:43173 \
--spec ./demo/specs/diagnostics-sync.yaml \
--out ./artifacts/manual-runExample against your own local app:
npm run taskproof -- run \
--url http://127.0.0.1:3000 \
--spec ./specs/login-smoke.yaml \
--out ./taskproof-runs/login-smokeSupported steps:
clickfillpressnavigatewaitassertTextassertVisibleassertUrlassertCount
Example spec:
name: Diagnostics sync captures backend failure
steps:
- type: click
selector: '[data-testid="view-diagnostics"]'
- type: click
selector: '[data-testid="run-sync"]'
- type: wait
ms: 600
- type: assertText
selector: '[data-testid="sync-status"]'
text: 'Sync failed gracefully.'
match: exactThe committed sample proof lives in examples/sample-report.
- Open
examples/sample-report/report/index.htmllocally to inspect the live report UI. - GitHub will show the HTML source, not the rendered report.
- The raw proof bundle is committed alongside it for inspection and diffing.
The bundled demo app is intentionally real enough to exercise the harness:
- URL-changing views for
assertUrl - deterministic
data-testidhooks - task creation and completion flows
- filter controls and count assertions
- a diagnostics path that intentionally emits failed network and console evidence
<run-output>/
bundle.json
spec.json
rerun.sh
artifacts/
screenshots/
dom/
logs/
console-events.json
network-events.json
report/
index.html
assets/
taskproof-evidence.zip
bundle.json is the source-of-truth artifact. The HTML report is a projection of that bundle for human review.
- TaskProof validates and normalizes the task spec.
- The runner drives the target app with Playwright.
- Every step records timing, assertions, DOM, screenshots, console, and network failures.
- The report generator emits a static self-contained HTML report.
- The full run is zipped for deterministic sharing and reruns.
These are the expected local quality signals:
npm install
npx playwright install chromium
npm run validate
npm run demo:evalGitHub Actions runs the same core path from .github/workflows/ci.yml.
Generated showcase assets live in examples/assets:
taskproof-logo.svgsocial-preview.pngdemo-app.pngreport-overview.pngdemo.gifarchitecture.svg
Refresh them with:
npm run showcase:refreshThat flow expects ffmpeg on your PATH for GIF generation.
MIT


