@vardot/varbase-e2e 2.0.2 → 2.0.4

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 (281) hide show
  1. package/.playwright-mcp/console-2026-09-07T08-40-17-262Z.log +28 -0
  2. package/.playwright-mcp/console-2026-09-07T08-40-55-044Z.log +4 -0
  3. package/.playwright-mcp/console-2026-09-07T08-41-12-557Z.log +18 -0
  4. package/.playwright-mcp/console-2026-09-07T08-42-32-413Z.log +38 -0
  5. package/.playwright-mcp/console-2026-09-07T09-02-43-145Z.log +1 -0
  6. package/.playwright-mcp/console-2026-09-07T09-03-15-665Z.log +17 -0
  7. package/.playwright-mcp/page-2026-09-07T08-40-18-956Z.yml +261 -0
  8. package/.playwright-mcp/page-2026-09-07T08-40-55-673Z.yml +132 -0
  9. package/.playwright-mcp/page-2026-09-07T08-41-13-471Z.yml +386 -0
  10. package/.playwright-mcp/page-2026-09-07T08-42-33-250Z.yml +287 -0
  11. package/AGENTS.md +1 -1
  12. package/CLAUDE.md +6 -5
  13. package/README.md +2 -0
  14. package/docs/04-step-reference.md +15 -1
  15. package/docs/README.md +8 -5
  16. package/docs/install-varbase-e2e.md +0 -2
  17. package/docs/steps/README.md +6 -5
  18. package/docs/steps/assertion.md +90 -5
  19. package/docs/steps/drupal-drimage-improved.md +372 -0
  20. package/docs/steps/navigation.md +81 -1
  21. package/docs/steps/varbase.md +6 -65
  22. package/examples/access-denied.html +6 -0
  23. package/examples/drimage.html +55 -0
  24. package/examples/styles/drimage_improved_1000_667/public/sample.png +0 -0
  25. package/examples/styles/drimage_improved_1200_800/public/sample.png +0 -0
  26. package/examples/styles/drimage_improved_1400_933/public/sample.png +0 -0
  27. package/examples/styles/drimage_improved_1600_1067/public/sample.png +0 -0
  28. package/examples/styles/drimage_improved_1800_1200/public/sample.png +0 -0
  29. package/examples/styles/drimage_improved_2000_1333/public/sample.png +0 -0
  30. package/examples/styles/drimage_improved_200_133/public/sample.png +0 -0
  31. package/examples/styles/drimage_improved_2200_1467/public/sample.png +0 -0
  32. package/examples/styles/drimage_improved_2400_1600/public/sample.png +0 -0
  33. package/examples/styles/drimage_improved_2600_1734/public/sample.png +0 -0
  34. package/examples/styles/drimage_improved_2800_1867/public/sample.png +0 -0
  35. package/examples/styles/drimage_improved_3000_2000/public/sample.png +0 -0
  36. package/examples/styles/drimage_improved_3200_2134/public/sample.png +0 -0
  37. package/examples/styles/drimage_improved_3400_2267/public/sample.png +0 -0
  38. package/examples/styles/drimage_improved_3600_2400/public/sample.png +0 -0
  39. package/examples/styles/drimage_improved_3800_2534/public/sample.png +0 -0
  40. package/examples/styles/drimage_improved_4000_2667/public/sample.png +0 -0
  41. package/examples/styles/drimage_improved_400_267/public/sample.png +0 -0
  42. package/examples/styles/drimage_improved_600_400/public/sample.png +0 -0
  43. package/examples/styles/drimage_improved_800_533/public/sample.png +0 -0
  44. package/examples/user-login.html +12 -0
  45. package/images/varbase-e2e-logo.svg +24 -0
  46. package/package.json +1 -1
  47. package/tests/features/access.feature +33 -0
  48. package/tests/features/drupal-drimage-improved.feature +59 -0
  49. package/tests/features/http-status.feature +21 -0
  50. package/tests/features/page-title.feature +24 -0
  51. package/tests/step-definitions/assertion.steps.js +108 -19
  52. package/tests/step-definitions/drupal-drimage-improved.steps.js +486 -0
  53. package/tests/step-definitions/navigation.steps.js +101 -1
  54. package/tests/step-definitions/varbase.steps.js +0 -83
  55. package/.playwright-mcp/console-2026-08-09T19-48-04-420Z.log +0 -6
  56. package/.playwright-mcp/console-2026-08-09T19-48-21-910Z.log +0 -4
  57. package/.playwright-mcp/console-2026-08-09T19-48-37-544Z.log +0 -5
  58. package/.playwright-mcp/console-2026-08-09T20-02-58-240Z.log +0 -5
  59. package/.playwright-mcp/console-2026-08-09T20-15-05-487Z.log +0 -71
  60. package/.playwright-mcp/console-2026-08-09T20-31-11-228Z.log +0 -14
  61. package/.playwright-mcp/console-2026-08-09T20-34-03-115Z.log +0 -7
  62. package/.playwright-mcp/console-2026-08-09T20-34-34-018Z.log +0 -85
  63. package/.playwright-mcp/console-2026-08-09T20-34-34-740Z.log +0 -46
  64. package/.playwright-mcp/console-2026-08-09T20-34-35-618Z.log +0 -92
  65. package/.playwright-mcp/console-2026-08-09T22-57-59-606Z.log +0 -14
  66. package/.playwright-mcp/console-2026-08-09T23-09-53-902Z.log +0 -28
  67. package/.playwright-mcp/console-2026-08-09T23-09-55-918Z.log +0 -49
  68. package/.playwright-mcp/console-2026-08-09T23-09-57-522Z.log +0 -42
  69. package/.playwright-mcp/console-2026-08-09T23-40-26-847Z.log +0 -28
  70. package/.playwright-mcp/console-2026-08-10T00-05-53-423Z.log +0 -8
  71. package/.playwright-mcp/console-2026-08-10T08-51-59-747Z.log +0 -5
  72. package/.playwright-mcp/console-2026-08-10T09-00-26-735Z.log +0 -7
  73. package/.playwright-mcp/page-2026-08-09T19-48-23-422Z.yml +0 -288
  74. package/.playwright-mcp/page-2026-08-09T19-48-32-827Z.yml +0 -39
  75. package/.playwright-mcp/page-2026-08-09T19-48-39-150Z.yml +0 -39
  76. package/.playwright-mcp/page-2026-08-09T19-50-55-594Z.yml +0 -787
  77. package/.playwright-mcp/page-2026-08-09T19-51-28-160Z.yml +0 -391
  78. package/.playwright-mcp/page-2026-08-09T19-51-45-546Z.yml +0 -391
  79. package/.playwright-mcp/page-2026-08-09T19-51-46-085Z.yml +0 -391
  80. package/.playwright-mcp/page-2026-08-09T19-51-46-355Z.yml +0 -391
  81. package/.playwright-mcp/page-2026-08-09T19-51-49-918Z.yml +0 -391
  82. package/.playwright-mcp/page-2026-08-09T19-52-30-248Z.yml +0 -415
  83. package/.playwright-mcp/page-2026-08-09T19-52-42-510Z.yml +0 -415
  84. package/.playwright-mcp/page-2026-08-09T19-52-45-588Z.yml +0 -391
  85. package/.playwright-mcp/page-2026-08-09T19-52-54-615Z.yml +0 -391
  86. package/.playwright-mcp/page-2026-08-09T19-52-55-424Z.yml +0 -391
  87. package/.playwright-mcp/page-2026-08-09T19-52-55-553Z.yml +0 -391
  88. package/.playwright-mcp/page-2026-08-09T19-52-58-991Z.yml +0 -391
  89. package/.playwright-mcp/page-2026-08-09T19-53-29-261Z.yml +0 -415
  90. package/.playwright-mcp/page-2026-08-09T19-53-40-322Z.yml +0 -415
  91. package/.playwright-mcp/page-2026-08-09T19-53-44-146Z.yml +0 -391
  92. package/.playwright-mcp/page-2026-08-09T19-53-51-021Z.yml +0 -391
  93. package/.playwright-mcp/page-2026-08-09T19-53-51-565Z.yml +0 -391
  94. package/.playwright-mcp/page-2026-08-09T19-53-51-979Z.yml +0 -391
  95. package/.playwright-mcp/page-2026-08-09T19-53-54-883Z.yml +0 -391
  96. package/.playwright-mcp/page-2026-08-09T19-54-24-537Z.yml +0 -415
  97. package/.playwright-mcp/page-2026-08-09T20-01-07-921Z.yml +0 -404
  98. package/.playwright-mcp/page-2026-08-09T20-01-35-366Z.yml +0 -404
  99. package/.playwright-mcp/page-2026-08-09T20-01-54-083Z.yml +0 -404
  100. package/.playwright-mcp/page-2026-08-09T20-02-07-954Z.yml +0 -416
  101. package/.playwright-mcp/page-2026-08-09T20-02-24-800Z.yml +0 -404
  102. package/.playwright-mcp/page-2026-08-09T20-02-29-695Z.yml +0 -404
  103. package/.playwright-mcp/page-2026-08-09T20-02-33-819Z.yml +0 -404
  104. package/.playwright-mcp/page-2026-08-09T20-02-41-437Z.yml +0 -404
  105. package/.playwright-mcp/page-2026-08-09T20-02-53-232Z.yml +0 -416
  106. package/.playwright-mcp/page-2026-08-09T20-03-00-246Z.yml +0 -404
  107. package/.playwright-mcp/page-2026-08-09T20-03-03-297Z.yml +0 -404
  108. package/.playwright-mcp/page-2026-08-09T20-03-11-014Z.yml +0 -404
  109. package/.playwright-mcp/page-2026-08-09T20-03-21-049Z.yml +0 -416
  110. package/.playwright-mcp/page-2026-08-10T01-04-54-039Z.yml +0 -410
  111. package/.playwright-mcp/page-2026-08-10T01-05-06-967Z.png +0 -0
  112. package/.playwright-mcp/page-2026-08-10T01-05-52-136Z.yml +0 -720
  113. package/.playwright-mcp/page-2026-08-10T01-06-05-985Z.yml +0 -410
  114. package/.playwright-mcp/page-2026-08-10T01-06-25-942Z.yml +0 -726
  115. package/.playwright-mcp/page-2026-08-10T01-25-57-152Z.yml +0 -395
  116. package/.playwright-mcp/page-2026-08-10T01-26-48-853Z.yml +0 -395
  117. package/.playwright-mcp/page-2026-08-10T01-27-47-127Z.yml +0 -413
  118. package/.playwright-mcp/page-2026-08-10T01-27-57-349Z.yml +0 -413
  119. package/.playwright-mcp/page-2026-08-10T01-28-07-943Z.yml +0 -425
  120. package/.playwright-mcp/page-2026-08-10T01-28-30-462Z.yml +0 -369
  121. package/.playwright-mcp/page-2026-08-10T01-29-00-369Z.yml +0 -413
  122. package/.playwright-mcp/page-2026-08-10T01-29-08-988Z.yml +0 -413
  123. package/.playwright-mcp/page-2026-08-10T01-29-19-888Z.yml +0 -425
  124. package/.playwright-mcp/page-2026-08-10T01-29-30-189Z.yml +0 -369
  125. package/.playwright-mcp/page-2026-08-10T01-30-08-272Z.yml +0 -413
  126. package/.playwright-mcp/page-2026-08-10T01-30-16-955Z.yml +0 -413
  127. package/.playwright-mcp/page-2026-08-10T01-30-27-612Z.yml +0 -425
  128. package/.playwright-mcp/page-2026-08-10T01-30-37-943Z.yml +0 -465
  129. package/.playwright-mcp/page-2026-08-10T01-31-15-265Z.yml +0 -413
  130. package/.playwright-mcp/page-2026-08-10T01-31-24-328Z.yml +0 -413
  131. package/.playwright-mcp/page-2026-08-10T01-31-36-622Z.yml +0 -425
  132. package/.playwright-mcp/page-2026-08-10T01-31-45-965Z.yml +0 -470
  133. package/.playwright-mcp/page-2026-08-10T01-32-13-400Z.yml +0 -413
  134. package/.playwright-mcp/page-2026-08-10T01-32-23-469Z.yml +0 -413
  135. package/.playwright-mcp/page-2026-08-10T01-32-33-859Z.yml +0 -425
  136. package/.playwright-mcp/page-2026-08-10T01-32-43-461Z.yml +0 -513
  137. package/.playwright-mcp/page-2026-08-10T01-33-13-160Z.yml +0 -413
  138. package/.playwright-mcp/page-2026-08-10T01-33-23-937Z.yml +0 -413
  139. package/.playwright-mcp/page-2026-08-10T01-33-35-367Z.yml +0 -425
  140. package/.playwright-mcp/page-2026-08-10T01-33-47-266Z.yml +0 -459
  141. package/.playwright-mcp/page-2026-08-10T01-34-14-452Z.yml +0 -413
  142. package/.playwright-mcp/page-2026-08-10T01-34-26-042Z.yml +0 -413
  143. package/.playwright-mcp/page-2026-08-10T01-34-40-869Z.yml +0 -425
  144. package/.playwright-mcp/page-2026-08-10T01-34-49-587Z.yml +0 -391
  145. package/.playwright-mcp/page-2026-08-10T01-35-16-735Z.yml +0 -413
  146. package/.playwright-mcp/page-2026-08-10T01-35-24-882Z.yml +0 -413
  147. package/.playwright-mcp/page-2026-08-10T01-35-36-165Z.yml +0 -425
  148. package/.playwright-mcp/page-2026-08-10T01-35-45-644Z.yml +0 -455
  149. package/.playwright-mcp/page-2026-08-10T01-36-18-148Z.yml +0 -413
  150. package/.playwright-mcp/page-2026-08-10T01-36-26-751Z.yml +0 -413
  151. package/.playwright-mcp/page-2026-08-10T01-36-37-834Z.yml +0 -425
  152. package/.playwright-mcp/page-2026-08-10T01-36-48-078Z.yml +0 -370
  153. package/.playwright-mcp/page-2026-08-10T01-37-16-309Z.yml +0 -413
  154. package/.playwright-mcp/page-2026-08-10T01-37-28-723Z.yml +0 -413
  155. package/.playwright-mcp/page-2026-08-10T01-37-39-325Z.yml +0 -425
  156. package/.playwright-mcp/page-2026-08-10T01-37-48-278Z.yml +0 -409
  157. package/.playwright-mcp/page-2026-08-10T01-38-27-405Z.yml +0 -413
  158. package/.playwright-mcp/page-2026-08-10T01-38-36-994Z.yml +0 -413
  159. package/.playwright-mcp/page-2026-08-10T01-38-49-584Z.yml +0 -425
  160. package/.playwright-mcp/page-2026-08-10T01-38-59-289Z.yml +0 -396
  161. package/.playwright-mcp/page-2026-08-10T01-39-24-880Z.yml +0 -413
  162. package/.playwright-mcp/page-2026-08-10T01-39-35-551Z.yml +0 -413
  163. package/.playwright-mcp/page-2026-08-10T01-39-47-960Z.yml +0 -425
  164. package/.playwright-mcp/page-2026-08-10T01-39-56-844Z.yml +0 -549
  165. package/.playwright-mcp/page-2026-08-10T01-40-24-645Z.yml +0 -413
  166. package/.playwright-mcp/page-2026-08-10T01-40-33-806Z.yml +0 -413
  167. package/.playwright-mcp/page-2026-08-10T01-40-46-946Z.yml +0 -425
  168. package/.playwright-mcp/page-2026-08-10T01-40-56-503Z.yml +0 -443
  169. package/.playwright-mcp/page-2026-08-10T01-41-32-064Z.yml +0 -413
  170. package/.playwright-mcp/page-2026-08-10T01-41-40-666Z.yml +0 -413
  171. package/.playwright-mcp/page-2026-08-10T01-41-51-325Z.yml +0 -425
  172. package/.playwright-mcp/page-2026-08-10T01-41-58-790Z.yml +0 -368
  173. package/.playwright-mcp/page-2026-08-10T01-42-26-459Z.yml +0 -413
  174. package/.playwright-mcp/page-2026-08-10T01-42-38-306Z.yml +0 -413
  175. package/.playwright-mcp/page-2026-08-10T01-42-49-073Z.yml +0 -425
  176. package/.playwright-mcp/page-2026-08-10T01-42-57-453Z.yml +0 -443
  177. package/.playwright-mcp/page-2026-08-10T01-43-32-099Z.yml +0 -413
  178. package/.playwright-mcp/page-2026-08-10T01-43-42-882Z.yml +0 -413
  179. package/.playwright-mcp/page-2026-08-10T01-43-54-853Z.yml +0 -425
  180. package/.playwright-mcp/page-2026-08-10T01-44-04-373Z.yml +0 -399
  181. package/.playwright-mcp/page-2026-08-10T01-44-30-874Z.yml +0 -413
  182. package/.playwright-mcp/page-2026-08-10T01-44-39-830Z.yml +0 -413
  183. package/.playwright-mcp/page-2026-08-10T01-44-51-515Z.yml +0 -425
  184. package/.playwright-mcp/page-2026-08-10T01-44-59-974Z.yml +0 -503
  185. package/.playwright-mcp/page-2026-08-10T01-45-26-748Z.yml +0 -413
  186. package/.playwright-mcp/page-2026-08-10T01-45-36-685Z.yml +0 -413
  187. package/.playwright-mcp/page-2026-08-10T01-45-47-715Z.yml +0 -425
  188. package/.playwright-mcp/page-2026-08-10T01-45-57-895Z.yml +0 -469
  189. package/.playwright-mcp/page-2026-08-10T01-46-36-371Z.yml +0 -413
  190. package/.playwright-mcp/page-2026-08-10T01-46-49-906Z.yml +0 -413
  191. package/.playwright-mcp/page-2026-08-10T01-47-01-554Z.yml +0 -425
  192. package/.playwright-mcp/page-2026-08-10T01-47-12-712Z.yml +0 -581
  193. package/.playwright-mcp/page-2026-08-10T01-47-39-024Z.yml +0 -413
  194. package/.playwright-mcp/page-2026-08-10T01-47-49-714Z.yml +0 -413
  195. package/.playwright-mcp/page-2026-08-10T01-48-00-608Z.yml +0 -425
  196. package/.playwright-mcp/page-2026-08-10T01-48-09-739Z.yml +0 -604
  197. package/.playwright-mcp/page-2026-08-10T01-48-51-940Z.yml +0 -413
  198. package/.playwright-mcp/page-2026-08-10T01-49-01-562Z.yml +0 -413
  199. package/.playwright-mcp/page-2026-08-10T01-49-13-751Z.yml +0 -425
  200. package/.playwright-mcp/page-2026-08-10T01-49-22-503Z.yml +0 -400
  201. package/.playwright-mcp/page-2026-08-10T01-49-49-311Z.yml +0 -413
  202. package/.playwright-mcp/page-2026-08-10T01-50-00-769Z.yml +0 -413
  203. package/.playwright-mcp/page-2026-08-10T01-50-12-083Z.yml +0 -425
  204. package/.playwright-mcp/page-2026-08-10T01-50-23-765Z.yml +0 -458
  205. package/.playwright-mcp/page-2026-08-10T01-51-02-339Z.yml +0 -413
  206. package/.playwright-mcp/page-2026-08-10T01-51-12-711Z.yml +0 -413
  207. package/.playwright-mcp/page-2026-08-10T01-51-25-370Z.yml +0 -425
  208. package/.playwright-mcp/page-2026-08-10T01-51-33-936Z.yml +0 -368
  209. package/.playwright-mcp/page-2026-08-10T01-52-09-467Z.yml +0 -413
  210. package/.playwright-mcp/page-2026-08-10T01-52-21-616Z.yml +0 -413
  211. package/.playwright-mcp/page-2026-08-10T01-52-32-806Z.yml +0 -425
  212. package/.playwright-mcp/page-2026-08-10T01-52-42-382Z.yml +0 -407
  213. package/.playwright-mcp/page-2026-08-10T01-53-11-994Z.yml +0 -413
  214. package/.playwright-mcp/page-2026-08-10T01-53-21-669Z.yml +0 -413
  215. package/.playwright-mcp/page-2026-08-10T01-53-33-141Z.yml +0 -425
  216. package/.playwright-mcp/page-2026-08-10T01-53-43-582Z.yml +0 -443
  217. package/.playwright-mcp/page-2026-08-10T01-54-19-884Z.yml +0 -413
  218. package/.playwright-mcp/page-2026-08-10T01-54-32-359Z.yml +0 -413
  219. package/.playwright-mcp/page-2026-08-10T01-54-43-530Z.yml +0 -425
  220. package/.playwright-mcp/page-2026-08-10T01-54-53-891Z.yml +0 -474
  221. package/.playwright-mcp/page-2026-08-10T01-55-24-634Z.yml +0 -413
  222. package/.playwright-mcp/page-2026-08-10T01-55-35-283Z.yml +0 -413
  223. package/.playwright-mcp/page-2026-08-10T01-55-46-649Z.yml +0 -425
  224. package/.playwright-mcp/page-2026-08-10T01-55-56-585Z.yml +0 -431
  225. package/.playwright-mcp/page-2026-08-10T01-56-31-670Z.yml +0 -413
  226. package/.playwright-mcp/page-2026-08-10T01-56-40-782Z.yml +0 -413
  227. package/.playwright-mcp/page-2026-08-10T01-56-52-065Z.yml +0 -425
  228. package/.playwright-mcp/page-2026-08-10T01-57-03-705Z.yml +0 -445
  229. package/.playwright-mcp/page-2026-08-10T01-57-31-390Z.yml +0 -413
  230. package/.playwright-mcp/page-2026-08-10T01-57-44-756Z.yml +0 -413
  231. package/.playwright-mcp/page-2026-08-10T01-57-56-802Z.yml +0 -425
  232. package/.playwright-mcp/page-2026-08-10T01-58-06-937Z.yml +0 -468
  233. package/.playwright-mcp/page-2026-08-10T01-58-40-595Z.yml +0 -413
  234. package/.playwright-mcp/page-2026-08-10T01-58-51-715Z.yml +0 -413
  235. package/.playwright-mcp/page-2026-08-10T01-59-04-402Z.yml +0 -425
  236. package/.playwright-mcp/page-2026-08-10T01-59-15-638Z.yml +0 -472
  237. package/.playwright-mcp/page-2026-08-10T01-59-58-162Z.yml +0 -413
  238. package/.playwright-mcp/page-2026-08-10T02-00-09-962Z.yml +0 -413
  239. package/.playwright-mcp/page-2026-08-10T02-00-21-468Z.yml +0 -425
  240. package/.playwright-mcp/page-2026-08-10T02-00-33-248Z.yml +0 -451
  241. package/.playwright-mcp/page-2026-08-10T02-01-15-418Z.yml +0 -413
  242. package/.playwright-mcp/page-2026-08-10T02-01-27-182Z.yml +0 -413
  243. package/.playwright-mcp/page-2026-08-10T02-01-38-250Z.yml +0 -425
  244. package/.playwright-mcp/page-2026-08-10T04-20-27-979Z.yml +0 -513
  245. package/.playwright-mcp/page-2026-08-10T04-20-41-431Z.yml +0 -513
  246. package/.playwright-mcp/page-2026-08-10T04-21-46-133Z.yml +0 -406
  247. package/.playwright-mcp/page-2026-08-10T04-22-10-938Z.yml +0 -406
  248. package/.playwright-mcp/page-2026-08-10T04-23-00-626Z.yml +0 -406
  249. package/.playwright-mcp/page-2026-08-10T04-23-19-844Z.yml +0 -418
  250. package/.playwright-mcp/page-2026-08-10T04-25-00-732Z.yml +0 -455
  251. package/.playwright-mcp/page-2026-08-10T04-25-35-125Z.yml +0 -412
  252. package/.playwright-mcp/page-2026-08-10T04-25-46-640Z.yml +0 -412
  253. package/.playwright-mcp/page-2026-08-10T04-25-55-092Z.yml +0 -549
  254. package/.playwright-mcp/page-2026-08-10T04-26-26-403Z.yml +0 -406
  255. package/.playwright-mcp/page-2026-08-10T04-26-40-673Z.yml +0 -406
  256. package/.playwright-mcp/page-2026-08-10T04-26-48-427Z.yml +0 -604
  257. package/.playwright-mcp/page-2026-08-10T04-27-23-584Z.yml +0 -408
  258. package/.playwright-mcp/page-2026-08-10T04-27-34-294Z.yml +0 -408
  259. package/.playwright-mcp/page-2026-08-10T04-27-42-299Z.yml +0 -443
  260. package/.playwright-mcp/page-2026-08-10T04-28-20-032Z.yml +0 -406
  261. package/.playwright-mcp/page-2026-08-10T04-28-32-275Z.yml +0 -406
  262. package/.playwright-mcp/page-2026-08-10T04-28-41-592Z.yml +0 -581
  263. package/.playwright-mcp/page-2026-08-10T04-29-19-972Z.yml +0 -414
  264. package/.playwright-mcp/page-2026-08-10T04-29-30-961Z.yml +0 -414
  265. package/.playwright-mcp/page-2026-08-10T04-29-39-044Z.yml +0 -465
  266. package/.playwright-mcp/page-2026-08-10T04-30-13-196Z.yml +0 -402
  267. package/.playwright-mcp/page-2026-08-10T04-30-24-867Z.yml +0 -402
  268. package/.playwright-mcp/page-2026-08-10T04-30-32-372Z.yml +0 -409
  269. package/.playwright-mcp/page-2026-08-10T04-31-06-199Z.yml +0 -402
  270. package/.playwright-mcp/page-2026-08-10T04-31-17-733Z.yml +0 -402
  271. package/.playwright-mcp/page-2026-08-10T04-31-26-296Z.yml +0 -445
  272. package/.playwright-mcp/page-2026-08-10T04-32-02-456Z.yml +0 -402
  273. package/.playwright-mcp/page-2026-08-10T04-32-14-091Z.yml +0 -402
  274. package/.playwright-mcp/page-2026-08-10T04-32-23-437Z.yml +0 -396
  275. package/.playwright-mcp/page-2026-08-10T04-32-58-401Z.yml +0 -403
  276. package/.playwright-mcp/page-2026-08-10T04-33-09-818Z.yml +0 -403
  277. package/.playwright-mcp/page-2026-08-10T04-33-20-858Z.yml +0 -468
  278. package/.playwright-mcp/page-2026-08-10T04-33-53-074Z.yml +0 -407
  279. package/.playwright-mcp/page-2026-08-10T04-34-05-806Z.yml +0 -407
  280. package/.playwright-mcp/page-2026-08-10T08-52-00-165Z.yml +0 -0
  281. package/.playwright-mcp/page-2026-08-10T08-52-17-430Z.yml +0 -410
