Skip to content

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

Step keys

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.

A stand-in for the claude command line

{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.

Clone this wiki locally