This documentation is available as Markdown. For the complete index, see llms.txt. Skip to content

Running tests

For the complete documentation index, see llms.txt

Run a scenario

Open a scenario and click Run (headless) or Debug (visible browser + pause on breakpoints and failure). A run tab opens immediately and updates live.

Live streaming

Results stream over WebSocket as each step executes — no waiting for the whole run to finish. Step status updates in place: pending → running → passed/failed.

Block view

The scenario renders as a block view: each step("…") is a foldable group, each DSL call a row with a status icon, line number and duration. Fold a step to see intent; unfold to see the calls.

Trace: the execution tree

The run header offers three views: Steps (the test’s source, with the run projected onto it), Trace (since 0.31.0) and Code. Trace is built from the run journal alone and follows what actually ran: a statement that calls a helper opens into the helper’s own statements and step(...) blocks (the file is named at the right of the row), a loop opens into one group per iteration — including an iteration that ran no statement — and a step(...) block into its envelope with its tag and duration. Helper calls and passed iterations start folded with a summary (“10 iterations · 1 failed”); the failed branch is open down to the failing statement, which carries the error card. Double-click a row to open its file at that line in Code — a helper file too. Notes, log lines and verdicts sit under the statement that produced them, as in Steps; screenshots open from the row, helper-frame captures included. The view you pick is remembered; a debug session always opens in Code. Runs recorded before 0.31.0 have no iteration markers: a loop body then reads flat under the loop. The inspector’s flat event list is the Events tab.

Notes, log lines and verdicts

A step that called note(label, value), log(...) or assertJudge(...) shows an ⓘ N chip on its row (since 0.31.0). Click it to open the list under the step: notes as label → value, log lines, and the judge’s verdict as judge ✓/✗ · rubric · text. The list opens by itself under a failed step and under a verdict that said no; what you open or close is remembered per scenario and step. A failed judge step’s error card carries the whole verdict — rubric, judged text, reasoning, model. After the run, the System pane lists the scenario’s log(...) lines with their time.

Step screenshots

With UNOTEST_STEP_SCREENSHOTS=1 the runner captures a PNG after every step (details). Step rows with a capture show a camera icon — click to open the frame full-screen and step through the run visually. screenshot() DSL captures appear the same way.

Error cards

When a step fails, an inline error card pins to the offending line — the error class, message, and the file:line source snippet — so you see exactly what broke without scrolling away.

Collections

Run a whole collection from its view. You get a per-scenario status list, a progress bar, and a one-click abort that stops all in-flight scenarios.

The run queue

Runs of one project and environment go through a queue, so a run started from the CLI, from the Run button and by an agent cannot drive the same browser and the same seeded database at once. The queue serialises runs, not scenarios: a collection’s workers still run in parallel under their parent’s slot. queue.concurrency in unotest.config sets how many runs may be in flight for one environment (1 by default — strict FIFO); queue.enabled: false turns the queue off for the project, UNOTEST_NO_QUEUE=1 for a single command. A CLI run that has to wait says so (queued behind N run(s) — waiting for a free slot), and Ctrl-C gives up its place in line. The Active section lists the runs waiting for a slot (queued · 1/1 slot busy), each with the kind of producer that queued it (cli, viewer, an agent) and since when, with a ✕ that takes a run out of the queue.

Schedule…

Right-click a scenario or a collection → Schedule… (once set, the item reads Schedule · daily at 03:00, Schedule · every 5 min, Schedule · hourly at :30, Schedule · Mon, Wed at 03:00 and the like). The popup is a small builder, not a cron field: pick a frequency — not set, every 5 minutesevery 12 hours, every day, every week — and the minutes, hours and days it applies to, optionally an env. Under it a caption shows the next tick and the cron it produces: next: tomorrow 03:00 · your clock cron: 0 3 * * *. The time is your browser’s clock; the box that executes the schedule usually ticks in UTC. Saving writes unotest/schedules.yaml; an entry declared in unotest.config is shown read-only (Declared in unotest.config — edit it there), and on a deployed tree (a box) every schedule is read-only. On Home, flip last run | schedule: tiles are tinted by frequency (brighter = more often, grey = not scheduled), the counters become scenarios / scheduled / no schedule filters, and an upcoming list orders the next ticks on your clock. Nothing in the viewer ticks — the schedules are declarations for the box or the CI that hosts your runs.