@@ -0,0 +1,372 @@
1
+ # Drimage Improved steps
2
+
3
+ 13 steps, defined in `tests/step-definitions/drupal-drimage-improved.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
+ These steps test the **dynamic responsive images** the [Drimage Improved](https://www.drupal.org/project/drimage_improved) module renders — the module Varbase's default theme uses for every image. They carry **no CSS selectors**: the module's formatter markup is stable (a wrapper carrying `data-drimage_improved`, a `<picture>` with an optional WebP `<source>`, the `<img>` on an SVG placeholder, a `<noscript>` fallback inside or right after the wrapper), and its JS swaps the placeholder for a derivative under `/styles/drimage_improved_*`. The pack knows all of that, so a tester writes `the drimage images should be loaded` and nothing else. Themes re-class the `<img>` freely — the Varbase theme drops `drimage-image` altogether — so nothing here depends on a class.
8
+
9
+ **The default budget is 2 seconds.** The module exists to make images fast; a step that waits 15 or 20 seconds is hiding a problem, not tolerating one. Every step settles the page first with the harness BBR wait (`smartSettle`: `networkidle` plus the AJAX, pending-timer and DOM-quiet counters), so the module's `setTimeout` swap has fired before the assertion looks — no static sleeps anywhere.
10
+
11
+ **The qualifier is optional and interchangeable**: `drimage`, `drimage improved`, `dynamic`, `dynamic responsive`, `responsive`, or none at all name the same images.
12
+
13
+ **Naming one image.** The single-image steps take a target instead of a selector, any of these ways:
14
+
15
+ | Say | Matches |
16
+ | --- | --- |
17
+ | `the drimage image "Hero banner"` | alt text **or** title, whichever equals it (a contains match as fallback) |
18
+ | `the drimage image with the alt text "Hero banner"` | alt only |
19
+ | `the drimage image titled "Vardot team"` / `with the title "…"` | the `title` attribute |
20
+ | `the drimage image captioned "Our team in 2026"` / `with the caption "…"` | the `<figcaption>` of its `<figure>` |
21
+ | `the first drimage image`, `the 3rd …`, `the last …` | order in the page |
22
+ | `the drimage image number 3` | the same, as a number |
23
+
24
+ Prefer alt text or caption on real pages: on a page with tabs or a carousel, "the last image" may sit in a hidden pane the module never renders (Horizon Aid's home does exactly that).
25
+
26
+ **Why the derivative URL matters**: the SVG placeholder itself decodes (`naturalWidth > 0`), so a bitmap check alone cannot tell a placeholder from a loaded image. An image counts as loaded only once its `src` is a real derivative *and* the bitmap decoded. Images still on their placeholder because lazy loading has not reached them are never counted against the page.
27
+
28
+ | # | Step |
29
+ | --- | --- |
30
+ | 1 | `Then the drimage images should be loaded` |
31
+ | 2 | `Then the drimage image "Team collaborating in a modern glass-walled office" should be loaded` |
32
+ | 3 | `Then the drimage images should be rendered` |
33
+ | 4 | `Then the drimage images should offer webp` |
34
+ | 5 | `Then the drimage images should have a noscript fallback` |
35
+ | 6 | `Then no drimage image should be broken` |
36
+ | 7 | `Then the drimage images should be sized for the viewport` |
37
+ | 8 | `Then the drimage images should use lazy loading` |
38
+ | 9 | `Then the drimage image "Team meeting around a table" should still be a placeholder` |
39
+ | 10 | `Then the first drimage image should have the caption "Our team in the new office"` |
40
+ | 11 | `Then the first drimage image should have the alt text "Team collaborating in a modern glass-walled office"` |
41
+ | 12 | `Then the drimage image "Team meeting around a table" should have the title "Vardot team"` |
42
+ | 13 | `Then the first drimage image should be in a figure` |
43
+
44
+ A typical page check, as the Vardot QA team runs it against a Varbase site:
45
+
46
+ ```gherkin
47
+ Given I am an anonymous user
48
+ When I go to homepage
49
+ Then the drimage images should be rendered
50
+ And the drimage images should offer webp
51
+ And the drimage images should have a noscript fallback
52
+ And the drimage images should use lazy loading
53
+ And the drimage images should be loaded
54
+ And no drimage image should be broken
55
+ And the drimage images should be sized for the viewport
56
+ When I scroll to the bottom of the page
57
+ Then the drimage images should be loaded within 2 seconds
58
+ When I set the viewport to the "xs" breakpoint
59
+ Then the drimage images should be sized for the viewport within 2 seconds
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 1. Then the drimage images should be loaded
65
+
66
+ Assert the Drimage images on the page loaded: at least one has swapped its placeholder for a real derivative, and every swapped one decoded a bitmap. A placeholder that never swaps, or a derivative the server failed to generate (a 4xx or 5xx on the `/styles/drimage_improved_*` request), fails red.
67
+
68
+ **Keyword**: `Then`
69
+
70
+ **Pattern**
71
+
72
+ ```js
73
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should be loaded(?: within (\d+) seconds?)?$/
74
+ ```
75
+
76
+ **Examples**
77
+
78
+ ```gherkin
79
+ Then the drimage images should be loaded
80
+ Then the drimage improved images should be loaded within 2 seconds
81
+ Then the dynamic responsive images should be loaded
82
+ And the responsive images should be loaded within 1 second
83
+ Then the images should be loaded
84
+ ```
85
+
86
+ ## 2. Then the drimage image "Team collaborating in a modern glass-walled office" should be loaded
87
+
88
+ Assert one Drimage image swapped its placeholder for a real derivative and decoded the bitmap. Name it any of the ways in the table above — alt or title in quotes, `titled`, `captioned`, `with the alt text`, an ordinal, or a number — never a class or an id.
89
+
90
+ **Keyword**: `Then`
91
+
92
+ **Pattern** (the target, then the assertion)
93
+
94
+ ```js
95
+ /^the (?:(first|second|…|tenth|last|\d+(?:st|nd|rd|th)) )?(?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?image(?: (titled|captioned|with the alt text|with the title|with the caption) "([^"]*)"| "([^"]*)"| number (\d+))? should be loaded(?: within (\d+) seconds?)?$/
96
+ ```
97
+
98
+ **Examples**
99
+
100
+ ```gherkin
101
+ Then the drimage image "Team collaborating in a modern glass-walled office" should be loaded
102
+ Then the first drimage image should be loaded
103
+ Then the drimage image captioned "Our team in the new office" should be loaded within 2 seconds
104
+ Then the dynamic responsive image titled "Vardot team" should be loaded
105
+ Then the drimage image number 2 should be loaded within 1 second
106
+ ```
107
+
108
+ ## 3. Then the drimage images should be rendered
109
+
110
+ Assert the page renders at least one Drimage image: the formatter wrapper carrying the module's data object is in the DOM. The formatter check — did the field display actually go through Drimage Improved — before any loading question.
111
+
112
+ **Keyword**: `Then`
113
+
114
+ **Pattern**
115
+
116
+ ```js
117
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should be rendered(?: within (\d+) seconds?)?$/
118
+ ```
119
+
120
+ **Examples**
121
+
122
+ ```gherkin
123
+ Then the drimage images should be rendered
124
+ Then the drimage improved images should be rendered within 2 seconds
125
+ Then the dynamic responsive images should be rendered
126
+ And the responsive images should be rendered within 1 second
127
+ Then the images should be rendered
128
+ ```
129
+
130
+ ## 4. Then the drimage images should offer webp
131
+
132
+ Assert every rendered wrapper has a `<source type="image/webp">` in its `<picture>` — present when core WebP or ImageAPI Optimize WebP is on. This is how a test proves the setting reached the front end.
133
+
134
+ **Keyword**: `Then`
135
+
136
+ **Pattern**
137
+
138
+ ```js
139
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should offer webp(?: within (\d+) seconds?)?$/
140
+ ```
141
+
142
+ **Examples**
143
+
144
+ ```gherkin
145
+ Then the drimage images should offer webp
146
+ Then the drimage improved images should offer webp within 2 seconds
147
+ Then the dynamic responsive images should offer webp
148
+ And the responsive images should offer webp within 1 second
149
+ Then the images should offer webp
150
+ ```
151
+
152
+ ## 5. Then the drimage images should have a noscript fallback
153
+
154
+ Assert every Drimage image carries a `<noscript>` fallback, so a visitor without JavaScript still gets an image. The module template puts it inside the wrapper; the `vartheme_bs5` component puts it right after — both count.
155
+
156
+ **Keyword**: `Then`
157
+
158
+ **Pattern**
159
+
160
+ ```js
161
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should have a noscript fallback(?: within (\d+) seconds?)?$/
162
+ ```
163
+
164
+ **Examples**
165
+
166
+ ```gherkin
167
+ Then the drimage images should have a noscript fallback
168
+ Then the drimage improved images should have a noscript fallback within 2 seconds
169
+ Then the dynamic responsive images should have a noscript fallback
170
+ And the responsive images should have a noscript fallback within 1 second
171
+ Then the images should have a noscript fallback
172
+ ```
173
+
174
+ ## 6. Then no drimage image should be broken
175
+
176
+ Assert no Drimage image on the page is broken: every one that swapped to a derivative decoded it. Images still on their placeholder pass, so this is the safe check for a long page where lazy loading has not reached the bottom.
177
+
178
+ **Keyword**: `Then`
179
+
180
+ **Pattern**
181
+
182
+ ```js
183
+ /^no (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?image should be broken(?: within (\d+) seconds?)?$/
184
+ ```
185
+
186
+ **Examples**
187
+
188
+ ```gherkin
189
+ Then no drimage image should be broken
190
+ Then no drimage improved image should be broken within 2 seconds
191
+ Then no dynamic responsive image should be broken
192
+ And no responsive image should be broken within 1 second
193
+ Then no image should be broken
194
+ ```
195
+
196
+ ## 7. Then the drimage images should be sized for the viewport
197
+
198
+ Assert every loaded Drimage image is served at a derivative width that fits where it is rendered: within one threshold step of the rendered width times the device pixel ratio, inside the module's upscale / downscale clamps. The threshold, upscale, downscale and multiplier are read from each wrapper's own data object, so the test follows the site's settings.
199
+
200
+ This is the **responsive-image check**. Resize with `When I set the viewport to the "xs" breakpoint` and assert again: the module requests a smaller derivative for the smaller viewport, and a page that ships a 1920px derivative into a 375px phone fails here.
201
+
202
+ **Keyword**: `Then`
203
+
204
+ **Pattern**
205
+
206
+ ```js
207
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should be sized for the viewport(?: within (\d+) seconds?)?$/
208
+ ```
209
+
210
+ **Examples**
211
+
212
+ ```gherkin
213
+ Then the drimage images should be sized for the viewport
214
+ Then the drimage improved images should be sized for the viewport within 2 seconds
215
+ Then the dynamic responsive images should be sized for the viewport
216
+ And the responsive images should be sized for the viewport within 1 second
217
+ Then the images should be sized for the viewport
218
+ ```
219
+
220
+ ## 8. Then the drimage images should use lazy loading
221
+
222
+ Assert the Drimage images defer offscreen loading. Each wrapper's data object must ask for lazy loading, and every image must be either still on its placeholder (the module has not rendered it because it is not near the viewport — that deferral *is* the lazy loading) or carry `loading="lazy"`, which the module sets the moment it renders one.
223
+
224
+ Learnt on demo.varbase.vardot.com: the module puts no `loading` attribute on an image it has not reached, and hidden slider slides never get one, so "every img has loading=lazy" would fail a page that is lazy loading perfectly. An image that swapped to a derivative *without* the attribute, or a wrapper configured eager, is what fails.
225
+
226
+ **Keyword**: `Then`
227
+
228
+ **Pattern**
229
+
230
+ ```js
231
+ /^the (?:drimage improved |drimage |dynamic responsive |dynamic |responsive )?images should use lazy loading(?: within (\d+) seconds?)?$/
232
+ ```
233
+
234
+ **Examples**
235
+
236
+ ```gherkin
237
+ Then the drimage images should use lazy loading
238
+ Then the drimage improved images should use lazy loading within 2 seconds
239
+ Then the dynamic responsive images should use lazy loading
240
+ And the responsive images should use lazy loading within 1 second
241
+ Then the images should use lazy loading
242
+ ```
243
+
244
+ ## 9. Then the drimage image "Team meeting around a table" should still be a placeholder
245
+
246
+ Assert a Drimage image (named any of the ways above) has **not** loaded yet: it is still on the module's SVG placeholder because it sits outside the viewport and lazy loading has not reached it. This is the **intersection check** — settle the page, look once (no waiting for something not to happen), then scroll it into view and assert it loads:
247
+
248
+ ```gherkin
249
+ Then the drimage image "Team meeting around a table" should still be a placeholder
250
+ When I scroll to the bottom of the page
251
+ Then the drimage image "Team meeting around a table" should be loaded within 2 seconds
252
+ ```
253
+
254
+ **Keyword**: `Then`
255
+
256
+ **Pattern**
257
+
258
+ ```js
259
+ /^<target> should (?:still be a placeholder|not be loaded yet)$/
260
+ ```
261
+
262
+ **Examples**
263
+
264
+ ```gherkin
265
+ Then the drimage image "Team meeting around a table" should still be a placeholder
266
+ Then the last drimage image should not be loaded yet
267
+ Then the drimage image captioned "Our team in the new office" should still be a placeholder
268
+ And the responsive image number 2 should not be loaded yet
269
+ Then the second image should still be a placeholder
270
+ ```
271
+
272
+ ## 10. Then the first drimage image should have the caption "Our team in the new office"
273
+
274
+ Assert a Drimage image has a caption: its `<figure>` carries a `<figcaption>`, and when a text is given, that is the caption (exact after trimming). `should have a caption` checks only that one exists.
275
+
276
+ **Keyword**: `Then`
277
+
278
+ **Pattern**
279
+
280
+ ```js
281
+ /^<target> should have (?:a caption|the caption "([^"]*)")$/
282
+ ```
283
+
284
+ **Examples**
285
+
286
+ ```gherkin
287
+ Then the first drimage image should have the caption "Our team in the new office"
288
+ Then the drimage image "Team meeting around a table" should have a caption
289
+ Then the drimage image titled "Vardot team" should have the caption "Our team in the new office"
290
+ Then the last dynamic responsive image should have a caption
291
+ Then the drimage image number 2 should have the caption "Our team in the new office"
292
+ ```
293
+
294
+ ## 11. Then the first drimage image should have the alt text "Team collaborating in a modern glass-walled office"
295
+
296
+ Assert a Drimage image's alt text — what a screen reader says and what search engines index. Name the image by order, title or caption, then check the alt an editor typed reached the front end.
297
+
298
+ **Keyword**: `Then`
299
+
300
+ **Pattern**
301
+
302
+ ```js
303
+ /^<target> should have the alt text "([^"]*)"$/
304
+ ```
305
+
306
+ **Examples**
307
+
308
+ ```gherkin
309
+ Then the first drimage image should have the alt text "Team collaborating in a modern glass-walled office"
310
+ Then the drimage image captioned "Our team in the new office" should have the alt text "Team meeting around a table"
311
+ Then the last dynamic responsive image should have the alt text "Team meeting around a table"
312
+ Then the drimage image number 1 should have the alt text "Team collaborating in a modern glass-walled office"
313
+ Then the drimage image titled "Vardot team" should have the alt text "Team meeting around a table"
314
+ ```
315
+
316
+ ## 12. Then the drimage image "Team meeting around a table" should have the title "Vardot team"
317
+
318
+ Assert a Drimage image's `title` attribute, the tooltip text.
319
+
320
+ **Keyword**: `Then`
321
+
322
+ **Pattern**
323
+
324
+ ```js
325
+ /^<target> should have the title "([^"]*)"$/
326
+ ```
327
+
328
+ **Examples**
329
+
330
+ ```gherkin
331
+ Then the drimage image "Team meeting around a table" should have the title "Vardot team"
332
+ Then the second drimage image should have the title "Vardot team"
333
+ Then the drimage image captioned "Our team in the new office" should have the title "Vardot team"
334
+ Then the last dynamic responsive image should have the title "Vardot team"
335
+ Then the drimage image number 2 should have the title "Vardot team"
336
+ ```
337
+
338
+ ## 13. Then the first drimage image should be in a figure
339
+
340
+ Assert a Drimage image is wrapped in a `<figure>`, the semantic element the theme's image component renders so a caption has somewhere to live.
341
+
342
+ **Keyword**: `Then`
343
+
344
+ **Pattern**
345
+
346
+ ```js
347
+ /^<target> should be in a figure$/
348
+ ```
349
+
350
+ **Examples**
351
+
352
+ ```gherkin
353
+ Then the drimage image "Team collaborating in a modern glass-walled office" should be in a figure
354
+ Then the first drimage image should be in a figure
355
+ Then the drimage image captioned "Our team in the new office" should be in a figure
356
+ Then the last dynamic responsive image should be in a figure
357
+ Then the drimage image number 2 should be in a figure
358
+ ```
359
+
360
+ `<target>` in the patterns above is the single-image grammar shown in full under step 2.
361
+
362
+ ## Verified on the live demos
363
+
364
+ Run anonymously on 7 September 2026 with the recipe at the top of this page plus the single-image steps:
365
+
366
+ | Site | Result |
367
+ | --- | --- |
368
+ | demo.varbase.vardot.com (Home) | 14 steps green, 5.0 s |
369
+ | Educare Sandbox 1 (Home) | 18 steps green, 8.3 s, including `the last drimage image` after a scroll |
370
+ | Horizon Aid Client Demo 1 (Home) | 14 of 18 green; `the last drimage image should be loaded` correctly fails because the last two images are carousel slides and four more sit in hidden tab panes — name those by alt text instead |
371
+
372
+ Draft feature files in each project's own conventions (`15-quality/15-04-drimage-images.feature` in `varbase_project`, `07-quality/07-04-…` in `educare`, `07-quality/07-03-…` in `horizonaid`) came out of that session.
@@ -1,6 +1,6 @@
1
1
  # Navigation steps
