This is the contract for writing good scenarios — the same guidance shipped with
the package at node_modules/@unotest/web/guides/agent-integration.md. Point your
agent here.
Structure
- One scenario file per feature, in a subfolder of
unotest/e2e/(not its root). - Export
test_*functions. - Wrap every executable step in
step("intent", () => { … }). The label is the human-readable intent; keep it specific. - Factor repeated journeys into
flow_*helpers; seed data withdbExec/apiCall/shellmocks.
Selectors
Use the most stable matcher available:
getByTestId → getByRole(name) → getByLabel → getByText → locator(css)Refine with filter({ hasText }) before first(). Avoid index-only nth(),
deep CSS, XPath, and hashed class names — the linter flags them.
Waiting
Prefer waitFor / assert* (which poll) over pause(ms). If you must pause,
add a // reason: comment.
Variables
Reference secrets and config by bare UPPER_SNAKE identifiers — never hardcode
credentials, never use {{mustache}}.
The repair loop
On failure: call inspect_runtime, read the failure bundle, classify the cause
(rewrite-selector / add-waitfor / change-assertion), produce a diff, and
hand it to the human. Do not apply patches silently.
Verify before finishing
Run the scenario (run_test) and confirm it passes. Lint it
(npx @unotest/web lint). The result must be clean, readable .js.