Skip to main content
You write English; Testorim writes steps. This page documents what those steps are, because reading them is the fastest way to understand why a run did what it did, and because a saved test shows them to you.

Actions

Assertion conditions

assert takes a condition from a closed grammar. Anything outside it fails the step with the list of what is supported. It never degrades into “is it visible?”, which is how an enabled button used to satisfy a check for disabled.
Keywords are case-insensitive and tolerate natural wrappers, so “is disabled” and “loads successfully” both parse.

Scope is decided by the target

If the target names a control, meaning a control noun (button, link, field, toggle, dropdown, checkbox…), an identifier (submitBtn, cart_link) or a selector (#total, .toast), the condition is checked against that control and nothing else. A heading elsewhere on the page cannot satisfy it. If the target is page, body, empty, or prose that names no control at all (“the welcome message”), the check widens to the page, keeping the condition exactly as written. A control-scoped text check that fails while the text is somewhere else on the page says so, and is attributed to the test rather than the app.

Asserting something is gone

hidden and absent are the one case where failing to find the element is the point. Testorim runs a dedicated absence probe that searches wider than normal resolution (text split across inline children, accessible names, identity attributes, aria-labelledby, every frame, open shadow roots) and then requires three pieces of evidence before certifying absence: that this target was seen or resolved earlier, on this same page, and that some other element from that page is still there (so a blank, crashed or signed-out render cannot pass). Absence is read twice, half a second apart. If any of that is missing, the step fails and names what was missing. It does not quietly pass because nothing matched.

Step options

Extra checks bolted onto a step

After the step’s UI action, check a request it triggered. Filter by URL substring or glob, optionally by method, and assert an exact status or a bucket (2xx, 4xx…).“Click Sign in and verify POST /api/login returned 200.”
For a step that triggers a download, assert the filename contains something, the content type matches, or the file is at least N bytes. The file is captured either way.“Click Export CSV and check the file is named invoice-something and is over 1 KB.”
assertDb runs a read-only SELECT against a Postgres connection you configured in project settings, inside a read-only transaction. Anything that is not a SELECT is rejected. Assert an exact row count, a minimum row count, or that one cell equals a value.The query text is never echoed back into a report.

Coverage gaps

If you ask for a check and the plan does not contain it, a judge catches it. The planner gets one chance to write the missing check; anything still uncovered becomes a visible skipped step saying so, and the run does not pass. A gap is never inferred to be stricter than you asked. If you said “until a colour is chosen”, a plan that checks both sides of that transition covers it. the judge does not invent a “before any colour is chosen” requirement you never stated.