Part 4: Supplementary Keywords
Permalink to Part 4: Supplementary KeywordsThese handle situations beyond the six core interaction keywords.
# Pause execution (use sparingly — prefer wait_for)
# `2000`, `2000ms` and `2s` all work; a bare number means milliseconds
- wait: 2000
- wait: 2s
# Wait for a condition before continuing
- wait_for: text "Loading complete"
- wait_for: button "Submit"
# Navigate directly to a URL
- navigate: 'https://app.example.com/settings'
# Take a screenshot (saved to screenshot_dir)
- screenshot: 'after-form-submit'
# Send raw keyboard input — key names only
- keyboard: 'Tab'
- keyboard: 'Shift+Tab'
- keyboard: 'ArrowDown ArrowDown Enter'
- keyboard: 'Escape'
# Type literal text into whatever currently holds focus
- type: Hello accessible world
# Scroll an element into view
- scroll: to text "Terms and Conditions"
- scroll: to button "Load More"
# Mouse hover over an element (no keyboard equivalent — by design)
- hover: button "Save"
- hover_out: button "Save"
# Add a tester note (no action, appears in reports)
- note: 'Visual layout matches mockup'
# Resize the viewport for the rest of the case
- viewport: mobile
- viewport: 414x896
keyboard vs type. keyboard presses keys. Every whitespace-separated
token has to name one — Tab, Enter, Shift+Tab, ArrowDown, F5, or a
single character. It is not a way to type words:
# Wrong — these are not key names, and validation rejects it
- keyboard: 'Hello accessible world'
# Right
- focus: field "Title"
- type: Hello accessible world
Use type when there is no nameable field for enter to address — a
contenteditable rich-text editor, a canvas-backed editor — or when the page
reacts to individual keystrokes. type sends real per-character key events, so
live word counts, markdown shortcuts and autocomplete all fire the way they
would for a real typist. enter: field "X" value "..." fills the field in one
go and is the better choice when you just need a value in an input.
About hover. hover and hover_out are intentionally mouse-only. They
exist for tooltip exposure and carousel auto-rotation-pause patterns that gate
behavior on pointer hover. Tests using them will fail in keyboard-only profiles
by design — pair with a focus-driven companion step (focus: button "X" + a
hover-equivalent assertion) when WCAG 1.4.13 also requires keyboard parity.
About viewport. Some controls only exist at some sizes. A navigation menu
that collapses to a hamburger below 768px is not hidden at desktop width — the
button is not in the accessibility tree at all, so
locate: button "Open navigation menu" fails naming a missing element, and the
report says nothing about the breakpoint being the reason.
viewport moves the journey to the size the flow is written for:
- viewport: mobile
- locate: button "Open navigation menu"
- activate: button "Open navigation menu"
- verify: visible navigation "Main"
Four presets are available — mobile (375×812), tablet (768×1024), desktop
(1280×720) and reflow (320×256) — or give an explicit <width>x<height> such
as 414x896.
Prefer a preset. An explicit size stops crossing the boundary it was chosen for
the moment the project moves its breakpoints, and nothing in the file says so.
reflow is named after WCAG 2.2 SC 1.4.10 rather than after a device: 320
CSS px is what 1280px becomes at 400% zoom, which is the width the success
criterion actually names.
That last one pairs with audit, because the delegating keywords resolve
against the page as it stands. Auditing at the default size never reaches the
viewport-sensitive criteria; auditing at the reflow width does:
- viewport: reflow
- audit: page level "AA"
The size persists for the rest of the case — there is no automatic restore, so
set it back explicitly if a later step needs the original width. And a value
that is neither a preset nor two in-range integers separated by x is a parse
error rather than a silent fall back to a default: a case that reads as though
it changed size while running at the previous one is exactly the failure this
keyword exists to remove.