Criteria, checks and packs
A criterion is one thing a step must meet. It has an id (AC1), a text for people and exactly one check. How to add them to a scenario: Add criteria and packs. How the results turn into a verdict: How verdicts are decided.
Kinds of check #
type | When to use it | Options |
|---|
deterministic | anything countable or exact: presence, counts, text, the URL, styles, values in the page | assert and its options (below) |
semantic | judgement: is the copy clear, is there one primary action | question (English, yes = met), true and false (what counts as yes and no), scope (CSS selector sent to the evaluator), about: console (read the console errors instead of the page), vision: true (also show the screenshot) |
manual | neither works; a reviewer decides on the canvas | note |
Numbers, dates and counts belong in deterministic checks, never in a semantic question. Ask one thing per question.
Deterministic checks (assert) #
Common options: selector (CSS), pattern (a regex) with flags (i, m, s), value, min, max, all (every match must pass, not just one).
Page content #
assert | Passes when |
|---|
exists | selector matches at least one element |
absent | selector matches nothing |
count | the number of matches is between min and max |
text_matches | the element's visible text matches pattern |
text_absent | no visible text matches pattern |
text_equals | the whole text equals value (whitespace collapsed) |
attr_equals | attribute attr equals value |
attr_matches | attribute attr matches pattern |
no_overflow | the page does not scroll sideways |
no_console_errors | the console has no errors |
assert | Passes when |
|---|
title_matches | the page title matches pattern |
meta_matches | the content of the selector meta tag matches pattern |
link_matches | the href of the selector link matches pattern |
url_matches | the URL after the step matches pattern; part picks href, path, query, hash, host or origin |
url_equals | the URL equals value (a path or a whole URL); ignore_query drops ?… and #… |
http_status | the document's status is between min and max (default 200–299), or equals value |
link_home | the page links back to the home page |
links_ok | every same-origin link answers below 400 (max links per page, pattern skips paths, follow outside read-only environments) |
hreflang_pairs | at least min languages, each version answers 200 and links back |
Styles and values in the page #
assert | Passes when |
|---|
style_equals | the computed CSS property equals value or a design token; op compares numbers (>=), tolerance allows px rounding |
style_matches | the computed property matches pattern |
js_equals | one read-only JavaScript expression in the page returns value (or matches pattern, or compares with op) |
Accessibility (the a11y pack uses these) #
assert | Passes when |
|---|
a11y_images_alt | images have alternative text |
a11y_names | links and buttons have an accessible name |
a11y_labels | form fields have labels |
a11y_headings | heading levels are not skipped |
a11y_contrast | text meets WCAG AA contrast |
a11y_main | the page has a main landmark |
a11y_unique_ids | element ids are unique |
a11y_focus_order | Tab order follows the page and reaches every control |
a11y_focus_visible | focus is visible with at least 3 : 1 contrast |
a11y_keyboard_trap | Tab never gets stuck |
a11y_skip_link | a skip link or the main content within three Tab stops |
a11y_ax_names | controls have a name in the browser's accessibility tree |
a11y_landmarks | landmarks are complete and repeated ones labelled |
a11y_aria | ARIA roles and attributes are valid |
assert | Passes when |
|---|
perf_lcp, perf_cls, perf_ttfb, perf_weight | largest contentful paint, layout shift, time to first byte or page weight stays within max |
app_labels | every app control has an accessible label |
app_touch_targets | touch targets are at least 48 dp (Android) or 44 pt (iOS) |
app_no_truncation | no text is cut off with an ellipsis |
app_no_crash | the app did not crash or stop responding |
design_pixels | the screen differs from the design reference in at most ratio of pixels (default 0.03) |
design_structure | headings, landmarks, actions and fields match the design reference |
uses_tokens | colours, fonts, sizes, spacing and radii come from the token set |
Packs #
packs: [seo, a11y] on a step adds a fixed set of criteria. A criterion of your own with the same id replaces the pack's, which is how you change a limit (AC401 with max: 4000).
| Pack | Ids | What it adds |
|---|
seo | AC101–AC111 | one H1, title 10–70 and description 50–160 characters, canonical, hreflang for every language, Open Graph, not noindex, viewport meta, html lang, no overflow, no console errors |
usability | AC201–AC204 | the purpose is clear on the first screen, one primary action, labelled fields, link texts that say what they do |
a11y | AC301–AC314 | every accessibility check above; the walk also presses Tab through the page, without clicking or typing |
perf | AC401–AC404 | LCP within 2.5 s, CLS below 0.1, TTFB within 800 ms, page weight within 3 MB (measured in the walk's browser) |
console | AC501 | the evaluator reads the console errors and says whether they touch what the step accepts |
errors | AC601–AC606 | a real 4xx/5xx status, a link home, navigation or search, no stack trace, a plain message with a way forward, no console errors |
app | AC701–AC705 | labels, touch targets, no truncated text, no crash, a clear purpose and next action |
design | AC801–AC803 | the implementation against the design reference: pixels, structure, tokens |
The a11y pack covers part of WCAG 2.2 AA. It does not replace an audit with a screen reader.