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:
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.
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:
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:
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:
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.
Carry a value between steps
readValue puts the contents of an input into a variable that later steps can read:
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:
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:
setup:
- wait: { css: '.order-row' }
comment: the list has settled, so the row can be measured Related
- Steps reference
- Queries reference
- Share setup between recipes
- Why recipes cannot run code, if the step you want does not exist