Skip to content

Macros and data

Setup shared between recipes goes in paths.macros, one file per macro. The filename is its name.

screenshots/macros/sign-in.yaml
defaults:
  who: [email protected]
steps:
  - fill: { label: Email }
    value: $who
  - click: { role: button, name: Sign in }
screenshots/recipes/dashboard.yaml
setup:
  - use: sign-in
  - use: sign-in
    with: { who: [email protected] }

Data files

Files in paths.data are in scope by filename: screenshots/data/orders.yaml is $orders, and each: $orders iterates it.

screenshots/recipes/orders.yaml
setup:
  - each: $orders
    as: order
    steps:
      - click: { text: '${order.name}' }

each also takes the list itself, for the handful of values not worth a file.

screenshots/recipes/searches.yaml
setup:
  - each: [Acme Corp, Globex, Initech]
    as: customer
    steps:
      - fill: { label: Search }
        value: $customer
      - click: { role: button, name: Search }

The filename becomes a $name, so keep it to letters, digits and underscores — a $ reference stops at a hyphen, and open-orders.yaml cannot be reached. Group what would have been several hyphenated files into one and read them by path: $orders.open, $orders.shipped.

Writing a reference

$name and ${name} are the same thing, and $a.b reads a path into whatever $a holds. The braces matter in one place: where the reference runs into text that would otherwise be read as part of the name. A name runs on through letters, digits, underscores and dots, so Order $order.name. looks for a path ending in a dot and Order ${order.name}. does not.

A reference that is the whole value keeps that value's type. each: $orders gets the list, not a rendering of one. A reference sitting inside a longer string becomes text, because that is all a string can hold.

Three things fill the same table: data files, by filename; with: on a use:, for the macro it calls; and readValue: … as: total, which puts what an input holds into $total for the steps after it. each: … as: binds its name for its own steps only.

References are substituted in steps, and nowhere else. clip, marks and callouts are read as written, so text: $total on a callout draws those six characters. Steps are where a recipe varies; what it points at afterwards is fixed.

A reference reads what the data holds and nothing else. Keys that belong to the language — __proto__, constructor, prototype — resolve to nothing, and a reference that matches nothing is an error rather than an empty string. A literal $ inside a longer string is left alone, so a shot of "costs $5" survives.