@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,414 @@
1
+ # Drupal Canvas steps
2
+
3
+ 12 steps, defined in `tests/step-definitions/drupal-canvas.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 | `When I add the "Contact Us" webform to the bottom of the "Contact" Canvas page` |
10
+ | 2 | `Then the Drupal Canvas component library should list the "Hero" component` |
11
+ | 3 | `When I create a Canvas page "Landing" at "/landing" with the "Hero" component:` |
12
+ | 4 | `When I add the "Hero" component to the "Landing" Canvas page using the editor` |
13
+ | 5 | `When I publish the Canvas page changes` |
14
+ | 6 | `Given there is a new Canvas page "Landing" at "/landing"` |
15
+ | 7 | `When I set the Canvas component option "Heading" to "Welcome"` |
16
+ | 8 | `When I open the "Landing" Canvas page in the editor` |
17
+ | 9 | `When I open the "Patterns" tab in the Canvas Library` |
18
+ | 10 | `When I insert the "Hero Slider" pattern from the Canvas Library` |
19
+ | 11 | `When I publish the Canvas page changes through the editor` |
20
+ | 12 | `Then the Canvas Library "Patterns" tab should list "Hero Slider"` |
21
+
22
+ ---
23
+
24
+ ## 1. When I add the "Contact Us" webform to the bottom of the "Contact" Canvas page
25
+
26
+ Add a Webform block component to the bottom of a Drupal Canvas page and
27
+ publish the page. Drupal Canvas builds pages from a React editor whose
28
+ drag-and-drop cannot be driven by a browser test (the drop target lives in a
29
+ cross-document iframe), so this step performs the same change the editor
30
+ makes by calling Canvas's own authoring API:
31
+ 1. resolve the canvas_page id by title,
32
+ 2. append a `block.webform_block` component to the page's main content,
33
+ 3. POST the updated layout (creates an auto-save),
34
+ 4. publish the pending auto-save.
35
+
36
+ Requires an authenticated user with "publish auto-saves" access (e.g. the
37
+ webmaster) — run a login step first. The webform value is the entity
38
+ autocomplete format "Label (machine_name)".
39
+
40
+ Example:
41
+ Given I am a logged in user with the "webmaster" user
42
+ When I add the "Newsletter Subscribe (newsletter_subscribe)" webform to the bottom of the "Home" Canvas page and publish it
43
+
44
+ **Keyword**: `When`
45
+
46
+ **Pattern**
47
+
48
+ ```js
49
+ /^(?:I |we )*add the "([^"]*)" webform to the bottom of the "([^"]*)" (?:Canvas )?page(?: and publish(?: it)?)?$/
50
+ ```
51
+
52
+ **Examples**
53
+
54
+ ```gherkin
55
+ When I add the "Contact Us" webform to the bottom of the "Contact" Canvas page
56
+ And I add the "Newsletter" webform to the bottom of the "Home" page and publish it
57
+ When we add the "Business Contact" webform to the bottom of the "About Us" Canvas page and publish
58
+ And I add the "Feedback" webform to the bottom of the "Support" page
59
+ When I add the "Careers" webform to the bottom of the "Jobs" Canvas page and publish it
60
+ ```
61
+
62
+ ## 2. Then the Drupal Canvas component library should list the "Hero" component
63
+
64
+ Assert that a component is (or is not) offered in the Drupal Canvas editor's
65
+ component library. The editor populates its library from the same
66
+ `/canvas/api/v0/config/component` endpoint queried here, so this verifies
67
+ what an editor sees when building a page - without driving the React editor.
68
+
69
+ Requires an authenticated user who can edit Canvas pages (run a login step
70
+ and navigate to an admin page first so the request is same-origin).
71
+
72
+ Example:
73
+ Then the Drupal Canvas component library should list the "block.system_menu_block.main" component
74
+
75
+ **Keyword**: `Then`
76
+
77
+ **Pattern**
78
+
79
+ ```js
80
+ /^the Drupal Canvas component library should( not)? list the "([^"]*)" component$/
81
+ ```
82
+
83
+ **Examples**
84
+
85
+ ```gherkin
86
+ Then the Drupal Canvas component library should list the "Hero" component
87
+ And the Drupal Canvas component library should list the "Card" component
88
+ Then the Drupal Canvas component library should not list the "Legacy Slider" component
89
+ And the Drupal Canvas component library should list the "Accordion" component
90
+ Then the Drupal Canvas component library should not list the "Deprecated Banner" component
91
+ ```
92
+
93
+ ## 3. When I create a Canvas page "Landing" at "/landing" with the "Hero" component:
94
+
95
+ Create (or replace) a published Drupal Canvas page that contains a single
96
+ component, configured from a Gherkin data table of input/value rows. The
97
+ Canvas editor's drag-and-drop cannot be driven by a browser test, so this
98
+ builds the page through Canvas's own content API:
99
+ 1. delete any existing page at the same path (idempotent re-runs),
100
+ 2. read the live component version (never hard-coded),
101
+ 3. POST a new published page whose component tree is that one component
102
+ with the given inputs.
103
+
104
+ This step is generic: pass any Canvas component id (e.g.
105
+ "sdc.vartheme_bs5.card-hero", "block.webform_block"). Boolean-looking values
106
+ ("true"/"false") are coerced so checkbox props work. Requires a logged-in
107
+ user who can create Canvas pages (run a login step first).
108
+
109
+ Example:
110
+ When I create a Canvas page "Hero - primary" at "/test-hero-primary" with the "sdc.vartheme_bs5.card-hero" component:
111
+ | title | Primary hero |
112
+ | background_color | bg-primary |
113
+ | card_border | true |
114
+
115
+ **Keyword**: `When`
116
+
117
+ **Pattern**
118
+
119
+ ```js
120
+ /^(?:I |we )*create a Canvas page "([^"]*)" at "([^"]*)" with the "([^"]*)" component:$/
121
+ ```
122
+
123
+ **Examples**
124
+
125
+ ```gherkin
126
+ When I create a Canvas page "Landing" at "/landing" with the "Hero" component:
127
+ And I create a Canvas page "Pricing" at "/pricing" with the "Card" component:
128
+ When we create a Canvas page "Team" at "/about/team" with the "Grid" component:
129
+ And I create a Canvas page "Events" at "/events" with the "Listing" component:
130
+ When I create a Canvas page "Support" at "/support" with the "Accordion" component:
131
+ ```
132
+
133
+ ## 4. When I add the "Hero" component to the "Landing" Canvas page using the editor
134
+
135
+ Add a component to a Drupal Canvas page the way a human site builder does:
136
+ open the page in the Canvas editor, open the Library, find the named
137
+ component, and drag it onto the (empty) canvas drop zone. The dropped
138
+ component is left selected with its Settings panel open, ready for option
139
+ steps. Drupal Canvas renders its drop zones in the top document during an
140
+ active drag, so the drag is performed with real pointer moves and only
141
+ released once a drop zone reports it is being hovered.
142
+
143
+ Run a login step first (e.g. the webmaster). Use the component's visible
144
+ Library name (e.g. "Hero Card").
145
+
146
+ Example:
147
+ When I add the "Hero Card" component to the "Test Hero Editor" Canvas page using the editor
148
+
149
+ **Keyword**: `When`
150
+
151
+ **Pattern**
152
+
153
+ ```js
154
+ /^(?:I |we )*add the "([^"]*)" component to the "([^"]*)" Canvas page using the editor$/
155
+ ```
156
+
157
+ **Examples**
158
+
159
+ ```gherkin
160
+ When I add the "Hero" component to the "Landing" Canvas page using the editor
161
+ And I add the "Card" component to the "Pricing" Canvas page using the editor
162
+ When we add the "Accordion" component to the "Support" Canvas page using the editor
163
+ And I add the "Grid" component to the "Team" Canvas page using the editor
164
+ When I add the "Listing" component to the "Events" Canvas page using the editor
165
+ ```
166
+
167
+ ## 5. When I publish the Canvas page changes
168
+
169
+ Publish the pending changes for the Canvas page currently open in the editor.
170
+
171
+ The editor's React "Review changes" publish widget is not reliable to drive
172
+ headless on CI (it can hang), so this commits through Canvas's own authoring
173
+ API - the same endpoints the widget calls: re-POST the page's auto-saved
174
+ layout (which the editor's drag-and-drop and Settings-panel edits have
175
+ populated) to guarantee a pending auto-save, then POST it to the publish
176
+ endpoint. Deterministic and fast, with no editor-UI timing.
177
+
178
+ Example: When I publish the Canvas page changes
179
+
180
+ **Keyword**: `When`
181
+
182
+ **Pattern**
183
+
184
+ ```js
185
+ /^(?:I |we )*publish the Canvas page changes$/
186
+ ```
187
+
188
+ **Examples**
189
+
190
+ ```gherkin
191
+ When I publish the Canvas page changes
192
+ And I publish the Canvas page changes
193
+ When we publish the Canvas page changes
194
+ Given I publish the Canvas page changes
195
+ And we publish the Canvas page changes
196
+ ```
197
+
198
+ ## 6. Given there is a new Canvas page "Landing" at "/landing"
199
+
200
+ Create (or replace) an empty published Drupal Canvas page, so a later editor
201
+ step can add a component to it the human way. This only sets up the page
202
+ container; it does not add components. Idempotent by path.
203
+
204
+ Example: Given a new Canvas page "Test Hero Editor" at "/test-hero-editor"
205
+
206
+ **Keyword**: `When`
207
+
208
+ **Pattern**
209
+
210
+ ```js
211
+ /^(?:there is |I have )?a new Canvas page "([^"]*)" at "([^"]*)"$/
212
+ ```
213
+
214
+ **Examples**
215
+
216
+ ```gherkin
217
+ Given there is a new Canvas page "Landing" at "/landing"
218
+ And I have a new Canvas page "Pricing" at "/pricing"
219
+ Given a new Canvas page "Team" at "/about/team"
220
+ And there is a new Canvas page "Events" at "/events"
221
+ Given I have a new Canvas page "Support" at "/support"
222
+ ```
223
+
224
+ ## 7. When I set the Canvas component option "Heading" to "Welcome"
225
+
226
+ Set an option on the component currently selected in the Drupal Canvas editor
227
+ Settings panel, by its visible field label. Scoped to the component props
228
+ form so it never clashes with same-named page fields (e.g. "Title").
229
+ Dispatches input/change so Canvas auto-saves the change. Works for text
230
+ inputs, textareas and select dropdowns (match the option by its visible text
231
+ or its value).
232
+
233
+ Example:
234
+ When I set the Canvas component option "Background color" to "Primary"
235
+ And I set the Canvas component option "Title" to "Configured hero"
236
+
237
+ **Keyword**: `When`
238
+
239
+ **Pattern**
240
+
241
+ ```js
242
+ /^(?:I |we )*set the Canvas component option "([^"]*)" to "([^"]*)"$/
243
+ ```
244
+
245
+ **Examples**
246
+
247
+ ```gherkin
248
+ When I set the Canvas component option "Heading" to "Welcome"
249
+ And I set the Canvas component option "Style" to "Primary"
250
+ When we set the Canvas component option "Alignment" to "Center"
251
+ And I set the Canvas component option "Background" to "Light"
252
+ When I set the Canvas component option "Link text" to "Read more"
253
+ ```
254
+
255
+ ## 8. When I open the "Landing" Canvas page in the editor
256
+
257
+ Open a Canvas page in the real Drupal Canvas editor the way a site builder
258
+ does: navigate to /canvas/editor/canvas_page/<id> and wait until the editor
259
+ is ready to drive. Drupal Canvas is a heavy React SPA, so readiness is polled
260
+ off the left toolbar "Library" button (it can take several seconds to mount)
261
+ rather than a fixed sleep.
262
+
263
+ Resolves the page id by its title, so create the page first (e.g. with a
264
+ "a new Canvas page ..." step) and run a login step as a user who can edit
265
+ Canvas pages (e.g. the webmaster).
266
+
267
+ **Keyword**: `When`
268
+
269
+ **Pattern**
270
+
271
+ ```js
272
+ /^(?:I |we )*open the "([^"]*)" Canvas page in the editor$/
273
+ ```
274
+
275
+ **Examples**
276
+
277
+ ```gherkin
278
+ When I open the "Landing" Canvas page in the editor
279
+ And I open the "Test Pattern Counters" Canvas page in the editor
280
+ When we open the "Home" Canvas page in the editor
281
+ And we open the "Test Pattern Header Footer" Canvas page in the editor
282
+ Given I open the "Pattern Library Check" Canvas page in the editor
283
+ ```
284
+
285
+ ## 9. When I open the "Patterns" tab in the Canvas Library
286
+
287
+ Open a named tab in the Drupal Canvas editor Library panel, the way a site
288
+ builder browses ready-made sections. Opens the Library panel if it is closed
289
+ (idempotent - it never toggles an already-open panel shut), activates the
290
+ requested tab, and waits until the tab's list has actually populated (a known
291
+ item is visible) so a following assertion or insert reads real, on-screen
292
+ content - not an empty, still-loading panel.
293
+
294
+ Only "Patterns" and "Components" are valid tab names. Open a page in the
295
+ editor first.
296
+
297
+ **Keyword**: `When`
298
+
299
+ **Pattern**
300
+
301
+ ```js
302
+ /^(?:I |we )*open the "(Patterns|Components)" tab in the Canvas Library$/
303
+ ```
304
+
305
+ **Examples**
306
+
307
+ ```gherkin
308
+ When I open the "Patterns" tab in the Canvas Library
309
+ And I open the "Components" tab in the Canvas Library
310
+ When we open the "Patterns" tab in the Canvas Library
311
+ And we open the "Components" tab in the Canvas Library
312
+ Given I open the "Patterns" tab in the Canvas Library
313
+ ```
314
+
315
+ ## 10. When I insert the "Hero Slider" pattern from the Canvas Library
316
+
317
+ Insert a default Canvas Pattern into the page open in the editor, exactly as a
318
+ site builder does: right-click the pattern's row in the Library > Patterns
319
+ list (a context-menu trigger) and choose "Insert". The whole section is added
320
+ and the just-inserted component becomes selected, so the editor URL gains a
321
+ fresh /component/<uuid>; the step waits for that uuid to change to confirm the
322
+ insert registered. Inserting the same pattern twice therefore lands two
323
+ independent copies (each gets its own uuid).
324
+
325
+ Open the page in the editor and open the "Patterns" Library tab first. Use the
326
+ pattern's visible human label (e.g. "Hero Slider", "Counters", "Site Header").
327
+
328
+ **Keyword**: `When`
329
+
330
+ **Pattern**
331
+
332
+ ```js
333
+ /^(?:I |we )*insert the "([^"]*)" pattern from the Canvas Library$/
334
+ ```
335
+
336
+ **Examples**
337
+
338
+ ```gherkin
339
+ When I insert the "Hero Slider" pattern from the Canvas Library
340
+ And I insert the "Counters" pattern from the Canvas Library
341
+ And I insert the "Counters" pattern from the Canvas Library
342
+ When we insert the "Site Header" pattern from the Canvas Library
343
+ And we insert the "Site Footer" pattern from the Canvas Library
344
+ ```
345
+
346
+ ## 11. When I publish the Canvas page changes through the editor
347
+
348
+ Publish the pending Canvas changes through the editor's own Review/Publish
349
+ widget, the way a site builder ships a page: click the topbar "Review N
350
+ change(s)" button, "Select All" in the review list, then "Publish N selected".
351
+ The step waits until the topbar widget resets to "No changes", confirming the
352
+ publish landed. Drupal Canvas's review list is site-wide, so "Select All"
353
+ publishes every pending change; drive this right after inserting on the page
354
+ under test so only that page's changes are pending.
355
+
356
+ Open a page in the editor and make at least one change (e.g. insert a pattern)
357
+ first.
358
+
359
+ **Keyword**: `When`
360
+
361
+ **Pattern**
362
+
363
+ ```js
364
+ /^(?:I |we )*publish the Canvas page changes through the editor$/
365
+ ```
366
+
367
+ **Examples**
368
+
369
+ ```gherkin
370
+ When I publish the Canvas page changes through the editor
371
+ And I publish the Canvas page changes through the editor
372
+ When we publish the Canvas page changes through the editor
373
+ And we publish the Canvas page changes through the editor
374
+ Then I publish the Canvas page changes through the editor
375
+ ```
376
+
377
+ ## 12. Then the Canvas Library "Patterns" tab should list "Hero Slider"
378
+
379
+ Assert that a Drupal Canvas Library panel does (or does not) list an item by
380
+ its visible label. Scoped to the panel element by CSS selector (e.g. the
381
+ Patterns or Components tab content) and read straight from the panel's
382
+ on-screen text - the labels a site builder actually sees, not any API dump.
383
+
384
+ This is the fast, panel-scoped counterpart of the generic "I should see ... in
385
+ the ... element" assertion: it reads the panel's innerText once and checks the
386
+ label against the panel's line items, so a library with a dozen checks stays
387
+ quick and never trips a step timeout. Matches a whole line item exactly (so
388
+ "Share" does not match "Social media menu" and an absent admin label is never
389
+ a false positive from a longer entry).
390
+
391
+ The panel selector is resolved from the named-selector registry
392
+ (tests/selectors/<preset>.json): the "Patterns" tab maps to the
393
+ "canvas patterns library" selector and "Components" to
394
+ "canvas components library", so the feature reads by tab name and the CSS
395
+ lives in one place. Open the page in the editor and open that Library tab
396
+ first.
397
+
398
+ **Keyword**: `Then`
399
+
400
+ **Pattern**
401
+
402
+ ```js
403
+ /^the Canvas Library "(Patterns|Components)" tab should( not)? list "([^"]*)"$/
404
+ ```
405
+
406
+ **Examples**
407
+
408
+ ```gherkin
409
+ Then the Canvas Library "Patterns" tab should list "Hero Slider"
410
+ And the Canvas Library "Patterns" tab should list "Counters"
411
+ Then the Canvas Library "Components" tab should list "Webform"
412
+ And the Canvas Library "Components" tab should not list "Events Feed"
413
+ And the Canvas Library "Components" tab should not list "Recent pages"
414
+ ```
@@ -0,0 +1,118 @@
1
+ # CKEditor 5 steps
2
+
3
+ 4 steps, defined in `tests/step-definitions/drupal-ckeditor.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 | `When I fill in the rich text editor field "Body" with "Test Body text"` |
10
+ | 2 | `When I append the rich text editor field "Body" with "More text"` |
11
+ | 3 | `When I click on "media" command button in the rich text editor field "Body"` |
12
+ | 4 | `When I fill in the link URL "Linking to"` |
13
+
14
+ ---
15
+
16
+ ## 1. When I fill in the rich text editor field "Body" with "Test Body text"
17
+
18
+ Set the value of a CKEditor 5 rich text editor field by the field label/name.
19
+
20
+ Ports VarbaseContext::iFillInTheRichTextEditorField. Resolves the form field
21
+ (label, name, or id), reads its CKEditor 5 instance id from the data
22
+ attribute, and calls setData(). No Varbase E2E equivalent (Varbase E2E's
23
+ "WYSIWYG field" step is CKEditor-version agnostic and may not target CK5).
24
+
25
+ **Keyword**: `When`
26
+
27
+ **Pattern**
28
+
29
+ ```js
30
+ /^(?:I |we )*fill in the rich text editor field "([^"]*)" with(?: the)? "([^"]*)"$/
31
+ ```
32
+
33
+ **Examples**
34
+
35
+ ```gherkin
36
+ When I fill in the rich text editor field "Body" with "Test Body text"
37
+ And I fill in the rich text editor field "Body" with "<p>Hello</p>"
38
+ When we fill in the rich text editor field "Description" with "Text"
39
+ And I fill in the rich text editor field "Summary" with "Intro"
40
+ Given I fill in the rich text editor field "Body" with "Content"
41
+ ```
42
+
43
+ ## 2. When I append the rich text editor field "Body" with "More text"
44
+
45
+ Append text to the end of a CKEditor 5 rich text editor field.
46
+
47
+ Ports VarbaseContext::appendTheRichTextEditorField.
48
+
49
+ **Keyword**: `When`
50
+
51
+ **Pattern**
52
+
53
+ ```js
54
+ /^(?:I |we )*append(?: after)? the rich text editor field "([^"]*)" with "([^"]*)"$/
55
+ ```
56
+
57
+ **Examples**
58
+
59
+ ```gherkin
60
+ When I append the rich text editor field "Body" with "More text"
61
+ And I append after the rich text editor field "Body" with "End"
62
+ When we append the rich text editor field "Body" with "Tail"
63
+ And I append after the rich text editor field "Description" with "!"
64
+ Given I append the rich text editor field "Body" with "Extra"
65
+ ```
66
+
67
+ ## 3. When I click on "media" command button in the rich text editor field "Body"
68
+
69
+ Click a toolbar command button inside a CKEditor 5 field.
70
+
71
+ Ports VarbaseContext::iClickOnCommandButtonInTheRichTextEditorField and
72
+ iClickOnTheSaveButtonInTheEditor. Matches both:
73
+ When I click on "bold" command button in the rich text editor field "Body"
74
+ When I click on the insert button in "Body" rich text editor field
75
+
76
+ **Keyword**: `When`
77
+
78
+ **Pattern**
79
+
80
+ ```js
81
+ /^(?:I |we )*click on (?:"([^"]*)" command button in the rich text editor field "([^"]*)"|the (save|insert|action|apply) button in "([^"]*)" rich text editor field)$/
82
+ ```
83
+
84
+ **Examples**
85
+
86
+ ```gherkin
87
+ When I click on "media" command button in the rich text editor field "Body"
88
+ And I click on "bold" command button in the rich text editor field "Body"
89
+ When I click on the insert button in "Body" rich text editor field
90
+ And I click on the save button in "Body" rich text editor field
91
+ When we click on "link" command button in the rich text editor field "Body"
92
+ ```
93
+
94
+ ## 4. When I fill in the link URL "Linking to"
95
+
96
+ Type a query into the open CKEditor 5 Drupal-link balloon's "Link URL" field
97
+ so Linkit's autocomplete (ul.ui-autocomplete) searches for internal content.
98
+
99
+ The balloon holds several inputs (Displayed text, Title, ARIA label, CSS
100
+ classes … from editor_advanced_link), so target the one whose label is
101
+ "Link URL". CKEditor 5's input reacts only to real per-character typing (a
102
+ value assignment is ignored), so type with a small delay to let Linkit
103
+ debounce and query. This replaces the CKEditor-4-era "fill in … for
104
+ 'Link URL'" + keypress steps.
105
+
106
+ **Keyword**: `When`
107
+
108
+ **Pattern**
109
+
110
+ ```js
111
+ /^(?:I |we )*fill in the link URL "([^"]*)"$/
112
+ ```
113
+
114
+ **Examples**
115
+
116
+ ```gherkin
117
+ When I fill in the link URL "Linking to"
118
+ ```