@vardot/varbase-e2e 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +148 -0
- package/CLAUDE.md +544 -0
- package/README.md +22 -0
- package/bin/generate-reports.js +363 -0
- package/bin/init-varbase-e2e.js +330 -0
- package/bin/postinstall.js +26 -0
- package/cucumber.js +125 -0
- package/docs/00-quick-start.md +102 -0
- package/docs/01-getting-started.md +102 -0
- package/docs/02-bbr-smart-waits.md +77 -0
- package/docs/03-selector-registry.md +95 -0
- package/docs/04-step-reference.md +801 -0
- package/docs/05-web-first-assertions.md +91 -0
- package/docs/06-network-and-dialogs.md +83 -0
- package/docs/07-auth-state.md +75 -0
- package/docs/08-clock-mocking.md +59 -0
- package/docs/09-api-testing.md +114 -0
- package/docs/10-accessibility.md +167 -0
- package/docs/11-debugging.md +129 -0
- package/docs/12-ai-agent-guide.md +338 -0
- package/docs/13-faq.md +236 -0
- package/docs/14-recipes-cookbook.md +255 -0
- package/docs/15-tag-conventions.md +76 -0
- package/docs/16-ci-cd.md +90 -0
- package/docs/README.md +125 -0
- package/docs/advanced-screenshots/then-i-save-fullscreen-screenshot.md +36 -0
- package/docs/advanced-screenshots/then-i-save-width-x-height-screenshot.md +34 -0
- package/docs/advanced-screenshots/when-i-save-screenshot-name-filename.md +45 -0
- package/docs/advanced-screenshots.md +52 -0
- package/docs/advanced-selectors.md +18 -0
- package/docs/api-step-definitions.md +45 -0
- package/docs/global-settings.md +267 -0
- package/docs/install-varbase-e2e/ddev-varbase-e2e.md +52 -0
- package/docs/install-varbase-e2e.md +34 -0
- package/docs/overview.md +40 -0
- package/docs/step-definitions/given-i-am-anonymous-user.md +67 -0
- package/docs/step-definitions/given-i-am-homepage.md +68 -0
- package/docs/step-definitions/given-i-am-specific-page.md +72 -0
- package/docs/step-definitions/then-i-should-be.md +56 -0
- package/docs/step-definitions/then-i-should-see.md +62 -0
- package/docs/step-definitions/then-item-checkbox.md +54 -0
- package/docs/step-definitions/then-item-link-should-contain-url.md +84 -0
- package/docs/step-definitions/then-item-should-contain.md +67 -0
- package/docs/step-definitions/then-radio-button-value-should-be-selected.md +68 -0
- package/docs/step-definitions/then-response-status-code-should-be-number.md +69 -0
- package/docs/step-definitions/then-value-radio-button-selected.md +62 -0
- package/docs/step-definitions/when-i-attach-file-file-name-element.md +71 -0
- package/docs/step-definitions/when-i-check-checkbox.md +60 -0
- package/docs/step-definitions/when-i-click-link.md +51 -0
- package/docs/step-definitions/when-i-click-operation-text-row.md +71 -0
- package/docs/step-definitions/when-i-fill.md +59 -0
- package/docs/step-definitions/when-i-go-homepage.md +60 -0
- package/docs/step-definitions/when-i-go-specific-page.md +67 -0
- package/docs/step-definitions/when-i-move-backward-one-page.md +49 -0
- package/docs/step-definitions/when-i-move-forward-one-page.md +58 -0
- package/docs/step-definitions/when-i-press-button.md +58 -0
- package/docs/step-definitions/when-i-reload-page.md +51 -0
- package/docs/step-definitions/when-i-scroll.md +73 -0
- package/docs/step-definitions/when-i-select-option-select-list.md +53 -0
- package/docs/step-definitions/when-i-select-radio-button-value.md +62 -0
- package/docs/step-definitions/when-i-uncheck-checkbox.md +57 -0
- package/docs/step-definitions/when-i-wait-ajax-finish.md +64 -0
- package/docs/step-definitions/when-i-wait.md +62 -0
- package/docs/step-definitions.md +82 -0
- package/docs/steps/README.md +137 -0
- package/docs/steps/a11y.md +731 -0
- package/docs/steps/action.md +181 -0
- package/docs/steps/api.md +679 -0
- package/docs/steps/assertion.md +328 -0
- package/docs/steps/auth.md +108 -0
- package/docs/steps/clock.md +171 -0
- package/docs/steps/cookie.md +293 -0
- package/docs/steps/debug.md +52 -0
- package/docs/steps/dialog.md +226 -0
- package/docs/steps/drupal-canvas.md +414 -0
- package/docs/steps/drupal-ckeditor.md +118 -0
- package/docs/steps/drupal-core.md +688 -0
- package/docs/steps/drupal-layout-builder.md +437 -0
- package/docs/steps/drupal-media.md +107 -0
- package/docs/steps/drupal-moderation.md +81 -0
- package/docs/steps/drupal-paragraphs.md +36 -0
- package/docs/steps/element.md +455 -0
- package/docs/steps/field.md +648 -0
- package/docs/steps/file-download.md +235 -0
- package/docs/steps/form.md +344 -0
- package/docs/steps/iframe.md +248 -0
- package/docs/steps/input.md +220 -0
- package/docs/steps/javascript.md +111 -0
- package/docs/steps/keyboard.md +107 -0
- package/docs/steps/link.md +217 -0
- package/docs/steps/metatag.md +99 -0
- package/docs/steps/modal.md +232 -0
- package/docs/steps/navigation.md +275 -0
- package/docs/steps/network.md +284 -0
- package/docs/steps/path.md +203 -0
- package/docs/steps/response.md +102 -0
- package/docs/steps/responsive.md +139 -0
- package/docs/steps/rest.md +140 -0
- package/docs/steps/screenshot.md +211 -0
- package/docs/steps/scroll.md +266 -0
- package/docs/steps/selectors.md +848 -0
- package/docs/steps/storage.md +254 -0
- package/docs/steps/table.md +216 -0
- package/docs/steps/varbase.md +391 -0
- package/docs/steps/video.md +111 -0
- package/docs/steps/wait.md +553 -0
- package/docs/steps/web-first.md +289 -0
- package/docs/steps/xml.md +505 -0
- package/docs/steps/yaml.md +951 -0
- package/examples/a11y.html +31 -0
- package/examples/about-us.html +11 -0
- package/examples/account.html +32 -0
- package/examples/ajax-wait-examples.html +147 -0
- package/examples/contact-us.html +10 -0
- package/examples/cookies.html +10 -0
- package/examples/date.html +12 -0
- package/examples/dynamic-examples.html +498 -0
- package/examples/element.html +11 -0
- package/examples/example-api.json +28 -0
- package/examples/existing-page.html +11 -0
- package/examples/field.html +24 -0
- package/examples/index.html +37 -0
- package/examples/keyboard.html +11 -0
- package/examples/links.html +9 -0
- package/examples/modal.html +14 -0
- package/examples/path.html +3 -0
- package/examples/table.html +13 -0
- package/examples/test--modal-dialogs.html +252 -0
- package/examples/test--then--i-should--not--see-text-in-element.html +48 -0
- package/examples/test--then--i-should--see-text-in-element.html +48 -0
- package/examples/test--then--i-should--see-text-matching-pattern.html +31 -0
- package/examples/test--then--i-should-see-text-in-table-row.html +232 -0
- package/examples/test--then--the-checkbox-checked.html +68 -0
- package/examples/test--then--the-element-should_not-contain-cssproperty.html +47 -0
- package/examples/test--then--the-link-should-contain.html +21 -0
- package/examples/test--when--i-additionally-select.html +27 -0
- package/examples/test--when--i-attach-file-to-feild.html +50 -0
- package/examples/test--when--i-check-uncheck-checkbox.html +47 -0
- package/examples/test--when--i-click-link.html +18 -0
- package/examples/test--when--i-click-text-in-table-row.html +178 -0
- package/examples/test--when--i-fill-in.html +48 -0
- package/examples/test--when--i-press-button.html +31 -0
- package/examples/test--when--i-reload-page.html +27 -0
- package/examples/test--when--i-scroll-functionality.html +177 -0
- package/examples/test--when--i-scroll-left-right-functionality.html +149 -0
- package/examples/test--when--i-select-option-from-dropdownlist.html +35 -0
- package/examples/test--when--i-select-radio-button.html +95 -0
- package/examples/test--when-i-wait-max-of-time.html +39 -0
- package/examples/test--when-i-wait-page-until-is-loaded.html +47 -0
- package/examples/test--when-i-wait-specific-time.html +39 -0
- package/examples/test-acceptable-url-path.html +11 -0
- package/examples/video-demo.html +43 -0
- package/package.json +56 -0
- package/playwright.config.ts +39 -0
- package/tests/assets/test-document.pdf +14 -0
- package/tests/assets/vardot.png +0 -0
- package/tests/features/a11y.feature +39 -0
- package/tests/features/ajax-wait-examples.feature +24 -0
- package/tests/features/api-step-definitions-individual.feature +185 -0
- package/tests/features/complete-api-testing-examples.feature +205 -0
- package/tests/features/cookie.feature +13 -0
- package/tests/features/date.feature +11 -0
- package/tests/features/dynamic-content-examples.feature +156 -0
- package/tests/features/element.feature +16 -0
- package/tests/features/field.feature +25 -0
- package/tests/features/keyboard.feature +10 -0
- package/tests/features/link.feature +11 -0
- package/tests/features/modal-advanced-example.feature +54 -0
- package/tests/features/modal-basic-example.feature +42 -0
- package/tests/features/modal-error-handling-example.feature +37 -0
- package/tests/features/modal.feature +11 -0
- package/tests/features/path.feature +16 -0
- package/tests/features/response.feature +8 -0
- package/tests/features/responsive.feature +10 -0
- package/tests/features/table.feature +18 -0
- package/tests/features/test--given--i-am-an-anonymous-user.feature +10 -0
- package/tests/features/test--given--i-am-on-homepage.feature +16 -0
- package/tests/features/test--then--i-save-screenshot.feature +33 -0
- package/tests/features/test--then--i-see-locator.feature +320 -0
- package/tests/features/test--then--i-should--not--see-text-in-element.feature +13 -0
- package/tests/features/test--then--i-should--see-text-in-element-by-attr.feature +10 -0
- package/tests/features/test--then--i-should--see-text-in-element.feature +10 -0
- package/tests/features/test--then--i-should--see-text-matching-pattern-in-element.feature +13 -0
- package/tests/features/test--then--i-should--see-text-matching-pattern.feature +18 -0
- package/tests/features/test--then--i-should-be-on-page.feature +10 -0
- package/tests/features/test--then--i-should-be-on-the-homepage.feature +10 -0
- package/tests/features/test--then--i-should-not-see-an-element-by-attr.feature +8 -0
- package/tests/features/test--then--i-should-not-see-an-element.feature +8 -0
- package/tests/features/test--then--i-should-see-an-element-by-attr.feature +8 -0
- package/tests/features/test--then--i-should-see-an-element.feature +8 -0
- package/tests/features/test--then--i-should-see-n-elements.feature +24 -0
- package/tests/features/test--then--i-should-see-text-in-table-row.feature +96 -0
- package/tests/features/test--then--print-current-url-and-response.feature +21 -0
- package/tests/features/test--then--the-checkbox-is-checked.feature +18 -0
- package/tests/features/test--then--the-checkbox-should-be-checked.feature +16 -0
- package/tests/features/test--then--the-element-should-contain-cssproperty.feature +9 -0
- package/tests/features/test--then--the-element-should-not-contain-cssproperty.feature +10 -0
- package/tests/features/test--then--the-field-should-contain-value.feature +11 -0
- package/tests/features/test--then--the-response-should-contain.feature +11 -0
- package/tests/features/test--then--the-response-status-code-should-be.feature +31 -0
- package/tests/features/test--then--the-url-should-match.feature +7 -0
- package/tests/features/test--then-the-link-should-contain-by-attribute.feature +18 -0
- package/tests/features/test--then-the-link-should-contain.feature +7 -0
- package/tests/features/test--when--i-additionally-select.feature +30 -0
- package/tests/features/test--when--i-attach-file-to-feild.feature +9 -0
- package/tests/features/test--when--i-check-checkbox.feature +21 -0
- package/tests/features/test--when--i-click-link-by-attribute.feature +21 -0
- package/tests/features/test--when--i-click-link.feature +9 -0
- package/tests/features/test--when--i-click-text-in-table-row.feature +37 -0
- package/tests/features/test--when--i-fill-in-by-attr.feature +31 -0
- package/tests/features/test--when--i-fill-in-table-by-attr.feature +19 -0
- package/tests/features/test--when--i-fill-in.feature +32 -0
- package/tests/features/test--when--i-follow.feature +22 -0
- package/tests/features/test--when--i-go-to-homepage.feature +9 -0
- package/tests/features/test--when--i-move-forward-backward-one-page.feature +14 -0
- package/tests/features/test--when--i-press-button-by-attribute.feature +18 -0
- package/tests/features/test--when--i-press-button.feature +13 -0
- package/tests/features/test--when--i-reload-page.feature +11 -0
- package/tests/features/test--when--i-scroll-left-right.feature +48 -0
- package/tests/features/test--when--i-scroll.feature +48 -0
- package/tests/features/test--when--i-select-option-from-dropdownlist.feature +21 -0
- package/tests/features/test--when--i-select-radio-button.feature +37 -0
- package/tests/features/test--when--i-wait-page-is-loaded.feature +8 -0
- package/tests/features/test--when--i-wait-time.feature +21 -0
- package/tests/features/video.feature +18 -0
- package/tests/features/wait.feature +7 -0
- package/tests/features/yaml.feature +102 -0
- package/tests/selectors/_canonical-keys.json +113 -0
- package/tests/selectors/back-end-selectors.json +19 -0
- package/tests/selectors/cms-contentful-admin.json +35 -0
- package/tests/selectors/cms-craft-admin.json +39 -0
- package/tests/selectors/cms-drupal-cms-gin.json +56 -0
- package/tests/selectors/cms-drupal-core-claro.json +50 -0
- package/tests/selectors/cms-generic-admin.json +34 -0
- package/tests/selectors/cms-ghost-admin.json +34 -0
- package/tests/selectors/cms-joomla-admin.json +41 -0
- package/tests/selectors/cms-magento2-admin.json +32 -0
- package/tests/selectors/cms-prestashop-admin.json +38 -0
- package/tests/selectors/cms-shopify-admin.json +25 -0
- package/tests/selectors/cms-strapi-admin.json +42 -0
- package/tests/selectors/cms-typo3-admin.json +41 -0
- package/tests/selectors/cms-woocommerce-front.json +50 -0
- package/tests/selectors/cms-wordpress-admin.json +31 -0
- package/tests/selectors/framework-ant-design.json +80 -0
- package/tests/selectors/framework-bootstrap.json +86 -0
- package/tests/selectors/framework-bulma.json +74 -0
- package/tests/selectors/framework-chakra.json +58 -0
- package/tests/selectors/framework-foundation.json +51 -0
- package/tests/selectors/framework-material-ui.json +72 -0
- package/tests/selectors/framework-shadcn.json +51 -0
- package/tests/selectors/framework-tailwind.json +40 -0
- package/tests/selectors/framework-vuetify.json +61 -0
- package/tests/selectors/front-end-selectors.json +16 -0
- package/tests/selectors/homepage-selectors.json +13 -0
- package/tests/step-definitions/a11y.steps.js +800 -0
- package/tests/step-definitions/action.steps.js +167 -0
- package/tests/step-definitions/api.steps.js +732 -0
- package/tests/step-definitions/assertion.steps.js +352 -0
- package/tests/step-definitions/auth.steps.js +126 -0
- package/tests/step-definitions/clock.steps.js +128 -0
- package/tests/step-definitions/cookie.steps.js +216 -0
- package/tests/step-definitions/debug.steps.js +39 -0
- package/tests/step-definitions/dialog.steps.js +193 -0
- package/tests/step-definitions/drupal-canvas.steps.js +764 -0
- package/tests/step-definitions/drupal-ckeditor.steps.js +108 -0
- package/tests/step-definitions/drupal-core.steps.js +665 -0
- package/tests/step-definitions/drupal-helpers.js +371 -0
- package/tests/step-definitions/drupal-layout-builder.steps.js +466 -0
- package/tests/step-definitions/drupal-media.steps.js +99 -0
- package/tests/step-definitions/drupal-moderation.steps.js +71 -0
- package/tests/step-definitions/drupal-paragraphs.steps.js +50 -0
- package/tests/step-definitions/element.steps.js +356 -0
- package/tests/step-definitions/field.steps.js +653 -0
- package/tests/step-definitions/file-download.steps.js +211 -0
- package/tests/step-definitions/form.steps.js +333 -0
- package/tests/step-definitions/iframe.steps.js +228 -0
- package/tests/step-definitions/input.steps.js +202 -0
- package/tests/step-definitions/javascript.steps.js +232 -0
- package/tests/step-definitions/keyboard.steps.js +112 -0
- package/tests/step-definitions/link.steps.js +142 -0
- package/tests/step-definitions/metatag.steps.js +91 -0
- package/tests/step-definitions/modal.steps.js +244 -0
- package/tests/step-definitions/navigation.steps.js +218 -0
- package/tests/step-definitions/network.steps.js +280 -0
- package/tests/step-definitions/path.steps.js +141 -0
- package/tests/step-definitions/response.steps.js +98 -0
- package/tests/step-definitions/responsive.steps.js +125 -0
- package/tests/step-definitions/rest.steps.js +111 -0
- package/tests/step-definitions/screenshot.steps.js +423 -0
- package/tests/step-definitions/scroll.steps.js +189 -0
- package/tests/step-definitions/selectors.steps.js +1003 -0
- package/tests/step-definitions/storage.steps.js +194 -0
- package/tests/step-definitions/table.steps.js +181 -0
- package/tests/step-definitions/varbase-e2e.js +897 -0
- package/tests/step-definitions/varbase.steps.js +458 -0
- package/tests/step-definitions/video.steps.js +178 -0
- package/tests/step-definitions/wait.steps.js +400 -0
- package/tests/step-definitions/web-first.steps.js +298 -0
- package/tests/step-definitions/xml.steps.js +411 -0
- package/tests/step-definitions/yaml.steps.js +913 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
# Accessibility steps
|
|
2
|
+
|
|
3
|
+
26 steps, defined in `tests/step-definitions/a11y.steps.js`.
|
|
4
|
+
|
|
5
|
+
Cucumber-js loads every `*.steps.js` in that directory automatically — you never `require()` a step file from a feature.
|
|
6
|
+
|
|
7
|
+
| # | Step |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| 1 | `Then every image should have an alt attribute` |
|
|
10
|
+
| 2 | `Then every form field should have an accessible label` |
|
|
11
|
+
| 3 | `Then the page should have a main landmark` |
|
|
12
|
+
| 4 | `Then the page should have a navigation landmark` |
|
|
13
|
+
| 5 | `Then the page should have exactly one h1` |
|
|
14
|
+
| 6 | `Then the focused element should match "#email"` |
|
|
15
|
+
| 7 | `Then the focused element should be labeled "Email"` |
|
|
16
|
+
| 8 | `Then the page should declare a language` |
|
|
17
|
+
| 9 | `Then the page language should be "en"` |
|
|
18
|
+
| 10 | `Then the heading hierarchy should be valid` |
|
|
19
|
+
| 11 | `Then the page should have a skip link` |
|
|
20
|
+
| 12 | `Then every button should have an accessible name` |
|
|
21
|
+
| 13 | `Then every link should have an accessible name` |
|
|
22
|
+
| 14 | `Then no element should have a positive tabindex` |
|
|
23
|
+
| 15 | `Then every ARIA reference should resolve` |
|
|
24
|
+
| 16 | `Then every ARIA role should be valid` |
|
|
25
|
+
| 17 | `Then required fields should be consistently marked` |
|
|
26
|
+
| 18 | `Then the page should have a title` |
|
|
27
|
+
| 19 | `Then user zoom should be allowed` |
|
|
28
|
+
| 20 | `Then the page should pass an accessibility audit` |
|
|
29
|
+
| 21 | `Then the page should have no critical accessibility violations` |
|
|
30
|
+
| 22 | `Then the element "main" should pass an accessibility audit` |
|
|
31
|
+
| 23 | `Then the page should pass an accessibility audit excluding "iframe.payment"` |
|
|
32
|
+
| 24 | `Then the page should not violate the accessibility rule "color-contrast"` |
|
|
33
|
+
| 25 | `Then I print accessibility violations` |
|
|
34
|
+
| 26 | `Then the page should pass the accessibility rules "image-alt, label"` |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 1. Then every image should have an alt attribute
|
|
39
|
+
|
|
40
|
+
Assert every <img> on the page has an `alt` attribute.
|
|
41
|
+
|
|
42
|
+
Empty `alt=""` is allowed (decorative images per WCAG); `role="presentation"`
|
|
43
|
+
is also allowed. Only a missing `alt` attribute fails. Iterates every <img>
|
|
44
|
+
in the document, including those nested in shadow-light DOM that the page
|
|
45
|
+
has rendered, so it works on infinite-scroll lists and image galleries too.
|
|
46
|
+
|
|
47
|
+
**Keyword**: `Then`
|
|
48
|
+
|
|
49
|
+
**Pattern**
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
/^every image should have an alt attribute$/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Examples**
|
|
56
|
+
|
|
57
|
+
```gherkin
|
|
58
|
+
Then every image should have an alt attribute
|
|
59
|
+
And every image should have an alt attribute
|
|
60
|
+
Given I am on "/photos"
|
|
61
|
+
Then every image should have an alt attribute
|
|
62
|
+
When I scroll to the bottom
|
|
63
|
+
Then every image should have an alt attribute
|
|
64
|
+
When I follow "Gallery"
|
|
65
|
+
Then every image should have an alt attribute
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 2. Then every form field should have an accessible label
|
|
69
|
+
|
|
70
|
+
Assert every form input/select/textarea has an accessible name.
|
|
71
|
+
|
|
72
|
+
Pass condition: each field has at least ONE of —
|
|
73
|
+
- `aria-label` attribute
|
|
74
|
+
- `aria-labelledby` attribute pointing at a real element
|
|
75
|
+
- matching `<label for="...">`
|
|
76
|
+
- wrapping `<label>` element
|
|
77
|
+
|
|
78
|
+
Submit/reset/button/image inputs and `type="hidden"` are exempt because
|
|
79
|
+
they get their accessible name from `value` or `alt`.
|
|
80
|
+
|
|
81
|
+
**Keyword**: `Then`
|
|
82
|
+
|
|
83
|
+
**Pattern**
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
/^every form field should have an accessible label$/
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Examples**
|
|
90
|
+
|
|
91
|
+
```gherkin
|
|
92
|
+
Then every form field should have an accessible label
|
|
93
|
+
Given I am on "/register"
|
|
94
|
+
Then every form field should have an accessible label
|
|
95
|
+
When I open the settings modal
|
|
96
|
+
Then every form field should have an accessible label
|
|
97
|
+
And every form field should have an accessible label
|
|
98
|
+
Then the page should have a main landmark
|
|
99
|
+
And every form field should have an accessible label
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 3. Then the page should have a main landmark
|
|
103
|
+
|
|
104
|
+
Assert the page has a primary `<main>` (or `[role="main"]`) landmark.
|
|
105
|
+
|
|
106
|
+
Screen readers announce landmarks; missing the main landmark forces users
|
|
107
|
+
to navigate the page linearly. WCAG 2.4.1 (Bypass Blocks) requires it.
|
|
108
|
+
|
|
109
|
+
**Keyword**: `Then`
|
|
110
|
+
|
|
111
|
+
**Pattern**
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
/^the page should have a main landmark$/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Examples**
|
|
118
|
+
|
|
119
|
+
```gherkin
|
|
120
|
+
Then the page should have a main landmark
|
|
121
|
+
Given I am on "/about"
|
|
122
|
+
Then the page should have a main landmark
|
|
123
|
+
When I follow "Pricing"
|
|
124
|
+
Then the page should have a main landmark
|
|
125
|
+
And the page should have a main landmark
|
|
126
|
+
Then the page should have a navigation landmark
|
|
127
|
+
And the page should have a main landmark
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 4. Then the page should have a navigation landmark
|
|
131
|
+
|
|
132
|
+
Assert the page has at least one navigation landmark.
|
|
133
|
+
|
|
134
|
+
Counts both `<nav>` and `[role="navigation"]`.
|
|
135
|
+
|
|
136
|
+
**Keyword**: `Then`
|
|
137
|
+
|
|
138
|
+
**Pattern**
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
/^the page should have a navigation landmark$/
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Examples**
|
|
145
|
+
|
|
146
|
+
```gherkin
|
|
147
|
+
Then the page should have a navigation landmark
|
|
148
|
+
Given I am on the homepage
|
|
149
|
+
Then the page should have a navigation landmark
|
|
150
|
+
Given I am on "/admin"
|
|
151
|
+
Then the page should have a navigation landmark
|
|
152
|
+
And the page should have a navigation landmark
|
|
153
|
+
Then the page should have exactly one h1
|
|
154
|
+
And the page should have a navigation landmark
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 5. Then the page should have exactly one h1
|
|
158
|
+
|
|
159
|
+
Assert the page has exactly one `<h1>`.
|
|
160
|
+
|
|
161
|
+
Multiple h1s are valid HTML5 with sectioning roots, but most assistive tech
|
|
162
|
+
still treats the document outline as flat. One h1 per page is the safe
|
|
163
|
+
default.
|
|
164
|
+
|
|
165
|
+
**Keyword**: `Then`
|
|
166
|
+
|
|
167
|
+
**Pattern**
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
/^the page should have exactly one h1$/
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Examples**
|
|
174
|
+
|
|
175
|
+
```gherkin
|
|
176
|
+
Then the page should have exactly one h1
|
|
177
|
+
Given I am on the homepage
|
|
178
|
+
Then the page should have exactly one h1
|
|
179
|
+
When I follow "About"
|
|
180
|
+
Then the page should have exactly one h1
|
|
181
|
+
And the page should have exactly one h1
|
|
182
|
+
Then the page should have a main landmark
|
|
183
|
+
And the page should have exactly one h1
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 6. Then the focused element should match "#email"
|
|
187
|
+
|
|
188
|
+
Assert the currently focused element matches a CSS selector.
|
|
189
|
+
|
|
190
|
+
Useful for tab-order and skip-link tests.
|
|
191
|
+
|
|
192
|
+
**Keyword**: `Then`
|
|
193
|
+
|
|
194
|
+
**Pattern**
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
/^the focused element should match "([^"]*)"$/
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Examples**
|
|
201
|
+
|
|
202
|
+
```gherkin
|
|
203
|
+
Then the focused element should match "#email"
|
|
204
|
+
When I press the "Tab" key
|
|
205
|
+
Then the focused element should match "#email"
|
|
206
|
+
When I press the "Tab" key 2 times
|
|
207
|
+
Then the focused element should match "#password"
|
|
208
|
+
When I focus on the element "#search"
|
|
209
|
+
Then the focused element should match "input[type=search]"
|
|
210
|
+
When I follow "Skip to main content"
|
|
211
|
+
Then the focused element should match "main h1"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 7. Then the focused element should be labeled "Email"
|
|
215
|
+
|
|
216
|
+
Assert the currently focused element's accessible name contains text.
|
|
217
|
+
|
|
218
|
+
Resolution order: aria-label → aria-labelledby → label[for] → wrapping
|
|
219
|
+
<label> → value/placeholder/title/textContent.
|
|
220
|
+
|
|
221
|
+
**Keyword**: `Then`
|
|
222
|
+
|
|
223
|
+
**Pattern**
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
/^the focused element should be labeled "([^"]*)"$/
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Examples**
|
|
230
|
+
|
|
231
|
+
```gherkin
|
|
232
|
+
Then the focused element should be labeled "Email"
|
|
233
|
+
When I press the "Tab" key
|
|
234
|
+
Then the focused element should be labeled "Email"
|
|
235
|
+
When I press the "Tab" key 2 times
|
|
236
|
+
Then the focused element should be labeled "Password"
|
|
237
|
+
When I press the "Tab" key 3 times
|
|
238
|
+
Then the focused element should be labeled "Sign in"
|
|
239
|
+
When I focus on the element "#agree"
|
|
240
|
+
Then the focused element should be labeled "I agree"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## 8. Then the page should declare a language
|
|
244
|
+
|
|
245
|
+
Assert the document has a `lang` attribute on `<html>`.
|
|
246
|
+
|
|
247
|
+
Required by WCAG 3.1.1 — screen readers use `lang` to pick the right
|
|
248
|
+
pronunciation engine. Missing or empty `lang` fails.
|
|
249
|
+
|
|
250
|
+
**Keyword**: `Then`
|
|
251
|
+
|
|
252
|
+
**Pattern**
|
|
253
|
+
|
|
254
|
+
```js
|
|
255
|
+
/^the page should declare a language$/
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Examples**
|
|
259
|
+
|
|
260
|
+
```gherkin
|
|
261
|
+
Then the page should declare a language
|
|
262
|
+
Given I am on the homepage
|
|
263
|
+
Then the page should declare a language
|
|
264
|
+
When I follow "About"
|
|
265
|
+
Then the page should declare a language
|
|
266
|
+
And the page should declare a language
|
|
267
|
+
Then the page should have a main landmark
|
|
268
|
+
And the page should declare a language
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 9. Then the page language should be "en"
|
|
272
|
+
|
|
273
|
+
Assert the document `lang` equals an expected value.
|
|
274
|
+
|
|
275
|
+
**Keyword**: `Then`
|
|
276
|
+
|
|
277
|
+
**Pattern**
|
|
278
|
+
|
|
279
|
+
```js
|
|
280
|
+
/^the page language should be "([^"]*)"$/
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Examples**
|
|
284
|
+
|
|
285
|
+
```gherkin
|
|
286
|
+
Then the page language should be "en"
|
|
287
|
+
Given I am on the homepage
|
|
288
|
+
Then the page language should be "en"
|
|
289
|
+
When I switch to the French version
|
|
290
|
+
Then the page language should be "fr"
|
|
291
|
+
When I switch to the Arabic version
|
|
292
|
+
Then the page language should be "ar"
|
|
293
|
+
And the page language should be "en-US"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## 10. Then the heading hierarchy should be valid
|
|
297
|
+
|
|
298
|
+
Assert headings appear in non-skipping order (h1 → h2 → h3 — never
|
|
299
|
+
h1 → h3). Required by WCAG 1.3.1 / 2.4.6 for screen-reader navigation.
|
|
300
|
+
|
|
301
|
+
**Keyword**: `Then`
|
|
302
|
+
|
|
303
|
+
**Pattern**
|
|
304
|
+
|
|
305
|
+
```js
|
|
306
|
+
/^the heading hierarchy should be valid$/
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Examples**
|
|
310
|
+
|
|
311
|
+
```gherkin
|
|
312
|
+
Then the heading hierarchy should be valid
|
|
313
|
+
Given I am on the homepage
|
|
314
|
+
Then the heading hierarchy should be valid
|
|
315
|
+
When I follow "About"
|
|
316
|
+
Then the heading hierarchy should be valid
|
|
317
|
+
And the heading hierarchy should be valid
|
|
318
|
+
Then the page should have exactly one h1
|
|
319
|
+
And the heading hierarchy should be valid
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 11. Then the page should have a skip link
|
|
323
|
+
|
|
324
|
+
Assert the page exposes a skip-link as the first focusable element. WCAG
|
|
325
|
+
2.4.1 requires a mechanism to bypass repeated content blocks.
|
|
326
|
+
|
|
327
|
+
Detection: anchor with href="#..." that resolves to an existing target
|
|
328
|
+
AND text matching "skip" / "main content" / "to content".
|
|
329
|
+
|
|
330
|
+
**Keyword**: `Then`
|
|
331
|
+
|
|
332
|
+
**Pattern**
|
|
333
|
+
|
|
334
|
+
```js
|
|
335
|
+
/^the page should have a skip link$/
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Examples**
|
|
339
|
+
|
|
340
|
+
```gherkin
|
|
341
|
+
Then the page should have a skip link
|
|
342
|
+
Given I am on the homepage
|
|
343
|
+
Then the page should have a skip link
|
|
344
|
+
When I press the key "Tab"
|
|
345
|
+
Then the focused element should match "a[href^='#']"
|
|
346
|
+
And the page should have a skip link
|
|
347
|
+
Then the page should have a skip link
|
|
348
|
+
And the page should have a main landmark
|
|
349
|
+
When I follow "About"
|
|
350
|
+
Then the page should have a skip link
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## 12. Then every button should have an accessible name
|
|
354
|
+
|
|
355
|
+
Assert every <button> / role="button" has an accessible name (visible
|
|
356
|
+
text, aria-label, or aria-labelledby).
|
|
357
|
+
|
|
358
|
+
**Keyword**: `Then`
|
|
359
|
+
|
|
360
|
+
**Pattern**
|
|
361
|
+
|
|
362
|
+
```js
|
|
363
|
+
/^every button should have an accessible name$/
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Examples**
|
|
367
|
+
|
|
368
|
+
```gherkin
|
|
369
|
+
Then every button should have an accessible name
|
|
370
|
+
Given I am on the homepage
|
|
371
|
+
Then every button should have an accessible name
|
|
372
|
+
When I am on "/checkout"
|
|
373
|
+
Then every button should have an accessible name
|
|
374
|
+
And every button should have an accessible name
|
|
375
|
+
Then every button should have an accessible name
|
|
376
|
+
And every link should have an accessible name
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## 13. Then every link should have an accessible name
|
|
380
|
+
|
|
381
|
+
Assert every <a> has an accessible name.
|
|
382
|
+
|
|
383
|
+
**Keyword**: `Then`
|
|
384
|
+
|
|
385
|
+
**Pattern**
|
|
386
|
+
|
|
387
|
+
```js
|
|
388
|
+
/^every link should have an accessible name$/
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Examples**
|
|
392
|
+
|
|
393
|
+
```gherkin
|
|
394
|
+
Then every link should have an accessible name
|
|
395
|
+
Given I am on the homepage
|
|
396
|
+
Then every link should have an accessible name
|
|
397
|
+
When I am on "/blog"
|
|
398
|
+
Then every link should have an accessible name
|
|
399
|
+
And every link should have an accessible name
|
|
400
|
+
Then every button should have an accessible name
|
|
401
|
+
And every link should have an accessible name
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## 14. Then no element should have a positive tabindex
|
|
405
|
+
|
|
406
|
+
Assert NO interactive element uses a positive `tabindex`. Positive values
|
|
407
|
+
break natural focus order — WCAG 2.4.3 violation in practice.
|
|
408
|
+
|
|
409
|
+
**Keyword**: `Then`
|
|
410
|
+
|
|
411
|
+
**Pattern**
|
|
412
|
+
|
|
413
|
+
```js
|
|
414
|
+
/^no element should have a positive tabindex$/
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Examples**
|
|
418
|
+
|
|
419
|
+
```gherkin
|
|
420
|
+
Then no element should have a positive tabindex
|
|
421
|
+
Given I am on the homepage
|
|
422
|
+
Then no element should have a positive tabindex
|
|
423
|
+
When I am on "/form"
|
|
424
|
+
Then no element should have a positive tabindex
|
|
425
|
+
And no element should have a positive tabindex
|
|
426
|
+
Then no element should have a positive tabindex
|
|
427
|
+
And the heading hierarchy should be valid
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## 15. Then every ARIA reference should resolve
|
|
431
|
+
|
|
432
|
+
Assert every `aria-labelledby` / `aria-describedby` / `aria-controls`
|
|
433
|
+
/ `aria-owns` references an existing element id.
|
|
434
|
+
|
|
435
|
+
**Keyword**: `Then`
|
|
436
|
+
|
|
437
|
+
**Pattern**
|
|
438
|
+
|
|
439
|
+
```js
|
|
440
|
+
/^every ARIA reference should resolve$/
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Examples**
|
|
444
|
+
|
|
445
|
+
```gherkin
|
|
446
|
+
Then every ARIA reference should resolve
|
|
447
|
+
Given I am on the homepage
|
|
448
|
+
Then every ARIA reference should resolve
|
|
449
|
+
When I am on "/dashboard"
|
|
450
|
+
Then every ARIA reference should resolve
|
|
451
|
+
And every ARIA reference should resolve
|
|
452
|
+
Then every ARIA reference should resolve
|
|
453
|
+
And every button should have an accessible name
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## 16. Then every ARIA role should be valid
|
|
457
|
+
|
|
458
|
+
Assert no element uses an invalid ARIA role. Reference: WAI-ARIA 1.2.
|
|
459
|
+
|
|
460
|
+
**Keyword**: `Then`
|
|
461
|
+
|
|
462
|
+
**Pattern**
|
|
463
|
+
|
|
464
|
+
```js
|
|
465
|
+
/^every ARIA role should be valid$/
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
**Examples**
|
|
469
|
+
|
|
470
|
+
```gherkin
|
|
471
|
+
Then every ARIA role should be valid
|
|
472
|
+
Given I am on the homepage
|
|
473
|
+
Then every ARIA role should be valid
|
|
474
|
+
When I am on "/dashboard"
|
|
475
|
+
Then every ARIA role should be valid
|
|
476
|
+
And every ARIA role should be valid
|
|
477
|
+
Then every ARIA role should be valid
|
|
478
|
+
And every ARIA reference should resolve
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## 17. Then required fields should be consistently marked
|
|
482
|
+
|
|
483
|
+
Assert every form field exposing `aria-required="true"` is also marked
|
|
484
|
+
with the native `required` attribute (or vice versa). Mismatch confuses
|
|
485
|
+
assistive tech.
|
|
486
|
+
|
|
487
|
+
**Keyword**: `Then`
|
|
488
|
+
|
|
489
|
+
**Pattern**
|
|
490
|
+
|
|
491
|
+
```js
|
|
492
|
+
/^required fields should be consistently marked$/
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Examples**
|
|
496
|
+
|
|
497
|
+
```gherkin
|
|
498
|
+
Then required fields should be consistently marked
|
|
499
|
+
Given I am on "/signup"
|
|
500
|
+
Then required fields should be consistently marked
|
|
501
|
+
When I am on "/checkout"
|
|
502
|
+
Then required fields should be consistently marked
|
|
503
|
+
And required fields should be consistently marked
|
|
504
|
+
Then every form field should have an accessible label
|
|
505
|
+
And required fields should be consistently marked
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## 18. Then the page should have a title
|
|
509
|
+
|
|
510
|
+
Assert the document has a non-empty `<title>`. WCAG 2.4.2.
|
|
511
|
+
|
|
512
|
+
**Keyword**: `Then`
|
|
513
|
+
|
|
514
|
+
**Pattern**
|
|
515
|
+
|
|
516
|
+
```js
|
|
517
|
+
/^the page should have a title$/
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Examples**
|
|
521
|
+
|
|
522
|
+
```gherkin
|
|
523
|
+
Then the page should have a title
|
|
524
|
+
Given I am on the homepage
|
|
525
|
+
Then the page should have a title
|
|
526
|
+
When I am on "/about"
|
|
527
|
+
Then the page should have a title
|
|
528
|
+
And the page should have a title
|
|
529
|
+
Then the page should have a title
|
|
530
|
+
And the page should declare a language
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## 19. Then user zoom should be allowed
|
|
534
|
+
|
|
535
|
+
Assert the viewport meta tag does not disable user-scaling
|
|
536
|
+
(`user-scalable=no` or `maximum-scale=1`). WCAG 1.4.4 / 1.4.10.
|
|
537
|
+
|
|
538
|
+
**Keyword**: `Then`
|
|
539
|
+
|
|
540
|
+
**Pattern**
|
|
541
|
+
|
|
542
|
+
```js
|
|
543
|
+
/^user zoom should be allowed$/
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Examples**
|
|
547
|
+
|
|
548
|
+
```gherkin
|
|
549
|
+
Then user zoom should be allowed
|
|
550
|
+
Given I am on the homepage
|
|
551
|
+
Then user zoom should be allowed
|
|
552
|
+
When I am on "/article"
|
|
553
|
+
Then user zoom should be allowed
|
|
554
|
+
And user zoom should be allowed
|
|
555
|
+
Then user zoom should be allowed
|
|
556
|
+
And the page should declare a language
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
## 20. Then the page should pass an accessibility audit
|
|
560
|
+
|
|
561
|
+
Run an axe-core audit and assert ZERO violations across the supplied WCAG
|
|
562
|
+
level. Defaults to AA — the level mandated by most accessibility laws.
|
|
563
|
+
|
|
564
|
+
**Keyword**: `Then`
|
|
565
|
+
|
|
566
|
+
**Pattern**
|
|
567
|
+
|
|
568
|
+
```js
|
|
569
|
+
/^the page should pass an accessibility audit(?: at level "(A|AA|AAA)")?$/
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**Examples**
|
|
573
|
+
|
|
574
|
+
```gherkin
|
|
575
|
+
Then the page should pass an accessibility audit
|
|
576
|
+
Then the page should pass an accessibility audit at level "A"
|
|
577
|
+
Then the page should pass an accessibility audit at level "AA"
|
|
578
|
+
And the page should pass an accessibility audit at level "AAA"
|
|
579
|
+
When I am on "/dashboard"
|
|
580
|
+
Then the page should pass an accessibility audit at level "AA"
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## 21. Then the page should have no critical accessibility violations
|
|
584
|
+
|
|
585
|
+
Assert NO axe violations of the given impact severity.
|
|
586
|
+
Levels: `minor`, `moderate`, `serious`, `critical`.
|
|
587
|
+
|
|
588
|
+
Use to gate merges on critical/serious issues while triaging minor regressions.
|
|
589
|
+
|
|
590
|
+
**Keyword**: `Then`
|
|
591
|
+
|
|
592
|
+
**Pattern**
|
|
593
|
+
|
|
594
|
+
```js
|
|
595
|
+
/^the page should have no (critical|serious|moderate|minor) accessibility violations$/
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Examples**
|
|
599
|
+
|
|
600
|
+
```gherkin
|
|
601
|
+
Then the page should have no critical accessibility violations
|
|
602
|
+
Then the page should have no serious accessibility violations
|
|
603
|
+
And the page should have no moderate accessibility violations
|
|
604
|
+
When I am on "/checkout"
|
|
605
|
+
Then the page should have no critical accessibility violations
|
|
606
|
+
Then the page should have no critical accessibility violations
|
|
607
|
+
And the page should have no serious accessibility violations
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
## 22. Then the element "main" should pass an accessibility audit
|
|
611
|
+
|
|
612
|
+
Audit ONLY the subtree under a CSS selector. Use when third-party widgets
|
|
613
|
+
are known-bad and you only want to gate your own components.
|
|
614
|
+
|
|
615
|
+
**Keyword**: `Then`
|
|
616
|
+
|
|
617
|
+
**Pattern**
|
|
618
|
+
|
|
619
|
+
```js
|
|
620
|
+
/^the element "([^"]*)" should pass an accessibility audit$/
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Examples**
|
|
624
|
+
|
|
625
|
+
```gherkin
|
|
626
|
+
Then the element "main" should pass an accessibility audit
|
|
627
|
+
Then the element "#checkout-form" should pass an accessibility audit
|
|
628
|
+
And the element ".product-card" should pass an accessibility audit
|
|
629
|
+
Then the element "#dashboard-widget" should pass an accessibility audit
|
|
630
|
+
Then the element "[data-testid=signup]" should pass an accessibility audit
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
## 23. Then the page should pass an accessibility audit excluding "iframe.payment"
|
|
634
|
+
|
|
635
|
+
Audit the page but EXCLUDE the subtree under a CSS selector. Skip
|
|
636
|
+
known-bad embedded content (third-party iframes, legacy widgets, ads).
|
|
637
|
+
|
|
638
|
+
**Keyword**: `Then`
|
|
639
|
+
|
|
640
|
+
**Pattern**
|
|
641
|
+
|
|
642
|
+
```js
|
|
643
|
+
/^the page should pass an accessibility audit excluding "([^"]*)"$/
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
**Examples**
|
|
647
|
+
|
|
648
|
+
```gherkin
|
|
649
|
+
Then the page should pass an accessibility audit excluding "iframe.payment"
|
|
650
|
+
Then the page should pass an accessibility audit excluding "#chat-widget"
|
|
651
|
+
And the page should pass an accessibility audit excluding ".legacy-banner"
|
|
652
|
+
Then the page should pass an accessibility audit excluding "[data-third-party]"
|
|
653
|
+
Then the page should pass an accessibility audit excluding ".ads"
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
## 24. Then the page should not violate the accessibility rule "color-contrast"
|
|
657
|
+
|
|
658
|
+
Assert a specific axe rule does not fire. Use for fine-grained gates —
|
|
659
|
+
e.g. ensure color-contrast is fixed even if other rules still red.
|
|
660
|
+
|
|
661
|
+
Common rule ids: `color-contrast`, `image-alt`, `label`, `link-name`,
|
|
662
|
+
`button-name`, `heading-order`, `landmark-one-main`, `region`,
|
|
663
|
+
`aria-valid-attr`, `tabindex`, `bypass`, `frame-title`, `meta-viewport`,
|
|
664
|
+
`valid-lang`, `duplicate-id-aria`, `list`, `listitem`.
|
|
665
|
+
|
|
666
|
+
**Keyword**: `Then`
|
|
667
|
+
|
|
668
|
+
**Pattern**
|
|
669
|
+
|
|
670
|
+
```js
|
|
671
|
+
/^the page should not violate the accessibility rule "([^"]*)"$/
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Examples**
|
|
675
|
+
|
|
676
|
+
```gherkin
|
|
677
|
+
Then the page should not violate the accessibility rule "color-contrast"
|
|
678
|
+
Then the page should not violate the accessibility rule "image-alt"
|
|
679
|
+
And the page should not violate the accessibility rule "label"
|
|
680
|
+
Then the page should not violate the accessibility rule "link-name"
|
|
681
|
+
Then the page should not violate the accessibility rule "heading-order"
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
## 25. Then I print accessibility violations
|
|
685
|
+
|
|
686
|
+
Print every axe violation to stdout (debug aid). Strip from CI runs.
|
|
687
|
+
|
|
688
|
+
**Keyword**: `Then`
|
|
689
|
+
|
|
690
|
+
**Pattern**
|
|
691
|
+
|
|
692
|
+
```js
|
|
693
|
+
/^(I |we )*print accessibility violations$/
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
**Examples**
|
|
697
|
+
|
|
698
|
+
```gherkin
|
|
699
|
+
Then I print accessibility violations
|
|
700
|
+
When I am on "/checkout"
|
|
701
|
+
Then I print accessibility violations
|
|
702
|
+
And we print accessibility violations
|
|
703
|
+
Then I print accessibility violations
|
|
704
|
+
And the page should have no critical accessibility violations
|
|
705
|
+
When I follow "Pricing"
|
|
706
|
+
Then I print accessibility violations
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
## 26. Then the page should pass the accessibility rules "image-alt, label"
|
|
710
|
+
|
|
711
|
+
Assert axe finds zero violations of an exact list of rules. Use for
|
|
712
|
+
smoke-test gating: pin the small list of rules you absolutely require to
|
|
713
|
+
pass, run them on every page.
|
|
714
|
+
|
|
715
|
+
**Keyword**: `Then`
|
|
716
|
+
|
|
717
|
+
**Pattern**
|
|
718
|
+
|
|
719
|
+
```js
|
|
720
|
+
/^the page should pass the accessibility rules "([^"]*)"$/
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**Examples**
|
|
724
|
+
|
|
725
|
+
```gherkin
|
|
726
|
+
Then the page should pass the accessibility rules "image-alt, label"
|
|
727
|
+
Then the page should pass the accessibility rules "color-contrast"
|
|
728
|
+
And the page should pass the accessibility rules "button-name, link-name"
|
|
729
|
+
Then the page should pass the accessibility rules "landmark-one-main, region"
|
|
730
|
+
Then the page should pass the accessibility rules "aria-valid-attr, aria-valid-attr-value"
|
|
731
|
+
```
|