# Capture a page after interaction

Most screenshots worth taking are not of a page as it first loads. This guide drives the page into the state you want before anything is measured or captured.

## Add setup steps

Put the interaction under `setup`. Steps run in order, before `clip` and `marks` are resolved:

screenshots/recipes/order-detail.yaml

```
name: order-detail

setup:
  - click: { role: link, name: Orders }
  - fill: { label: Search }
    value: Acme
  - wait: { css: '.order-row' }

clip: { css: '.order-row', contains: Acme Corp, pad: 20 }
```

Each step is a mapping led by one verb. Some verbs take a second key alongside: `fill` takes `value`, `select` takes `option`, and `press` and `type` take `on`. The full list is in the [steps reference](/docs/reference/steps/).

## Wait for the right thing

`wait` accepts either a number of milliseconds or a query. Prefer the query: it finishes as soon as the element exists, and it fails loudly if the element never arrives, where a fixed wait silently captures a half-rendered page.

If the page needs a moment to settle after the element appears, set `site.settle` in your configuration rather than adding fixed waits to every recipe.

## Handle something that may not be there

A consent banner that appears only on a fresh browser profile will break a recipe that always clicks it. Wrap those steps in `optional`, which ignores failures:

screenshots/recipes/order-detail.yaml

```
setup:
  - optional:
      - click: { role: button, name: Accept cookies }
  - click: { role: link, name: Orders }
```

## Get past a confirm the browser draws

`alert`, `confirm` and `prompt` are drawn by the browser rather than by the page, so no query reaches one and no click closes one. Left alone they are dismissed, which means a click on a control guarded by `confirm()` quietly takes the cancel branch and the shot is of the page that never changed. Say what to do with them before the step that raises one:

screenshots/recipes/order-detail.yaml

```
setup:
  - dialog: accept
  - click: { role: button, name: Delete }
  - wait: { text: Order deleted }
  - dialog: dismiss
```

The setting holds until another `dialog` step replaces it, so a recipe that accepts one dialog and dismisses the next writes both. `dialog: accept` takes a `value`, which is what a `prompt()` is answered with.

This is the failure that looks like a working recipe: nothing errors, and the screenshot is of the wrong state. A shot that comes back as though the click did nothing is the first place to check.

## Repeat a step

Use `repeat` when the same interaction has to happen several times:

screenshots/recipes/order-list.yaml

```
setup:
  - click: { role: link, name: Orders }
  - repeat: 3
    steps:
      - click: { role: button, name: Load more }
      - wait: 250
```

`repeat` is capped at 1000 iterations. To run steps once per item in a list instead, use `each` — see [Share setup between recipes](/docs/how-to/share-setup/).

## Carry a value between steps

`readValue` puts the contents of an input into a variable that later steps can read:

screenshots/recipes/refund.yaml

```
setup:
  - readValue: { label: Order total }
    as: total
  - fill: { label: Refund amount }
    value: $total
```

Variables are substituted in steps only. A `$total` written in `callouts` or `marks` is treated as literal text.

## Capture a page that opens in a new tab

Open the second page explicitly, give it a name, and switch to it:

screenshots/recipes/invoice.yaml

```
setup:
  - openPage: /orders/1042/invoice
    as: invoice
    viewport: { width: 800, height: 1200 }
  - usePage: invoice
```

Every step after `usePage` drives that page, and so does the capture.

## Leave a note for the next reader

Any step accepts `comment`, which is ignored at run time. It rides alongside a verb rather than being one, so a comment cannot be a step on its own:

screenshots/recipes/order-detail.yaml

```
setup:
  - wait: { css: '.order-row' }
    comment: the list has settled, so the row can be measured
```

## Related

- [Steps reference](/docs/reference/steps/)
- [Queries reference](/docs/reference/queries/)
- [Share setup between recipes](/docs/how-to/share-setup/)
- [Why recipes cannot run code](/docs/explanation/no-code/), if the step you want does not exist

Written by Nicola Mustone · Applies to shotlist 0.6.0 · Maintained by Nicola Mustone

Published date unavailable · Updated date unavailable · [View source](https://github.com/SirDarcanos/shotlist.dev/blob/main/src/pages/docs/how-to/drive-a-page.astro) · [Propose a correction](https://github.com/SirDarcanos/shotlist.dev/edit/main/src/pages/docs/how-to/drive-a-page.astro)