2
2
 
3
- 11 steps, defined in `tests/step-definitions/navigation.steps.js`.
3
+ 14 steps, defined in `tests/step-definitions/navigation.steps.js`.
4
4
 
5
5
  Cucumber-js loads every `*.steps.js` in that directory automatically — you never `require()` a step file from a feature.
6
6
 
@@ -17,6 +17,9 @@ Cucumber-js loads every `*.steps.js` in that directory automatically — you nev
17
17
  | 9 | `Then I should be on homepage` |
18
18
  | 10 | `Then I should be on "/"` |
19
19
  | 11 | `Then the url should match "/contact-us.html"` |
20
+ | 12 | `Then I am denied access to "/admin/config"` |
21
+ | 13 | `Then I should be allowed "/admin/content"` |
22
+ | 14 | `Then I should be denied access` |
20
23
 
21
24
  ---
22
25
 
@@ -273,3 +276,80 @@ Then the url should match "/contact-us.html"
273
276
  Then the url should not match "/contact-us.html"
274
277
  And the url should match "^https://"
275
278
  ```
279
+
280
+ ## 12. Then I am denied access to "/admin/config"
281
+
282
+ Assert the current user may **not** open a path: the site refuses it.
283
+
284
+ Four refusals count, because a site picks its own: HTTP 403, HTTP 404 (used to keep a route unguessable), HTTP 200 with an access-denied page, and a redirect to the log-in form. Asserting only on 403 makes a scenario pass or fail on how the site is configured rather than on who the user is. The failure message says which of the four it saw instead.
285
+
286
+ `should be refused` is the same step — five phrasings of this assertion had been invented independently across consuming projects, so both the `am denied access to` and the `should be refused` forms resolve here.
287
+
288
+ **Keyword**: `Then`
289
+
290
+ **Pattern**
291
+
292
+ ```js
293
+ /^(I |we )*(?:am|should be) (?:denied access to|refused) "([^"]*)?"$/
294
+ ```
295
+
296
+ **Examples**
297
+
298
+ ```gherkin
299
+ Then I am denied access to "/admin/config"
300
+ Then I should be refused "/node/add/article"
301
+ And we should be denied access to "/admin/people"
302
+ Given I am an anonymous user
303
+ Then I am denied access to "/admin/modules"
304
+ Then we am denied access to "/admin/reports/status"
305
+ ```
306
+
307
+ ## 13. Then I should be allowed "/admin/content"
308
+
309
+ Assert the current user **may** open a path: the site answers 2xx and renders it, with none of the refusal markers.
310
+
311
+ The positive half of a permission scenario, and it earns its place — a role that can reach nothing at all passes every refusal assertion in the suite, so the refusals only mean something next to this.
312
+
313
+ **Keyword**: `Then`
314
+
315
+ **Pattern**
316
+
317
+ ```js
318
+ /^(I |we )*(?:am|should be) (?:allowed|granted access to) "([^"]*)?"$/
319
+ ```
320
+
321
+ **Examples**
322
+
323
+ ```gherkin
324
+ Then I should be allowed "/admin/content"
325
+ Then I am granted access to "/node/add/article"
326
+ And we should be allowed "/admin/content/media"
327
+ Given I am a logged in user with the username "webmaster" user
328
+ Then I should be allowed "/admin/content"
329
+ Then we should be allowed "/user"
330
+ ```
331
+
332
+ ## 14. Then I should be denied access
333
+
334
+ Assert the page **already open** is a refusal — an access-denied page, or the log-in form the site redirected to.
335
+
336
+ Use it when the refusal is the result of an action rather than of a visit: submit a form, click an operation, follow a link, then assert the wall. It navigates nothing, so nothing about the failed attempt is lost. `the page should be access restricted` is the same step.
337
+
338
+ **Keyword**: `Then`
339
+
340
+ **Pattern**
341
+
342
+ ```js
343
+ /^(?:(?:I |we )*should be denied access|(?:the )*page should be access restricted)$/
344
+ ```
345
+
346
+ **Examples**
347
+
348
+ ```gherkin
349
+ Then I should be denied access
350
+ Then the page should be access restricted
351
+ When I click "Edit"
352
+ Then I should be denied access
353
+ And we should be denied access
354
+ Then the page should be access restricted
355
+ ```
@@ -15,11 +15,9 @@ Cucumber-js loads every `*.steps.js` in that directory automatically — you nev
15
15
  | 7 | `When I close the tour` |
16
16
  | 8 | `Then I should see the accessibility checker` |
17
17
  | 9 | `When I close the accessibility checker` |
18
- | 10 | `Then the page should have a working header` |
19
- | 11 | `Then the page should have a working footer` |
20
- | 12 | `When I press the "desktop" responsive preview device button` |
21
- | 13 | `Then the "site header" should be sticky` |
22
- | 14 | `Then the "site header" should have the "scrolled" class within 5 seconds` |
18
+ | 10 | `When I press the "desktop" responsive preview device button` |
19
+ | 11 | `Then the "site header" should be sticky` |
20
+ | 12 | `Then the "site header" should have the "scrolled" class within 5 seconds` |
23
21
 
24
22
  ---
25
23
 
@@ -256,64 +254,7 @@ Given I close the a11y checker
256
254
  And we close the accessibility checker
257
255
  ```
