Overview
Loops let you repeat a set of steps multiple times. Use them to iterate over UI elements on a page (e.g., all product cards) or over data (e.g., items from an API response) using Start Loop and End Loop.
At a glance
- Two sources: Elements on the page or an Expression that evaluates to an array/iterable
- Loop variable: Name the current item (e.g.,
item
,user
,index
) and reference it as{{vars.<name>}}
- Automatic pairing: Adding Start Loop automatically adds End Loop to close the block
- Presets: Quick-insert expressions like “Loop 5 times” and “API response”
How it works
When you insert a Start Loop, you choose what to iterate over and name the loop variable. All steps added below it run once for each item. End Loop marks where repetition stops.Generated code (conceptual)
Configure in the UI
Iterate over
- Elements on page: Pick or enter a locator that matches multiple elements. You’ll see an optional English description for readability.
- Expression (array/iterable): Provide a
{{ ... }}
expression that evaluates to an array/iterable at runtime, e.g.{{vars.items}}
,{{vars.apiResponse.users}}
, or{{[...Array(5).keys()]}}
.

Presets (for Expression)
- Loop 5 times → inserts
{{[...Array(5).keys()]}}
and sets loop variable toindex
- API response → inserts
{{vars.apiResponse.items}}
and sets loop variable toitem

Loop variable name
- Defaults to
item
. Must be a valid identifier. - Use it inside steps as
{{vars.item}}
, or whatever name you chose.
Expression tips
- Use
{{ ... }}
syntax to supply arrays/iterables, e.g.,{{vars.users}}
,{{[...Array(5).keys()]}}
- Normalize data before looping if needed:
{{vars.users.filter(u => u.active)}}
- Keep items small/light; avoid passing huge payloads; prefer extracting needed fields first
Examples
Iterate over elements
- Iterate over: Elements on page
- Element locator:
.product-card
- Loop variable:
card
- Click “Add to cart” within the current
card
- Verify cart count increases
Iterate over data
- Iterate over: Expression (array/iterable)
- Expression:
{{vars.users}}
- Loop variable:
user

- Fill
#name
with{{vars.user.name}}
- Fill
#email
with{{vars.user.email}}
- Submit form
Fixed count
- Iterate over: Expression (array/iterable)
- Expression:
{{[...Array(5).keys()]}}
- Loop variable:
index
- Click retry
- Use a conditional to stop when successful
Best practices
- Prefer stable locators: Use
data-testid
for element loops to avoid flakiness - Keep loops small: Limit steps inside the loop; extract long sequences into Snippets
- Name variables clearly:
user
,row
,card
are better thanitem1
- Be mindful of size: Very large loops increase runtime; sample or narrow selectors
- Compose with conditions: Combine with Start/End Condition for branching or early exits
Troubleshooting
- Selector matches 0 items: Verify the locator; add waits if content is async
- Expression not iterable: Ensure it evaluates to an array or iterable (e.g.,
[]
, result ofmap
/filter
) - Index confusion:
[...Array(5).keys()]
yields 0–4
Performance considerations
- Prefer stable selectors; resolve element lists once, then reuse inside the loop
- Avoid large loops when possible; sample or cap the iteration count
- Move expensive setup outside the loop; keep loop body minimal