@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,289 @@
1
+ # Web-first matchers steps
2
+
3
+ 12 steps, defined in `tests/step-definitions/web-first.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 "#dashboard" should be visible` |
10
+ | 2 | `Then "#loading-spinner" should not be visible` |
11
+ | 3 | `Then "#hero" should be in the viewport` |
12
+ | 4 | `Then "#footer" should not be in the viewport` |
13
+ | 5 | `Then ".product-card" should have a count of 12` |
14
+ | 6 | `Then "h1" should have text "Welcome"` |
15
+ | 7 | `Then "h1" should contain text "Welcome"` |
16
+ | 8 | `Then "#email" should have value "alice@example.com"` |
17
+ | 9 | `Then "#tab-1" should have attribute "aria-selected" with value "true"` |
18
+ | 10 | `Then "#tab-1" should have class "is-active"` |
19
+ | 11 | `When I click the "Sign in" button` |
20
+ | 12 | `Then the "Save changes" button should be visible` |
21
+
22
+ ---
23
+
24
+ ## 1. Then "#dashboard" should be visible
25
+
26
+ Auto-retrying state assertion. Polls the live page until the matcher passes
27
+ or the budget elapses. Default budget 5 s.
28
+
29
+ **Keyword**: `Then`
30
+
31
+ **Pattern**
32
+
33
+ ```js
34
+ /^"([^"]*)" should be (visible|hidden|attached|focused|enabled|disabled|editable)(?: within (\d+) seconds?)?$/
35
+ ```
36
+
37
+ **Examples**
38
+
39
+ ```gherkin
40
+ Then "#dashboard" should be visible
41
+ Then ".success-banner" should be visible within 10 seconds
42
+ And "[data-testid=signup-cta]" should be focused
43
+ Then "button.submit" should be enabled
44
+ Then "input#email" should be editable
45
+ ```
46
+
47
+ ## 2. Then "#loading-spinner" should not be visible
48
+
49
+ Auto-retrying negated state assertion.
50
+
51
+ **Keyword**: `Then`
52
+
53
+ **Pattern**
54
+
55
+ ```js
56
+ /^"([^"]*)" should not be (visible|hidden|attached|focused|enabled|disabled|editable)(?: within (\d+) seconds?)?$/
57
+ ```
58
+
59
+ **Examples**
60
+
61
+ ```gherkin
62
+ Then "#loading-spinner" should not be visible
63
+ Then ".error" should not be visible within 5 seconds
64
+ And "button.submit" should not be disabled
65
+ Then "input#email" should not be editable
66
+ Then "[data-testid=password]" should not be focused
67
+ ```
68
+
69
+ ## 3. Then "#hero" should be in the viewport
70
+
71
+ Assert an element's bounding box overlaps the visible viewport rectangle.
72
+
73
+ **Keyword**: `Then`
74
+
75
+ **Pattern**
76
+
77
+ ```js
78
+ /^"([^"]*)" should be in the viewport(?: within (\d+) seconds?)?$/
79
+ ```
80
+
81
+ **Examples**
82
+
83
+ ```gherkin
84
+ Then "#hero" should be in the viewport
85
+ Then "[data-testid=cta]" should be in the viewport within 3 seconds
86
+ When I scroll to the element "#footer"
87
+ Then "#footer" should be in the viewport
88
+ Then "h1" should be in the viewport
89
+ Then ".banner" should be in the viewport
90
+ ```
91
+
92
+ ## 4. Then "#footer" should not be in the viewport
93
+
94
+ Assert an element is OUTSIDE the visible viewport rectangle.
95
+
96
+ **Keyword**: `Then`
97
+
98
+ **Pattern**
99
+
100
+ ```js
101
+ /^"([^"]*)" should not be in the viewport(?: within (\d+) seconds?)?$/
102
+ ```
103
+
104
+ **Examples**
105
+
106
+ ```gherkin
107
+ Then "#footer" should not be in the viewport
108
+ Then "[data-testid=hidden]" should not be in the viewport within 3 seconds
109
+ And ".off-screen" should not be in the viewport
110
+ Then "section.below-fold" should not be in the viewport
111
+ When I scroll to the top
112
+ Then "#footer" should not be in the viewport
113
+ ```
114
+
115
+ ## 5. Then ".product-card" should have a count of 12
116
+
117
+ Assert exactly N elements match a selector (auto-retry).
118
+
119
+ **Keyword**: `Then`
120
+
121
+ **Pattern**
122
+
123
+ ```js
124
+ /^"([^"]*)" should have a count of (\d+)(?: within (\d+) seconds?)?$/
125
+ ```
126
+
127
+ **Examples**
128
+
129
+ ```gherkin
130
+ Then ".product-card" should have a count of 12
131
+ Then ".error" should have a count of 0 within 5 seconds
132
+ And "tr" should have a count of 21
133
+ Then "[data-testid=item]" should have a count of 5
134
+ Then ".feed-item" should have a count of 25 within 10 seconds
135
+ ```
136
+
137
+ ## 6. Then "h1" should have text "Welcome"
138
+
139
+ Assert an element's textContent equals an expected string (trimmed).
140
+
141
+ **Keyword**: `Then`
142
+
143
+ **Pattern**
144
+
145
+ ```js
146
+ /^"([^"]*)" should have text "([^"]*)"(?: within (\d+) seconds?)?$/
147
+ ```
148
+
149
+ **Examples**
150
+
151
+ ```gherkin
152
+ Then "h1" should have text "Welcome"
153
+ Then ".badge" should have text "12" within 3 seconds
154
+ And ".total" should have text "$99.00"
155
+ Then "[data-testid=subtitle]" should have text "Premium"
156
+ Then ".alert" should have text "Saved"
157
+ ```
158
+
159
+ ## 7. Then "h1" should contain text "Welcome"
160
+
161
+ Assert an element's textContent contains an expected substring.
162
+
163
+ **Keyword**: `Then`
164
+
165
+ **Pattern**
166
+
167
+ ```js
168
+ /^"([^"]*)" should contain text "([^"]*)"(?: within (\d+) seconds?)?$/
169
+ ```
170
+
171
+ **Examples**
172
+
173
+ ```gherkin
174
+ Then "h1" should contain text "Welcome"
175
+ Then ".badge" should contain text "unread" within 3 seconds
176
+ And ".total" should contain text "$99"
177
+ Then "[data-testid=subtitle]" should contain text "Premium"
178
+ Then ".alert" should contain text "Saved"
179
+ ```
180
+
181
+ ## 8. Then "#email" should have value "alice@example.com"
182
+
183
+ Assert an input's `value` property equals an expected string.
184
+
185
+ **Keyword**: `Then`
186
+
187
+ **Pattern**
188
+
189
+ ```js
190
+ /^"([^"]*)" should have value "([^"]*)"(?: within (\d+) seconds?)?$/
191
+ ```
192
+
193
+ **Examples**
194
+
195
+ ```gherkin
196
+ Then "#email" should have value "alice@example.com"
197
+ Then "input[name=q]" should have value "laptops"
198
+ And "[data-testid=phone]" should have value "0790000000"
199
+ Then "#bio" should have value "" within 3 seconds
200
+ Then "select#country" should have value "JO"
201
+ ```
202
+
203
+ ## 9. Then "#tab-1" should have attribute "aria-selected" with value "true"
204
+
205
+ Assert an element's attribute equals an expected value.
206
+
207
+ **Keyword**: `Then`
208
+
209
+ **Pattern**
210
+
211
+ ```js
212
+ /^"([^"]*)" should have attribute "([^"]*)" with value "([^"]*)"(?: within (\d+) seconds?)?$/
213
+ ```
214
+
215
+ **Examples**
216
+
217
+ ```gherkin
218
+ Then "#tab-1" should have attribute "aria-selected" with value "true"
219
+ Then "[data-testid=cta]" should have attribute "data-state" with value "open"
220
+ And "img.logo" should have attribute "alt" with value "Vardot"
221
+ Then "a.signup" should have attribute "href" with value "/signup"
222
+ Then "input#email" should have attribute "type" with value "email"
223
+ ```
224
+
225
+ ## 10. Then "#tab-1" should have class "is-active"
226
+
227
+ Assert an element's `class` attribute contains a class token.
228
+
229
+ **Keyword**: `Then`
230
+
231
+ **Pattern**
232
+
233
+ ```js
234
+ /^"([^"]*)" should have class "([^"]*)"(?: within (\d+) seconds?)?$/
235
+ ```
236
+
237
+ **Examples**
238
+
239
+ ```gherkin
240
+ Then "#tab-1" should have class "is-active"
241
+ Then ".modal" should have class "show" within 3 seconds
242
+ And ".dropdown" should have class "open"
243
+ Then "tr.row-1" should have class "selected"
244
+ Then "[data-testid=card]" should have class "highlighted"
245
+ ```
246
+
247
+ ## 11. When I click the "Sign in" button
248
+
249
+ Click an element by its accessible role + name (Playwright `getByRole`).
250
+
251
+ **Keyword**: `When`
252
+
253
+ **Pattern**
254
+
255
+ ```js
256
+ /^(I |we )*click the "([^"]*)" (button|link|tab|menuitem|checkbox|radio|option)$/
257
+ ```
258
+
259
+ **Examples**
260
+
261
+ ```gherkin
262
+ When I click the "Sign in" button
263
+ When I click the "Profile" link
264
+ And we click the "Notifications" tab
265
+ When I click the "Subscribe" checkbox
266
+ When I click the "Premium" radio
267
+ ```
268
+
269
+ ## 12. Then the "Save changes" button should be visible
270
+
271
+ Assert a role-addressed element is visible (auto-retry).
272
+
273
+ **Keyword**: `Then`
274
+
275
+ **Pattern**
276
+
277
+ ```js
278
+ /^the "([^"]*)" (button|link|tab|menuitem|checkbox|radio|option) should be visible(?: within (\d+) seconds?)?$/
279
+ ```
280
+
281
+ **Examples**
282
+
283
+ ```gherkin
284
+ Then the "Save changes" button should be visible
285
+ Then the "Profile" link should be visible within 5 seconds
286
+ And the "Privacy" tab should be visible
287
+ Then the "I agree" checkbox should be visible
288
+ Then the "Premium" radio should be visible
289
+ ```