258
256
 
259
- ## 10. Then the page should have a working header
260
-
261
- Verify the page header is "working".
262
-
263
- On a Varbase site the Main navigation menu is rendered through the Drupal
264
- Canvas global Header region, so a working header means those primary links
265
- are present. Alter the links below to match your own site's main menu.
266
-
267
- Example: Then the page should have a working header
268
-
269
- **Keyword**: `Then`
270
-
271
- **Pattern**
272
-
273
- ```js
274
- /^(?:the page should have|(?:I |we )*should have) a working header$/
275
- ```
276
-
277
- **Examples**
278
-
279
- ```gherkin
280
- Then the page should have a working header
281
- And I should have a working header
282
- Then I should have a working header
283
- And we should have a working header
284
- Then the page should have a working header
285
- ```
286
-
287
- ## 11. Then the page should have a working footer
288
-
289
- Verify the page footer is "working".
290
-
291
- On a Varbase site the Secondary, Footer and Social media menus are rendered
292
- through the Drupal Canvas global Footer region. A working footer means the
293
- footer link text is present, the social profiles are linked, and the credits
294
- and logos show. Alter the lines below to match your own site.
295
-
296
- Example: Then the page should have a working footer
297
-
298
- **Keyword**: `Then`
299
-
300
- **Pattern**
301
-
302
- ```js
303
- /^(?:the page should have|(?:I |we )*should have) a working footer$/
304
- ```
305
-
306
- **Examples**
307
-
308
- ```gherkin
309
- Then the page should have a working footer
310
- And I should have a working footer
311
- Then I should have a working footer
312
- And we should have a working footer
313
- Then the page should have a working footer
314
- ```
315
-
316
- ## 12. When I press the "desktop" responsive preview device button
257
+ ## 10. When I press the "desktop" responsive preview device button
317
258
 
