The linter keeps scenarios robust — stable selectors, no silent waits. Override any rule under linter.rules in your config ("off" | "warn" | "error"). Silence a single justified warning with a trailing // lint-ok: <reason> on its line — the reason is required, and error-severity diagnostics are never suppressible.
| Rule | Default | Purpose |
|---|---|---|
lint:deep-css | warn | Reject deep / brittle CSS selectors. Prefer role/label/testid. |
lint:xpath | warn | Reject XPath selectors. |
lint:obfuscated-class | warn | Reject hashed class names (Tailwind JIT, CSS Modules). |
lint:pause-explicit | warn | Discourage pause(ms). Silence a justified one with // lint-ok: <reason>. |
lint:disambig-by-index | off | Flag index-only refinement (.nth) as fragile (info). |
lint:evaluate-discouraged | warn | Discourage bare evaluate() — prefer typed helpers. |
lint:scenario-in-root | error | Scenarios must live in a feature subfolder, not the e2e root. |
lint:mustache-in-dsl | error | No {{VAR}} string literals — reference bare identifiers. |
lint:goto-concat | warn | goto(BASE_URL + ‘/x’) → write goto(‘/x’); the base comes from the environment. |
lint:regex-invalid | error | Regex literal that does not compile. |
lint:echo-assert | warn | waitForText/assertText overlaps a value the scenario itself filled — the assert can match your own message (chat echo trap). |
lint:api-call-file-body | warn | A JSON apiCall body with a file key sends the value as a string — no file is attached. Pass upload(...) as the body for a real multipart upload. |
lint:lint-ok-missing-reason | warn | Bare // lint-ok without a reason — suppresses nothing. |
lint:flow-returns-value | warn | A flow_* helper returns a value. Legitimate when the flow acts and yields its result (email = flow_signup()); if it only reads state, rename it to a plain snake_case helper — flow_* is an executable entry the agent may replay. |
lint:legacy-layout | warn | unotest.config.* still sits at the project root (pre-0.28 layout), where nothing reads it. lint grades the suite on default settings and says so once; e2e / collection / bundle push refuse until the config is moved. |
lint:external-variable-undeclared | error | A bare UPPER_SNAKE identifier that no layer file declares (unotest/.env, .secrets, the active --env overlay). It would fail at that statement at run time; the message lists the files searched. The shell is not a declaration — NAME= with no value in unotest/.env declares a name the shell provides. |
lint:one-test-per-file | warn | A second test_* in one scenario file. The file is the unit a collection runs and the viewer shows (Steps projects the run onto the first test_*); iterate cases inside one test with step("…", {tag: id}, …) or move journeys to _helpers/. Warning in 0.31, error in a later release. |
validator:unknown-function | error | Unknown DSL function (typo, unsupported call). |
validator:arity | error | Wrong number of arguments for a DSL function. |
validator:arg-kind | error | Argument of the wrong kind (locator where a string is required, and so on). |
validator:step-coverage | error | A test_* entry function with executable statements outside step("…", () => { … }). |
validator:step-shape | error | Malformed step(...) — the label must be a string literal and the body an arrow function. |
validator:meta-shape | error | Malformed scenario metadata block. |
validator:function-shape | error | Malformed function declaration in a scenario or helper. |
validator:for-shape | error | Unsupported for form — iterate with the supported shape. |
validator:if-shape | error | Unsupported if form. |
validator:var-shape | error | Unsupported variable declaration. |
validator:unsupported-statement | error | Statement the DSL engine does not execute (try, while, class, …). |
validator:unsupported-expression | error | Expression the DSL engine does not evaluate. |
validator:string-concat | error | Literal-free string addition (a + b between string variables) — use textJoin([...]). |
validator:semantic-loss | error | A construct that would silently change meaning when executed. |
validator:list-arg | error | Malformed list argument. |
validator:wrapped-format | error | Malformed wrapped/format call. |