Guides
Script steps
A script step runs a program you wrote, in your own Node or Python, and reads back what it
reports. Use one when a check needs a loop, a client library, or a flow that a plan cannot express;
keep everything else in plain http, sql and exec steps, where vero can see and time each request.
- script:
runtime: node # node, or python (python3 is tried before python)
entry: ./scripts/checkout.mjs
input: { baseUrl: "{{ env.baseUrl }}", apiKey: "node-{{ run.id }}" }
timeout: 30s
assert: [ok == true, result.total == 2000]
results: { orderId: result.orderId }
Writing one
The whole protocol is in vero.script/v1. In short:
- Read one JSON line from stdin:
{"protocol":"vero.script/v1","input":{...},"deadline":"..."}.inputis the step'sinputwith templates rendered; it is the only thing from the run you see. - Write events to stdout, one JSON object per line:
{"type":"log","level":"info","msg":"..."}for anything worth reading later;{"type":"step","name":"...","status":"passed","durationMs":12}for each thing you checked;{"type":"result","ok":true,"result":{...}}last.okandresultare what the plan's assertions see.
- Exit 0. stderr is kept as log lines. A non-zero exit code makes the step
errored, result event or not;ok: falsemakes itfailed.
Report steps. A script that returns ok: true without a single step event is reported as
passed (unverified): vero cannot tell whether it checked three things or nothing. Both examples
here emit one step per request.
The examples
First build and start the fixture. The
example prerequisites cover both runtimes and other plans. The combined
examples/scripts.yaml needs Node with global fetch and Python 3 on PATH.
The scripts live in examples/scripts/.
checkout.mjs: Node,fetchonly, nopackage.json.checkout.py: Python,urllib.requestonly, no packages.examples/scripts.yaml: runs both againstvero-testserverand verifies the Node script's order with an http step that reads the id through a derived edge.- A browser through the script step: the same checkout through a real browser, with Playwright from npm. It needs installs the two above do not.
In Terminal 1 at the checkout root, run the fixture in the foreground:
bin/vero-testserver
In Terminal 2 at the checkout root:
bin/vero run examples/scripts.yaml
The child receives PATH, HOME, and LANG from the parent environment, not arbitrary parent
variables, plus VERO_SCRIPT_TOKEN, a value unique to the step that vero uses to find a process
that outlived it. The fixture address reaches the scripts via plan input ({{ env.baseUrl }}), not a
constant in the script. Pass configuration explicitly through input to retarget a script.
Secrets you pass in input are scrubbed from the script's events and stderr, not from anything it
writes to disk. An exec or script step runs with your privileges and is not a sandbox.
This page is docs/content/guides/script-steps.md in the repository.