@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.
Files changed (301) hide show
  1. package/AGENTS.md +148 -0
  2. package/CLAUDE.md +544 -0
  3. package/README.md +22 -0
  4. package/bin/generate-reports.js +363 -0
  5. package/bin/init-varbase-e2e.js +330 -0
  6. package/bin/postinstall.js +26 -0
  7. package/cucumber.js +125 -0
  8. package/docs/00-quick-start.md +102 -0
  9. package/docs/01-getting-started.md +102 -0
  10. package/docs/02-bbr-smart-waits.md +77 -0
  11. package/docs/03-selector-registry.md +95 -0
  12. package/docs/04-step-reference.md +801 -0
  13. package/docs/05-web-first-assertions.md +91 -0
  14. package/docs/06-network-and-dialogs.md +83 -0
  15. package/docs/07-auth-state.md +75 -0
  16. package/docs/08-clock-mocking.md +59 -0
  17. package/docs/09-api-testing.md +114 -0
  18. package/docs/10-accessibility.md +167 -0
  19. package/docs/11-debugging.md +129 -0
  20. package/docs/12-ai-agent-guide.md +338 -0
  21. package/docs/13-faq.md +236 -0
  22. package/docs/14-recipes-cookbook.md +255 -0
  23. package/docs/15-tag-conventions.md +76 -0
  24. package/docs/16-ci-cd.md +90 -0
  25. package/docs/README.md +125 -0
  26. package/docs/advanced-screenshots/then-i-save-fullscreen-screenshot.md +36 -0
  27. package/docs/advanced-screenshots/then-i-save-width-x-height-screenshot.md +34 -0
  28. package/docs/advanced-screenshots/when-i-save-screenshot-name-filename.md +45 -0
  29. package/docs/advanced-screenshots.md +52 -0
  30. package/docs/advanced-selectors.md +18 -0
  31. package/docs/api-step-definitions.md +45 -0
  32. package/docs/global-settings.md +267 -0
  33. package/docs/install-varbase-e2e/ddev-varbase-e2e.md +52 -0
  34. package/docs/install-varbase-e2e.md +34 -0
  35. package/docs/overview.md +40 -0
  36. package/docs/step-definitions/given-i-am-anonymous-user.md +67 -0
  37. package/docs/step-definitions/given-i-am-homepage.md +68 -0
  38. package/docs/step-definitions/given-i-am-specific-page.md +72 -0
  39. package/docs/step-definitions/then-i-should-be.md +56 -0
  40. package/docs/step-definitions/then-i-should-see.md +62 -0
  41. package/docs/step-definitions/then-item-checkbox.md +54 -0
  42. package/docs/step-definitions/then-item-link-should-contain-url.md +84 -0
  43. package/docs/step-definitions/then-item-should-contain.md +67 -0
  44. package/docs/step-definitions/then-radio-button-value-should-be-selected.md +68 -0
  45. package/docs/step-definitions/then-response-status-code-should-be-number.md +69 -0
  46. package/docs/step-definitions/then-value-radio-button-selected.md +62 -0
  47. package/docs/step-definitions/when-i-attach-file-file-name-element.md +71 -0
  48. package/docs/step-definitions/when-i-check-checkbox.md +60 -0
  49. package/docs/step-definitions/when-i-click-link.md +51 -0
  50. package/docs/step-definitions/when-i-click-operation-text-row.md +71 -0
  51. package/docs/step-definitions/when-i-fill.md +59 -0
  52. package/docs/step-definitions/when-i-go-homepage.md +60 -0
  53. package/docs/step-definitions/when-i-go-specific-page.md +67 -0
  54. package/docs/step-definitions/when-i-move-backward-one-page.md +49 -0
  55. package/docs/step-definitions/when-i-move-forward-one-page.md +58 -0
  56. package/docs/step-definitions/when-i-press-button.md +58 -0
  57. package/docs/step-definitions/when-i-reload-page.md +51 -0
  58. package/docs/step-definitions/when-i-scroll.md +73 -0
  59. package/docs/step-definitions/when-i-select-option-select-list.md +53 -0
  60. package/docs/step-definitions/when-i-select-radio-button-value.md +62 -0
  61. package/docs/step-definitions/when-i-uncheck-checkbox.md +57 -0
  62. package/docs/step-definitions/when-i-wait-ajax-finish.md +64 -0
  63. package/docs/step-definitions/when-i-wait.md +62 -0
  64. package/docs/step-definitions.md +82 -0
  65. package/docs/steps/README.md +137 -0
  66. package/docs/steps/a11y.md +731 -0
  67. package/docs/steps/action.md +181 -0
  68. package/docs/steps/api.md +679 -0
  69. package/docs/steps/assertion.md +328 -0
  70. package/docs/steps/auth.md +108 -0
  71. package/docs/steps/clock.md +171 -0
  72. package/docs/steps/cookie.md +293 -0
  73. package/docs/steps/debug.md +52 -0
  74. package/docs/steps/dialog.md +226 -0
  75. package/docs/steps/drupal-canvas.md +414 -0
  76. package/docs/steps/drupal-ckeditor.md +118 -0
  77. package/docs/steps/drupal-core.md +688 -0
  78. package/docs/steps/drupal-layout-builder.md +437 -0
  79. package/docs/steps/drupal-media.md +107 -0
  80. package/docs/steps/drupal-moderation.md +81 -0
  81. package/docs/steps/drupal-paragraphs.md +36 -0
  82. package/docs/steps/element.md +455 -0
  83. package/docs/steps/field.md +648 -0
  84. package/docs/steps/file-download.md +235 -0
  85. package/docs/steps/form.md +344 -0
  86. package/docs/steps/iframe.md +248 -0
  87. package/docs/steps/input.md +220 -0
  88. package/docs/steps/javascript.md +111 -0
  89. package/docs/steps/keyboard.md +107 -0
  90. package/docs/steps/link.md +217 -0
  91. package/docs/steps/metatag.md +99 -0
  92. package/docs/steps/modal.md +232 -0
  93. package/docs/steps/navigation.md +275 -0
  94. package/docs/steps/network.md +284 -0
  95. package/docs/steps/path.md +203 -0
  96. package/docs/steps/response.md +102 -0
  97. package/docs/steps/responsive.md +139 -0
  98. package/docs/steps/rest.md +140 -0
  99. package/docs/steps/screenshot.md +211 -0
  100. package/docs/steps/scroll.md +266 -0
  101. package/docs/steps/selectors.md +848 -0
  102. package/docs/steps/storage.md +254 -0
  103. package/docs/steps/table.md +216 -0
  104. package/docs/steps/varbase.md +391 -0
  105. package/docs/steps/video.md +111 -0
  106. package/docs/steps/wait.md +553 -0
  107. package/docs/steps/web-first.md +289 -0
  108. package/docs/steps/xml.md +505 -0
  109. package/docs/steps/yaml.md +951 -0
  110. package/examples/a11y.html +31 -0
  111. package/examples/about-us.html +11 -0
  112. package/examples/account.html +32 -0
  113. package/examples/ajax-wait-examples.html +147 -0
  114. package/examples/contact-us.html +10 -0
  115. package/examples/cookies.html +10 -0
  116. package/examples/date.html +12 -0
  117. package/examples/dynamic-examples.html +498 -0
  118. package/examples/element.html +11 -0
  119. package/examples/example-api.json +28 -0
  120. package/examples/existing-page.html +11 -0
  121. package/examples/field.html +24 -0
  122. package/examples/index.html +37 -0
  123. package/examples/keyboard.html +11 -0
  124. package/examples/links.html +9 -0
  125. package/examples/modal.html +14 -0
  126. package/examples/path.html +3 -0
  127. package/examples/table.html +13 -0
  128. package/examples/test--modal-dialogs.html +252 -0
  129. package/examples/test--then--i-should--not--see-text-in-element.html +48 -0
  130. package/examples/test--then--i-should--see-text-in-element.html +48 -0
  131. package/examples/test--then--i-should--see-text-matching-pattern.html +31 -0
  132. package/examples/test--then--i-should-see-text-in-table-row.html +232 -0
  133. package/examples/test--then--the-checkbox-checked.html +68 -0
  134. package/examples/test--then--the-element-should_not-contain-cssproperty.html +47 -0
  135. package/examples/test--then--the-link-should-contain.html +21 -0
  136. package/examples/test--when--i-additionally-select.html +27 -0
  137. package/examples/test--when--i-attach-file-to-feild.html +50 -0
  138. package/examples/test--when--i-check-uncheck-checkbox.html +47 -0
  139. package/examples/test--when--i-click-link.html +18 -0
  140. package/examples/test--when--i-click-text-in-table-row.html +178 -0
  141. package/examples/test--when--i-fill-in.html +48 -0
  142. package/examples/test--when--i-press-button.html +31 -0
  143. package/examples/test--when--i-reload-page.html +27 -0
  144. package/examples/test--when--i-scroll-functionality.html +177 -0
  145. package/examples/test--when--i-scroll-left-right-functionality.html +149 -0
  146. package/examples/test--when--i-select-option-from-dropdownlist.html +35 -0
  147. package/examples/test--when--i-select-radio-button.html +95 -0
  148. package/examples/test--when-i-wait-max-of-time.html +39 -0
  149. package/examples/test--when-i-wait-page-until-is-loaded.html +47 -0
  150. package/examples/test--when-i-wait-specific-time.html +39 -0
  151. package/examples/test-acceptable-url-path.html +11 -0
  152. package/examples/video-demo.html +43 -0
  153. package/package.json +56 -0
  154. package/playwright.config.ts +39 -0
  155. package/tests/assets/test-document.pdf +14 -0
  156. package/tests/assets/vardot.png +0 -0
  157. package/tests/features/a11y.feature +39 -0
  158. package/tests/features/ajax-wait-examples.feature +24 -0
  159. package/tests/features/api-step-definitions-individual.feature +185 -0
  160. package/tests/features/complete-api-testing-examples.feature +205 -0
  161. package/tests/features/cookie.feature +13 -0
  162. package/tests/features/date.feature +11 -0
  163. package/tests/features/dynamic-content-examples.feature +156 -0
  164. package/tests/features/element.feature +16 -0
  165. package/tests/features/field.feature +25 -0
  166. package/tests/features/keyboard.feature +10 -0
  167. package/tests/features/link.feature +11 -0
  168. package/tests/features/modal-advanced-example.feature +54 -0
  169. package/tests/features/modal-basic-example.feature +42 -0
  170. package/tests/features/modal-error-handling-example.feature +37 -0
  171. package/tests/features/modal.feature +11 -0
  172. package/tests/features/path.feature +16 -0
  173. package/tests/features/response.feature +8 -0
  174. package/tests/features/responsive.feature +10 -0
  175. package/tests/features/table.feature +18 -0
  176. package/tests/features/test--given--i-am-an-anonymous-user.feature +10 -0
  177. package/tests/features/test--given--i-am-on-homepage.feature +16 -0
  178. package/tests/features/test--then--i-save-screenshot.feature +33 -0
  179. package/tests/features/test--then--i-see-locator.feature +320 -0
  180. package/tests/features/test--then--i-should--not--see-text-in-element.feature +13 -0
  181. package/tests/features/test--then--i-should--see-text-in-element-by-attr.feature +10 -0
  182. package/tests/features/test--then--i-should--see-text-in-element.feature +10 -0
  183. package/tests/features/test--then--i-should--see-text-matching-pattern-in-element.feature +13 -0
  184. package/tests/features/test--then--i-should--see-text-matching-pattern.feature +18 -0
  185. package/tests/features/test--then--i-should-be-on-page.feature +10 -0
  186. package/tests/features/test--then--i-should-be-on-the-homepage.feature +10 -0
  187. package/tests/features/test--then--i-should-not-see-an-element-by-attr.feature +8 -0
  188. package/tests/features/test--then--i-should-not-see-an-element.feature +8 -0
  189. package/tests/features/test--then--i-should-see-an-element-by-attr.feature +8 -0
  190. package/tests/features/test--then--i-should-see-an-element.feature +8 -0
  191. package/tests/features/test--then--i-should-see-n-elements.feature +24 -0
  192. package/tests/features/test--then--i-should-see-text-in-table-row.feature +96 -0
  193. package/tests/features/test--then--print-current-url-and-response.feature +21 -0
  194. package/tests/features/test--then--the-checkbox-is-checked.feature +18 -0
  195. package/tests/features/test--then--the-checkbox-should-be-checked.feature +16 -0
  196. package/tests/features/test--then--the-element-should-contain-cssproperty.feature +9 -0
  197. package/tests/features/test--then--the-element-should-not-contain-cssproperty.feature +10 -0
  198. package/tests/features/test--then--the-field-should-contain-value.feature +11 -0
  199. package/tests/features/test--then--the-response-should-contain.feature +11 -0
  200. package/tests/features/test--then--the-response-status-code-should-be.feature +31 -0
  201. package/tests/features/test--then--the-url-should-match.feature +7 -0
  202. package/tests/features/test--then-the-link-should-contain-by-attribute.feature +18 -0
  203. package/tests/features/test--then-the-link-should-contain.feature +7 -0
  204. package/tests/features/test--when--i-additionally-select.feature +30 -0
  205. package/tests/features/test--when--i-attach-file-to-feild.feature +9 -0
  206. package/tests/features/test--when--i-check-checkbox.feature +21 -0
  207. package/tests/features/test--when--i-click-link-by-attribute.feature +21 -0
  208. package/tests/features/test--when--i-click-link.feature +9 -0
  209. package/tests/features/test--when--i-click-text-in-table-row.feature +37 -0
  210. package/tests/features/test--when--i-fill-in-by-attr.feature +31 -0
  211. package/tests/features/test--when--i-fill-in-table-by-attr.feature +19 -0
  212. package/tests/features/test--when--i-fill-in.feature +32 -0
  213. package/tests/features/test--when--i-follow.feature +22 -0
  214. package/tests/features/test--when--i-go-to-homepage.feature +9 -0
  215. package/tests/features/test--when--i-move-forward-backward-one-page.feature +14 -0
  216. package/tests/features/test--when--i-press-button-by-attribute.feature +18 -0
  217. package/tests/features/test--when--i-press-button.feature +13 -0
  218. package/tests/features/test--when--i-reload-page.feature +11 -0
  219. package/tests/features/test--when--i-scroll-left-right.feature +48 -0
  220. package/tests/features/test--when--i-scroll.feature +48 -0
  221. package/tests/features/test--when--i-select-option-from-dropdownlist.feature +21 -0
  222. package/tests/features/test--when--i-select-radio-button.feature +37 -0
  223. package/tests/features/test--when--i-wait-page-is-loaded.feature +8 -0
  224. package/tests/features/test--when--i-wait-time.feature +21 -0
  225. package/tests/features/video.feature +18 -0
  226. package/tests/features/wait.feature +7 -0
  227. package/tests/features/yaml.feature +102 -0
  228. package/tests/selectors/_canonical-keys.json +113 -0
  229. package/tests/selectors/back-end-selectors.json +19 -0
  230. package/tests/selectors/cms-contentful-admin.json +35 -0
  231. package/tests/selectors/cms-craft-admin.json +39 -0
  232. package/tests/selectors/cms-drupal-cms-gin.json +56 -0
  233. package/tests/selectors/cms-drupal-core-claro.json +50 -0
  234. package/tests/selectors/cms-generic-admin.json +34 -0
  235. package/tests/selectors/cms-ghost-admin.json +34 -0
  236. package/tests/selectors/cms-joomla-admin.json +41 -0
  237. package/tests/selectors/cms-magento2-admin.json +32 -0
  238. package/tests/selectors/cms-prestashop-admin.json +38 -0
  239. package/tests/selectors/cms-shopify-admin.json +25 -0
  240. package/tests/selectors/cms-strapi-admin.json +42 -0
  241. package/tests/selectors/cms-typo3-admin.json +41 -0
  242. package/tests/selectors/cms-woocommerce-front.json +50 -0
  243. package/tests/selectors/cms-wordpress-admin.json +31 -0
  244. package/tests/selectors/framework-ant-design.json +80 -0
  245. package/tests/selectors/framework-bootstrap.json +86 -0
  246. package/tests/selectors/framework-bulma.json +74 -0
  247. package/tests/selectors/framework-chakra.json +58 -0
  248. package/tests/selectors/framework-foundation.json +51 -0
  249. package/tests/selectors/framework-material-ui.json +72 -0
  250. package/tests/selectors/framework-shadcn.json +51 -0
  251. package/tests/selectors/framework-tailwind.json +40 -0
  252. package/tests/selectors/framework-vuetify.json +61 -0
  253. package/tests/selectors/front-end-selectors.json +16 -0
  254. package/tests/selectors/homepage-selectors.json +13 -0
  255. package/tests/step-definitions/a11y.steps.js +800 -0
  256. package/tests/step-definitions/action.steps.js +167 -0
  257. package/tests/step-definitions/api.steps.js +732 -0
  258. package/tests/step-definitions/assertion.steps.js +352 -0
  259. package/tests/step-definitions/auth.steps.js +126 -0
  260. package/tests/step-definitions/clock.steps.js +128 -0
  261. package/tests/step-definitions/cookie.steps.js +216 -0
  262. package/tests/step-definitions/debug.steps.js +39 -0
  263. package/tests/step-definitions/dialog.steps.js +193 -0
  264. package/tests/step-definitions/drupal-canvas.steps.js +764 -0
  265. package/tests/step-definitions/drupal-ckeditor.steps.js +108 -0
  266. package/tests/step-definitions/drupal-core.steps.js +665 -0
  267. package/tests/step-definitions/drupal-helpers.js +371 -0
  268. package/tests/step-definitions/drupal-layout-builder.steps.js +466 -0
  269. package/tests/step-definitions/drupal-media.steps.js +99 -0
  270. package/tests/step-definitions/drupal-moderation.steps.js +71 -0
  271. package/tests/step-definitions/drupal-paragraphs.steps.js +50 -0
  272. package/tests/step-definitions/element.steps.js +356 -0
  273. package/tests/step-definitions/field.steps.js +653 -0
  274. package/tests/step-definitions/file-download.steps.js +211 -0
  275. package/tests/step-definitions/form.steps.js +333 -0
  276. package/tests/step-definitions/iframe.steps.js +228 -0
  277. package/tests/step-definitions/input.steps.js +202 -0
  278. package/tests/step-definitions/javascript.steps.js +232 -0
  279. package/tests/step-definitions/keyboard.steps.js +112 -0
  280. package/tests/step-definitions/link.steps.js +142 -0
  281. package/tests/step-definitions/metatag.steps.js +91 -0
  282. package/tests/step-definitions/modal.steps.js +244 -0
  283. package/tests/step-definitions/navigation.steps.js +218 -0
  284. package/tests/step-definitions/network.steps.js +280 -0
  285. package/tests/step-definitions/path.steps.js +141 -0
  286. package/tests/step-definitions/response.steps.js +98 -0
  287. package/tests/step-definitions/responsive.steps.js +125 -0
  288. package/tests/step-definitions/rest.steps.js +111 -0
  289. package/tests/step-definitions/screenshot.steps.js +423 -0
  290. package/tests/step-definitions/scroll.steps.js +189 -0
  291. package/tests/step-definitions/selectors.steps.js +1003 -0
  292. package/tests/step-definitions/storage.steps.js +194 -0
  293. package/tests/step-definitions/table.steps.js +181 -0
  294. package/tests/step-definitions/varbase-e2e.js +897 -0
  295. package/tests/step-definitions/varbase.steps.js +458 -0
  296. package/tests/step-definitions/video.steps.js +178 -0
  297. package/tests/step-definitions/wait.steps.js +400 -0
  298. package/tests/step-definitions/web-first.steps.js +298 -0
  299. package/tests/step-definitions/xml.steps.js +411 -0
  300. package/tests/step-definitions/yaml.steps.js +913 -0
  301. package/tsconfig.json +26 -0
