steps lets you script interactions between screenshots.
Canonical format
Use structured action objects:
steps:
- action: waitFor
selector: "[data-testid='login-page']"
state: visible
timeoutMs: 5000
- action: assert
type: exists
selector: "[data-testid='login-email']"
- action: select
selector: "#login-email"
steps:
- action: write
value: [email protected]
- action: select
testId: login-submit
steps:
- action: click
- action: waitFor
selector: "[data-testid='dashboard']"
state: visible
timeoutMs: 5000
- action: assert
type: url
value: /dashboard
match: includes
- action: screenshot
Select behavior
action: select accepts exactly one of:
testId: targetsdata-testid="<testId>"selector: targets the CSS selector directly, for example#login-submit
Inside select blocks VT uses:
- first interactive child (
input,textarea,button,select,a) when present - otherwise the host element
Action properties
| Action | Required properties | Optional properties | Notes |
|---|---|---|---|
assert |
type |
match, selector, timeoutMs, value, global, fn, args |
js requires exactly one of global or fn; value deep-equals for js |
blur |
- | - | select block only |
check |
- | - | select block only |
clear |
- | - | select block only |
click |
- | x, y |
if no coordinates, requires select block |
customEvent |
name |
detail |
dispatches window CustomEvent |
dblclick |
- | x, y |
if no coordinates, requires select block |
focus |
- | - | select block only |
goto |
url |
- | waitUntil: networkidle |
hover |
- | x, y |
if no coordinates, requires select block |
keypress |
key |
- | Playwright key string |
mouseDown |
- | - | left button down |
mouseUp |
- | - | left button up |
move |
x, y |
- | mouse move |
rclick |
- | x, y |
if no coordinates, requires select block |
rightMouseDown |
- | - | right button down |
rightMouseUp |
- | - | right button up |
scroll |
deltaX, deltaY |
- | mouse wheel |
select |
steps |
testId or selector |
exactly one target required; only nested/block action |
selectOption |
exactly one of value / label / index |
- | select block only |
setViewport |
width, height |
- | integer >= 1 |
screenshot |
- | - | additional capture point |
uncheck |
- | - | select block only |
upload |
files |
- | non-empty array, select block only |
wait |
ms |
- | non-negative number |
waitFor |
- | selector, state, timeoutMs |
state: `attached |
write |
value |
- | string, select block only |
assert
steps:
- action: assert
type: text
selector: "[data-testid='status']"
value: ready
match: includes
action: assert supports:
type:url | exists | visible | hidden | text | js(required)match:includes | equals(optional; used forurlandtext, defaultincludes)selector: required outsideselectforexists | visible | hidden | texttimeoutMs: optional non-negative integer forexists | visible | hiddenvalue:- required string for
urlandtext - required YAML/JSON value for
js(deep-equal, including objects/arrays)
- required string for
global(js): window global pathfn(js): window function pathargs(js): optional function args array
js rule:
- exactly one of
globalorfnis required
js example:
steps:
- action: assert
type: js
fn: app.getPayload
args: [foo]
value:
ok: true
tags: [a, b]
blur
steps:
- action: select
selector: "#email-input"
steps:
- action: blur
check
steps:
- action: select
selector: "#accept-checkbox"
steps:
- action: check
clear
steps:
- action: select
selector: "#search-input"
steps:
- action: clear
click
steps:
- action: click
x: 320
y: 180
customEvent
steps:
- action: customEvent
name: app:ready
detail:
source: vt
mode: smoke
dblclick
steps:
- action: dblclick
x: 240
y: 120
focus
steps:
- action: select
selector: "#username"
steps:
- action: focus
goto
steps:
- action: goto
url: /docs
hover
steps:
- action: select
selector: "#tooltip-trigger"
steps:
- action: hover
keypress
steps:
- action: keypress
key: Escape
mouseDown
steps:
- action: mouseDown
mouseUp
steps:
- action: mouseUp
move
steps:
- action: move
x: 400
y: 260
rclick
steps:
- action: rclick
x: 420
y: 200
rightMouseDown
steps:
- action: rightMouseDown
rightMouseUp
steps:
- action: rightMouseUp
scroll
steps:
- action: scroll
deltaX: 0
deltaY: 600
select
steps:
- action: select
testId: login-submit
steps:
- action: click
selectOption
steps:
- action: select
testId: role-select
steps:
- action: selectOption
value: admin
setViewport
steps:
- action: setViewport
width: 390
height: 844
screenshot
steps:
- action: screenshot
uncheck
steps:
- action: select
testId: accept-checkbox
steps:
- action: uncheck
upload
steps:
- action: select
testId: avatar-upload
steps:
- action: upload
files:
- ./fixtures/avatar.png
wait
steps:
- action: wait
ms: 300
waitFor
steps:
- action: waitFor
selector: '#dialog[open]'
state: visible
timeoutMs: 1500
write
steps:
- action: select
testId: email-input
steps:
- action: write
value: [email protected]