Repository navigation
Scenarios
Arttu Jantunen edited this page Nov 2, 2026
·
1 revision
A scenario is scenarios/<name>.yaml: what to do, step by step. capture writes them for you while you use the
app (see Getting Started); you can also write and edit them by hand. After a change, run
parityrun record <name>.
description: Sign in, add a note, list it, a refusal.
env: {FEATURE_X: "1"} # on top of env(run); {stub} {repo} {python} {data} {fake_claude} are filled in
files: {settings.json: settings.json} # fixtures copied into the data folder before the start
steps:
- call: GET /login
capture: {csrf: 'name="_token" value="([^"]+)"'}
- call: POST /login
form: {_token: "{{csrf}}", email: ann@example.com, password: secret}
follow: true
- call: POST /notes
id: made # later steps use {{made.id}}
body: {text: "Buy oat milk"}
llm: ["Errands"] # replies the LLM stub gives, in order; {$file: reply.json}; {$http: 429}
- call: GET /jobs/{{made.job}}
until: {path: status, in: [done, failed]} # poll background work; the last answer is compared
timeout: 120
- cli: "export --format md" # the implementation's command line, next to the running service| Key | Meaning |
|---|---|
call: METHOD /path |
the request; {{name[0].id}} takes a value from an earlier step's JSON or a capture |
id |
names this step's JSON for later steps |
body |
JSON; a whole "{{x}}" keeps its type; $merge: "{{x}}" sends x back with keys changed |
form |
a web form (urlencoded); true is a ticked checkbox (on), false leaves the field out |
upload |
{field: fixture}: files sent with form as multipart |
raw: file |
sends fixtures/<file> as the body |
capture |
{name: regex} over the answer's text, or {name: {header: location, regex: ...}}: {{name}} in later steps; values of 8+ characters (tokens) are recorded as <name>
|
follow |
follow redirects to the page they end on (recorded as redirects) |
headers |
request headers (a 206 answer is compared by its range and length) |
llm |
replies for the LLM stub; they wait until asked for, so a background task may take them later |
until, timeout, every
|
repeat until {path, equals / in / not / length} holds |
sse: n |
also listen to the project's events and compare the first n |
ignore |
dotted paths (* = any key) that depend on the machine, not the code |
unordered |
compare a list response without its order |
cli |
run the command line instead of a request: exit code, stdout and stderr are compared |
fn, new, args, as
|
a call into a library instead of a request (see Libraries) |
Quote text with a comma inside {...}: YAML splits it otherwise, and the loader refuses such files.
{fake_claude} in a scenario's env becomes a real executable that stands in for the claude command line
(CLAUDE_BIN: "{fake_claude}"): its arguments and stdin are recorded like any LLM request, and it answers with a
--output-format json envelope.
parityrun is MIT-licensed. Install: pip install parityrun. Issues and source: github.com/arttujan/parityrun.
Start
Porting
Reference
Links