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. A page-wide check reads what a person sees: visible text inside the page, with advertisements left out.

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). It 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. This way a blank, crashed or signed-out render cannot pass. Absence is read twice, half a second apart. The “seen earlier” evidence can come from an earlier step that found the target, or from the page having shown it earlier in the run, so “remove the item, then check it is gone” works without an extra step. If any of that is missing, the step names what was missing. It does not quietly pass because nothing matched. When Testorim’s own plan wrote the check, the run is marked Needs review rather than Failed.

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 → Databases, inside a read-only transaction. Anything that is not a SELECT is rejected, and so is any dblink call. 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 is marked Needs review, never Passed. A gap can still be settled during the run when a step’s own reading answers it, such as a count that shows the number you asked about. A plan holds up to 40 steps. The gap step says whether the plan ran out of room, simply missed the check, or was asked for something a browser cannot observe. 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.