# Steps

The actions a step can take and the keys every step accepts.

A step is an object with exactly one action key, plus any of the common keys below. `when` and `loop_until` are control steps that hold steps of their own.

## Actions

| Action | Type | Description |
|---|---|---|
| [`fill`](https://docs.kaab.ist/reference/dsl/actions/fill) | `target` | Types a value into a field. The target must be visible and editable; values typed into `type=password` fields are redacted. |
| [`click`](https://docs.kaab.ist/reference/dsl/actions/click) | `target` | Clicks an element once it is visible, enabled and not covered; an obstacle in the way is handled by the obstacle layer first. |
| [`press`](https://docs.kaab.ist/reference/dsl/actions/press) | `string` | Presses a key, named as Playwright names keys (`Enter`, `Tab`, `Control+A`). |
| [`hover`](https://docs.kaab.ist/reference/dsl/actions/hover) | `target` | Moves the mouse over an element, for menus and tooltips that open on hover. |
| [`select`](https://docs.kaab.ist/reference/dsl/actions/select) | `target` | Chooses an option of a native `<select>` element, by exactly one of `value`, `label` or `index` (lint `E001` otherwise). |
| [`check`](https://docs.kaab.ist/reference/dsl/actions/check) | `target` | Checks a checkbox or selects a radio button. |
| [`uncheck`](https://docs.kaab.ist/reference/dsl/actions/uncheck) | `target` | Unchecks a checkbox. |
| [`upload`](https://docs.kaab.ist/reference/dsl/actions/upload) | `target` | Sets the files of a file input from your organisation's uploaded assets. |
| [`scroll`](https://docs.kaab.ist/reference/dsl/actions/scroll) | `target or object` | Scrolls an element into view when given a target, or scrolls the page with the object form, for infinite-scroll lists. The object form needs `to` or `until`. |
| [`wait_for`](https://docs.kaab.ist/reference/dsl/actions/wait-for) | `condition` | Waits until a condition holds, up to the step's `timeout_ms`, without doing anything else. |
| [`set_session`](https://docs.kaab.ist/reference/dsl/actions/set-session) | `string` | Loads the named session's storage state at this point in the program. Rarely needed; prefer `options.session`. |
| [`extract`](https://docs.kaab.ist/reference/dsl/actions/extract) | `extract` | Reads data from the page with an extract schema. The last extract into `data` produces the job's result; several merge shallowly, later keys winning. |
| [`capture_response`](https://docs.kaab.ist/reference/dsl/actions/capture-response) | `object` | Waits for a network response matching `url` (and `method`), observed since the step started, and stores its parsed JSON body in a variable. Bodies are limited to 2 MB. |
| [`evaluate`](https://docs.kaab.ist/reference/dsl/actions/evaluate) | `object` | Runs your own JavaScript in the page. The healer cannot see inside it, so lint warns `W006`, and it requires a paid organisation. |
| [`paginate`](https://docs.kaab.ist/reference/dsl/actions/paginate) | `object` | Runs `extract` on each page, then follows `next`. Top-level `many: true` fields are concatenated across pages and other fields come from the first page; it stops at `max_pages`, when `stop_when` holds, when `next` is not found, or when the step's `expect` does not hold after `next`. A page whose extraction fails fails the step on that page; a `next` that breaks after some pages keeps them, with a `pagination_incomplete` warning. |
| [`download`](https://docs.kaab.ist/reference/dsl/actions/download) | `object` | Clicks a trigger, captures the file it downloads and stores it as a job artifact with the response's content type. A PDF passes the [PDF security gate](https://docs.kaab.ist/concepts/documents-and-pdfs) first: a blocked one is never stored, and the step fails with its code. |
| [`read_pdf`](https://docs.kaab.ist/reference/dsl/actions/read-pdf) | `object` | Reads the tables of a PDF the job has stored: the page the job is on when it is a PDF, or a named artifact such as a `download`'s. Cells are returned exactly as printed, as strings; a table that continues over pages is one table. The file already passed the [PDF security gate](https://docs.kaab.ist/concepts/documents-and-pdfs); nothing is fetched again. Lint warns `W010` when no earlier `goto` or `download` could have produced the PDF. |
| [`set_vars`](https://docs.kaab.ist/reference/dsl/actions/set-vars) | `map of string` | Sets variables from templates, as a map of variable name to template; each is readable later as `{{vars.<name>}}`. |
| [`sleep`](https://docs.kaab.ist/reference/dsl/actions/sleep) | `integer` | Pauses for a fixed number of milliseconds, at most `10000`. Lint warns `W003`; a `wait_for` condition is usually better. |
| [`reload`](https://docs.kaab.ist/reference/dsl/actions/reload) | `true` | Reloads the current page. The value is always `true`. |
| [`goto`](https://docs.kaab.ist/reference/dsl/actions/goto) | `string or object` | Navigates the top frame to a URL, given as a template string or an object. It then waits for the page to settle (500 ms of network quiet, at most 10 s); lint warns `W001` without an `expect`. |
| [`await_input`](https://docs.kaab.ist/reference/dsl/actions/await-input) | `string or object` | Pauses the job as `awaiting_input` until a value such as a one-time code is supplied, then stores it in `vars.<name>`. The string form names the input. |
| [`checkpoint`](https://docs.kaab.ist/reference/dsl/actions/checkpoint) | `string or object` | Saves the page URL, variables and browser state so a parked or resumed job can return here. The string form is the checkpoint's name. |
| [`screenshot`](https://docs.kaab.ist/reference/dsl/actions/screenshot) | `string or object` | Takes a screenshot, stored as the artifact `artifacts.<name>`. The string form is the name. |
| [`when`](https://docs.kaab.ist/reference/dsl/actions/when) | `condition` | Runs `do` when a condition holds and `else`, if given, when it does not. |
| [`loop_until`](https://docs.kaab.ist/reference/dsl/actions/loop-until) | `condition` | Repeats `do` until a condition holds. The condition is checked before each iteration; after `max` iterations the job fails with `loop_exhausted` unless the step is `optional`. |

## Common keys

| Key | Type | Description |
|---|---|---|
| `expect` | `condition` | A postcondition that must hold after the action, re-evaluated every 250 ms until `timeout_ms`. When it never holds, Kaabist diagnoses the failure; lint `W001` warns about a `goto` or `click` without one. |
| `id` | `string` | The step's id, matching `^[a-z0-9][a-z0-9-]{0,31}$` and unique within the program (lint `E006`). Assigned as `s<N>` when absent. |
| `if` | `condition` | A guard condition evaluated before the step; when it is false the step is skipped without failing. |
| `name` | `string` | A human-readable label for the step. |
| `on_error` | `"fail" \| "skip" \| "park"` | What happens when the step fails and nothing else recovered it: `fail` (the default), `skip`, or `park`, which stops the job as `needs_attention` with the step's evidence. |
| `optional` | `boolean` | When `true`, a failure of this step is recorded as the warning `step_skipped` and the job continues. Defaults to `false`; not allowed on a `side_effect` step (lint `E011`). |
| `retry` | `object` | How many times a transient failure of this step is retried. Not allowed on a `side_effect` step (lint `E011`). |
| `retry.backoff_ms` | `integer` | The wait between retries in milliseconds, from `0` to `60000`. Defaults to `1000`. |
| `retry.max` | `integer` | The number of retries, from `0` to `5`. |
| `side_effect` | `boolean` | Marks a step that changes something outside the page, such as placing an order. It runs behind a fence: a side effect that was interrupted, or that failed after its action reached the page, parks the job as `side_effect_ambiguous` instead of repeating it; it is never retried, healed or escalated. Defaults to `false`. |
| `timeout_ms` | `integer` | How long the step may take, in milliseconds, up to `900000`. Defaults to `30000`, `60000` for `goto`, and the `ttl` for `await_input`. |
| `x_kaab` | `object` | A free-form object written by tools such as the recorder, takeover and picker, for example `{ "source": "takeover" }`. Lint ignores it and the engine never reads it, but it is kept through normalization, diffs and versions. |