318
259
  Press a responsive-preview device button (Drupal core Responsive preview).
319
260
 
@@ -338,7 +279,7 @@ And I press the "widescreen" responsive preview device button
338
279
  When I press the "mobile" responsive preview device button
339
280
  ```
340
281
 
341
- ## 13. Then the "site header" should be sticky
282
+ ## 11. Then the "site header" should be sticky
342
283
 
343
284
  Assert an element renders as a sticky element (CSS position: sticky).
344
285
 
@@ -364,7 +305,7 @@ And the "footer" should not be sticky
364
305
  Then the "main content" should be sticky
365
306
  ```
366
307
 
367
- ## 14. Then the "site header" should have the "scrolled" class within 5 seconds
308
+ ## 12. Then the "site header" should have the "scrolled" class within 5 seconds
368
309
 
369
310
  Assert a named element gains (or loses) a CSS class, with auto-retry.
370
311
 
@@ -0,0 +1,6 @@
1
+ <!DOCTYPE html>
2
+ <html><head><title>Access denied</title></head>
3
+ <body>
4
+ <h1>Access denied</h1>
5
+ <p>You are not authorized to access this page.</p>
6
+ </body></html>
@@ -0,0 +1,55 @@
1
+ <!DOCTYPE html>
2
+ <html><head><title>Drimage Demo</title>
3
+ <style>body{margin:0} figure{margin:0} .below-the-fold{margin-top:3000px}</style>
4
+ </head>
5
+ <body>
6
+ <h1>Drimage Improved demo</h1>
7
+
8
+ <!-- The markup Drimage Improved renders on a Varbase site, copied from the
9
+ vartheme_bs5 dynamic-responsive-image component on demo.varbase.vardot.com:
10
+ a wrapper carrying the data object, a picture with a webp source, the img on
11
+ an SVG placeholder with the theme's own classes (no drimage-image class),
12
+ and the noscript fallback as the wrapper's next sibling.
13
+
14
+ The script at the bottom stands in for the module's JS: it marks the img
15
+ loading="lazy", swaps the placeholder for a derivative under
16
+ /styles/drimage_improved_W_H/ only once the image intersects the viewport,
17
+ rounds W up to the module's 200px threshold from the rendered width times
18
+ the device pixel ratio, and re-renders on resize. -->
19
+ <figure>
20
+ <div class="w-100 img-fluid object-fit-cover drimage" data-drimage_improved='{"fid":12,"subdir":"sites/default/files","scheme":"public","original_source":"2026-05/varbase-hero-collaboration.jpg","original_width":"4096","original_height":"2731","core_webp":1,"threshold":200,"upscale":320,"downscale":3840,"multiplier":1,"lazyload":"lazy","image_handling":"scale","focal_point":true}'><picture><source data-format="webp" srcset="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%20width='4096'%20height='2731'%20viewBox='0%200%204096%202731'%20%3E%3C/svg%3E" type="image/webp"><img class="w-100 img-fluid object-fit-cover" style="width:100%;height:auto" src="data:image/svg+xml;charset=utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='4096'%20height='2731'%20viewBox='0%200%204096%202731'%20%3E%3C/svg%3E" width="4096" height="2731" alt="Team collaborating in a modern glass-walled office"></picture></div><noscript><img src="2026-05/varbase-hero-collaboration.jpg" alt="Team collaborating in a modern glass-walled office" width="4096" height="2731"></noscript>
21
+ <figcaption>Our team in the new office</figcaption>
22
+ </figure>
23
+
24
+ <figure class="below-the-fold">
25
+ <div class="w-100 img-fluid object-fit-cover drimage" data-drimage_improved='{"fid":37,"subdir":"sites/default/files","scheme":"public","original_source":"2026-01/meeting-2.webp","original_width":"4096","original_height":"2733","core_webp":1,"threshold":200,"upscale":320,"downscale":3840,"multiplier":1,"lazyload":"lazy","image_handling":"scale","focal_point":true}'><picture><source data-format="webp" srcset="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%20width='4096'%20height='2733'%20viewBox='0%200%204096%202733'%20%3E%3C/svg%3E" type="image/webp"><img class="w-100 img-fluid object-fit-cover" style="width:100%;height:auto" src="data:image/svg+xml;charset=utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='4096'%20height='2733'%20viewBox='0%200%204096%202733'%20%3E%3C/svg%3E" width="4096" height="2733" alt="Team meeting around a table" title="Vardot team"></picture></div><noscript><img src="2026-01/meeting-2.webp" alt="Team meeting around a table" width="4096" height="2733"></noscript>
26
+ </figure>
27
+
28
+ <script>
29
+ (function () {
30
+ function render(el) {
31
+ var data = JSON.parse(el.getAttribute('data-drimage_improved'));
32
+ var img = el.querySelector('img');
33
+ img.setAttribute('loading', data.lazyload);
34
+ var rendered = img.clientWidth * (window.devicePixelRatio || 1) * data.multiplier;
35
+ var w = Math.ceil(rendered / data.threshold) * data.threshold;
36
+ w = Math.max(data.upscale, Math.min(data.downscale, w));
37
+ w = Math.max(200, Math.min(4000, Math.round(w / 200) * 200));
38
+ var h = Math.round(w * 2731 / 4096);
39
+ el.classList.add('is-loading');
40
+ img.src = '/styles/drimage_improved_' + w + '_' + h + '/public/sample.png';
41
+ }
42
+ var els = document.querySelectorAll('.drimage');
43
+ var io = new IntersectionObserver(function (entries) {
44
+ entries.forEach(function (e) { if (e.isIntersecting) { render(e.target); e.target.setAttribute('data-seen', '1'); } });
45
+ });
46
+ els.forEach(function (el) {
47
+ el.querySelector('img').setAttribute('loading', 'lazy');
48
+ io.observe(el);
49
+ });
50
+ window.addEventListener('resize', function () {
51
+ els.forEach(function (el) { if (el.getAttribute('data-seen')) render(el); });
52
+ });
53
+ })();
54
+ </script>
55
+ </body></html>