@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,26 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { run } = require('./init-varbase-e2e');
8
+
9
+ const packagePath = path.join(__dirname, '..');
10
+ const projectPath = process.env.INIT_CWD || process.cwd();
11
+
12
+ // Skip when invoked from varbase-e2e itself (development / CI).
13
+ if (
14
+ projectPath === packagePath ||
15
+ projectPath.startsWith(path.join(packagePath, 'node_modules'))
16
+ ) {
17
+ process.exit(0);
18
+ }
19
+
20
+ // Only run on a fresh project — cucumber.js absence marks an uninitialized project.
21
+ // Re-installs (npm install, npm ci) will not overwrite user customizations.
22
+ if (fs.existsSync(path.join(projectPath, 'cucumber.js'))) {
23
+ process.exit(0);
24
+ }
25
+
26
+ run(['--cwd', projectPath]);
package/cucumber.js ADDED
@@ -0,0 +1,125 @@
1
+ module.exports = {
2
+ default: {
3
+ // Cucumber step timeout must exceed Playwright's default 30s so the
4
+ // try/catch wrappers in step files always see the Playwright error
5
+ // first (and emit a friendly message) rather than cucumber's raw
6
+ // "function timed out" stack.
7
+ timeout: 45000,
8
+ // tsx/cjs registers a require() hook so cucumber-js can load both
9
+ // `.js` and `.ts` step files with zero build step. If you ship only
10
+ // JavaScript, drop `requireModule` and the `.ts` half of the glob.
11
+ requireModule: ['tsx/cjs'],
12
+ require: [
13
+ 'tests/step-definitions/**/*.js',
14
+ ],
15
+ paths: ['tests/features/**/*.feature'],
16
+ format: [
17
+ '@cucumber/pretty-formatter',
18
+ 'json:tests/reports/cucumber_report.json',
19
+ ],
20
+ formatOptions: {
21
+ // Color toggle is controlled via the FORCE_COLOR env var (per
22
+ // cucumber-js v10+); the deprecated `colorsEnabled` option is gone.
23
+ theme: {
24
+ 'feature keyword': ['bold', 'blue'],
25
+ 'feature name': ['blue', 'underline'],
26
+ 'feature description': ['blueBright'],
27
+ 'scenario keyword': ['bold', 'magenta'],
28
+ 'scenario name': ['magenta', 'underline'],
29
+ 'step keyword': ['bold', 'green'],
30
+ 'step text': ['greenBright', 'italic'],
31
+ },
32
+ },
33
+ worldParameters: {
34
+ launchUrl: process.env.LAUNCH_URL || 'http://localhost:8080',
35
+ minWaitTime: {
36
+ page: 3000,
37
+ before_scenario: 0,
38
+ after_scenario: 0,
39
+ before_step: 0,
40
+ after_step: 0,
41
+ },
42
+ selectors: {
43
+ // Named CSS selectors — layout components and element locators in one registry.
44
+ // Register inline: When I add "name" selector for "css" css selector
45
+ // Or in bulk: Given I define css selectors:
46
+ // | name | css selector |
47
+ css: {
48
+ // 'header': 'header.page-header',
49
+ // 'main nav': 'nav[role="navigation"]',
50
+ // 'breadcrumb': '.breadcrumb',
51
+ // 'breadcrumb first link': '.breadcrumb li:nth-child(1) a',
52
+ // 'message': '.messages',
53
+ // 'error message': '.messages.error',
54
+ // 'success message': '.messages.status',
55
+ // 'warning message': '.messages.warning',
56
+ },
57
+ // Named XPath selectors — use with: When I add "name" selector for "xpath" xpath selector
58
+ xpath: {
59
+ // 'page title': '//h1[contains(@class,"page-header")]',
60
+ },
61
+ // Load additional selectors from JSON files at scenario start.
62
+ filesPath: './tests/selectors/', // base path for selector files
63
+ files: [], // e.g. ['homepage-selectors.json'] or ['front-end-selectors.json', 'back-end-selectors.json']
64
+ // Relative-position scroll offset (px) — VARBASE_E2E_SELECTORS_OFFSET
65
+ offset: 60,
66
+ // Viewport breakpoints — VARBASE_E2E_SELECTORS_BREAKPOINTS (JSON string)
67
+ breakpoints: {
68
+ xs: { width: 375, height: 667 }, // phone portrait
69
+ sm: { width: 576, height: 800 }, // large phone / phablet
70
+ md: { width: 768, height: 1024 }, // tablet portrait
71
+ lg: { width: 992, height: 768 }, // small laptop / tablet landscape
72
+ xl: { width: 1200, height: 900, default: true }, // desktop
73
+ xxl: { width: 1400, height: 900 }, // wide desktop / HD
74
+ xxxl: { width: 1920, height: 1080 }, // Full HD / large monitor
75
+ },
76
+ },
77
+ screenshot: {
78
+ dir: './screenshots', // VARBASE_E2E_SCREENSHOT_DIR
79
+ purge: false, // VARBASE_E2E_SCREENSHOT_PURGE
80
+ onFailed: true, // VARBASE_E2E_SCREENSHOT_ON_FAILED
81
+ onEveryStep: false, // VARBASE_E2E_SCREENSHOT_ON_EVERY_STEP
82
+ alwaysFullscreen: false, // VARBASE_E2E_SCREENSHOT_FULLSCREEN
83
+ failedPrefix: 'failed_', // VARBASE_E2E_SCREENSHOT_FAILED_PREFIX
84
+ filenamePattern: '{datetime}.{feature_file}.feature_{step_line}.{ext}', // VARBASE_E2E_SCREENSHOT_PATTERN
85
+ filenamePatternFailed: '{failed_prefix}{datetime}.{feature_file}.feature_{step_line}.{ext}', // VARBASE_E2E_SCREENSHOT_PATTERN_FAIL
86
+ infoTypes: '', // VARBASE_E2E_SCREENSHOT_INFO_TYPES e.g. "url,feature,step,datetime"
87
+ },
88
+ video: {
89
+ // Record the browser as a webm video.
90
+ // 'off' (default) — no recording.
91
+ // 'on' — record every scenario.
92
+ // 'on-failure' — record every scenario, keep only failures.
93
+ // 'tag' — record only scenarios tagged @video.
94
+ // Override per scenario with tags:
95
+ // @video — force recording on (independent of mode).
96
+ // @no-video — suppress recording for this scenario.
97
+ // Override per run with env: VARBASE_E2E_VIDEO.
98
+ mode: 'off', // VARBASE_E2E_VIDEO
99
+ dir: './videos', // VARBASE_E2E_VIDEO_DIR
100
+ size: { width: 1280, height: 720 }, // viewport size of the recording
101
+ // Filename template tokens: {datetime} {feature_file} {feature} {scenario}
102
+ // {status} {ext}. Sanitised to filesystem-safe characters.
103
+ filenamePattern: '{datetime}.{feature_file}.{scenario}.{status}.{ext}',
104
+ },
105
+ javascript: {
106
+ // How to report collected JavaScript errors at scenario end.
107
+ // 'warn' (default) — log a yellow warning, scenario still passes.
108
+ // 'fail' — fail the scenario.
109
+ // 'off' — silent.
110
+ // Override per scenario with tags: @js-fail, @js-warn, @js-off.
111
+ // Override per run with env: VARBASE_E2E_JS_ERROR_MODE.
112
+ mode: 'warn', // VARBASE_E2E_JS_ERROR_MODE
113
+ // Console levels to capture in addition to `pageerror`.
114
+ // Common: ['error'], ['error','warning'], ['error','warning','info'].
115
+ levels: ['error'], // VARBASE_E2E_JS_ERROR_LEVELS (csv)
116
+ // Regex string. Errors whose message matches are ignored.
117
+ ignore: '', // VARBASE_E2E_JS_ERROR_IGNORE
118
+ // Snapshot any pre-existing errors at scenario start.
119
+ beforeScenario: false, // VARBASE_E2E_JS_ERROR_BEFORE
120
+ // Report collected errors at scenario end (default true).
121
+ afterScenario: true, // VARBASE_E2E_JS_ERROR_AFTER
122
+ },
123
+ },
124
+ },
125
+ };
@@ -0,0 +1,102 @@
1
+ # Quick Start (5 minutes)
2
+
3
+ Brand new to varbase-e2e? Read this page once. You'll be writing tests in
4
+ five minutes.
5
+
6
+ ## What you write
7
+
8
+ Plain English scenarios. No JavaScript required.
9
+
10
+ ```gherkin
11
+ Feature: Sign in
12
+
13
+ Scenario: Successful login
14
+ Given I am on "/login"
15
+ When I fill in "Email" with "alice@example.com"
16
+ And I fill in "Password" with "s3cret"
17
+ And I press "Sign in"
18
+ Then I should see "Welcome, Alice"
19
+ ```
20
+
21
+ That's a complete test. Every line maps to a built-in step. No setup
22
+ code. No selector jargon.
23
+
24
+ ## What you get
25
+
26
+ * **Real browser** — runs in Chromium, Firefox, or WebKit via Playwright.
27
+ * **Automatic smart waits** — every action waits for the page to
28
+ settle. No `sleep` / `wait 5s` needed in the happy path.
29
+ * **HTML report** — runs auto-generate `tests/reports/cucumber_report.html`.
30
+ * **Screenshots on failure** — saved to `screenshots/` for instant
31
+ debugging.
32
+
33
+ ## 30-second install
34
+
35
+ ```bash
36
+ npm install @vardot/varbase-e2e --save-dev
37
+ ```
38
+
39
+ The post-install script copies a starter `cucumber.js`,
40
+ `playwright.config.ts`, and `tests/` skeleton.
41
+
42
+ ## 60-second first test
43
+
44
+ 1. Drop your scenario into `tests/features/smoke.feature`.
45
+ 2. Make sure your dev server is running on `http://localhost:8080`
46
+ (or set `LAUNCH_URL` to point elsewhere).
47
+ 3. Run:
48
+
49
+ ```bash
50
+ npm test
51
+ ```
52
+
53
+ If your scenario passes, you're done. If it fails, the Cucumber output
54
+ names the step that failed and the expected vs actual.
55
+
56
+ ## Where to go next
57
+
58
+ | Want to… | Read |
59
+ | --- | --- |
60
+ | Understand smart waits (no `sleep`) | [02 BBR smart waits](02-bbr-smart-waits.md) |
61
+ | Use named selectors instead of long CSS | [03 Selector registry](03-selector-registry.md) |
62
+ | See every built-in step | [04 Step reference](04-step-reference.md) |
63
+ | Test forms / clicks / modals | [04 Step reference](04-step-reference.md) |
64
+ | Mock APIs / dialogs | [06 Networking & dialogs](06-network-and-dialogs.md) |
65
+ | Accessibility audits | [10 Accessibility](10-accessibility.md) |
66
+ | Use AI to generate tests | [12 AI agent guide](12-ai-agent-guide.md) |
67
+ | FAQ | [13 FAQ](13-faq.md) |
68
+ | Recipes cookbook | [14 Recipes cookbook](14-recipes-cookbook.md) |
69
+
70
+ ## The mental model
71
+
72
+ * `Given` — set up the scene (navigate, restore auth, seed data).
73
+ * `When` — do something (click, fill, submit).
74
+ * `Then` — check what should be true (text visible, URL changed).
75
+ * `And` / `But` — continuation. Pick whichever reads naturally.
76
+ * `Background:` — steps shared across every scenario in a feature.
77
+ * `Scenario Outline:` + `Examples:` — same scenario with different data.
78
+
79
+ ## The golden rule
80
+
81
+ **Wait for events, not time.** Varbase E2E does this for you in the
82
+ common case. If you ever feel tempted to add `wait 5 seconds` because
83
+ something flaked, look for an event-based wait first:
84
+
85
+ ```gherkin
86
+ # Bad — slow, brittle.
87
+ When I press "Save"
88
+ And I wait 5 seconds
89
+ Then I should see "Saved"
90
+
91
+ # Good — instant when fast, patient when slow.
92
+ When I press "Save"
93
+ Then I should see "Saved"
94
+
95
+ # Best when "Save" navigates.
96
+ When I press "Save"
97
+ And I wait until the URL contains "/saved"
98
+ Then I should see "Saved"
99
+ ```
100
+
101
+ That's the entire philosophy. Read [02 BBR smart waits](02-bbr-smart-waits.md)
102
+ when you're ready to internalise the details.
@@ -0,0 +1,102 @@
1
+ # Getting Started
2
+
3
+ Varbase E2E is an automated functional testing harness built on Playwright + Cucumber-js. You write feature files in plain Gherkin; varbase-e2e handles the browser, smart waits, screenshots, reports, and CMS-aware selectors out of the box.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @vardot/varbase-e2e --save-dev
9
+ ```
10
+
11
+ The post-install script copies a starter `cucumber.js`, `playwright.config.ts`, and `tests/` skeleton into your project on first install.
12
+
13
+ ## Project layout
14
+
15
+ ```
16
+ your-project/
17
+ ├── cucumber.js # Profiles + worldParameters
18
+ ├── playwright.config.ts # Browser launch + context options
19
+ └── tests/
20
+ ├── features/ # *.feature files (Gherkin)
21
+ ├── selectors/ # CMS / framework selector JSON
22
+ └── step-definitions/ # *.js or *.ts (loaded automatically)
23
+ ```
24
+
25
+ ## TypeScript and JavaScript together
26
+
27
+ Step definitions can be plain JavaScript (`.js`) or TypeScript (`.ts`) — mix freely in the same project. The default `cucumber.js` registers the [`tsx`](https://tsx.is) require hook, so `.ts` files run with zero build step:
28
+
29
+ ```js
30
+ // cucumber.js (default)
31
+ requireModule: ['tsx/cjs'],
32
+ require: ['tests/step-definitions/**/*.{js,ts}'],
33
+ ```
34
+
35
+ Add a TypeScript step alongside JS ones:
36
+
37
+ ```ts
38
+ // tests/step-definitions/custom.steps.ts
39
+ import { Then } from '@cucumber/cucumber';
40
+ import assert from 'node:assert';
41
+
42
+ Then(/^(I |we )*see a TypeScript step$/, async function (this: { page: import('playwright').Page }) {
43
+ assert.ok(this.page);
44
+ });
45
+ ```
46
+
47
+ Pure-JS shops can drop both `requireModule` and the `.ts` half of the glob.
48
+
49
+ ## Run the suite
50
+
51
+ ```bash
52
+ # Default — full pretty output, optional auto-screenshots on failure.
53
+ npm test
54
+
55
+ # Fast run — no slow-mo.
56
+ npm run test:fast
57
+
58
+ # Watch the browser interactively.
59
+ npm run test:headed
60
+
61
+ # Pick a single browser.
62
+ BROWSER=firefox npm test
63
+ BROWSER=webkit npm test
64
+
65
+ # Parallel + retry (CLI flags — no separate profile needed).
66
+ npx cucumber-js --parallel 4 --retry 1 --retry-tag-filter @flaky
67
+ ```
68
+
69
+ ## Environment variables
70
+
71
+ | Variable | Default | Effect |
72
+ | --- | --- | --- |
73
+ | `LAUNCH_URL` | `http://localhost:8080` | Base URL for `Given I am on "/path"` |
74
+ | `BROWSER` | `chromium` | `chromium` / `firefox` / `webkit` |
75
+ | `HEADLESS` | `true` | Set to `false` for headed mode |
76
+ | `SLOW_MO` | `300` headed: `800` | Per-action delay (ms); set `0` for fast runs |
77
+ | `VARBASE_E2E_AUTO_SETTLE` | on | Set to `off` to disable auto edge-wait after actions |
78
+
79
+ ## First feature file
80
+
81
+ ```gherkin
82
+ Feature: Smoke
83
+
84
+ Scenario: Homepage loads
85
+ Given I am on the homepage
86
+ Then the page should declare a language
87
+ And the page should have exactly one h1
88
+ And there should be no JavaScript errors
89
+ ```
90
+
91
+ ## Next reading
92
+
93
+ - [BBR smart waits](02-bbr-smart-waits.md) — why we never `sleep N seconds`.
94
+ - [Selector registry](03-selector-registry.md) — named selectors + CMS presets.
95
+ - [Step reference](04-step-reference.md) — every built-in step, by topic.
96
+ - [Web-first assertions](05-web-first-assertions.md) — auto-retrying matchers.
97
+ - [Networking & dialogs](06-network-and-dialogs.md) — mocks, routes, alerts.
98
+ - [Auth state](07-auth-state.md) — save / restore login.
99
+ - [Clock mocking](08-clock-mocking.md) — control time.
100
+ - [API testing](09-api-testing.md) — direct HTTP from BDD.
101
+ - [Accessibility](10-accessibility.md) — POUR smoke checks.
102
+ - [Debugging](11-debugging.md) — screenshots, headed mode, traces.
@@ -0,0 +1,77 @@
1
+ # BBR Smart Waits
2
+
3
+ Varbase E2E follows a **Behavior-Based Robotics** philosophy: **react to the environment, not the clock.** A test never sleeps for a fixed N seconds. Instead, every wait step returns as soon as the page is at the **edge** of activity — DOM ready, no in-flight network, no pending timers, no live mutations.
4
+
5
+ ## What gets tracked
6
+
7
+ Varbase E2E installs a small init script in every browser context. It exposes four signals:
8
+
9
+ | Signal | Counter / time | Source |
10
+ | --- | --- | --- |
11
+ | Fetch / XHR in flight | `window.__varbaseE2eAjaxCount` | wraps `window.fetch` and `XMLHttpRequest.send` |
12
+ | Pending `setTimeout` | `window.__varbaseE2ePendingTimers` | wraps `window.setTimeout` / `clearTimeout` |
13
+ | Last DOM mutation | `window.__varbaseE2eLastMutation` | `MutationObserver` on `<html>` |
14
+ | Network idle | (Playwright internal) | `page.waitForLoadState('networkidle')` |
15
+
16
+ `smartSettle(page, budget)` polls all four atomically and returns when:
17
+
18
+ ```
19
+ __varbaseE2eAjaxCount === 0
20
+ && __varbaseE2ePendingTimers === 0
21
+ && (Date.now() - __varbaseE2eLastMutation) >= 250 ms
22
+ ```
23
+
24
+ …or when `budget` elapses, whichever comes first. Each phase is best-effort, so a slow network does not stall the others.
25
+
26
+ ## Step phrasings
27
+
28
+ ```gherkin
29
+ # Bounded smart wait (returns early on idle).
30
+ When I wait 5 seconds
31
+ When I wait max of 5 seconds
32
+ When I wait for 3 seconds for AJAX to finish
33
+
34
+ # Pure edge waits.
35
+ When I wait until the page is loaded
36
+ When I wait for AJAX to finish
37
+ When I wait until pending timers settle
38
+ When I wait until the network is idle
39
+
40
+ # Targeted edge waits.
41
+ When I wait for "#dashboard" to appear
42
+ When I wait for "#loading" to disappear
43
+ When I wait for the text "Welcome" to appear
44
+ When I wait until the URL contains "/dashboard"
45
+ When I wait until the page title contains "Dashboard"
46
+ When I wait until 5 elements match ".product-card"
47
+ When I wait until at least 3 elements match ".item"
48
+
49
+ # Modal-specific.
50
+ When I wait for the modal to appear
51
+ When I wait for the modal to disappear
52
+
53
+ # Body + DOMContentLoaded only (cheaper than full smart settle).
54
+ When I wait until the page is interactive
55
+
56
+ # Polling text assertion — re-runs the matcher until the deadline.
57
+ Then eventually I should see "Done"
58
+ Then eventually I should see "Done" within 10 seconds
59
+ ```
60
+
61
+ ## Auto-settle after actions
62
+
63
+ After every state-changing step (click, press, fill, submit, select, check, uncheck, choose, attach, reload, navigate), varbase-e2e silently runs `smartSettle(page, 1500)`. Tests do not need an explicit wait between an action and its follow-up assertion in the typical case. Disable per-run with `VARBASE_E2E_AUTO_SETTLE=off`.
64
+
65
+ ## What this kills
66
+
67
+ - **Sleep-driven testing** — `wait 3s` no longer means "sleep three seconds." It means "wait up to three seconds for the page to become quiet."
68
+ - **`networkidle` blind spots** — animations and `setTimeout`-driven UI changes that did not trigger a network request still register on the DOM-mutation and timer-pending signals.
69
+ - **Race-condition flake** — a click followed by an assertion that runs before the DOM finishes updating is now caught by the auto-settle hook.
70
+
71
+ ## When to override
72
+
73
+ You generally don't. A few legitimate cases:
74
+
75
+ - **Real animation** with a known duration (`wait 3 seconds` is fine — smart wait will exit early but the budget is still honored).
76
+ - **Polling backend** that mutates without fetch/XHR (e.g. raw WebSocket pushes). Use a targeted edge wait: `wait for the text "..." to appear`.
77
+ - **Off-by-design UI** that runs an `setInterval` heartbeat. The pending-timer counter only tracks `setTimeout`, so heartbeats do not block `smartSettle`.
@@ -0,0 +1,95 @@
1
+ # Selector Registry
2
+
3
+ Long, brittle CSS strings poison feature files. Varbase E2E solves this with a **named selector registry**: register a CSS or XPath string once, refer to it by a friendly name in every step.
4
+
5
+ ## Three ways to register
6
+
7
+ ### 1. Inline (one selector at a time)
8
+
9
+ ```gherkin
10
+ Scenario: Add to cart
11
+ Given I am on "/products/101"
12
+ When I add "buy button" selector for ".product__buy button[type=submit]" css selector
13
+ And I click "buy button" by attr
14
+ ```
15
+
16
+ ### 2. Bulk (Gherkin data table)
17
+
18
+ ```gherkin
19
+ Scenario: Layout assertions
20
+ Given I define css selectors:
21
+ | header | header.site |
22
+ | nav | nav[role="navigation"] |
23
+ | main | main |
24
+ | footer | footer |
25
+ Then "main" should be visible
26
+ ```
27
+
28
+ ### 3. JSON file (project-wide preset)
29
+
30
+ ```js
31
+ // cucumber.js
32
+ worldParameters: {
33
+ selectors: {
34
+ filesPath: './tests/selectors/',
35
+ files: ['cms-drupal-cms-gin.json'],
36
+ }
37
+ }
38
+ ```
39
+
40
+ Every scenario starts with a fresh registry. Later entries with the same name override earlier ones (last wins).
41
+
42
+ ## Built-in CMS / framework presets
43
+
44
+ Varbase E2E ships ready-made selector packs:
45
+
46
+ ```
47
+ tests/selectors/
48
+ ├── _canonical-keys.json # Index of canonical keys + naming rules
49
+ ├── back-end-selectors.json # Generic admin layout
50
+ ├── front-end-selectors.json # Generic public layout
51
+ ├── cms-drupal-cms-gin.json # Drupal CMS (Gin admin theme)
52
+ ├── cms-drupal-core-claro.json # Drupal Core (Claro admin theme)
53
+ ├── cms-generic-admin.json # Pattern-matching generic CMS admin
54
+ ├── cms-ghost-admin.json # Ghost
55
+ ├── cms-joomla-admin.json # Joomla
56
+ ├── cms-magento2-admin.json # Magento 2
57
+ ├── cms-prestashop-admin.json # PrestaShop
58
+ ├── cms-shopify-admin.json # Shopify Polaris admin
59
+ ├── cms-strapi-admin.json # Strapi
60
+ ├── cms-typo3-admin.json # TYPO3
61
+ ├── cms-contentful-admin.json # Contentful
62
+ ├── cms-craft-admin.json # Craft CMS
63
+ ├── cms-wordpress-admin.json # WordPress
64
+ ├── cms-woocommerce-front.json # WooCommerce storefront
65
+ ├── framework-ant-design.json # Ant Design
66
+ ├── framework-bootstrap.json # Bootstrap
67
+ ├── framework-bulma.json # Bulma
68
+ ├── framework-chakra.json # Chakra UI
69
+ ├── framework-foundation.json # Foundation
70
+ ├── framework-material-ui.json # MUI
71
+ ├── framework-shadcn.json # shadcn / Radix
72
+ ├── framework-tailwind.json # Tailwind common patterns
73
+ └── framework-vuetify.json # Vuetify
74
+ ```
75
+
76
+ ## Canonical key set
77
+
78
+ To keep tests portable, every preset exposes the same core names. See `tests/selectors/_canonical-keys.json` for the full list. Highlights:
79
+
80
+ - **Layout** — `main nav`, `main nav item`, `sidebar`, `header bar`, `main content`, `page title`, `breadcrumb`, `user menu`
81
+ - **Modal** — `modal`, `modal overlay`, `modal title`, `modal body`, `modal footer`, `modal close`
82
+ - **Buttons** — `primary button`, `secondary button`, `danger button`, `save button`, `cancel button`, `delete button`
83
+ - **Notices** — `notice success`, `notice error`, `notice warning`, `notice info`, `toast`
84
+ - **Forms** — `form`, `form item`, `form label`, `form input`, `form select`, `form textarea`, `form actions`
85
+ - **Tables** — `data table`, `table header`, `table row`, `table first row`, `table row cell`
86
+ - **Tabs** — `tabs`, `tab item`, `active tab`, `tab content`
87
+ - **Search** — `search input`
88
+ - **Pagination** — `pagination`
89
+
90
+ ## Naming rules
91
+
92
+ - Lowercase words separated by single spaces (`primary button`, not `primary-button`).
93
+ - Modifier first (`active tab`, `danger button`, `first list item`).
94
+ - Synonyms collapse to canonical names (`alert success` / `notification success` / `callout success` → `notice success`).
95
+ - `data table` for HTML tables; `data list` for `ul`/`ol` collections.