@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,149 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <title>Scrolling Functionality Test</title>
6
+ <style>
7
+ body {
8
+ margin: 0;
9
+ padding: 20px;
10
+ font-family: Arial, sans-serif;
11
+ }
12
+ .indicator {
13
+ display: none;
14
+ font-size: 22px;
15
+ font-weight: bold;
16
+ color: #007bff;
17
+ padding: 12px 20px;
18
+ margin: 10px 0;
19
+ border: 2px solid #007bff;
20
+ background-color: #e7f3ff;
21
+ border-radius: 4px;
22
+ }
23
+ .content-block {
24
+ height: 300px;
25
+ background: #f0f4f8;
26
+ border: 1px solid #ccc;
27
+ margin: 10px 0;
28
+ padding: 20px;
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ font-size: 18px;
33
+ color: #555;
34
+ }
35
+ #scrollable-container {
36
+ width: 100%;
37
+ height: 150px;
38
+ overflow-y: scroll;
39
+ border: 2px solid #333;
40
+ margin: 20px 0;
41
+ padding: 10px;
42
+ background-color: #f9f9f9;
43
+ box-sizing: border-box;
44
+ }
45
+ .scrollable-inner {
46
+ height: 500px;
47
+ background: linear-gradient(to bottom, #ff9999, #99ff99, #9999ff);
48
+ padding: 10px;
49
+ }
50
+ #element-scroll-top { display: none; font-size: 18px; font-weight: bold; padding: 8px; }
51
+ #element-scroll-bottom { display: none; font-size: 18px; font-weight: bold; padding: 8px; }
52
+ </style>
53
+ </head>
54
+ <body>
55
+ <h1>Scrolling Functionality Test Page</h1>
56
+
57
+ <div id="basic-scroll-down" class="indicator">Basic scroll down works</div>
58
+ <div id="basic-scroll-up" class="indicator">Basic scroll up works</div>
59
+ <div id="custom-scroll-down" class="indicator">Custom scroll down works</div>
60
+ <div id="custom-scroll-up" class="indicator">Custom scroll up works</div>
61
+ <div id="scroll-to-top" class="indicator">Scroll to top works</div>
62
+ <div id="scroll-to-bottom" class="indicator">Scroll to bottom works</div>
63
+
64
+ <div class="content-block">Section 1 - Scroll down to see more</div>
65
+ <div class="content-block">Section 2</div>
66
+ <div class="content-block">Section 3</div>
67
+ <div class="content-block">Section 4</div>
68
+ <div class="content-block">Section 5</div>
69
+ <div class="content-block">Section 6</div>
70
+ <div class="content-block">Section 7</div>
71
+ <div class="content-block">Section 8</div>
72
+ <div class="content-block">Section 9</div>
73
+ <div class="content-block">Section 10 - Near the bottom</div>
74
+
75
+ <h2>Scrollable Element Container</h2>
76
+ <div id="scrollable-container">
77
+ <div class="scrollable-inner">
78
+ <div id="element-scroll-top">Element scroll to top works</div>
79
+ <p>Scrollable content - scroll this container to see indicators</p>
80
+ <div id="element-scroll-bottom">Element scroll to bottom works</div>
81
+ </div>
82
+ </div>
83
+
84
+ <div class="content-block">End of page content</div>
85
+
86
+ <script>
87
+ var lastScrollY = 0;
88
+ var wasAtBottom = false;
89
+ var everScrolledDown = false;
90
+
91
+ window.addEventListener('scroll', function () {
92
+ var scrollY = window.scrollY;
93
+ var docHeight = document.documentElement.scrollHeight;
94
+ var winHeight = window.innerHeight;
95
+ var maxScroll = docHeight - winHeight;
96
+ var atBottom = scrollY >= maxScroll - 10;
97
+ var atTop = scrollY <= 0;
98
+ var goingDown = scrollY > lastScrollY;
99
+
100
+ document.getElementById('basic-scroll-down').style.display = 'none';
101
+ document.getElementById('basic-scroll-up').style.display = 'none';
102
+ document.getElementById('custom-scroll-down').style.display = 'none';
103
+ document.getElementById('custom-scroll-up').style.display = 'none';
104
+ document.getElementById('scroll-to-top').style.display = 'none';
105
+ document.getElementById('scroll-to-bottom').style.display = 'none';
106
+
107
+ if (atTop && everScrolledDown) {
108
+ document.getElementById('scroll-to-top').style.display = 'block';
109
+ } else if (atBottom) {
110
+ document.getElementById('scroll-to-bottom').style.display = 'block';
111
+ wasAtBottom = true;
112
+ everScrolledDown = true;
113
+ } else if (wasAtBottom && !goingDown) {
114
+ var distFromBottom = maxScroll - scrollY;
115
+ if (distFromBottom >= 340) {
116
+ document.getElementById('basic-scroll-up').style.display = 'block';
117
+ } else {
118
+ document.getElementById('custom-scroll-up').style.display = 'block';
119
+ }
120
+ } else if (scrollY >= 450) {
121
+ document.getElementById('custom-scroll-down').style.display = 'block';
122
+ } else if (scrollY > 0) {
123
+ document.getElementById('basic-scroll-down').style.display = 'block';
124
+ everScrolledDown = true;
125
+ }
126
+
127
+ lastScrollY = scrollY;
128
+ });
129
+
130
+ var scrollContainer = document.getElementById('scrollable-container');
131
+ var containerWasAtBottom = false;
132
+
133
+ scrollContainer.addEventListener('scroll', function () {
134
+ var scrollTop = this.scrollTop;
135
+ var maxScrollTop = this.scrollHeight - this.clientHeight;
136
+
137
+ document.getElementById('element-scroll-top').style.display = 'none';
138
+ document.getElementById('element-scroll-bottom').style.display = 'none';
139
+
140
+ if (scrollTop >= maxScrollTop - 5) {
141
+ document.getElementById('element-scroll-bottom').style.display = 'block';
142
+ containerWasAtBottom = true;
143
+ } else if (scrollTop <= 0 && containerWasAtBottom) {
144
+ document.getElementById('element-scroll-top').style.display = 'block';
145
+ }
146
+ });
147
+ </script>
148
+ </body>
149
+ </html>
@@ -0,0 +1,35 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <title>Select Option</title>
6
+ <style>
7
+ .style{
8
+ height: 50px;
9
+ font-size: 26px;
10
+ line-height: 50px;
11
+ }
12
+ </style>
13
+ <script>
14
+ function onClick(){
15
+ const cars = document.getElementById("cars");
16
+ const selectedOption = cars.options[cars.selectedIndex].text;
17
+ const element = document.getElementById("result");
18
+ element.innerText = "Option ( " + selectedOption + " ) has been selected successfully";
19
+ }
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <h1>Select Option</h1>
24
+ <label for="cars">Choose a car:</label>
25
+
26
+ <select name="cars" id="cars">
27
+ <option value="volvo">Volvo</option>
28
+ <option value="saab">Saab</option>
29
+ <option value="mercedes">Mercedes</option>
30
+ <option value="audi">Audi</option>
31
+ </select>
32
+ <input id="btnClick" class="btnClick" name="btnClick" type="button" value="Submit" onclick="onClick()">
33
+ <div id="result" class="style"></div><br/>
34
+ </body>
35
+ </html>
@@ -0,0 +1,95 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset='utf-8'>
6
+ <title>Select Radio Button</title>
7
+ <style>
8
+ .style {
9
+ height: 50px;
10
+ font-size: 26px;
11
+ line-height: 50px;
12
+ }
13
+ .section {
14
+ margin: 20px 0;
15
+ padding: 15px;
16
+ border: 1px solid #ccc;
17
+ }
18
+ </style>
19
+ <script>
20
+ function onGenderSubmit() {
21
+ var genderForm = document.forms[0];
22
+ var selectedGender = "";
23
+ for (var i = 0; i < genderForm.length; i++) {
24
+ if (genderForm[i].type === 'radio' && genderForm[i].checked) {
25
+ selectedGender = genderForm[i].value;
26
+ break;
27
+ }
28
+ }
29
+ const element = document.getElementById("gender-result");
30
+ element.innerText = "Selected: " + selectedGender;
31
+ }
32
+
33
+ function onPlanSubmit() {
34
+ var planForm = document.forms[2];
35
+ var selectedPlan = "";
36
+ for (var i = 0; i < planForm.length; i++) {
37
+ if (planForm[i].type === 'radio' && planForm[i].checked) {
38
+ selectedPlan = planForm[i].value;
39
+ break;
40
+ }
41
+ }
42
+ const element = document.getElementById("plan-result");
43
+ element.innerText = "Plan: " + selectedPlan;
44
+ }
45
+ </script>
46
+ </head>
47
+
48
+ <body>
49
+ <h1>Select Radio Button Options</h1>
50
+
51
+ <div class="section">
52
+ <h2>Gender Selection (by Label)</h2>
53
+ <form>
54
+ <input type="radio" id="gender-male" name="gender" value="Male">
55
+ <label for="gender-male">Male</label><br>
56
+ <input type="radio" id="gender-female" name="gender" value="Female">
57
+ <label for="gender-female">Female</label><br>
58
+ <input type="radio" id="gender-other" name="gender" value="Other">
59
+ <label for="gender-other">Other</label><br>
60
+ </form>
61
+ <input type="button" value="Submit" onclick="onGenderSubmit()">
62
+ <div id="gender-result" class="style"></div>
63
+ </div>
64
+
65
+ <div class="section">
66
+ <h2>Color Selection (by Value)</h2>
67
+ <form>
68
+ <label>
69
+ <input type="radio" name="color" value="red"> Red
70
+ </label><br>
71
+ <label>
72
+ <input type="radio" name="color" value="blue"> Blue
73
+ </label><br>
74
+ <label>
75
+ <input type="radio" name="color" value="green"> Green
76
+ </label><br>
77
+ </form>
78
+ </div>
79
+
80
+ <div class="section">
81
+ <h2>Plan Selection (by ID Selector)</h2>
82
+ <form>
83
+ <input type="radio" id="plan-basic" name="plan" value="Basic">
84
+ <label for="plan-basic">Basic Plan</label><br>
85
+ <input type="radio" id="plan-premium" name="plan" value="Premium">
86
+ <label for="plan-premium">Premium Plan</label><br>
87
+ <input type="radio" id="plan-enterprise" name="plan" value="Enterprise">
88
+ <label for="plan-enterprise">Enterprise Plan</label><br>
89
+ </form>
90
+ <input type="button" value="Plan Submit" onclick="onPlanSubmit()">
91
+ <div id="plan-result" class="style"></div>
92
+ </div>
93
+ </body>
94
+
95
+ </html>
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset='utf-8'>
6
+ <title>I wait time</title>
7
+ <style>
8
+ .container,
9
+ .container input,
10
+ .container button {
11
+ font-size: 26px;
12
+ }
13
+
14
+ .style {
15
+ font-size: 22px;
16
+ line-height: 50px;
17
+ }
18
+ </style>
19
+
20
+ </head>
21
+
22
+ <body>
23
+ <h1>Waiting Max number of Time</h1>
24
+
25
+ <div class="container">
26
+ <b><div id="result" class="style">Waiting . . .</div></b>
27
+ </div>
28
+ </body>
29
+
30
+ <script>
31
+ const element = document.getElementById("result");
32
+ const timeWate = 3;
33
+
34
+ setTimeout(() => {
35
+ element.innerText = 'Welcome with waiting until page load';
36
+ }, timeWate * 1000);
37
+
38
+ </script>
39
+ </html>
@@ -0,0 +1,47 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset='utf-8'>
6
+ <title>I wait page until is loaded</title>
7
+ <style>
8
+ .container,
9
+ .container input,
10
+ .container button {
11
+ font-size: 26px;
12
+ }
13
+
14
+ .style {
15
+ font-size: 22px;
16
+ line-height: 30px;
17
+ }
18
+
19
+ #complete{
20
+ font-size: 32px;
21
+ line-height: 30px;
22
+ }
23
+
24
+ </style>
25
+
26
+ </head>
27
+
28
+ <body>
29
+ <h1>Waiting for the page to load</h1>
30
+ <div id="complete">
31
+
32
+ </div>
33
+
34
+ <div id="container">
35
+
36
+ </div>
37
+ </body>
38
+
39
+ <script>
40
+
41
+ for(var i=0; i<2000; i++){
42
+ document.getElementById("container").innerHTML += '<p class="style">' + i + '</p>';
43
+ }
44
+ document.getElementById("complete").innerHTML += "The waiting process was completed successfully.";
45
+
46
+ </script>
47
+ </html>
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset='utf-8'>
6
+ <title>I wait time</title>
7
+ <style>
8
+ .container,
9
+ .container input,
10
+ .container button {
11
+ font-size: 26px;
12
+ }
13
+
14
+ .style {
15
+ font-size: 22px;
16
+ line-height: 50px;
17
+ }
18
+ </style>
19
+
20
+ </head>
21
+
22
+ <body>
23
+ <h1>Waiting a Specific number of Time</h1>
24
+
25
+ <div class="container">
26
+ <b><div id="result" class="style">Waiting . . .</div></b>
27
+ </div>
28
+ </body>
29
+
30
+ <script>
31
+ const element = document.getElementById("result");
32
+ const timeWate = 3;
33
+
34
+ setTimeout(() => {
35
+ element.innerText = 'Welcome with waiting full time';
36
+ }, timeWate * 1000);
37
+
38
+ </script>
39
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <meta http-equiv='X-UA-Compatible' content='IE=edge'>
6
+ <title>Test Acceptable URL Path</title>
7
+ </head>
8
+ <body>
9
+ Example for test acceptable URL path that have "-" between words.
10
+ </body>
11
+ </html>
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>🎬 Video Demo</title>
6
+ <style>
7
+ body { font-family: system-ui, sans-serif; max-width: 720px; margin: 2rem auto; padding: 1rem; background: linear-gradient(180deg, #fdf6e3 0%, #eee8d5 100%); color: #073642; }
8
+ h1 { font-size: 2rem; }
9
+ main { background: #fff; border-radius: 12px; padding: 2rem; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
10
+ button { font-size: 1.1rem; padding: 0.6rem 1.2rem; background: #268bd2; color: #fff; border: 0; border-radius: 8px; cursor: pointer; margin-right: 0.5rem; }
11
+ button:hover { background: #2aa198; }
12
+ .status { font-size: 1.4rem; padding: 1rem; margin-top: 1rem; border-radius: 8px; background: #fdf6e3; min-height: 2rem; }
13
+ .smile { font-size: 3rem; }
14
+ </style>
15
+ </head>
16
+ <body>
17
+ <h1>🎬 Varbase E2E Video Demo</h1>
18
+ <main role="main">
19
+ <p>Click a button below — the recording captures the page state change.</p>
20
+ <button id="wave">👋 Wave</button>
21
+ <button id="rocket">🚀 Launch</button>
22
+ <button id="party">🎉 Celebrate</button>
23
+ <div class="status" id="status">Ready to record ⏺️</div>
24
+ <div class="smile" id="smile"></div>
25
+ </main>
26
+ <script>
27
+ const status = document.getElementById('status');
28
+ const smile = document.getElementById('smile');
29
+ document.getElementById('wave').addEventListener('click', () => {
30
+ status.textContent = 'Hello, world 👋';
31
+ smile.textContent = '😀';
32
+ });
33
+ document.getElementById('rocket').addEventListener('click', () => {
34
+ status.textContent = 'Liftoff! 🚀';
35
+ smile.textContent = '🌕';
36
+ });
37
+ document.getElementById('party').addEventListener('click', () => {
38
+ status.textContent = 'Party time 🎉';
39
+ smile.textContent = '🥳';
40
+ });
41
+ </script>
42
+ </body>
43
+ </html>
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@vardot/varbase-e2e",
3
+ "version": "2.0.0",
4
+ "description": "Varbase E2E automated functional testing.",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "init-varbase-e2e": "./bin/init-varbase-e2e.js",
8
+ "generate-reports": "./bin/generate-reports.js"
9
+ },
10
+ "directories": {
11
+ "test": "test"
12
+ },
13
+ "engines": {
14
+ "node": ">= 20.0"
15
+ },
16
+ "scripts": {
17
+ "postinstall": "node ./bin/postinstall.js",
18
+ "test": "cucumber-js --config cucumber.js",
19
+ "test:chromium": "BROWSER=chromium cucumber-js --config cucumber.js",
20
+ "test:firefox": "BROWSER=firefox cucumber-js --config cucumber.js",
21
+ "test:webkit": "BROWSER=webkit cucumber-js --config cucumber.js",
22
+ "test:headed": "HEADLESS=false cucumber-js --config cucumber.js",
23
+ "test:fast": "SLOW_MO=0 cucumber-js --config cucumber.js",
24
+ "generate-reports": "node ./bin/generate-reports.js",
25
+ "start": "http-server examples -p 8080 -s"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/Vardot/varbase-e2e.git"
30
+ },
31
+ "author": "Vardot",
32
+ "license": "MIT",
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/Vardot/varbase-e2e/issues"
38
+ },
39
+ "homepage": "https://github.com/Vardot/varbase-e2e",
40
+ "dependencies": {
41
+ "@axe-core/playwright": "^4.11.3",
42
+ "@cucumber/cucumber": "*",
43
+ "@cucumber/pretty-formatter": "~1",
44
+ "@types/node": "~20",
45
+ "ajv": "^8.20.0",
46
+ "ajv-formats": "^3.0.1",
47
+ "axe-core": "^4.11.4",
48
+ "axios": "~1",
49
+ "cucumber-html-reporter": "^6.0.0",
50
+ "http-server": "^14.1.1",
51
+ "js-yaml": "^4.1.1",
52
+ "playwright": "^1.58.2",
53
+ "tsx": "^4.19.2",
54
+ "typescript": "~5"
55
+ }
56
+ }
@@ -0,0 +1,39 @@
1
+ import type { LaunchOptions, BrowserContextOptions } from 'playwright';
2
+
3
+ type BrowserName = 'chromium' | 'firefox' | 'webkit';
4
+
5
+ const browser = (process.env.BROWSER || 'chromium') as BrowserName;
6
+
7
+ const chromiumArgs: string[] = [
8
+ '--no-sandbox',
9
+ '--disable-dev-shm-usage',
10
+ '--disable-setuid-sandbox',
11
+ '--disable-web-security',
12
+ '--ignore-certificate-errors',
13
+ '--disable-extensions',
14
+ '--incognito',
15
+ '--disable-infobars',
16
+ '--start-maximized',
17
+ ];
18
+
19
+ interface PlaywrightConfig {
20
+ browser: BrowserName;
21
+ launchOptions: LaunchOptions;
22
+ contextOptions: BrowserContextOptions;
23
+ }
24
+
25
+ const config: PlaywrightConfig = {
26
+ browser,
27
+ launchOptions: {
28
+ headless: process.env.HEADLESS !== 'false',
29
+ // SLOW_MO env var: 0 in CI for speed, 800ms when watching headed runs.
30
+ slowMo: parseInt(process.env.SLOW_MO || (process.env.HEADLESS === 'false' ? '800' : '300'), 10),
31
+ args: browser === 'chromium' ? chromiumArgs : [],
32
+ },
33
+ contextOptions: {
34
+ viewport: null,
35
+ ignoreHTTPSErrors: true,
36
+ },
37
+ };
38
+
39
+ export = config;
@@ -0,0 +1,14 @@
1
+ %PDF-1.4
2
+ 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
3
+ 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj
4
+ 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R>>endobj
5
+ xref
6
+ 0 4
7
+ 0000000000 65535 f
8
+ 0000000009 00000 n
9
+ 0000000058 00000 n
10
+ 0000000115 00000 n
11
+ trailer<</Size 4/Root 1 0 R>>
12
+ startxref
13
+ 190
14
+ %%EOF
Binary file
@@ -0,0 +1,39 @@
1
+ Feature: Accessibility (a11y) smoke checks
2
+
3
+ Scenario: Page-level landmarks and language
4
+ Given I am on "/a11y.html"
5
+ Then the page should declare a language
6
+ And the page language should be "en"
7
+ And the page should have a main landmark
8
+ And the page should have a navigation landmark
9
+ And the page should have exactly one h1
10
+
11
+ Scenario: Image alt text and form labels
12
+ Given I am on "/a11y.html"
13
+ Then every image should have an alt attribute
14
+ And every form field should have an accessible label
15
+
16
+ Scenario: Focused element assertions
17
+ Given I am on "/a11y.html"
18
+ When I focus on the element "#email"
19
+ Then the focused element should match "#email"
20
+ And the focused element should be labeled "Email"
21
+
22
+ Scenario: WCAG hygiene checks (custom probes)
23
+ Given I am on "/a11y.html"
24
+ Then the page should have a title
25
+ And user zoom should be allowed
26
+ And the heading hierarchy should be valid
27
+ And every button should have an accessible name
28
+ And every link should have an accessible name
29
+ And no element should have a positive tabindex
30
+ And every ARIA reference should resolve
31
+ And every ARIA role should be valid
32
+ And required fields should be consistently marked
33
+
34
+ Scenario: axe-core full WCAG audit
35
+ Given I am on "/a11y.html"
36
+ Then the page should have no critical accessibility violations
37
+ And the page should not violate the accessibility rule "image-alt"
38
+ And the page should not violate the accessibility rule "label"
39
+ And the page should pass the accessibility rules "image-alt, label, button-name"
@@ -0,0 +1,24 @@
1
+ Feature: AJAX Wait Examples
2
+ As a tester
3
+ I want to wait for AJAX requests to complete
4
+ So that I can verify content that loads asynchronously
5
+
6
+ Background:
7
+ Given I am on "/ajax-wait-examples.html"
8
+
9
+ # Example 1: Wait for AJAX to finish before verifying content
10
+ Scenario: Wait for AJAX to finish after search
11
+ When I fill in "laptop" for "#search-input" by attr
12
+ And I press "Search" button
13
+ And I wait for AJAX to finish
14
+ Then I should see "Search Results"
15
+ And I should see "Laptop Pro 15"
16
+
17
+ # Example 2: Wait for AJAX to finish after form submission
18
+ Scenario: Wait for AJAX to finish after submitting form
19
+ When I fill in "John Doe" for "#name-input" by attr
20
+ And I fill in "john@example.com" for "#email-input" by attr
21
+ And I press "Submit" button
22
+ And I wait for AJAX to finish
23
+ Then I should see "Form submitted successfully"
24
+ And I should see "Thank you, John Doe"