@@ -0,0 +1,801 @@
1
+ # Step Definition Reference
2
+
3
+ All step definitions ship in `tests/step-definitions/*.steps.js`. Cucumber-js loads every file in that directory automatically — you never `require()` a step file from your features.
4
+
5
+ This is a topical reference — the fast lookup when you know roughly what you want.
6
+
7
+ For the **full catalogue**, with every step's pattern and at least five valid Gherkin examples each, see [`steps/`](steps/README.md): 495 steps across 44 category pages, generated from the step definitions themselves. The Drupal and Varbase packs are documented there and not repeated below.
8
+
9
+ ## Navigation
10
+
11
+ | Step | Source |
12
+ | --- | --- |
13
+ | `Given I am on the homepage` | `varbase-e2e.js` |
14
+ | `Given I am on "/path"` | `varbase-e2e.js` |
15
+ | `When I go to the homepage` | `varbase-e2e.js` |
16
+ | `When I go to "/path"` | `varbase-e2e.js` |
17
+ | `When I move backward one page` | `varbase-e2e.js` |
18
+ | `When I move forward one page` | `varbase-e2e.js` |
19
+ | `When I reload the page` | `varbase-e2e.js` |
20
+
21
+ ## Click & press
22
+
23
+ | Step | Notes |
24
+ | --- | --- |
25
+ | `When I click "Text"` | Finds link/button by visible text |
26
+ | `When I click "value" by attr` | Finds by id/class/name/aria/data-test |
27
+ | `When I click "Text" in the "Row" row` | Click inside a table row |
28
+ | `When I press "Submit" button` | Native form submit / role=button |
29
+
30
+ ## Form fields
31
+
32
+ | Step | Notes |
33
+ | --- | --- |
34
+ | `When I fill in "Label" with "value"` | Resolves by label / placeholder / name |
35
+ | `When I fill in "value" for "Label"` | Reverse phrasing |
36
+ | `When I fill in "value" for "selector" by attr` | By attribute |
37
+ | `When I fill in the following:` (table) | Bulk fill |
38
+ | `When I select "Option" from "Label"` | `<select>` |
39
+ | `When I additionally select "Option" from "Label"` | Multi-select |
40
+ | `When I check the checkbox "#agree"` | |
41
+ | `When I uncheck the checkbox "#agree"` | |
42
+ | `When I choose the radio button "#radio"` | |
43
+
44
+ ## Waits — see [BBR](02-bbr-smart-waits.md)
45
+
46
+ All wait phrasings live in `wait.steps.js`. Quick list:
47
+
48
+ ```
49
+ I wait N seconds # Bounded smart wait
50
+ I wait max of N seconds # Same; explicit "max"
51
+ I wait for N seconds # Cucumber {int}
52
+ I wait for N seconds for AJAX to finish # Same
53
+ I wait until the page is loaded # Edge
54
+ I wait for AJAX to finish # Edge
55
+ I wait until the network is idle # Edge alias
56
+ I wait until the page is interactive # body+DOMContentLoaded
57
+ I wait until pending timers settle # setTimeout drain
58
+ I wait for "selector" to appear # Selector edge
59
+ I wait for "selector" to disappear # Selector edge
60
+ I wait for the text "..." to appear/disappear # Text edge
61
+ I wait until the URL contains "..." # URL edge
62
+ I wait until the page title is/contains "..." # Title edge
63
+ I wait until N elements match "selector" # Count edge
64
+ I wait until at least N elements match "selector" # Count edge
65
+ I wait for the modal to appear/disappear # Modal edge
66
+ eventually I should see "..." # Polling text assertion
67
+ ```
68
+
69
+ ## Modal
70
+
71
+ | Step | |
72
+ | --- | --- |
73
+ | `Then I should see the modal` | |
74
+ | `Then I should not see the modal` | |
75
+ | `Then I should see "text" in the modal` | |
76
+ | `Then the modal should contain "text"` | |
77
+ | `When I click "OK" in the modal` | |
78
+ | `When I click on "#sel" in the modal` | |
79
+ | `When I close the modal` | |
80
+
81
+ ## Web-first assertions (auto-retry)
82
+
83
+ ```
84
+ "selector" should be visible|hidden|attached|focused|enabled|disabled|editable [within N seconds]
85
+ "selector" should be in the viewport [within N seconds]
86
+ "selector" should have a count of N
87
+ "selector" should have text "..."
88
+ "selector" should contain text "..."
89
+ "selector" should have value "..."
90
+ "selector" should have attribute "name" with value "..."
91
+ "selector" should have class "..."
92
+ I click the "Text" button|link|tab|menuitem|checkbox|radio|option
93
+ the "Text" button should be visible
94
+ ```
95
+
96
+ ## Cookies / response / metatag
97
+
98
+ See `cookie.steps.js`, `response.steps.js`, `metatag.steps.js`.
99
+
100
+ ## Tables
101
+
102
+ ```
103
+ the table "selector" should have N rows
104
+ the table "selector" should have N columns
105
+ the table "selector" should not be empty
106
+ I should see "Text" in the "RowMatch" row
107
+ ```
108
+
109
+ ## Iframes / file download / REST / XML / keyboard
110
+
111
+ See per-topic files in `tests/step-definitions/`. Each file has JSDoc above every step with all pronoun and tense variants.
112
+
113
+ ## Network mocking — see [Networking](06-network-and-dialogs.md)
114
+
115
+ ```
116
+ Given the URL "**/api/**" returns the JSON: """ ... """
117
+ Given the URL "**/api/login" returns status 401 with body "..."
118
+ Given the URL "**/analytics.js" is blocked
119
+ Given the URL "**/api/**" is delayed by 1500 ms
120
+ Given the network is offline
121
+ Given the network is online
122
+ Given I start recording network requests
123
+ Then a GET request to "**/api/users" should have been made
124
+ Then no request to "**/tracking" should have been made
125
+ ```
126
+
127
+ ## Browser dialogs
128
+
129
+ Single-shot (auto-detach after the next dialog):
130
+
131
+ ```
132
+ Given I will accept the next dialog
133
+ Given I will dismiss the next dialog
134
+ Given I will accept the next dialog with "input"
135
+ ```
136
+
137
+ Persistent (handler stays for the rest of the scenario):
138
+
139
+ ```
140
+ Given I accept all confirmation dialogs
141
+ Given I do not accept any confirmation dialogs
142
+ ```
143
+
144
+ Inspect the most recent dialog:
145
+
146
+ ```
147
+ Then the last dialog message should be "..."
148
+ Then the last dialog message should contain "..."
149
+ Then the last dialog type should be "alert"|"confirm"|"prompt"|"beforeunload"
150
+ ```
151
+
152
+ ## Clock — see [Clock](08-clock-mocking.md)
153
+
154
+ ```
155
+ Given the system time is "2026-05-08T10:00:00Z"
156
+ When I advance the clock by N ms|seconds|minutes
157
+ When I pause the clock
158
+ When I resume the clock
159
+ When I set the system time to "..."
160
+ ```
161
+
162
+ ## Auth — see [Auth state](07-auth-state.md)
163
+
164
+ ```
165
+ When I save the auth state to "tests/auth/admin.json"
166
+ Given I restore the auth state from "tests/auth/admin.json"
167
+ Given I clear the auth state
168
+ ```
169
+
170
+ ## API — see [API testing](09-api-testing.md)
171
+
172
+ ```
173
+ Given I set the header "X-Token" to "abc123"
174
+ Given I set the request body to '{"name": "Alice"}'
175
+ When I send a POST request to "/api/users"
176
+ When I send a POST request to "/api/users" with body: """ ... """
177
+ When I send a POST request to "/api/users" with form data: """ ... """
178
+ Then the API response code should be 200
179
+ Then the API response should contain "Alice"
180
+ Then the JSON property "user.name" should be "Alice"
181
+ Then the response header "content-type" should contain "json"
182
+ ```
183
+
184
+ ## A11y — see [Accessibility](10-accessibility.md)
185
+
186
+ ```
187
+ Then every image should have an alt attribute
188
+ Then every form field should have an accessible label
189
+ Then the page should have a main landmark
190
+ Then the page should have a navigation landmark
191
+ Then the page should have exactly one h1
192
+ Then the page should declare a language
193
+ Then the page language should be "en"
194
+ Then the focused element should match "selector"
195
+ Then the focused element should be labeled "..."
196
+ ```
197
+
198
+ ## JS errors
199
+
200
+ ```
201
+ Then there should be no JavaScript errors
202
+ Then there should be no JavaScript warnings
203
+ Then JavaScript errors should not match "TypeError"
204
+ Then print JavaScript errors
205
+ ```
206
+
207
+ Errors are always tracked (page errors + matched console levels). At scenario end the collector reports per the active **mode**:
208
+
209
+ | Mode | Behaviour |
210
+ | --- | --- |
211
+ | `warn` (default) | Logs a yellow warning to stderr — scenario still passes |
212
+ | `fail` | Fails the scenario with the error list |
213
+ | `off` | Silent |
214
+
215
+ Mode resolution (first match wins):
216
+
217
+ 1. **Scenario tag** — `@js-fail`, `@js-warn`, `@js-off`, plus back-compat `@javascript` (= fail) and `@js-errors` (= off).
218
+ 2. **Env var** — `VARBASE_E2E_JS_ERROR_MODE=warn|fail|off`.
219
+ 3. **`worldParameters.javascript.mode`** in `cucumber.js`.
220
+ 4. **Default** — `warn`.
221
+
222
+ Settings (`worldParameters.javascript`):
223
+
224
+ | Key | Env override | Default | Effect |
225
+ | --- | --- | --- | --- |
226
+ | `mode` | `VARBASE_E2E_JS_ERROR_MODE` | `warn` | `warn` / `fail` / `off` |
227
+ | `levels` | `VARBASE_E2E_JS_ERROR_LEVELS` | `['error']` | Console levels to capture (csv when via env: `error,warning`) |
228
+ | `ignore` | `VARBASE_E2E_JS_ERROR_IGNORE` | _none_ | Regex; matching messages dropped before report |
229
+ | `beforeScenario` | `VARBASE_E2E_JS_ERROR_BEFORE` | `false` | Snapshot pre-existing errors at scenario start |
230
+ | `afterScenario` | `VARBASE_E2E_JS_ERROR_AFTER` | `true` | Report at scenario end |
231
+
232
+ The explicit step `Then there should be no JavaScript errors` always asserts (independent of `mode`) and suppresses the auto-report so a single error is not announced twice.
233
+
234
+ ## Video recording
235
+
236
+ ```
237
+ When I start video recording
238
+ When I stop video recording
239
+ When I save the current video as "checkout-flow.webm"
240
+ Then print video path
241
+ ```
242
+
243
+ Recording is **off by default**. Resolution priority:
244
+
245
+ 1. **Scenario tag** — `@video` (force on) / `@no-video` (force off).
246
+ 2. **Env var** — `VARBASE_E2E_VIDEO=on|off|on-failure|tag`.
247
+ 3. **`worldParameters.video.mode`** — `'off'` (default) / `'on'` / `'on-failure'` / `'tag'`.
248
+
249
+ Mode semantics:
250
+
251
+ | Mode | Behaviour |
252
+ | --- | --- |
253
+ | `off` (default) | No recording. |
254
+ | `on` | Every scenario produces a `webm`. |
255
+ | `on-failure` | Every scenario records; only failures are kept on disk. |
256
+ | `tag` | Only scenarios tagged `@video` record. |
257
+
258
+ Settings (`worldParameters.video`):
259
+
260
+ | Key | Env override | Default | Effect |
261
+ | --- | --- | --- | --- |
262
+ | `mode` | `VARBASE_E2E_VIDEO` | `off` | Activation mode. |
263
+ | `dir` | `VARBASE_E2E_VIDEO_DIR` | `./videos` | Output directory (created automatically). |
264
+ | `size` | _none_ | `{ width: 1280, height: 720 }` | Recording resolution. |
265
+ | `filenamePattern` | _none_ | `{datetime}.{feature_file}.{scenario}.{status}.{ext}` | Per-scenario filename. Tokens: `{datetime} {feature_file} {feature} {scenario} {status} {ext}`. |
266
+
267
+ The `start` / `stop` mid-scenario steps close + reopen the browser context (Playwright records at context creation only). Page state is lost across the boundary — call `start` BEFORE any navigation. `videos/` is gitignored.
268
+
269
+ ## Date tokens
270
+
271
+ Use `[relative:OFFSET]` or `[relative:OFFSET#FORMAT]` anywhere in a step argument:
272
+
273
+ ```gherkin
274
+ Given the system time is "[relative:now#YYYY-MM-DD]"
275
+ When I fill in "[relative:+1 day#YYYY-MM-DD]" for "Birth date"
276
+ ```
277
+
278
+ OFFSET examples: `now`, `+1 day`, `-2 hours`, `+1 week`, `next monday`, `last friday`. FORMAT tokens: `YYYY MM DD HH mm ss`.
279
+
280
+ ## Per-file step index
281
+
282
+ This index lists every public step grouped by source file, with one Gherkin example per step. It is generated from the JSDoc above each step definition. For 5+ examples per step, see the JSDoc in the source file directly.
283
+
284
+ ### a11y.steps.js
285
+
286
+ - *^every image should have an alt attribute$* · Example: `Then every image should have an alt attribute`
287
+ - *^every form field should have an accessible label$* · Example: `Then every form field should have an accessible label`
288
+ - *^the page should have a main landmark$* · Example: `Then the page should have a main landmark`
289
+ - *^the page should have a navigation landmark$* · Example: `Then the page should have a navigation landmark`
290
+ - *^the page should have exactly one h1$* · Example: `Then the page should have exactly one h1`
291
+ - *^the focused element should match "([^"]*)"$* · Example: `Then the focused element should match "#email"`
292
+ - *^the focused element should be labeled "([^"]*)"$* · Example: `Then the focused element should be labeled "Email"`
293
+ - *^the page should declare a language$* · Example: `Then the page should declare a language`
294
+ - *^the page language should be "([^"]*)"$* · Example: `Then the page language should be "en"`
295
+ - *^the heading hierarchy should be valid$* · Example: `Then the heading hierarchy should be valid`
296
+ - *^the page should have a skip link$* · Example: `Then the page should have a skip link`
297
+ - *^every button should have an accessible name$* · Example: `Then every button should have an accessible name`
298
+ - *^every link should have an accessible name$* · Example: `Then every link should have an accessible name`
299
+ - *^no element should have a positive tabindex$* · Example: `Then no element should have a positive tabindex`
300
+ - *^every ARIA reference should resolve$* · Example: `Then every ARIA reference should resolve`
301
+ - *^every ARIA role should be valid$* · Example: `Then every ARIA role should be valid`
302
+ - *^required fields should be consistently marked$* · Example: `Then required fields should be consistently marked`
303
+ - *^the page should have a title$* · Example: `Then the page should have a title`
304
+ - *^user zoom should be allowed$* · Example: `Then user zoom should be allowed`
305
+ - *^the page should pass an accessibility audit(?: at level "(A|AA|AAA)")?$* · Example: `Then the page should pass an accessibility audit`
306
+ - *^the page should have no (critical|serious|moderate|minor) accessibility violations$* · Example: `Then the page should have no critical accessibility violations`
307
+ - *^the element "([^"]*)" should pass an accessibility audit$* · Example: `Then the element "main" should pass an accessibility audit`
308
+ - *^the page should pass an accessibility audit excluding "([^"]*)"$* · Example: `Then the page should pass an accessibility audit excluding "iframe.payment"`
309
+ - *^the page should not violate the accessibility rule "([^"]*)"$* · Example: `Then the page should not violate the accessibility rule "color-contrast"`
310
+ - *^(I |we )*print accessibility violations$* · Example: `Then I print accessibility violations`
311
+ - *^the page should pass the accessibility rules "([^"]*)"$* · Example: `Then the page should pass the accessibility rules "image-alt, label"`
312
+
313
+ ### action.steps.js
314
+
315
+ - *^(I |we )*press( the)* "([^"]*)?"( button)*$* · Example: `When I press "Log In"`
316
+ - *^(I |we )*press "([^"]*)?" by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I press "btn-pressid" by attr`
317
+ - *^(I |we )*click "([^"]*)?"$* · Example: `When I click "Contact Us"`
318
+ - *^(I |we )*click "([^"]*)?" by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I click "#about-us-id" by attr`
319
+ - *^(I |we )*click "([^"]*)?" in( the)* "([^"]*)?" row$* · Example: `When I click "Edit" in the "John Smith" row`
320
+ - *^(I |we )*follow "([^"]*)"$* · Example: `When I follow "Contact Us"`
321
+ - *^(I |we )*attach( the)* file "([^"]*)?" to "([^"]*)?"$* · Example: `When I attach the file "profile-icon.jpg" to "#profile-icon-upload"`
322
+
323
+ ### api.steps.js
324
+
325
+ - *^(?:I am|we are) authenticating as "([^"]*)" with "([^"]*)" password$* · Example: `Given I am authenticating as "admin" with "password123" password`
326
+ - *^(?:I |we )?set header "([^"]*)" with value "([^"]*)"$* · Example: `Given I set header "Content-Type" with value "application/json"`
327
+ - *^(?:the API base URL is|I set the API base URL to|the base URL is) "([^"]*)"$* · Example: `Given the API base URL is "https://jsonplaceholder.typicode.com"`
328
+ - *^(?:I set the header|we set the header|the header) "([^"]*)" (?:to|is) "([^"]*)"$* · Example: `Given I set the header "Content-Type" to "application/json"`
329
+ - *^(?:I|we) set the following headers:$* · Example: `Given I set the following headers:`
330
+ - *^(?:I set the request body to|we set the request body to|the request body is) '([^']*)'$* · Example: `Given I set the request body to '{"name": "John", "email": "john@example.com"}'`
331
+ - *^(?:I|we) set the request body with:$* · Example: `Given I set the request body with:`
332
+ - *^(?:I |we )?send a ([A-Z]+) request to "([^"]+)"$* · Example: `When I send a GET request to "/users"`
333
+ - *^(?:I |we )?send a ([A-Z]+) request to "([^"]+)" with values:$* · Example: `When I send a POST request to "/users" with values:`
334
+ - *^(?:I |we )?send a ([A-Z]+) request to "([^"]+)" with body:$* · Example: `When I send a POST request to "/users" with body:`
335
+ - *^(?:I |we )?send a ([A-Z]+) request to "([^"]+)" with form data:$* · Example: `When I send a POST request to "/login" with form data:`
336
+ - *^(?:the )?API response code should be (\d+)$* · Example: `Then the API response code should be 200`
337
+ - *^(?:the )?API response should contain "([^"]*)"$* · Example: `Then the API response should contain "success"`
338
+ - *^(?:the )?API response should not contain "([^"]*)"$* · Example: `Then the API response should not contain "error"`
339
+ - *^(?:the )?API response should contain json:$* · Example: `Then the API response should contain json:`
340
+ - *^(?:the JSON response should have|the API response should have|the JSON property) "([^"]*)" (?:equal to|should be) (.+)$* · Example: `Then the JSON response should have "name" equal to "John Doe"`
341
+ - *^(?:the JSON response should have property|the API response should contain property) "([^"]*)"$* · Example: `Then the JSON response should have property "id"`
342
+ - *^(?:the JSON response should not have property|the API response should not contain property) "([^"]*)"$* · Example: `Then the JSON response should not have property "password"`
343
+ - *^(?:the response should be valid JSON|the API response should be valid JSON)$* · Example: `Then the response should be valid JSON`
344
+ - *^(?:the response header|the header) "([^"]*)" should (?:be|contain) "([^"]*)"$* · Example: `Then the response header "Content-Type" should be "application/json"`
345
+ - *^print API response$* · Example: `Then print API response`
346
+ - *^(?:I|we) set placeholder "([^"]*)" to "([^"]*)"$* · Example: `Given I set placeholder "{{userId}}" to "123"`
347
+
348
+ ### assertion.steps.js
349
+
350
+ - *^(I |we )*should( not)* see "([^"]*)?"$* · Example: `Then I should see "Welcome"`
351
+ - *^(I |we )*should( not)* see text matching "([^"]*)?"$* · Example: `Then I should see text matching "^T\w+"`
352
+ - *^(I |we )*should( not)* see "([^"]*)?" in( the)* "([^"]*)?" row$* · Example: `Then I should see "Active" in the "John Smith" row`
353
+ - *^(I |we )*should( not)* see (a|an) "([^"]*)?" element$* · Example: `Then I should see a "Username" element`
354
+ - *^(I |we )*should( not)* see (a|an) "([^"]*)?" element by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `Then I should see a "uname" element by its "id" attr`
355
+ - *^(I |we )*should( not)* see "([^"]*)?" in( the)* "([^"]*)?" element$* · Example: `Then I should see "John Smith" in the "Username" element`
356
+ - *^(I |we )*should( not)* see "([^"]*)?" in( the)* "([^"]*)?" element by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `Then I should see "John Smith" in the "uname" element by its "id" attr`
357
+ - *^(I |we )*should( not)* see text matching "([^"]*)?" in( the)* "([^"]*)?" element$* · Example: `Then I should see text matching "\d{4}" in the "#year" element`
358
+ - *^(the )*"([^"]*)?" element should( not)* contain "([^"]*)?"$* · Example: `Then the "body" element should contain "color:white;"`
359
+ - *^(I |we )*should see (\d+) "([^"]*)" elements?$* · Example: `Then I should see 3 "li" elements`
360
+ - *^(the )*"([^"]*)?" link should contain "([^"]*)?"$* · Example: `Then the "Login" link should contain "/log-in"`
361
+ - *^(the )*"([^"]*)?" link should contain "([^"]*)?" by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `Then the "#about-us-id" link should contain "about" by attr`
362
+ - *^(the )*response should( not)* contain "([^"]*)?"$* · Example: `Then the response should contain "Welcome visitor"`
363
+ - *^(the )*response status code should( not)* be (\d+)$* · Example: `Then the response status code should be 200`
364
+
365
+ ### auth.steps.js
366
+
367
+ - *^(I |we )*save the auth state to "([^"]*)"$* · Example: `When I save the auth state to "tests/auth/admin.json"`
368
+ - *^(I |we )*restore the auth state from "([^"]*)"$* · Example: `Given I restore the auth state from "tests/auth/admin.json"`
369
+ - *^(I |we )*clear the auth state$* · Example: `Given I clear the auth state`
370
+
371
+ ### clock.steps.js
372
+
373
+ - *^the system time is "([^"]*)"$* · Example: `Given the system time is "2026-05-08T10:00:00Z"`
374
+ - *^(I |we )*advance the clock by (\d+) ?ms$* · Example: `When I advance the clock by 500 ms`
375
+ - *^(I |we )*advance the clock by (\d+) seconds?$* · Example: `When I advance the clock by 30 seconds`
376
+ - *^(I |we )*advance the clock by (\d+) minutes?$* · Example: `When I advance the clock by 5 minutes`
377
+ - *^(I |we )*pause the clock$* · Example: `When I pause the clock`
378
+ - *^(I |we )*resume the clock$* · Example: `When I resume the clock`
379
+ - *^(I |we )*set the system time to "([^"]*)"$* · Example: `When I set the system time to "2026-05-08T12:30:00Z"`
380
+
381
+ ### cookie.steps.js
382
+
383
+ - *a cookie with the name {string} should exist* · Example: `Then a cookie with the name "session_id" should exist`
384
+ - *a cookie with the name {string} and the value {string} should exist* · Example: `Then a cookie with the name "lang" and the value "en" should exist`
385
+ - *a cookie with the name {string} and a value containing {string} should exist* · Example: `Then a cookie with the name "session_id" and a value containing "abc" should exist`
386
+ - *a cookie with a name containing {string} should exist* · Example: `Then a cookie with a name containing "session" should exist`
387
+ - *a cookie with a name containing {string} and the value {string} should exist* · Example: `Then a cookie with a name containing "session" and the value "active" should exist`
388
+ - *a cookie with a name containing {string} and a value containing {string} should exist* · Example: `Then a cookie with a name containing "session" and a value containing "active" should exist`
389
+ - *a cookie with the name {string} should not exist* · Example: `Then a cookie with the name "session_id" should not exist`
390
+ - *a cookie with the name {string} and the value {string} should not exist* · Example: `Then a cookie with the name "lang" and the value "fr" should not exist`
391
+ - *a cookie with the name {string} and a value containing {string} should not exist* · Example: `Then a cookie with the name "preferences" and a value containing "lightmode" should not exist`
392
+ - *a cookie with a name containing {string} should not exist* · Example: `Then a cookie with a name containing "old_" should not exist`
393
+ - *a cookie with a name containing {string} and the value {string} should not exist* · Example: `Then a cookie with a name containing "session" and the value "expired" should not exist`
394
+ - *a cookie with a name containing {string} and a value containing {string} should not exist* · Example: `Then a cookie with a name containing "session" and a value containing "old" should not exist`
395
+
396
+ ### debug.steps.js
397
+
398
+ - *^print current URL$* · Example: `Then print current URL`
399
+ - *^print last response$* · Example: `Then print last response`
400
+
401
+ ### dialog.steps.js
402
+
403
+ - *^(I |we )*will accept the next dialog$* · Example: `Given I will accept the next dialog`
404
+ - *^(I |we )*will dismiss the next dialog$* · Example: `Given I will dismiss the next dialog`
405
+ - *^(I |we )*will accept the next dialog with "([^"]*)"$* · Example: `Given I will accept the next dialog with "alice@example.com"`
406
+ - *^the last dialog message should be "([^"]*)"$* · Example: `Then the last dialog message should be "Are you sure?"`
407
+ - *^the last dialog message should contain "([^"]*)"$* · Example: `Then the last dialog message should contain "Are you sure"`
408
+ - *^the last dialog type should be "([^"]*)"$* · Example: `Then the last dialog type should be "confirm"`
409
+ - *^(I |we )*accept all confirmation dialogs$* · Example: `Given I accept all confirmation dialogs`
410
+ - *^(I |we )*do not accept any confirmation dialogs$* · Example: `Given I do not accept any confirmation dialogs`
411
+
412
+ ### element.steps.js
413
+
414
+ - *the element {string} should appear after the element {string}* · Example: `Then the element "#footer" should appear after the element "#main"`
415
+ - *the text {string} should appear after the text {string}* · Example: `Then the text "Sign in" should appear after the text "Welcome"`
416
+ - *the element {string} with the attribute {string} and the value {string} should exist* · Example: `Then the element "a" with the attribute "href" and the value "/about" should exist`
417
+ - *the element {string} with the attribute {string} and the value containing {string} should exist* · Example: `Then the element "a" with the attribute "href" and the value containing "/about" should exist`
418
+ - *the element {string} with the attribute {string} and the value {string} should not exist* · Example: `Then the element "a" with the attribute "href" and the value "/admin" should not exist`
419
+ - *the element {string} with the attribute {string} and the value containing {string} should not exist* · Example: `Then the element "a" with the attribute "href" and the value containing "/old" should not exist`
420
+ - *the element {string} should be at the top of the viewport* · Example: `Then the element "#header" should be at the top of the viewport`
421
+ - *the element {string} should be centered in the viewport* · Example: `Then the element ".hero" should be centered in the viewport`
422
+ - *^(I |we )*click on the element "([^"]*)"$* · Example: `When I click on the element "#sign-in"`
423
+ - *^(I |we )*trigger the JS event "([^"]*)" on the element "([^"]*)"$* · Example: `When I trigger the JS event "click" on the element "#cta"`
424
+ - *^(I |we )*scroll to the element "([^"]*)"$* · Example: `When I scroll to the element "#footer"`
425
+ - *^(I |we )*hover over the element "([^"]*)"$* · Example: `When I hover over the element ".tooltip-trigger"`
426
+ - *^(I |we )*focus on the element "([^"]*)"$* · Example: `When I focus on the element "#email"`
427
+ - *the element {string} should be displayed* · Example: `Then the element "#dashboard" should be displayed`
428
+ - *the element {string} should not be displayed* · Example: `Then the element "#loading-spinner" should not be displayed`
429
+ - *the element {string} should be displayed within a viewport* · Example: `Then the element "#hero" should be displayed within a viewport`
430
+ - *the element {string} should be displayed within a viewport with a top offset of {int} pixels* · Example: `Then the element "#hero" should be displayed within a viewport with a top offset of 60 pixels`
431
+ - *the element {string} should not be displayed within a viewport with a top offset of {int} pixels* · Example: `Then the element "#footer" should not be displayed within a viewport with a top offset of 60 pixels`
432
+ - *the element {string} should not be displayed within a viewport* · Example: `Then the element "#footer" should not be displayed within a viewport`
433
+
434
+ ### field.steps.js
435
+
436
+ - *the field {string} should be empty* · Example: `Then the field "username" should be empty`
437
+ - *the field {string} should not be empty* · Example: `Then the field "username" should not be empty`
438
+ - *the field {string} should exist* · Example: `Then the field "username" should exist`
439
+ - *the field {string} should not exist* · Example: `Then the field "missing-field" should not exist`
440
+ - *the field {string} should have {string} state* · Example: `Then the field "username" should have "enabled" state`
441
+ - *the field {string} should be required* · Example: `Then the field "username" should be required`
442
+ - *the field {string} should not be required* · Example: `Then the field "bio" should not be required`
443
+ - *^(I |we )*fill in the multi-value field "([^"]*)" with the following values:$* · Example: `When I fill in the multi-value field "tags" with the following values:`
444
+ - *^(I |we )*fill in the color field "([^"]*)" with the value "([^"]*)"$* · Example: `When I fill in the color field "favorite" with the value "#ff0000"`
445
+ - *the color field {string} should have the value {string}* · Example: `Then the color field "favorite" should have the value "#ff0000"`
446
+ - *^(I |we )*fill in the WYSIWYG field "([^"]*)" with the "([^"]*)"$* · Example: `When I fill in the WYSIWYG field "body" with the "Hello world"`
447
+ - *the option {string} should exist within the select element {string}* · Example: `Then the option "Mercedes" should exist within the select element "#cars"`
448
+ - *the option {string} should not exist within the select element {string}* · Example: `Then the option "Manager" should not exist within the select element "#role"`
449
+ - *the option {string} should be selected within the select element {string}* · Example: `Then the option "Mercedes" should be selected within the select element "#cars"`
450
+ - *the option {string} should not be selected within the select element {string}* · Example: `Then the option "Admin" should not be selected within the select element "#role"`
451
+ - *^(I |we )*unselect "([^"]*)" from "([^"]*)"$* · Example: `When I unselect "Red" from "#colors"`
452
+ - *^(I |we )*clear the select "([^"]*)"$* · Example: `When I clear the select "#colors"`
453
+ - *^(I |we )*check the checkbox "([^"]*)"$* · Example: `When I check the checkbox "#agree"`
454
+ - *^(I |we )*uncheck the checkbox "([^"]*)"$* · Example: `When I uncheck the checkbox "#newsletter"`
455
+ - *^(I |we )*choose the radio button "([^"]*)"$* · Example: `When I choose the radio button "#gender-male"`
456
+ - *^(I |we )*fill in the field "([^"]*)" with "([^"]*)"$* · Example: `When I fill in the field "#username" with "alice"`
457
+ - *browser validation for the form {string} is disabled* · Example: `Given browser validation for the form "#signup" is disabled`
458
+ - *^(I |we )*fill in the datetime field "([^"]*)" with date "([^"]*)" and time "([^"]*)"$* · Example: `When I fill in the datetime field "Start" with date "2026-05-08" and time "10:00"`
459
+ - *^(I |we )*fill in the date part of the datetime field "([^"]*)" with "([^"]*)"$* · Example: `When I fill in the date part of the datetime field "Start" with "2026-05-08"`
460
+ - *^(I |we )*fill in the time part of the datetime field "([^"]*)" with "([^"]*)"$* · Example: `When I fill in the time part of the datetime field "Start" with "10:00"`
461
+ - *^(I |we )*fill in the start datetime field "([^"]*)" with date "([^"]*)" and time "([^"]*)"$* · Example: `When I fill in the start datetime field "Event" with date "2026-05-08" and time "10:00"`
462
+ - *^(I |we )*fill in the end datetime field "([^"]*)" with date "([^"]*)" and time "([^"]*)"$* · Example: `When I fill in the end datetime field "Event" with date "2026-05-09" and time "18:00"`
463
+
464
+ ### file-download.steps.js
465
+
466
+ - *^(I |we )*download the file from the URL "([^"]*)"$* · Example: `When I download the file from the URL "/exports/users.csv"`
467
+ - *^(I |we )*download the file from the link "([^"]*)"$* · Example: `When I download the file from the link "Download report"`
468
+ - *the downloaded file should contain:* · Example: `Then the downloaded file should contain:`
469
+ - *the downloaded file name should be {string}* · Example: `Then the downloaded file name should be "report.pdf"`
470
+ - *the downloaded file name should contain {string}* · Example: `Then the downloaded file name should contain "report"`
471
+ - *the downloaded file should be a zip archive containing the following files named:* · Example: `Then the downloaded file should be a zip archive containing the following files named:`
472
+ - *the downloaded file should be a zip archive containing the following files partially named:* · Example: `Then the downloaded file should be a zip archive containing the following files partially named:`
473
+ - *the downloaded file should be a zip archive not containing the following files partially named:* · Example: `Then the downloaded file should be a zip archive not containing the following files partially named:`
474
+
475
+ ### form.steps.js
476
+
477
+ - *^(I |we )*fill in "([^"]*)?" with "([^"]*)?"$* · Example: `When I fill in "Username" with "John Smith"`
478
+ - *^(I |we )*fill in "([^"]*)?" with "([^"]*)?" by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I fill in "#uname" with "John Smith" by attr`
479
+ - *^(I |we )*fill in "([^"]*)?" with:$* · Example: `When I fill in "Username" with:`
480
+ - *^(I |we )*fill in "([^"]*)?" with: by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I fill in "#uname" with: by attr`
481
+ - *^(I |we )*fill in "([^"]*)?" for "([^"]*)?"$* · Example: `When I fill in "jon-smith" for "Username"`
482
+ - *^(I |we )*fill in "([^"]*)?" for "([^"]*)?" by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I fill in "John Smith" for "#uname" by attr`
483
+ - *^(I |we )*fill in( the)* following:$* · Example: `When I fill in the following:`
484
+ - *^(I |we )*fill in( the)* following: by( its)*(?: "([^"]*)?")* (attribute|attr)$* · Example: `When I fill in the following: by attr`
485
+ - *^(I |we )*select "([^"]*)?" from "([^"]*)?"$* · Example: `When I select "Mercedes" from "Cars"`
486
+ - *^(I |we )*additionally select "([^"]*)" from "([^"]*)"$* · Example: `When I additionally select "Red" from "Colors"`
487
+ - *^(I |we )*check "([^"]*)?"$* · Example: `When I check "Remember me"`
488
+ - *^(I |we )*uncheck "([^"]*)?"$* · Example: `When I uncheck "Remember me"`
489
+ - *^(I |we )*select radio button "([^"]*)?"$* · Example: `When I select radio button "Male"`
490
+
491
+ ### iframe.steps.js
492
+
493
+ - *^(I |we )*switch to (the )?iframe "([^"]*)"$* · Example: `When I switch to iframe "iframe.payment"`
494
+ - *^(I |we )*switch to iframe with locator "([^"]*)"$* · Example: `When I switch to iframe with locator "iframe.payment"`
495
+ - *^(I |we )*switch to the root document$* · Example: `When I switch to the root document`
496
+ - *^(I |we )*switch to the iframe with title "([^"]*)"$* · Example: `When I switch to the iframe with title "Payment"`
497
+ - *^(I |we )*switch to the iframe with name "([^"]*)"$* · Example: `When I switch to the iframe with name "payment"`
498
+ - *^(I |we )*click "([^"]*)" inside the iframe$* · Example: `When I click "Confirm" inside the iframe`
499
+ - *^(I |we )*click "([^"]*)" by attr inside the iframe$* · Example: `When I click "submit-btn" by attr inside the iframe`
500
+ - *^(I |we )*fill in "([^"]*)" with "([^"]*)" inside the iframe$* · Example: `When I fill in "card_number" with "4242 4242 4242 4242" inside the iframe`
501
+ - *^I should see "([^"]*)" inside the iframe$* · Example: `Then I should see "Payment received" inside the iframe`
502
+ - *^I should not see "([^"]*)" inside the iframe$* · Example: `Then I should not see "Error" inside the iframe`
503
+
504
+ ### input.steps.js
505
+
506
+ - *^(I |we )*hover over "([^"]*)"$* · Example: `When I hover over "#nav-products"`
507
+ - *^(I |we )*move the pointer to "([^"]*)"$* · Example: `When I move the pointer to "#cta"`
508
+ - *^(I |we )*double[- ]click on "([^"]*)"$* · Example: `When I double-click on "#row-1"`
509
+ - *^(I |we )*right[- ]click on "([^"]*)"$* · Example: `When I right-click on "#row-1"`
510
+ - *^(I |we )*middle[- ]click on "([^"]*)"$* · Example: `When I middle-click on "a.external"`
511
+ - *^(I |we )*click on "([^"]*)" while holding "([^"]*)"$* · Example: `When I click on "#row-1" while holding "Shift"`
512
+ - *^(I |we )*drag "([^"]*)" to "([^"]*)"$* · Example: `When I drag "#card-1" to "#column-done"`
513
+ - *^(I |we )*set the viewport size to (\d+)x(\d+)$* · Example: `When I set the viewport size to 1280x720`
514
+ - *^(I |we )*tap on "([^"]*)"$* · Example: `When I tap on "#cta"`
515
+
516
+ ### javascript.steps.js
517
+
518
+ - *^there should be no JavaScript errors$* · Example: `Then there should be no JavaScript errors`
519
+ - *^there should be no JavaScript warnings$* · Example: `Then there should be no JavaScript warnings`
520
+ - *^JavaScript errors should not match "([^"]*)"$* · Example: `Then JavaScript errors should not match "TypeError"`
521
+ - *^print JavaScript errors$* · Example: `Then print JavaScript errors`
522
+
523
+ ### keyboard.steps.js
524
+
525
+ - *^(I |we )*press the key "([^"]*)"$* · Example: `When I press the key "Enter"`
526
+ - *^(I |we )*press the key "([^"]*)" on the element "([^"]*)"$* · Example: `When I press the key "Enter" on the element "#search"`
527
+ - *^(I |we )*press the keys "([^"]*)"$* · Example: `When I press the keys "Control+a"`
528
+ - *^(I |we )*press the keys "([^"]*)" on the element "([^"]*)"$* · Example: `When I press the keys "Control+a" on the element "#editor"`
529
+
530
+ ### link.steps.js
531
+
532
+ - *the link {string} with the href {string} should exist* · Example: `Then the link "About" with the href "/about" should exist`
533
+ - *the link {string} with the href {string} within the element {string} should exist* · Example: `Then the link "Home" with the href "/" within the element "#main-nav" should exist`
534
+ - *the link {string} with the href {string} should not exist* · Example: `Then the link "Sign in" with the href "/login" should not exist`
535
+ - *the link {string} with the href {string} within the element {string} should not exist* · Example: `Then the link "Logout" with the href "/logout" within the element ".guest-nav" should not exist`
536
+ - *the link with the title {string} should exist* · Example: `Then the link with the title "Open menu" should exist`
537
+ - *the link with the title {string} should not exist* · Example: `Then the link with the title "Delete user" should not exist`
538
+ - *the link {string} should be an absolute link* · Example: `Then the link "Twitter" should be an absolute link`
539
+ - *the link {string} should not be an absolute link* · Example: `Then the link "Home" should not be an absolute link`
540
+ - *^(I |we )*click on the link with the title "([^"]*)"$* · Example: `When I click on the link with the title "Open menu"`
541
+
542
+ ### metatag.steps.js
543
+
544
+ - *the meta tag should exist with the following attributes:* · Example: `Then the meta tag should exist with the following attributes:`
545
+ - *the meta tag should not exist with the following attributes:* · Example: `Then the meta tag should not exist with the following attributes:`
546
+ - *the {string} meta tag should not contain any HTML tags* · Example: `Then the "description" meta tag should not contain any HTML tags`
547
+
548
+ ### modal.steps.js
549
+
550
+ - *^(I |we )*should( not)* see (a |the )*modal( dialog)*$* · Example: `Then I should see a modal`
551
+ - *^(I |we )*should( not)* see (a |the )*modal with title "([^"]*)?"$* · Example: `Then I should see a modal with title "Confirm Action"`
552
+ - *^(I |we )*should( not)* see (a |the )*"([^"]*)?" modal$* · Example: `Then I should see a "confirmation-modal" modal`
553
+ - *^(I |we )*should( not)* see "([^"]*)?" in( the)* modal( dialog)*$* · Example: `Then I should see "Are you sure?" in the modal`
554
+ - *the modal should contain {string}* · Example: `Then the modal should contain "Welcome modal text"`
555
+ - *the modal should not contain {string}* · Example: `Then the modal should not contain "Goodbye"`
556
+ - *^(I |we )*click "([^"]*)?"( button)* in( the)* modal( dialog)*$* · Example: `When I click "Confirm" in the modal`
557
+ - *^(I |we )*click on "([^"]*)" in the modal$* · Example: `When I click on "#close-btn" in the modal`
558
+ - *^(I |we )*(close|dismiss)( the)* modal( dialog)*$* · Example: `When I close the modal`
559
+
560
+ ### navigation.steps.js
561
+
562
+ - *^(I am |we are )?an anonymous user$* · Example: `Given I am an anonymous user`
563
+ - *^(I am |we are )?on( the)* (homepage|frontpage)$* · Example: `Given I am on homepage`
564
+ - *^(I am |we are )*on( the)* "([^"]*)?"( page)*$* · Example: `Given I am on "/about-us.html"`
565
+ - *^(I go |I navigate |we go |we navigate |navigating )?to( the)* (homepage|frontpage)$* · Example: `When I go to homepage`
566
+ - *^(I go |I navigate |we go |we navigate |navigating )?to "([^"]*)?"$* · Example: `When I go to "/contact-us.html"`
567
+ - *^(I |we )*move forward one page$* · Example: `When I move forward one page`
568
+ - *^(I |we )*move backward one page$* · Example: `When I move backward one page`
569
+ - *^(I |we )*reload( the)*( page)*$* · Example: `When I reload`
570
+ - *^(I |we )*should( not)* be on( the)* (homepage|frontpage)$* · Example: `Then I should be on homepage`
571
+ - *^(I |we )*should( not)* be on( the)* "([^"]*)?"( page)*$* · Example: `Then I should be on "/"`
572
+ - *^(the )*url should( not)* match "([^"]*)?"$* · Example: `Then the url should match "/contact-us.html"`
573
+
574
+ ### network.steps.js
575
+
576
+ - *^the URL "([^"]*)" returns the JSON:$* · Example: `Given the URL "**\/api/users" returns the JSON:`
577
+ - *^the URL "([^"]*)" returns status (\d+)(?: with body "([^"]*)")?$* · Example: `Given the URL "**\/api/login" returns status 401 with body "Unauthorized"`
578
+ - *^the URL "([^"]*)" is blocked$* · Example: `Given the URL "**\/analytics.js" is blocked`
579
+ - *^the URL "([^"]*)" is delayed by (\d+) ?ms$* · Example: `Given the URL "**\/api/**" is delayed by 1500 ms`
580
+ - *^the network is offline$* · Example: `Given the network is offline`
581
+ - *^the network is online$* · Example: `Given the network is online`
582
+ - *^(I |we )*start recording network requests$* · Example: `Given I start recording network requests`
583
+ - *^a request to "([^"]*)" should have been made$* · Example: `Then a request to "**\/api/users" should have been made`
584
+ - *^a (GET|POST|PUT|PATCH|DELETE) request to "([^"]*)" should have been made$* · Example: `Then a GET request to "**\/api/users" should have been made`
585
+ - *^no request to "([^"]*)" should have been made$* · Example: `Then no request to "**\/tracking" should have been made`
586
+
587
+ ### path.steps.js
588
+
589
+ - *the path should be {string}* · Example: `Then the path should be "/dashboard"`
590
+ - *the path should not be {string}* · Example: `Then the path should not be "/login"`
591
+ - *current url should have the {string} parameter* · Example: `Then current url should have the "lang" parameter`
592
+ - *current url should have the {string} parameter with the {string} value* · Example: `Then current url should have the "lang" parameter with the "en" value`
593
+ - *current url should not have the {string} parameter* · Example: `Then current url should not have the "missing" parameter`
594
+ - *current url should not have the {string} parameter with the {string} value* · Example: `Then current url should not have the "lang" parameter with the "fr" value`
595
+ - *the basic authentication with the username {string} and the password {string}* · Example: `Given the basic authentication with the username "admin" and the password "secret"`
596
+ - *^(I |we )*go back$* · Example: `When I go back`
597
+
598
+ ### response.steps.js
599
+
600
+ - *the response should contain the header {string}* · Example: `Then the response should contain the header "content-type"`
601
+ - *the response should not contain the header {string}* · Example: `Then the response should not contain the header "x-fake-header"`
602
+ - *the response header {string} should contain the value {string}* · Example: `Then the response header "content-type" should contain the value "html"`
603
+ - *the response header {string} should not contain the value {string}* · Example: `Then the response header "content-type" should not contain the value "application/json"`
604
+
605
+ ### responsive.steps.js
606
+
607
+ - *the following responsive breakpoints:* · Example: `Given the following responsive breakpoints:`
608
+ - *^(I |we )*set the viewport to the "([^"]*)" breakpoint$* · Example: `When I set the viewport to the "mobile" breakpoint`
609
+ - *^(I |we )*set the viewport width to (\d+)$* · Example: `When I set the viewport width to 1200`
610
+ - *^(I |we )*set the viewport height to (\d+)$* · Example: `When I set the viewport height to 800`
611
+ - *^(I |we )*set the viewport to (\d+) by (\d+)$* · Example: `When I set the viewport to 1200 by 800`
612
+
613
+ ### rest.steps.js
614
+
615
+ - *a REST header {string} with value {string}* · Example: `Given a REST header "Authorization" with value "Bearer abc123"`
616
+ - *^(I |we )*send a REST "([^"]*)" request to "([^"]*)"$* · Example: `When I send a REST "GET" request to "/api/users"`
617
+ - *^(I |we )*send a REST "([^"]*)" request to "([^"]*)" with body:$* · Example: `When I send a REST "POST" request to "/api/users" with body:`
618
+ - *the REST response status code should be {int}* · Example: `Then the REST response status code should be 200`
619
+ - *the REST response should contain {string}* · Example: `Then the REST response should contain "Alice"`
620
+
621
+ ### screenshot.steps.js
622
+
623
+ - *^(I |we )*save screenshot$* · Example: `Then I save screenshot`
624
+ - *^(I |we )*save fullscreen screenshot$* · Example: `Then I save fullscreen screenshot`
625
+ - *^(I |we )*save (\d+) x (\d+) screenshot$* · Example: `Then I save 1440 x 900 screenshot`
626
+ - *^(I |we )*save fullscreen (\d+) x (\d+) screenshot$* · Example: `Then I save fullscreen 1440 x 900 screenshot`
627
+ - *^(I |we )*save screenshot with name "([^"]*)"$* · Example: `Then I save screenshot with name "homepage.png"`
628
+ - *^(I |we )*save fullscreen screenshot with name "([^"]*)"$* · Example: `Then I save fullscreen screenshot with name "homepage-full.png"`
629
+
630
+ ### scroll.steps.js
631
+
632
+ - *^(I scroll|we scroll|scrolling)? down(?: (\d+))?$* · Example: `And I scroll down`
633
+ - *^(I scroll|we scroll|scrolling)? up(?: (\d+))?$* · Example: `And I scroll up`
634
+ - *^(I scroll|we scroll|scrolling)? to( the)* top( of the page)*$* · Example: `When I scroll to top`
635
+ - *^(I scroll|we scroll|scrolling)? to( the)* bottom( of the page)*$* · Example: `When I scroll to the bottom`
636
+ - *^(I scroll|we scroll|scrolling)? to top of "([^"]*)"$* · Example: `When I scroll to top of "#off-canvas"`
637
+ - *^(I scroll|we scroll|scrolling)? to bottom of "([^"]*)"$* · Example: `When I scroll to bottom of "#off-canvas"`
638
+ - *^(I scroll|we scroll|scrolling)? right(?: (\d+))?$* · Example: `And I scroll right`
639
+ - *^(I scroll|we scroll|scrolling)? left(?: (\d+))?$* · Example: `And I scroll left`
640
+ - *^(I scroll|we scroll|scrolling)? to( the)* start( of the page)*$* · Example: `When I scroll to start`
641
+ - *^(I scroll|we scroll|scrolling)? to( the)* end( of the page)*$* · Example: `When I scroll to the end`
642
+ - *^(I scroll|we scroll|scrolling)? to start of "([^"]*)"$* · Example: `When I scroll to start of "#off-canvas"`
643
+ - *^(I scroll|we scroll|scrolling)? to end of "([^"]*)"$* · Example: `When I scroll to end of "#off-canvas"`
644
+
645
+ ### selectors.steps.js
646
+
647
+ - *^(I |we )*add "([^"]*)" selector for "([^"]*)" css selector$* · Example: `When I add "mobile logo" selector for "header img#logo" css selector`
648
+ - *^(I |we )*add "([^"]*)" selector for "([^"]*)" xpath selector$* · Example: `When I add "page title" selector for "//h1[contains(@class,'page-header')]" xpath selector`
649
+ - *^(I |we )*add selectors from "([^"]*)" file$* · Example: `When I add selectors from "selectors.json" file`
650
+ - *^(I |we )*print css selectors$* · Example: `Then I print css selectors`
651
+ - *^(I |we )*print xpath selectors$* · Example: `Then I print xpath selectors`
652
+ - *^(I am |we are )?viewing the site on a (?:"([^"]+)"|([a-zA-Z0-9 _,]+)) (?:screen|device)$* · Example: `Given I am viewing the site on a xl screen`
653
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) above ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see header above footer`
654
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) below ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see footer below header`
655
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) to (?:the )?left of ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see logo to the left of nav`
656
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) to (?:the )?right of ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see nav to the right of logo`
657
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) inside of ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see logo inside of header`
658
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) outside of ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see header outside of logo`
659
+ - *^(I |we )*see ((?:[a-zA-Z0-9 ,\-](?!not))+) over ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see modal over content`
660
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) not over ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see header not over content`
661
+ - *^(I |we )*see visible ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I see visible header`
662
+ - *^(I |we )*(don't|do not) see ([a-zA-Z0-9 ,\-]+)$* · Example: `Then I don't see modal`
663
+ - *^(I |we )*see ([a-zA-Z0-9 ,\-]+) has focus$* · Example: `Then I see search has focus`
664
+ - *^(I |we )*move focus to "([^"]*)" field$* · Example: `When I move focus to "Title" field`
665
+ - *^(I |we )*select all text in "([^"]*)" field$* · Example: `When I select all text in "Title" field`
666
+ - *^(I |we )*select from (\d+) to (\d+) text in "([^"]*)" field$* · Example: `When I select from 0 to 5 text in "Title" field`
667
+ - *^(I |we )*select "([^"]*)" text in "([^"]*)" field$* · Example: `When I select "title name" text in "Title" field`
668
+ - *^(I |we )*click (?:on |a )?([a-zA-Z0-9 ,\-]+)$* · Example: `When I click nav`
669
+
670
+ ### storage.steps.js
671
+
672
+ - *^(?:the cookie|cookie) "([^"]*)" is set to "([^"]*)"$* · Example: `Given the cookie "session" is set to "abc123"`
673
+ - *^the cookie "([^"]*)" is removed$* · Example: `Given the cookie "session" is removed`
674
+ - *^all cookies are cleared$* · Example: `Given all cookies are cleared`
675
+ - *^(?:the )?local storage "([^"]*)" is set to "([^"]*)"$* · Example: `Given the local storage "user" is set to "Alice"`
676
+ - *^(?:the )?local storage "([^"]*)" is removed$* · Example: `Given the local storage "user" is removed`
677
+ - *^local storage is cleared$* · Example: `Given local storage is cleared`
678
+ - *^(?:the )?session storage "([^"]*)" is set to "([^"]*)"$* · Example: `Given the session storage "checkout step" is set to "2"`
679
+ - *^(?:the )?session storage "([^"]*)" is removed$* · Example: `Given the session storage "checkout step" is removed`
680
+ - *^session storage is cleared$* · Example: `Given session storage is cleared`
681
+
682
+ ### table.steps.js
683
+
684
+ - *the table {string} should have {int} row(s)* · Example: `Then the table "#users" should have 5 rows`
685
+ - *the table {string} should have {int} column(s)* · Example: `Then the table "#users" should have 4 columns`
686
+ - *the table {string} should contain the following columns:* · Example: `Then the table "#users" should contain the following columns:`
687
+ - *the table {string} should be empty* · Example: `Then the table "#users" should be empty`
688
+ - *the table {string} should not be empty* · Example: `Then the table "#users" should not be empty`
689
+ - *the table {string} should be sorted by {string} in {string} order* · Example: `Then the table "#users" should be sorted by "Name" in "ascending" order`
690
+ - *the table {string} should contain the following rows:* · Example: `Then the table "#users" should contain the following rows:`
691
+ - *the {string} row should contain the following:* · Example: `Then the "Alice" row should contain the following:`
692
+
693
+ ### video.steps.js
694
+
695
+ - *^(I |we )*start video recording$* · Example: `When I start video recording`
696
+ - *^(I |we )*stop video recording$* · Example: `When I stop video recording`
697
+ - *^(I |we )*save the current video as "([^"]*)"$* · Example: `When I save the current video as "checkout-flow.webm"`
698
+ - *^print video path$* · Example: `Then print video path`
699
+
700
+ ### wait.steps.js
701
+
702
+ - *^(I |we )*wait for (\d+) seconds?$* · Example: `When I wait for 1 second`
703
+ - *^(I |we )*wait for (\d+) seconds? for AJAX to finish$* · Example: `When I wait for 1 second for AJAX to finish`
704
+ - *^(I |we )*wait (\d+)( second| seconds|s)?$* · Example: `When I wait 1 second`
705
+ - *^(I |we )*wait max of (\d+)( second| seconds|s)?$* · Example: `When I wait max of 1 second`
706
+ - *^(I |we )*wait (\d+)( minute| minutes|m)?$* · Example: `When I wait 1 minute`
707
+ - *^(I |we )*wait max of (\d+)( minute| minutes|m)?$* · Example: `When I wait max of 1 minute`
708
+ - *^(I |we )*wait until( the)* page( is)* loaded*$* · Example: `When I wait until the page is loaded`
709
+ - *^(I |we )*wait for AJAX to finish$* · Example: `When I wait for AJAX to finish`
710
+ - *^(I |we )*wait for( the)* modal( dialog)* to (appear|disappear)$* · Example: `When I wait for the modal to appear`
711
+ - *^(I |we )*wait for "([^"]*)" to appear$* · Example: `When I wait for "#dashboard" to appear`
712
+ - *^(I |we )*wait for "([^"]*)" to disappear$* · Example: `When I wait for "#loading-spinner" to disappear`
713
+ - *^(I |we )*wait for( the)* text "([^"]*)" to appear$* · Example: `When I wait for the text "Dashboard" to appear`
714
+ - *^(I |we )*wait for( the)* text "([^"]*)" to disappear$* · Example: `When I wait for the text "Loading…" to disappear`
715
+ - *^(I |we )*wait until( the)* URL contains "([^"]*)"$* · Example: `When I wait until the URL contains "/dashboard"`
716
+ - *^(I |we )*wait until( the)* page title (is|contains) "([^"]*)"$* · Example: `When I wait until the page title is "Dashboard - MyApp"`
717
+ - *^(I |we )*wait until (\d+) elements? match(?:es)? "([^"]*)"$* · Example: `When I wait until 5 elements match ".product-card"`
718
+ - *^(I |we )*wait until at least (\d+) elements? match(?:es)? "([^"]*)"$* · Example: `When I wait until at least 3 elements match ".item"`
719
+ - *^(I |we )*wait until (the network is idle|requests are complete|network goes quiet)$* · Example: `When I wait until the network is idle`
720
+ - *^(I |we )*wait until( the)* page is interactive$* · Example: `When I wait until the page is interactive`
721
+ - *^(I |we )*wait until pending timers settle$* · Example: `When I wait until pending timers settle`
722
+ - *^eventually (I |we )*should see "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then eventually I should see "Done"`
723
+
724
+ ### web-first.steps.js
725
+
726
+ - *^"([^"]*)" should be (visible|hidden|attached|focused|enabled|disabled|editable)(?: within (\d+) seconds?)?$* · Example: `Then "#dashboard" should be visible`
727
+ - *^"([^"]*)" should not be (visible|hidden|attached|focused|enabled|disabled|editable)(?: within (\d+) seconds?)?$* · Example: `Then "#loading-spinner" should not be visible`
728
+ - *^"([^"]*)" should be in the viewport(?: within (\d+) seconds?)?$* · Example: `Then "#hero" should be in the viewport`
729
+ - *^"([^"]*)" should not be in the viewport(?: within (\d+) seconds?)?$* · Example: `Then "#footer" should not be in the viewport`
730
+ - *^"([^"]*)" should have a count of (\d+)(?: within (\d+) seconds?)?$* · Example: `Then ".product-card" should have a count of 12`
731
+ - *^"([^"]*)" should have text "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then "h1" should have text "Welcome"`
732
+ - *^"([^"]*)" should contain text "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then "h1" should contain text "Welcome"`
733
+ - *^"([^"]*)" should have value "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then "#email" should have value "alice@example.com"`
734
+ - *^"([^"]*)" should have attribute "([^"]*)" with value "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then "#tab-1" should have attribute "aria-selected" with value "true"`
735
+ - *^"([^"]*)" should have class "([^"]*)"(?: within (\d+) seconds?)?$* · Example: `Then "#tab-1" should have class "is-active"`
736
+ - *^(I |we )*click the "([^"]*)" (button|link|tab|menuitem|checkbox|radio|option)$* · Example: `When I click the "Sign in" button`
737
+ - *^the "([^"]*)" (button|link|tab|menuitem|checkbox|radio|option) should be visible(?: within (\d+) seconds?)?$* · Example: `Then the "Save changes" button should be visible`
738
+
739
+ ### xml.steps.js
740
+
741
+ - *the response content from the file {string}* · Example: `Given the response content from the file "feed.xml"`
742
+ - *the response content is the following:* · Example: `Given the response content is the following:`
743
+ - *the response should be in XML format* · Example: `Then the response should be in XML format`
744
+ - *the response should not be in XML format* · Example: `Then the response should not be in XML format`
745
+ - *the XML element {string} should exist* · Example: `Then the XML element "/root/item" should exist`
746
+ - *the XML element {string} should not exist* · Example: `Then the XML element "/root/missing" should not exist`
747
+ - *the XML element {string} should be equal to {string}* · Example: `Then the XML element "/root/item" should be equal to "Hello"`
748
+ - *the XML element {string} should not be equal to {string}* · Example: `Then the XML element "/root/item" should not be equal to "Bye"`
749
+ - *the XML element {string} should contain {string}* · Example: `Then the XML element "/root/item" should contain "Hello"`
750
+ - *the XML element {string} should not contain {string}* · Example: `Then the XML element "/root/item" should not contain "Error"`
751
+ - *the XML attribute {string} on element {string} should exist* · Example: `Then the XML attribute "id" on element "/root/item" should exist`
752
+ - *the XML attribute {string} on element {string} should not exist* · Example: `Then the XML attribute "deprecated" on element "/root/item" should not exist`
753
+ - *the XML attribute {string} on element {string} should be equal to {string}* · Example: `Then the XML attribute "id" on element "/root/item" should be equal to "1"`
754
+ - *the XML attribute {string} on element {string} should not be equal to {string}* · Example: `Then the XML attribute "id" on element "/root/item" should not be equal to "0"`
755
+ - *the XML attribute {string} on element {string} should contain {string}* · Example: `Then the XML attribute "id" on element "/root/item" should contain "abc"`
756
+ - *the XML attribute {string} on element {string} should not contain {string}* · Example: `Then the XML attribute "id" on element "/root/item" should not contain "old"`
757
+ - *the XML element {string} should have {int} element(s)* · Example: `Then the XML element "//entry" should have 5 elements`
758
+ - *the XML should use the namespace {string}* · Example: `Then the XML should use the namespace "http://www.w3.org/2005/Atom"`
759
+ - *the XML should not use the namespace {string}* · Example: `Then the XML should not use the namespace "http://example.com/legacy"`
760
+ - *^(I |we )*print last XML response$* · Example: `When I print last XML response`
761
+
762
+ ### yaml.steps.js
763
+
764
+ - *the YAML response content from the file {string}* · Example: `Given the YAML response content from the file "config.yml"`
765
+ - *the YAML response content is the following:* · Example: `Given the YAML response content is the following:`
766
+ - *the active YAML document is {int}* · Example: `Given the active YAML document is 1`
767
+ - *the YAML response should have {int} document(s)* · Example: `Then the YAML response should have 1 document`
768
+ - *the response should be in YAML format* · Example: `Then the response should be in YAML format`
769
+ - *the response should not be in YAML format* · Example: `Then the response should not be in YAML format`
770
+ - *the YAML should have no duplicate keys* · Example: `Then the YAML should have no duplicate keys`
771
+ - *the YAML element {string} should exist* · Example: `Then the YAML element "/name" should exist`
772
+ - *the YAML element {string} should not exist* · Example: `Then the YAML element "/missing" should not exist`
773
+ - *the YAML element {string} should be equal to {string}* · Example: `Then the YAML element "/name" should be equal to "example"`
774
+ - *the YAML element {string} should not be equal to {string}* · Example: `Then the YAML element "/name" should not be equal to "Other"`
775
+ - *the YAML element {string} should contain {string}* · Example: `Then the YAML element "/name" should contain "Web"`
776
+ - *the YAML element {string} should not contain {string}* · Example: `Then the YAML element "/name" should not contain "Error"`
777
+ - *the YAML attribute {string} on element {string} should exist* · Example: `Then the YAML attribute "id" on element "/items/0" should exist`
778
+ - *the YAML attribute {string} on element {string} should not exist* · Example: `Then the YAML attribute "deprecated" on element "/items/0" should not exist`
779
+ - *the YAML attribute {string} on element {string} should be equal to {string}* · Example: `Then the YAML attribute "id" on element "/items/0" should be equal to "1"`
780
+ - *the YAML attribute {string} on element {string} should not be equal to {string}* · Example: `Then the YAML attribute "id" on element "/items/0" should not be equal to "0"`
781
+ - *the YAML attribute {string} on element {string} should contain {string}* · Example: `Then the YAML attribute "id" on element "/items/0" should contain "abc"`
782
+ - *the YAML attribute {string} on element {string} should not contain {string}* · Example: `Then the YAML attribute "id" on element "/items/0" should not contain "old"`
783
+ - *the YAML element {string} should have {int} element(s)* · Example: `Then the YAML element "/items" should have 5 elements`
784
+ - *the YAML value at {string} should be of type {string}* · Example: `Then the YAML value at "/spec/replicas" should be of type "integer"`
785
+ - *the YAML value at {string} should be empty* · Example: `Then the YAML value at "/labels" should be empty`
786
+ - *the YAML value at {string} should not be empty* · Example: `Then the YAML value at "/items" should not be empty`
787
+ - *the YAML value at {string} should be greater than {float}* · Example: `Then the YAML value at "/spec/replicas" should be greater than 0`
788
+ - *the YAML value at {string} should be greater than or equal to {float}* · Example: `Then the YAML value at "/spec/replicas" should be greater than or equal to 1`
789
+ - *the YAML value at {string} should be less than {float}* · Example: `Then the YAML value at "/spec/replicas" should be less than 100`
790
+ - *the YAML value at {string} should be less than or equal to {float}* · Example: `Then the YAML value at "/spec/replicas" should be less than or equal to 10`
791
+ - *the YAML value at {string} should be between {float} and {float}* · Example: `Then the YAML value at "/spec/replicas" should be between 1 and 10`
792
+ - *the YAML array at {string} should contain an item where {string} is {string}* · Example: `Then the YAML array at "/spec/containers" should contain an item where "/name" is "nginx"`
793
+ - *the YAML array at {string} should contain no item where {string} is {string}* · Example: `Then the YAML array at "/spec/containers" should contain no item where "/image" is "alpine:latest"`
794
+ - *every item in {string} should have key {string}* · Example: `Then every item in "/spec/containers" should have key "image"`
795
+ - *the YAML keys at {string} should be exactly {string}* · Example: `Then the YAML keys at "/metadata" should be exactly "name, namespace, labels"`
796
+ - *the YAML at {string} should have keys {string}* · Example: `Then the YAML at "/metadata" should have keys "name, namespace"`
797
+ - *the YAML should match JSON Schema {string}* · Example: `Then the YAML should match JSON Schema "schemas/deployment.json"`
798
+ - *the YAML should equal the file {string} ignoring keys {string}* · Example: `Then the YAML should equal the file "expected.yaml" ignoring keys "/metadata/resourceVersion"`
799
+ - *the YAML should use the namespace {string}* · Example: `Then the YAML should use the namespace "v1"`
800
+ - *the YAML should not use the namespace {string}* · Example: `Then the YAML should not use the namespace "v0"`
801
+ - *^(I |we )*print last YAML response$* · Example: `When I print last YAML response`