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

DSL reference

For the complete documentation index, see llms.txt

Scenarios are plain .js on a sandboxed engine. The vocabulary mirrors Playwright, so it reads the way you expect. Every executable step lives inside step("intent", () => { ... }).

Drive the page: load URLs, go back/forward, and wait for state.

  • goto(url, { waitUntil?, timeout? }) — Navigate to a URL. waitUntil: ‘load’ | ‘domcontentloaded’ | ‘networkidle’. Relative paths resolve against baseUrl.
  • reload({ waitUntil?, timeout? }) — Reload the current page.
  • goBack({ timeout? }) — Navigate back in history.
  • goForward({ timeout? }) — Navigate forward in history.
  • waitForUrl(pattern, { timeout? }) — Wait until the URL contains pattern (substring match).
  • waitForNavigation({ timeout? }) — Wait for the next navigation event.
  • waitFor(locator, { state?, timeout? }) — Wait for an element state: ‘attached’ | ‘visible’ | ‘hidden’.
  • waitForText(text, { timeout? }) — Wait until text appears anywhere on the page.
  • pause(ms) — Explicit delay. Discouraged — the linter wants a // reason: comment. Prefer a waitFor*.

Locators

Build a locator. Prefer the most stable matcher available — see Stable selectors.

  • getByTestId(id) — Match by data-testid. Most stable — prefer this.
  • getByRole(role, { name?, exact? }) — Match by ARIA role + accessible name. name accepts a string or /regex/.
  • getByLabel(text, { exact? }) — Match a form control by its associated label.
  • getByText(text, { exact? }) — Match by visible text content.
  • getByPlaceholder(text, { exact? }) — Match an input by its placeholder.
  • getByAltText(text, { exact? }) — Match an image by its alt text.
  • getByTitle(text, { exact? }) — Match by title attribute.
  • locator(css) — Match by raw CSS selector. Last resort — the linter warns on deep/brittle CSS.

Chain refiners

Narrow a locator. Chains desugar to free calls: getByRole(...).filter(...).first().

  • filter(locator, { hasText?, hasNotText?, has?, hasNot? }) — Keep matches by contained text or a nested child locator.
  • first(locator) — First match.
  • last(locator) — Last match.
  • nth(locator, index) — The N-th match (0-indexed). Index-only refinement is fragile (linter info).
  • contentFrame(locator) — Resolve an <iframe> element to its content frame.

Actions

Interact with elements. Every action takes an options object; e.g. { force: true }.

  • click(locator, { force?, timeout?, noWaitAfter? }) — Click an element.
  • doubleClick(locator, { force?, timeout? }) — Double-click an element.
  • fill(locator, value, { timeout?, noWaitAfter? }) — Clear and type a value into an input.
  • press(locator, key, { delay?, timeout? }) — Press a key (e.g. ‘Enter’, ‘Control+A’).
  • check(locator, { force?, timeout? }) — Check a checkbox/radio.
  • uncheck(locator, { force?, timeout? }) — Uncheck a checkbox.
  • hover(locator, { force?, timeout? }) — Hover over an element.
  • selectOption(locator, value, { timeout? }) — Select option(s) in a <select>. value is a string or string[].
  • scrollIntoView(locator) — Scroll an element into the viewport.
  • dragAndDrop(from, to, { force?, timeout? }) — Drag one element onto another. Uses synthetic mouse events (not native HTML5 DragEvent).
  • uploadFile(locator, files) — Set files on a file input. files is a path or path[].
  • clipboardPaste(locator, text) — Paste text. Synthetic, not a native ClipboardEvent.

Assertions

Polling assertions (default timeout 5000ms). Assertion failures never retry.

  • assertText(locator, expected, { exact?, timeout? }) — Element’s text equals/contains expected.
  • assertVisible(locator, { timeout? }) — Element is visible.
  • assertHidden(locator, { timeout? }) — Element is hidden or detached.
  • assertValue(locator, expected, { timeout? }) — Input’s value equals expected.
  • assertCount(locator, expected, { timeout? }) — Number of matches equals expected.
  • assertUrl(pattern, { timeout? }) — Current URL contains pattern.
  • assertTrue(condition, message?) — Assert a boolean condition.

Queries

Read values (non-polling). Use to branch logic in plain JS.

  • count(locator) → number — Number of matching elements.
  • textContent(locator) → string — Text content ("" if none).
  • inputValue(locator) → string — Current input value.
  • isVisible(locator) → boolean — Whether the element is visible.
  • getAttribute(locator, name) → string — Attribute value ("" if missing).
  • getInnerText(locator) → string — Rendered inner text.
  • getInputValue(locator) → string — Input value (alias of inputValue).
  • getTitle() → string — Document title of the active page.
  • getUrl() → string — URL of the active page.

Storage & cookies

Read/write localStorage and cookies for setup and assertions.

  • setLocalStorage(key, value) — Set a localStorage item.
  • getLocalStorage(key) → string — Read a localStorage item ("" if missing).
  • setCookie(name, value, options?) — Set a cookie (options: path, domain, expires, httpOnly, secure, sameSite).
  • getCookie(name) → string — Read a cookie value ("" if missing).

Multi-tab & iframes

Work across tabs and nested frames.

  • setPage(index) — Switch the active tab/page by index (0-based).
  • enterFrame(locator) — Scope subsequent calls to an iframe (persists until exitFrame).
  • exitFrame() — Exit the innermost iframe scope.

Setup & data (sandbox)

Seed and verify state. Connection details are pinned in config — scenarios cannot redirect them.

  • dbQuery(sql, ...params) → rows[] — Parameterized SELECT. Dialect from the config database URL (postgres/mysql/sqlite).
  • dbExec(sql, ...params) → number — Parameterized INSERT/UPDATE/DELETE. Returns affected row count.
  • apiCall(method, path, body?, headers?) → { status, body, headers } — HTTP call. path is relative — base is the config apiBaseUrl.
  • shell(cmd, ...args) → { stdout, stderr, code } — Run a binary (execFile, no shell interpretation). cwd from config shellCwd.

Structure & escape hatch

The required step wrapper, logging, and the raw-JS escape hatch.

  • step(label, () => { ... }) — Required around every executable step in a test_* function. label is the human-readable intent the agent reads to repair the step.
  • log(...args) — Write to the run trace.
  • evaluate(js, ...args) → any — Run raw JS in the page context. Last resort — prefer typed helpers. Returns JSON-serializable values only.

Not supported

  • Comparison/logical operators in DSL conditions (== != < <= > >= && ||) — use bare truthy variables.
  • Control-flow keywords are plain JS around steps, not DSL primitives.
  • Regex literals are allowed in matcher args, ES5 flags only (g i m); s u y d, named groups and lookbehind are rejected at parse time.
  • waitForPage() is not shipped yet — use pause(ms) with a // reason: comment for tab races.