@wdio/image-comparison-core 1.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 (416) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/LICENSE +21 -0
  3. package/README.md +12 -0
  4. package/assets/ios/ipadair4th.ipadair5th-bottom.png +0 -0
  5. package/assets/ios/ipadair4th.ipadair5th-top.png +0 -0
  6. package/assets/ios/ipadmini6th-bottom.png +0 -0
  7. package/assets/ios/ipadmini6th-top.png +0 -0
  8. package/assets/ios/ipadpro11-bottom.png +0 -0
  9. package/assets/ios/ipadpro11-top.png +0 -0
  10. package/assets/ios/ipadpro129-bottom.png +0 -0
  11. package/assets/ios/ipadpro129-top.png +0 -0
  12. package/assets/ios/iphone11promax-bottom.png +0 -0
  13. package/assets/ios/iphone11promax-top.png +0 -0
  14. package/assets/ios/iphone12.iphone12pro-top.png +0 -0
  15. package/assets/ios/iphone12.iphone12pro.iphone13.iphone13pro.iphone14-bottom.png +0 -0
  16. package/assets/ios/iphone12mini-top.png +0 -0
  17. package/assets/ios/iphone12mini.iphone13mini-bottom.png +0 -0
  18. package/assets/ios/iphone12promax-top.png +0 -0
  19. package/assets/ios/iphone12promax.iphone13promax.iphone14plus-bottom.png +0 -0
  20. package/assets/ios/iphone13.iphone13pro.iphone14-top.png +0 -0
  21. package/assets/ios/iphone13mini-top.png +0 -0
  22. package/assets/ios/iphone13promax.iphone14plus-top.png +0 -0
  23. package/assets/ios/iphone14pro-bottom.png +0 -0
  24. package/assets/ios/iphone14pro-top.png +0 -0
  25. package/assets/ios/iphone14promax-bottom.png +0 -0
  26. package/assets/ios/iphone14promax-top.png +0 -0
  27. package/assets/ios/iphone15-bottom.png +0 -0
  28. package/assets/ios/iphone15-top.png +0 -0
  29. package/assets/ios/iphonex.iphonexs.iphone11pro-bottom.png +0 -0
  30. package/assets/ios/iphonex.iphonexs.iphone11pro-top.png +0 -0
  31. package/assets/ios/iphonexr.iphone11-bottom.png +0 -0
  32. package/assets/ios/iphonexr.iphone11-top.png +0 -0
  33. package/assets/ios/iphonexsmax-bottom.png +0 -0
  34. package/assets/ios/iphonexsmax-top.png +0 -0
  35. package/dist/base.d.ts +18 -0
  36. package/dist/base.d.ts.map +1 -0
  37. package/dist/base.interfaces.d.ts +200 -0
  38. package/dist/base.interfaces.d.ts.map +1 -0
  39. package/dist/base.interfaces.js +1 -0
  40. package/dist/base.js +58 -0
  41. package/dist/base.test.d.ts +2 -0
  42. package/dist/base.test.d.ts.map +1 -0
  43. package/dist/base.test.js +45 -0
  44. package/dist/clientSideScripts/checkMetaTag.d.ts +2 -0
  45. package/dist/clientSideScripts/checkMetaTag.d.ts.map +1 -0
  46. package/dist/clientSideScripts/checkMetaTag.js +9 -0
  47. package/dist/clientSideScripts/checkMetaTag.test.d.ts +2 -0
  48. package/dist/clientSideScripts/checkMetaTag.test.d.ts.map +1 -0
  49. package/dist/clientSideScripts/checkMetaTag.test.js +25 -0
  50. package/dist/clientSideScripts/customCss.interfaces.d.ts +8 -0
  51. package/dist/clientSideScripts/customCss.interfaces.d.ts.map +1 -0
  52. package/dist/clientSideScripts/customCss.interfaces.js +1 -0
  53. package/dist/clientSideScripts/drawTabbableOnCanvas.d.ts +8 -0
  54. package/dist/clientSideScripts/drawTabbableOnCanvas.d.ts.map +1 -0
  55. package/dist/clientSideScripts/drawTabbableOnCanvas.interfaces.d.ts +4 -0
  56. package/dist/clientSideScripts/drawTabbableOnCanvas.interfaces.d.ts.map +1 -0
  57. package/dist/clientSideScripts/drawTabbableOnCanvas.interfaces.js +1 -0
  58. package/dist/clientSideScripts/drawTabbableOnCanvas.js +275 -0
  59. package/dist/clientSideScripts/drawTabbableOnCanvas.test.d.ts +2 -0
  60. package/dist/clientSideScripts/drawTabbableOnCanvas.test.d.ts.map +1 -0
  61. package/dist/clientSideScripts/drawTabbableOnCanvas.test.js +251 -0
  62. package/dist/clientSideScripts/elementPosition.interfaces.d.ts +3 -0
  63. package/dist/clientSideScripts/elementPosition.interfaces.d.ts.map +1 -0
  64. package/dist/clientSideScripts/elementPosition.interfaces.js +1 -0
  65. package/dist/clientSideScripts/getBoundingClientRect.d.ts +6 -0
  66. package/dist/clientSideScripts/getBoundingClientRect.d.ts.map +1 -0
  67. package/dist/clientSideScripts/getBoundingClientRect.js +12 -0
  68. package/dist/clientSideScripts/getBoundingClientRect.test.d.ts +2 -0
  69. package/dist/clientSideScripts/getBoundingClientRect.test.d.ts.map +1 -0
  70. package/dist/clientSideScripts/getBoundingClientRect.test.js +28 -0
  71. package/dist/clientSideScripts/getDocumentScrollHeight.d.ts +5 -0
  72. package/dist/clientSideScripts/getDocumentScrollHeight.d.ts.map +1 -0
  73. package/dist/clientSideScripts/getDocumentScrollHeight.js +48 -0
  74. package/dist/clientSideScripts/getDocumentScrollHeight.test.d.ts +2 -0
  75. package/dist/clientSideScripts/getDocumentScrollHeight.test.d.ts.map +1 -0
  76. package/dist/clientSideScripts/getDocumentScrollHeight.test.js +30 -0
  77. package/dist/clientSideScripts/getElementPositionTopDom.d.ts +6 -0
  78. package/dist/clientSideScripts/getElementPositionTopDom.d.ts.map +1 -0
  79. package/dist/clientSideScripts/getElementPositionTopDom.js +11 -0
  80. package/dist/clientSideScripts/getElementPositionTopDom.test.d.ts +2 -0
  81. package/dist/clientSideScripts/getElementPositionTopDom.test.d.ts.map +1 -0
  82. package/dist/clientSideScripts/getElementPositionTopDom.test.js +11 -0
  83. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.d.ts +14 -0
  84. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.d.ts.map +1 -0
  85. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.js +19 -0
  86. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.test.d.ts +2 -0
  87. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.test.d.ts.map +1 -0
  88. package/dist/clientSideScripts/getElementPositionTopScreenNativeMobile.test.js +52 -0
  89. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.d.ts +6 -0
  90. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.d.ts.map +1 -0
  91. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.js +17 -0
  92. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.test.d.ts +2 -0
  93. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.test.d.ts.map +1 -0
  94. package/dist/clientSideScripts/getMobileWebviewClickAndDimensions.test.js +47 -0
  95. package/dist/clientSideScripts/getScreenDimensions.d.ts +6 -0
  96. package/dist/clientSideScripts/getScreenDimensions.d.ts.map +1 -0
  97. package/dist/clientSideScripts/getScreenDimensions.js +104 -0
  98. package/dist/clientSideScripts/getScreenDimensions.test.d.ts +2 -0
  99. package/dist/clientSideScripts/getScreenDimensions.test.d.ts.map +1 -0
  100. package/dist/clientSideScripts/getScreenDimensions.test.js +161 -0
  101. package/dist/clientSideScripts/hideRemoveElements.d.ts +8 -0
  102. package/dist/clientSideScripts/hideRemoveElements.d.ts.map +1 -0
  103. package/dist/clientSideScripts/hideRemoveElements.js +60 -0
  104. package/dist/clientSideScripts/hideRemoveElements.test.d.ts +2 -0
  105. package/dist/clientSideScripts/hideRemoveElements.test.d.ts.map +1 -0
  106. package/dist/clientSideScripts/hideRemoveElements.test.js +199 -0
  107. package/dist/clientSideScripts/hideScrollbars.d.ts +9 -0
  108. package/dist/clientSideScripts/hideScrollbars.d.ts.map +1 -0
  109. package/dist/clientSideScripts/hideScrollbars.js +15 -0
  110. package/dist/clientSideScripts/hideScrollbars.test.d.ts +2 -0
  111. package/dist/clientSideScripts/hideScrollbars.test.d.ts.map +1 -0
  112. package/dist/clientSideScripts/hideScrollbars.test.js +12 -0
  113. package/dist/clientSideScripts/injectWebviewOverlay.d.ts +5 -0
  114. package/dist/clientSideScripts/injectWebviewOverlay.d.ts.map +1 -0
  115. package/dist/clientSideScripts/injectWebviewOverlay.js +35 -0
  116. package/dist/clientSideScripts/injectWebviewOverlay.test.d.ts +2 -0
  117. package/dist/clientSideScripts/injectWebviewOverlay.test.d.ts.map +1 -0
  118. package/dist/clientSideScripts/injectWebviewOverlay.test.js +74 -0
  119. package/dist/clientSideScripts/removeElementFromDom.d.ts +5 -0
  120. package/dist/clientSideScripts/removeElementFromDom.d.ts.map +1 -0
  121. package/dist/clientSideScripts/removeElementFromDom.js +9 -0
  122. package/dist/clientSideScripts/removeElementFromDom.test.d.ts +2 -0
  123. package/dist/clientSideScripts/removeElementFromDom.test.d.ts.map +1 -0
  124. package/dist/clientSideScripts/removeElementFromDom.test.js +43 -0
  125. package/dist/clientSideScripts/screenDimensions.interfaces.d.ts +96 -0
  126. package/dist/clientSideScripts/screenDimensions.interfaces.d.ts.map +1 -0
  127. package/dist/clientSideScripts/screenDimensions.interfaces.js +1 -0
  128. package/dist/clientSideScripts/scrollElementIntoView.d.ts +5 -0
  129. package/dist/clientSideScripts/scrollElementIntoView.d.ts.map +1 -0
  130. package/dist/clientSideScripts/scrollElementIntoView.js +31 -0
  131. package/dist/clientSideScripts/scrollElementIntoView.test.d.ts +2 -0
  132. package/dist/clientSideScripts/scrollElementIntoView.test.d.ts.map +1 -0
  133. package/dist/clientSideScripts/scrollElementIntoView.test.js +79 -0
  134. package/dist/clientSideScripts/scrollToPosition.d.ts +5 -0
  135. package/dist/clientSideScripts/scrollToPosition.d.ts.map +1 -0
  136. package/dist/clientSideScripts/scrollToPosition.js +25 -0
  137. package/dist/clientSideScripts/scrollToPosition.test.d.ts +2 -0
  138. package/dist/clientSideScripts/scrollToPosition.test.d.ts.map +1 -0
  139. package/dist/clientSideScripts/scrollToPosition.test.js +72 -0
  140. package/dist/clientSideScripts/setCustomCss.d.ts +6 -0
  141. package/dist/clientSideScripts/setCustomCss.d.ts.map +1 -0
  142. package/dist/clientSideScripts/setCustomCss.js +36 -0
  143. package/dist/clientSideScripts/setCustomCss.test.d.ts +2 -0
  144. package/dist/clientSideScripts/setCustomCss.test.d.ts.map +1 -0
  145. package/dist/clientSideScripts/setCustomCss.test.js +68 -0
  146. package/dist/clientSideScripts/statusAddressToolBarOffsets.interfaces.d.ts +11 -0
  147. package/dist/clientSideScripts/statusAddressToolBarOffsets.interfaces.d.ts.map +1 -0
  148. package/dist/clientSideScripts/statusAddressToolBarOffsets.interfaces.js +1 -0
  149. package/dist/clientSideScripts/toggleTextTransparency.d.ts +5 -0
  150. package/dist/clientSideScripts/toggleTextTransparency.d.ts.map +1 -0
  151. package/dist/clientSideScripts/toggleTextTransparency.js +16 -0
  152. package/dist/clientSideScripts/toggleTextTransparency.test.d.ts +2 -0
  153. package/dist/clientSideScripts/toggleTextTransparency.test.d.ts.map +1 -0
  154. package/dist/clientSideScripts/toggleTextTransparency.test.js +35 -0
  155. package/dist/clientSideScripts/waitForFonts.d.ts +8 -0
  156. package/dist/clientSideScripts/waitForFonts.d.ts.map +1 -0
  157. package/dist/clientSideScripts/waitForFonts.js +20 -0
  158. package/dist/clientSideScripts/waitForFonts.test.d.ts +2 -0
  159. package/dist/clientSideScripts/waitForFonts.test.d.ts.map +1 -0
  160. package/dist/clientSideScripts/waitForFonts.test.js +37 -0
  161. package/dist/commands/check.interfaces.d.ts +35 -0
  162. package/dist/commands/check.interfaces.d.ts.map +1 -0
  163. package/dist/commands/check.interfaces.js +1 -0
  164. package/dist/commands/checkAppElement.d.ts +7 -0
  165. package/dist/commands/checkAppElement.d.ts.map +1 -0
  166. package/dist/commands/checkAppElement.js +44 -0
  167. package/dist/commands/checkAppElement.test.d.ts +2 -0
  168. package/dist/commands/checkAppElement.test.d.ts.map +1 -0
  169. package/dist/commands/checkAppElement.test.js +241 -0
  170. package/dist/commands/checkAppScreen.d.ts +7 -0
  171. package/dist/commands/checkAppScreen.d.ts.map +1 -0
  172. package/dist/commands/checkAppScreen.js +73 -0
  173. package/dist/commands/checkAppScreen.test.d.ts +2 -0
  174. package/dist/commands/checkAppScreen.test.d.ts.map +1 -0
  175. package/dist/commands/checkAppScreen.test.js +295 -0
  176. package/dist/commands/checkElement.d.ts +7 -0
  177. package/dist/commands/checkElement.d.ts.map +1 -0
  178. package/dist/commands/checkElement.js +10 -0
  179. package/dist/commands/checkElement.test.d.ts +2 -0
  180. package/dist/commands/checkElement.test.d.ts.map +1 -0
  181. package/dist/commands/checkElement.test.js +66 -0
  182. package/dist/commands/checkFullPageScreen.d.ts +7 -0
  183. package/dist/commands/checkFullPageScreen.d.ts.map +1 -0
  184. package/dist/commands/checkFullPageScreen.js +56 -0
  185. package/dist/commands/checkFullPageScreen.test.d.ts +2 -0
  186. package/dist/commands/checkFullPageScreen.test.d.ts.map +1 -0
  187. package/dist/commands/checkFullPageScreen.test.js +259 -0
  188. package/dist/commands/checkScreen.d.ts +7 -0
  189. package/dist/commands/checkScreen.d.ts.map +1 -0
  190. package/dist/commands/checkScreen.js +10 -0
  191. package/dist/commands/checkScreen.test.d.ts +2 -0
  192. package/dist/commands/checkScreen.test.d.ts.map +1 -0
  193. package/dist/commands/checkScreen.test.js +62 -0
  194. package/dist/commands/checkTabbablePage.d.ts +7 -0
  195. package/dist/commands/checkTabbablePage.d.ts.map +1 -0
  196. package/dist/commands/checkTabbablePage.js +28 -0
  197. package/dist/commands/checkTabbablePage.test.d.ts +2 -0
  198. package/dist/commands/checkTabbablePage.test.d.ts.map +1 -0
  199. package/dist/commands/checkTabbablePage.test.js +200 -0
  200. package/dist/commands/checkWebElement.d.ts +7 -0
  201. package/dist/commands/checkWebElement.d.ts.map +1 -0
  202. package/dist/commands/checkWebElement.js +52 -0
  203. package/dist/commands/checkWebElement.test.d.ts +2 -0
  204. package/dist/commands/checkWebElement.test.d.ts.map +1 -0
  205. package/dist/commands/checkWebElement.test.js +278 -0
  206. package/dist/commands/checkWebScreen.d.ts +7 -0
  207. package/dist/commands/checkWebScreen.d.ts.map +1 -0
  208. package/dist/commands/checkWebScreen.js +50 -0
  209. package/dist/commands/checkWebScreen.test.d.ts +2 -0
  210. package/dist/commands/checkWebScreen.test.d.ts.map +1 -0
  211. package/dist/commands/checkWebScreen.test.js +227 -0
  212. package/dist/commands/element.interfaces.d.ts +27 -0
  213. package/dist/commands/element.interfaces.d.ts.map +1 -0
  214. package/dist/commands/element.interfaces.js +1 -0
  215. package/dist/commands/fullPage.interfaces.d.ts +38 -0
  216. package/dist/commands/fullPage.interfaces.d.ts.map +1 -0
  217. package/dist/commands/fullPage.interfaces.js +1 -0
  218. package/dist/commands/save.interfaces.d.ts +27 -0
  219. package/dist/commands/save.interfaces.d.ts.map +1 -0
  220. package/dist/commands/save.interfaces.js +1 -0
  221. package/dist/commands/saveAppElement.d.ts +7 -0
  222. package/dist/commands/saveAppElement.d.ts.map +1 -0
  223. package/dist/commands/saveAppElement.js +30 -0
  224. package/dist/commands/saveAppElement.test.d.ts +2 -0
  225. package/dist/commands/saveAppElement.test.d.ts.map +1 -0
  226. package/dist/commands/saveAppElement.test.js +199 -0
  227. package/dist/commands/saveAppScreen.d.ts +7 -0
  228. package/dist/commands/saveAppScreen.d.ts.map +1 -0
  229. package/dist/commands/saveAppScreen.js +43 -0
  230. package/dist/commands/saveAppScreen.test.d.ts +2 -0
  231. package/dist/commands/saveAppScreen.test.d.ts.map +1 -0
  232. package/dist/commands/saveAppScreen.test.js +221 -0
  233. package/dist/commands/saveElement.d.ts +7 -0
  234. package/dist/commands/saveElement.d.ts.map +1 -0
  235. package/dist/commands/saveElement.js +10 -0
  236. package/dist/commands/saveElement.test.d.ts +2 -0
  237. package/dist/commands/saveElement.test.d.ts.map +1 -0
  238. package/dist/commands/saveElement.test.js +62 -0
  239. package/dist/commands/saveFullPageScreen.d.ts +7 -0
  240. package/dist/commands/saveFullPageScreen.d.ts.map +1 -0
  241. package/dist/commands/saveFullPageScreen.js +60 -0
  242. package/dist/commands/saveFullPageScreen.test.d.ts +2 -0
  243. package/dist/commands/saveFullPageScreen.test.d.ts.map +1 -0
  244. package/dist/commands/saveFullPageScreen.test.js +293 -0
  245. package/dist/commands/saveScreen.d.ts +7 -0
  246. package/dist/commands/saveScreen.d.ts.map +1 -0
  247. package/dist/commands/saveScreen.js +10 -0
  248. package/dist/commands/saveScreen.test.d.ts +2 -0
  249. package/dist/commands/saveScreen.test.d.ts.map +1 -0
  250. package/dist/commands/saveScreen.test.js +47 -0
  251. package/dist/commands/saveTabbablePage.d.ts +7 -0
  252. package/dist/commands/saveTabbablePage.d.ts.map +1 -0
  253. package/dist/commands/saveTabbablePage.js +20 -0
  254. package/dist/commands/saveTabbablePage.test.d.ts +2 -0
  255. package/dist/commands/saveTabbablePage.test.d.ts.map +1 -0
  256. package/dist/commands/saveTabbablePage.test.js +74 -0
  257. package/dist/commands/saveWebElement.d.ts +7 -0
  258. package/dist/commands/saveWebElement.d.ts.map +1 -0
  259. package/dist/commands/saveWebElement.js +53 -0
  260. package/dist/commands/saveWebElement.test.d.ts +2 -0
  261. package/dist/commands/saveWebElement.test.d.ts.map +1 -0
  262. package/dist/commands/saveWebElement.test.js +253 -0
  263. package/dist/commands/saveWebScreen.d.ts +7 -0
  264. package/dist/commands/saveWebScreen.d.ts.map +1 -0
  265. package/dist/commands/saveWebScreen.js +48 -0
  266. package/dist/commands/saveWebScreen.test.d.ts +2 -0
  267. package/dist/commands/saveWebScreen.test.d.ts.map +1 -0
  268. package/dist/commands/saveWebScreen.test.js +222 -0
  269. package/dist/commands/screen.interfaces.d.ts +16 -0
  270. package/dist/commands/screen.interfaces.d.ts.map +1 -0
  271. package/dist/commands/screen.interfaces.js +1 -0
  272. package/dist/commands/tabbable.interfaces.d.ts +29 -0
  273. package/dist/commands/tabbable.interfaces.d.ts.map +1 -0
  274. package/dist/commands/tabbable.interfaces.js +1 -0
  275. package/dist/helpers/afterScreenshot.d.ts +7 -0
  276. package/dist/helpers/afterScreenshot.d.ts.map +1 -0
  277. package/dist/helpers/afterScreenshot.interfaces.d.ts +46 -0
  278. package/dist/helpers/afterScreenshot.interfaces.d.ts.map +1 -0
  279. package/dist/helpers/afterScreenshot.interfaces.js +1 -0
  280. package/dist/helpers/afterScreenshot.js +55 -0
  281. package/dist/helpers/afterScreenshot.test.d.ts +2 -0
  282. package/dist/helpers/afterScreenshot.test.d.ts.map +1 -0
  283. package/dist/helpers/afterScreenshot.test.js +241 -0
  284. package/dist/helpers/beforeScreenshot.d.ts +6 -0
  285. package/dist/helpers/beforeScreenshot.d.ts.map +1 -0
  286. package/dist/helpers/beforeScreenshot.interfaces.d.ts +15 -0
  287. package/dist/helpers/beforeScreenshot.interfaces.d.ts.map +1 -0
  288. package/dist/helpers/beforeScreenshot.interfaces.js +1 -0
  289. package/dist/helpers/beforeScreenshot.js +79 -0
  290. package/dist/helpers/beforeScreenshot.test.d.ts +2 -0
  291. package/dist/helpers/beforeScreenshot.test.d.ts.map +1 -0
  292. package/dist/helpers/beforeScreenshot.test.js +261 -0
  293. package/dist/helpers/compare.interfaces.d.ts +16 -0
  294. package/dist/helpers/compare.interfaces.d.ts.map +1 -0
  295. package/dist/helpers/compare.interfaces.js +1 -0
  296. package/dist/helpers/constants.d.ts +108 -0
  297. package/dist/helpers/constants.d.ts.map +1 -0
  298. package/dist/helpers/constants.interfaces.d.ts +30 -0
  299. package/dist/helpers/constants.interfaces.d.ts.map +1 -0
  300. package/dist/helpers/constants.interfaces.js +11 -0
  301. package/dist/helpers/constants.js +436 -0
  302. package/dist/helpers/options.d.ts +64 -0
  303. package/dist/helpers/options.d.ts.map +1 -0
  304. package/dist/helpers/options.interfaces.d.ts +363 -0
  305. package/dist/helpers/options.interfaces.d.ts.map +1 -0
  306. package/dist/helpers/options.interfaces.js +1 -0
  307. package/dist/helpers/options.js +184 -0
  308. package/dist/helpers/options.test.d.ts +2 -0
  309. package/dist/helpers/options.test.d.ts.map +1 -0
  310. package/dist/helpers/options.test.js +428 -0
  311. package/dist/helpers/utils.d.ts +134 -0
  312. package/dist/helpers/utils.d.ts.map +1 -0
  313. package/dist/helpers/utils.interfaces.d.ts +254 -0
  314. package/dist/helpers/utils.interfaces.d.ts.map +1 -0
  315. package/dist/helpers/utils.interfaces.js +1 -0
  316. package/dist/helpers/utils.js +566 -0
  317. package/dist/helpers/utils.test.d.ts +2 -0
  318. package/dist/helpers/utils.test.d.ts.map +1 -0
  319. package/dist/helpers/utils.test.js +900 -0
  320. package/dist/index.d.ts +26 -0
  321. package/dist/index.d.ts.map +1 -0
  322. package/dist/index.js +18 -0
  323. package/dist/methods/compareReport.interfaces.d.ts +109 -0
  324. package/dist/methods/compareReport.interfaces.d.ts.map +1 -0
  325. package/dist/methods/compareReport.interfaces.js +1 -0
  326. package/dist/methods/createCompareReport.d.ts +7 -0
  327. package/dist/methods/createCompareReport.d.ts.map +1 -0
  328. package/dist/methods/createCompareReport.js +61 -0
  329. package/dist/methods/createCompareReport.test.d.ts +2 -0
  330. package/dist/methods/createCompareReport.test.d.ts.map +1 -0
  331. package/dist/methods/createCompareReport.test.js +236 -0
  332. package/dist/methods/elementPosition.d.ts +18 -0
  333. package/dist/methods/elementPosition.d.ts.map +1 -0
  334. package/dist/methods/elementPosition.interfaces.d.ts +14 -0
  335. package/dist/methods/elementPosition.interfaces.d.ts.map +1 -0
  336. package/dist/methods/elementPosition.interfaces.js +1 -0
  337. package/dist/methods/elementPosition.js +34 -0
  338. package/dist/methods/images.d.ts +69 -0
  339. package/dist/methods/images.d.ts.map +1 -0
  340. package/dist/methods/images.executeImageCompare.test.d.ts +2 -0
  341. package/dist/methods/images.executeImageCompare.test.d.ts.map +1 -0
  342. package/dist/methods/images.executeImageCompare.test.js +770 -0
  343. package/dist/methods/images.interfaces.d.ts +214 -0
  344. package/dist/methods/images.interfaces.d.ts.map +1 -0
  345. package/dist/methods/images.interfaces.js +1 -0
  346. package/dist/methods/images.js +428 -0
  347. package/dist/methods/images.test.d.ts +2 -0
  348. package/dist/methods/images.test.d.ts.map +1 -0
  349. package/dist/methods/images.test.js +1465 -0
  350. package/dist/methods/instanceData.d.ts +6 -0
  351. package/dist/methods/instanceData.d.ts.map +1 -0
  352. package/dist/methods/instanceData.interfaces.d.ts +57 -0
  353. package/dist/methods/instanceData.interfaces.d.ts.map +1 -0
  354. package/dist/methods/instanceData.interfaces.js +1 -0
  355. package/dist/methods/instanceData.js +42 -0
  356. package/dist/methods/instanceData.test.d.ts +2 -0
  357. package/dist/methods/instanceData.test.d.ts.map +1 -0
  358. package/dist/methods/instanceData.test.js +224 -0
  359. package/dist/methods/processDiffPixels.d.ts +59 -0
  360. package/dist/methods/processDiffPixels.d.ts.map +1 -0
  361. package/dist/methods/processDiffPixels.js +242 -0
  362. package/dist/methods/processDiffPixels.test.d.ts +2 -0
  363. package/dist/methods/processDiffPixels.test.d.ts.map +1 -0
  364. package/dist/methods/processDiffPixels.test.js +122 -0
  365. package/dist/methods/rectangles.d.ts +51 -0
  366. package/dist/methods/rectangles.d.ts.map +1 -0
  367. package/dist/methods/rectangles.interfaces.d.ts +146 -0
  368. package/dist/methods/rectangles.interfaces.d.ts.map +1 -0
  369. package/dist/methods/rectangles.interfaces.js +1 -0
  370. package/dist/methods/rectangles.js +266 -0
  371. package/dist/methods/rectangles.test.d.ts +2 -0
  372. package/dist/methods/rectangles.test.d.ts.map +1 -0
  373. package/dist/methods/rectangles.test.js +853 -0
  374. package/dist/methods/screenshots.d.ts +37 -0
  375. package/dist/methods/screenshots.d.ts.map +1 -0
  376. package/dist/methods/screenshots.interfaces.d.ts +203 -0
  377. package/dist/methods/screenshots.interfaces.d.ts.map +1 -0
  378. package/dist/methods/screenshots.interfaces.js +1 -0
  379. package/dist/methods/screenshots.js +394 -0
  380. package/dist/methods/screenshots.test.d.ts +2 -0
  381. package/dist/methods/screenshots.test.d.ts.map +1 -0
  382. package/dist/methods/screenshots.test.js +656 -0
  383. package/dist/methods/takeElementScreenshots.d.ts +3 -0
  384. package/dist/methods/takeElementScreenshots.d.ts.map +1 -0
  385. package/dist/methods/takeElementScreenshots.js +104 -0
  386. package/dist/methods/takeElementScreenshots.test.d.ts +2 -0
  387. package/dist/methods/takeElementScreenshots.test.d.ts.map +1 -0
  388. package/dist/methods/takeElementScreenshots.test.js +314 -0
  389. package/dist/methods/takeFullPageScreenshots.d.ts +3 -0
  390. package/dist/methods/takeFullPageScreenshots.d.ts.map +1 -0
  391. package/dist/methods/takeFullPageScreenshots.js +56 -0
  392. package/dist/methods/takeFullPageScreenshots.test.d.ts +2 -0
  393. package/dist/methods/takeFullPageScreenshots.test.d.ts.map +1 -0
  394. package/dist/methods/takeFullPageScreenshots.test.js +72 -0
  395. package/dist/methods/takeWebScreenshots.d.ts +3 -0
  396. package/dist/methods/takeWebScreenshots.d.ts.map +1 -0
  397. package/dist/methods/takeWebScreenshots.js +41 -0
  398. package/dist/methods/takeWebScreenshots.test.d.ts +2 -0
  399. package/dist/methods/takeWebScreenshots.test.d.ts.map +1 -0
  400. package/dist/methods/takeWebScreenshots.test.js +149 -0
  401. package/dist/mocks/image.d.ts +4 -0
  402. package/dist/mocks/image.d.ts.map +1 -0
  403. package/dist/mocks/image.js +3 -0
  404. package/dist/mocks/mocks.d.ts +745 -0
  405. package/dist/mocks/mocks.d.ts.map +1 -0
  406. package/dist/mocks/mocks.js +392 -0
  407. package/dist/resemble/compare.interfaces.d.ts +136 -0
  408. package/dist/resemble/compare.interfaces.d.ts.map +1 -0
  409. package/dist/resemble/compare.interfaces.js +1 -0
  410. package/dist/resemble/compareImages.d.ts +3 -0
  411. package/dist/resemble/compareImages.d.ts.map +1 -0
  412. package/dist/resemble/compareImages.js +21 -0
  413. package/dist/resemble/resemble.jimp.cjs +981 -0
  414. package/dist/resemble/resemble.jimp.d.cts +46 -0
  415. package/dist/resemble/resemble.jimp.d.cts.map +1 -0
  416. package/package.json +47 -0
@@ -0,0 +1,275 @@
1
+ /**
2
+ * This method is based on this blog post
3
+ * https://vivrichards.co.uk/accessibility/automating-page-tab-flows-using-visual-testing-and-javascript
4
+ * by Viv Richards and optimized for using Canvas
5
+ */
6
+ export default function drawTabbableOnCanvas(drawOptions) {
7
+ // 1. Scroll to top of page
8
+ window.scrollTo(0, 0);
9
+ // 2. Insert canvas
10
+ const width = window.innerWidth;
11
+ const height = getDocumentScrollHeight();
12
+ const canvasNode = `<canvas id="wic-tabbable-canvas" width="${width}" height="${height}" style="position:absolute;top:0;left:0;z-index:999999;">`;
13
+ document.body.insertAdjacentHTML('afterbegin', canvasNode);
14
+ // 3. Get all the elements
15
+ const accessibleElements = tabbable();
16
+ // 4a. Iterate over all accessibleElements and get the coordinates
17
+ const elementCoordinates = accessibleElements.map((node) => {
18
+ const currentElement = node.getBoundingClientRect();
19
+ return {
20
+ x: currentElement.left + currentElement.width / 2,
21
+ y: currentElement.top + currentElement.height / 2,
22
+ };
23
+ });
24
+ // 4b. Add the starting coordinates
25
+ elementCoordinates.unshift({ x: 0, y: 0 });
26
+ // 4c. Iterate over all coordinates and draw lines and circles
27
+ elementCoordinates.forEach((elementCoordinate, i) => {
28
+ if (i === 0) {
29
+ return;
30
+ }
31
+ drawLine(drawOptions.line, elementCoordinates[i - 1], elementCoordinate);
32
+ drawCircleAndNumber(drawOptions.circle, elementCoordinate, i);
33
+ });
34
+ /**
35
+ * Draw a line
36
+ */
37
+ function drawLine(options, start, end) {
38
+ const tabbableCanvasContext = document.getElementById('wic-tabbable-canvas').getContext('2d');
39
+ if (!tabbableCanvasContext) {
40
+ return;
41
+ }
42
+ // Draw the line
43
+ tabbableCanvasContext.beginPath();
44
+ tabbableCanvasContext.globalCompositeOperation = 'destination-over';
45
+ tabbableCanvasContext.lineWidth = options.width;
46
+ tabbableCanvasContext.strokeStyle = options.color;
47
+ tabbableCanvasContext.moveTo(start.x, start.y);
48
+ tabbableCanvasContext.lineTo(end.x, end.y);
49
+ tabbableCanvasContext.stroke();
50
+ }
51
+ /**
52
+ * Draw a circle
53
+ */
54
+ function drawCircleAndNumber(options, position, i) {
55
+ const tabbableCanvasContext = document.getElementById('wic-tabbable-canvas').getContext('2d');
56
+ if (!tabbableCanvasContext) {
57
+ return;
58
+ }
59
+ // Draw circle
60
+ tabbableCanvasContext.beginPath();
61
+ tabbableCanvasContext.globalCompositeOperation = 'source-over';
62
+ tabbableCanvasContext.fillStyle = options.backgroundColor;
63
+ tabbableCanvasContext.arc(position.x, position.y, options.size, 0, Math.PI * 2, true);
64
+ tabbableCanvasContext.fill();
65
+ // Draw border
66
+ tabbableCanvasContext.lineWidth = options.borderWidth;
67
+ tabbableCanvasContext.strokeStyle = options.borderColor;
68
+ tabbableCanvasContext.stroke();
69
+ if (options.showNumber) {
70
+ // Set the text
71
+ tabbableCanvasContext.font = `${options.fontSize}px ${options.fontFamily}`;
72
+ tabbableCanvasContext.textAlign = 'center';
73
+ tabbableCanvasContext.textBaseline = 'middle';
74
+ tabbableCanvasContext.fillStyle = options.fontColor;
75
+ tabbableCanvasContext.fillText(i.toString(), position.x, position.y);
76
+ }
77
+ }
78
+ /**
79
+ * Below code is coming from https://github.com/davidtheclark/tabbable
80
+ * and is modified a bit to work inside the browser.
81
+ * The original module couldn't be used for injection and didn't support TypeScript
82
+ */
83
+ /**
84
+ * Get all tabbable elements based on tabindex and then regular dom order
85
+ */
86
+ function tabbable() {
87
+ const regularTabbables = [];
88
+ const orderedTabbables = [];
89
+ const candidateSelectors = [
90
+ 'input',
91
+ 'select',
92
+ 'textarea',
93
+ 'a[href]',
94
+ 'button',
95
+ '[tabindex]',
96
+ 'audio[controls]',
97
+ 'video[controls]',
98
+ '[contenteditable]:not([contenteditable="false"])',
99
+ ].join(',');
100
+ const candidates = document.querySelectorAll(candidateSelectors);
101
+ for (let i = 0; i < candidates.length; i++) {
102
+ const candidate = candidates[i];
103
+ if (!isNodeMatchingSelectorTabbable(candidate)) {
104
+ continue;
105
+ }
106
+ const candidateTabindex = getTabindex(candidate);
107
+ if (candidateTabindex === 0) {
108
+ regularTabbables.push(candidate);
109
+ }
110
+ else {
111
+ orderedTabbables.push({
112
+ documentOrder: i,
113
+ tabIndex: candidateTabindex,
114
+ node: candidate,
115
+ });
116
+ }
117
+ }
118
+ return Array.prototype.slice.call(orderedTabbables
119
+ .sort(sortOrderedTabbables)
120
+ .map((a) => a.node)
121
+ .concat(regularTabbables));
122
+ }
123
+ /**
124
+ * Is the node tabbable
125
+ */
126
+ function isNodeMatchingSelectorTabbable(node) {
127
+ return !(!isNodeMatchingSelectorFocusable(node) || isNonTabbableRadio(node) || getTabindex(node) < 0);
128
+ }
129
+ /**
130
+ * Check if the node has a focused state
131
+ */
132
+ function isNodeMatchingSelectorFocusable(node) {
133
+ return !(node.hasAttribute('disabled') || node.getAttribute('disabled') || isHiddenInput(node) || isHidden(node));
134
+ }
135
+ /**
136
+ * Get the tab index of the node
137
+ */
138
+ function getTabindex(node) {
139
+ const tabindexAttr = parseInt(node.getAttribute('tabindex'), 10);
140
+ if (!isNaN(tabindexAttr)) {
141
+ return tabindexAttr;
142
+ }
143
+ // Browsers do not return `tabIndex` correctly for contentEditable nodes;
144
+ // so if they don't have a tabindex attribute specifically set, assume it's 0.
145
+ // TODO: Lines 173-174 are currently untestable with the current setup
146
+ // The radio input with no name case is hard to test through the public API
147
+ if (isContentEditable(node)) {
148
+ return 0;
149
+ }
150
+ return node.tabIndex;
151
+ }
152
+ /**
153
+ * Return ordered tabbable nodes
154
+ */
155
+ function sortOrderedTabbables(nodeA, nodeB) {
156
+ // TODO: Lines 187-191 are currently untestable with the current setup
157
+ // The findHighestNode function is hard to test through the public API
158
+ return nodeA.tabIndex === nodeB.tabIndex
159
+ ? // This is so bad :(, fix this!
160
+ nodeA.documentOrder - nodeB.documentOrder
161
+ : nodeA.tabIndex - nodeB.tabIndex;
162
+ }
163
+ /**
164
+ * Is the content editable
165
+ */
166
+ function isContentEditable(node) {
167
+ return node.contentEditable === 'true';
168
+ }
169
+ /**
170
+ * Is the node an input
171
+ */
172
+ function isInput(node) {
173
+ return node.tagName === 'INPUT';
174
+ }
175
+ /**
176
+ * Is the input hidden
177
+ */
178
+ function isHiddenInput(node) {
179
+ return isInput(node) && node.type === 'hidden';
180
+ }
181
+ /**
182
+ * Is the node a radio input
183
+ */
184
+ function isRadio(node) {
185
+ return isInput(node) && node.type === 'radio';
186
+ }
187
+ /**
188
+ * Is the node a radio input and can it be tabbed
189
+ */
190
+ function isNonTabbableRadio(node) {
191
+ return isRadio(node) && !isTabbableRadio(node);
192
+ }
193
+ /**
194
+ * Get the checked radio input
195
+ */
196
+ // @ts-ignore
197
+ function getCheckedRadio(nodes) {
198
+ for (let i = 0; i < nodes.length; i++) {
199
+ if (nodes[i].checked) {
200
+ return nodes[i];
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Is the radio input tabbable
206
+ */
207
+ function isTabbableRadio(node) {
208
+ if (!node.name) {
209
+ return true;
210
+ }
211
+ // This won't account for the edge case where you have radio groups with the same
212
+ // in separate forms on the same page.
213
+ // This is bad :(, but don't know how to fix this typing
214
+ const radioSet = node.ownerDocument.querySelectorAll(`input[type="radio"][name="${node.name}"]`);
215
+ const checked = getCheckedRadio(radioSet);
216
+ return !checked || checked === node;
217
+ }
218
+ /**
219
+ * Is the node hidden
220
+ */
221
+ function isHidden(node) {
222
+ // offsetParent being null will allow detecting cases where an element is invisible or inside an invisible element,
223
+ // as long as the element does not use position: fixed. For them, their visibility has to be checked directly as well.
224
+ return node.offsetParent === null || getComputedStyle(node).visibility === 'hidden';
225
+ }
226
+ /**
227
+ * Get the document scroll height
228
+ */
229
+ function getDocumentScrollHeight() {
230
+ const viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
231
+ const scrollHeight = document.documentElement.scrollHeight;
232
+ const bodyScrollHeight = document.body.scrollHeight;
233
+ // In some situations the default scrollheight can be equal to the viewport height
234
+ // but the body scroll height can be different, then return that one
235
+ if (viewPortHeight === scrollHeight && bodyScrollHeight > scrollHeight) {
236
+ return bodyScrollHeight;
237
+ }
238
+ // In some cases we can have a challenge determining the height of the page
239
+ // due to for example a `vh` property on the body element.
240
+ // If that is the case we need to walk over all the elements and determine the highest element
241
+ // this is a very time consuming thing, so our last hope :(
242
+ let pageHeight = 0;
243
+ let largestNodeElement = document.querySelector('body');
244
+ // TODO: Lines 288-293 are currently untestable with the current setup
245
+ if (bodyScrollHeight === scrollHeight && bodyScrollHeight === viewPortHeight) {
246
+ findHighestNode(document.documentElement.childNodes);
247
+ // There could be some elements above this largest element,
248
+ // add that on top
249
+ return pageHeight + largestNodeElement?.getBoundingClientRect().top;
250
+ }
251
+ // The scrollHeight is good enough
252
+ return scrollHeight;
253
+ /**
254
+ * Find the largest html element on the page
255
+ */
256
+ // This is so bad :(, fix the typings!!!
257
+ function findHighestNode(nodesList) {
258
+ // TODO: Lines 304-319 are currently untestable with the current setup
259
+ for (let i = nodesList.length - 1; i >= 0; i--) {
260
+ const currentNode = nodesList[i];
261
+ /* istanbul ignore next */
262
+ if (currentNode.scrollHeight && currentNode.clientHeight) {
263
+ const elHeight = Math.max(currentNode.scrollHeight, currentNode.clientHeight);
264
+ pageHeight = Math.max(elHeight, pageHeight);
265
+ if (elHeight === pageHeight) {
266
+ largestNodeElement = currentNode;
267
+ }
268
+ }
269
+ if (currentNode.childNodes.length) {
270
+ findHighestNode(currentNode.childNodes);
271
+ }
272
+ }
273
+ }
274
+ }
275
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=drawTabbableOnCanvas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawTabbableOnCanvas.test.d.ts","sourceRoot":"","sources":["../../src/clientSideScripts/drawTabbableOnCanvas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,251 @@
1
+ // @vitest-environment jsdom
2
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
3
+ import drawTabbableOnCanvas from './drawTabbableOnCanvas.js';
4
+ describe('drawTabbableOnCanvas', () => {
5
+ const mockCanvasContext = {
6
+ beginPath: vi.fn(),
7
+ globalCompositeOperation: '',
8
+ lineWidth: 0,
9
+ strokeStyle: '',
10
+ moveTo: vi.fn(),
11
+ lineTo: vi.fn(),
12
+ stroke: vi.fn(),
13
+ fillStyle: '',
14
+ arc: vi.fn(),
15
+ fill: vi.fn(),
16
+ font: '',
17
+ textAlign: '',
18
+ textBaseline: '',
19
+ fillText: vi.fn(),
20
+ };
21
+ const defaultOptions = {
22
+ line: {
23
+ color: '#ff0000',
24
+ width: 2,
25
+ },
26
+ circle: {
27
+ backgroundColor: '#ffffff',
28
+ borderColor: '#ff0000',
29
+ borderWidth: 2,
30
+ size: 10,
31
+ showNumber: true,
32
+ fontSize: 12,
33
+ fontFamily: 'Arial',
34
+ fontColor: '#000000',
35
+ },
36
+ };
37
+ beforeEach(() => {
38
+ document.body.innerHTML = '';
39
+ Object.defineProperty(window, 'innerWidth', { value: 1024, configurable: true });
40
+ Object.defineProperty(window, 'innerHeight', { value: 768, configurable: true });
41
+ Object.defineProperty(document.documentElement, 'clientHeight', { value: 768, configurable: true });
42
+ Object.defineProperty(document.documentElement, 'scrollHeight', { value: 1000, configurable: true });
43
+ Object.defineProperty(document.body, 'scrollHeight', { value: 1000, configurable: true });
44
+ window.scrollTo = vi.fn();
45
+ const mockGetContext = vi.fn().mockReturnValue(mockCanvasContext);
46
+ HTMLCanvasElement.prototype.getContext = mockGetContext;
47
+ vi.clearAllMocks();
48
+ });
49
+ it('should create a canvas element with correct dimensions', () => {
50
+ drawTabbableOnCanvas(defaultOptions);
51
+ const canvas = document.getElementById('wic-tabbable-canvas');
52
+ expect(canvas).toBeTruthy();
53
+ expect(canvas.width).toBe(1024);
54
+ expect(canvas.height).toBe(1000);
55
+ expect(canvas.style.position).toBe('absolute');
56
+ expect(canvas.style.top).toBe('0px');
57
+ expect(canvas.style.left).toBe('0px');
58
+ expect(canvas.style.zIndex).toBe('999999');
59
+ });
60
+ it('should draw lines and circles for tabbable elements', () => {
61
+ const button = document.createElement('button');
62
+ button.textContent = 'Test Button';
63
+ button.tabIndex = 0;
64
+ document.body.appendChild(button);
65
+ const input = document.createElement('input');
66
+ input.type = 'text';
67
+ input.tabIndex = 0;
68
+ document.body.appendChild(input);
69
+ const mockRect = {
70
+ left: 100,
71
+ top: 100,
72
+ width: 100,
73
+ height: 50,
74
+ right: 200,
75
+ bottom: 150,
76
+ };
77
+ Element.prototype.getBoundingClientRect = vi.fn().mockReturnValue(mockRect);
78
+ Object.defineProperty(button, 'offsetParent', { value: document.body, configurable: true });
79
+ Object.defineProperty(input, 'offsetParent', { value: document.body, configurable: true });
80
+ const beginPathSpy = vi.spyOn(mockCanvasContext, 'beginPath');
81
+ const globalCompositeOperationSpy = vi.spyOn(mockCanvasContext, 'globalCompositeOperation', 'set');
82
+ const fillStyleSpy = vi.spyOn(mockCanvasContext, 'fillStyle', 'set');
83
+ const strokeStyleSpy = vi.spyOn(mockCanvasContext, 'strokeStyle', 'set');
84
+ const lineWidthSpy = vi.spyOn(mockCanvasContext, 'lineWidth', 'set');
85
+ drawTabbableOnCanvas(defaultOptions);
86
+ expect(beginPathSpy).toHaveBeenCalled();
87
+ expect(globalCompositeOperationSpy).toHaveBeenNthCalledWith(1, 'destination-over');
88
+ expect(lineWidthSpy).toHaveBeenNthCalledWith(1, defaultOptions.line.width);
89
+ expect(strokeStyleSpy).toHaveBeenNthCalledWith(1, defaultOptions.line.color);
90
+ expect(mockCanvasContext.moveTo).toHaveBeenCalled();
91
+ expect(mockCanvasContext.lineTo).toHaveBeenCalled();
92
+ expect(mockCanvasContext.stroke).toHaveBeenCalled();
93
+ expect(globalCompositeOperationSpy).toHaveBeenNthCalledWith(2, 'source-over');
94
+ expect(fillStyleSpy).toHaveBeenNthCalledWith(1, defaultOptions.circle.backgroundColor);
95
+ expect(lineWidthSpy).toHaveBeenNthCalledWith(2, defaultOptions.circle.borderWidth);
96
+ expect(strokeStyleSpy).toHaveBeenNthCalledWith(2, defaultOptions.circle.borderColor);
97
+ expect(mockCanvasContext.arc).toHaveBeenCalled();
98
+ expect(mockCanvasContext.fill).toHaveBeenCalled();
99
+ expect(mockCanvasContext.stroke).toHaveBeenCalled();
100
+ expect(fillStyleSpy).toHaveBeenNthCalledWith(2, defaultOptions.circle.fontColor);
101
+ expect(mockCanvasContext.font).toBe(`${defaultOptions.circle.fontSize}px ${defaultOptions.circle.fontFamily}`);
102
+ expect(mockCanvasContext.textAlign).toBe('center');
103
+ expect(mockCanvasContext.textBaseline).toBe('middle');
104
+ expect(mockCanvasContext.fillText).toHaveBeenCalled();
105
+ });
106
+ it('should handle empty tabbable elements', () => {
107
+ drawTabbableOnCanvas(defaultOptions);
108
+ const canvas = document.getElementById('wic-tabbable-canvas');
109
+ expect(canvas).toBeTruthy();
110
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
111
+ });
112
+ it('should handle hidden elements', () => {
113
+ const button = document.createElement('button');
114
+ button.style.visibility = 'hidden';
115
+ document.body.appendChild(button);
116
+ drawTabbableOnCanvas(defaultOptions);
117
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
118
+ });
119
+ it('should handle disabled elements', () => {
120
+ const button = document.createElement('button');
121
+ button.disabled = true;
122
+ document.body.appendChild(button);
123
+ drawTabbableOnCanvas(defaultOptions);
124
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
125
+ });
126
+ it('should not include elements with negative tabindex', () => {
127
+ const div = document.createElement('div');
128
+ div.tabIndex = -1;
129
+ document.body.appendChild(div);
130
+ drawTabbableOnCanvas(defaultOptions);
131
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
132
+ });
133
+ it('should not include disabled elements', () => {
134
+ const input = document.createElement('input');
135
+ input.disabled = true;
136
+ document.body.appendChild(input);
137
+ drawTabbableOnCanvas(defaultOptions);
138
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
139
+ });
140
+ it('should not include hidden elements (visibility: hidden)', () => {
141
+ const input = document.createElement('input');
142
+ input.style.visibility = 'hidden';
143
+ document.body.appendChild(input);
144
+ drawTabbableOnCanvas(defaultOptions);
145
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
146
+ });
147
+ it('should only include checked radio in group as tabbable', () => {
148
+ const radio1 = document.createElement('input');
149
+ radio1.type = 'radio';
150
+ radio1.name = 'group1';
151
+ document.body.appendChild(radio1);
152
+ const radio2 = document.createElement('input');
153
+ radio2.type = 'radio';
154
+ radio2.name = 'group1';
155
+ radio2.checked = true;
156
+ document.body.appendChild(radio2);
157
+ Object.defineProperty(radio1, 'offsetParent', { value: document.body, configurable: true });
158
+ Object.defineProperty(radio2, 'offsetParent', { value: document.body, configurable: true });
159
+ radio2.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
160
+ drawTabbableOnCanvas(defaultOptions);
161
+ expect(mockCanvasContext.beginPath).toHaveBeenCalled();
162
+ });
163
+ it('should sort tabbable elements correctly (tabIndex 0 vs non-zero)', () => {
164
+ const btn1 = document.createElement('button');
165
+ btn1.tabIndex = 0;
166
+ document.body.appendChild(btn1);
167
+ const btn2 = document.createElement('button');
168
+ btn2.tabIndex = 1;
169
+ document.body.appendChild(btn2);
170
+ Object.defineProperty(btn1, 'offsetParent', { value: document.body, configurable: true });
171
+ Object.defineProperty(btn2, 'offsetParent', { value: document.body, configurable: true });
172
+ btn1.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
173
+ btn2.getBoundingClientRect = vi.fn().mockReturnValue({ left: 20, top: 20, width: 10, height: 10, right: 30, bottom: 30 });
174
+ drawTabbableOnCanvas(defaultOptions);
175
+ expect(mockCanvasContext.beginPath).toHaveBeenCalled();
176
+ });
177
+ it('should treat radio with no name as tabbable', () => {
178
+ const radio = document.createElement('input');
179
+ radio.type = 'radio';
180
+ document.body.appendChild(radio);
181
+ Object.defineProperty(radio, 'offsetParent', { value: document.body, configurable: true });
182
+ radio.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
183
+ drawTabbableOnCanvas(defaultOptions);
184
+ expect(mockCanvasContext.beginPath).toHaveBeenCalled();
185
+ });
186
+ it('should treat contentEditable as tabbable', () => {
187
+ const div = document.createElement('div');
188
+ div.contentEditable = 'true';
189
+ div.tabIndex = 0;
190
+ document.body.appendChild(div);
191
+ Object.defineProperty(div, 'offsetParent', { value: document.body, configurable: true });
192
+ div.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
193
+ drawTabbableOnCanvas(defaultOptions);
194
+ expect(mockCanvasContext.beginPath).toHaveBeenCalled();
195
+ });
196
+ it('should use body scrollHeight if it is greater than document scrollHeight', () => {
197
+ Object.defineProperty(document.documentElement, 'clientHeight', { value: 100, configurable: true });
198
+ Object.defineProperty(document.documentElement, 'scrollHeight', { value: 100, configurable: true });
199
+ Object.defineProperty(document.body, 'scrollHeight', { value: 200, configurable: true });
200
+ Object.defineProperty(window, 'innerHeight', { value: 100, configurable: true });
201
+ const btn = document.createElement('button');
202
+ btn.tabIndex = 0;
203
+ Object.defineProperty(btn, 'offsetParent', { value: document.body, configurable: true });
204
+ btn.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
205
+ document.body.appendChild(btn);
206
+ drawTabbableOnCanvas(defaultOptions);
207
+ const canvas = document.getElementById('wic-tabbable-canvas');
208
+ expect(canvas.height).toBe(200);
209
+ });
210
+ it('should walk DOM to find highest node if scrollHeight and bodyScrollHeight equal clientHeight', () => {
211
+ Object.defineProperty(document.documentElement, 'clientHeight', { value: 100, configurable: true });
212
+ Object.defineProperty(document.documentElement, 'scrollHeight', { value: 100, configurable: true });
213
+ Object.defineProperty(document.body, 'scrollHeight', { value: 100, configurable: true });
214
+ const tallDiv = document.createElement('div');
215
+ tallDiv.style.height = '300px';
216
+ document.body.appendChild(tallDiv);
217
+ tallDiv.getBoundingClientRect = vi.fn().mockReturnValue({ top: 0 });
218
+ drawTabbableOnCanvas(defaultOptions);
219
+ const canvas = document.getElementById('wic-tabbable-canvas');
220
+ expect(canvas.height).toBeGreaterThanOrEqual(100);
221
+ });
222
+ it('should not throw or attempt to draw if getContext returns null (drawLine)', () => {
223
+ const originalGetContext = HTMLCanvasElement.prototype.getContext;
224
+ HTMLCanvasElement.prototype.getContext = vi.fn().mockReturnValue(null);
225
+ const btn1 = document.createElement('button');
226
+ btn1.tabIndex = 0;
227
+ Object.defineProperty(btn1, 'offsetParent', { value: document.body, configurable: true });
228
+ btn1.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
229
+ document.body.appendChild(btn1);
230
+ const btn2 = document.createElement('button');
231
+ btn2.tabIndex = 0;
232
+ Object.defineProperty(btn2, 'offsetParent', { value: document.body, configurable: true });
233
+ btn2.getBoundingClientRect = vi.fn().mockReturnValue({ left: 20, top: 20, width: 10, height: 10, right: 30, bottom: 30 });
234
+ document.body.appendChild(btn2);
235
+ expect(() => drawTabbableOnCanvas(defaultOptions)).not.toThrow();
236
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
237
+ HTMLCanvasElement.prototype.getContext = originalGetContext;
238
+ });
239
+ it('should not throw or attempt to draw if getContext returns null (drawCircleAndNumber)', () => {
240
+ const originalGetContext = HTMLCanvasElement.prototype.getContext;
241
+ HTMLCanvasElement.prototype.getContext = vi.fn().mockReturnValue(null);
242
+ const btn = document.createElement('button');
243
+ btn.tabIndex = 0;
244
+ Object.defineProperty(btn, 'offsetParent', { value: document.body, configurable: true });
245
+ btn.getBoundingClientRect = vi.fn().mockReturnValue({ left: 0, top: 0, width: 10, height: 10, right: 10, bottom: 10 });
246
+ document.body.appendChild(btn);
247
+ expect(() => drawTabbableOnCanvas(defaultOptions)).not.toThrow();
248
+ expect(mockCanvasContext.beginPath).not.toHaveBeenCalled();
249
+ HTMLCanvasElement.prototype.getContext = originalGetContext;
250
+ });
251
+ });
@@ -0,0 +1,3 @@
1
+ import type { RectanglesOutput } from '../methods/rectangles.interfaces.js';
2
+ export type ElementPosition = RectanglesOutput;
3
+ //# sourceMappingURL=elementPosition.interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elementPosition.interfaces.d.ts","sourceRoot":"","sources":["../../src/clientSideScripts/elementPosition.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAE3E,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ElementPosition } from './elementPosition.interfaces.js';
2
+ /**
3
+ * Get the element position relative to the viewport
4
+ */
5
+ export declare function getBoundingClientRect(element: HTMLElement): ElementPosition;
6
+ //# sourceMappingURL=getBoundingClientRect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBoundingClientRect.d.ts","sourceRoot":"","sources":["../../src/clientSideScripts/getBoundingClientRect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AAEtE;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,WAAW,GACrB,eAAe,CASjB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Get the element position relative to the viewport
3
+ */
4
+ export function getBoundingClientRect(element) {
5
+ const { height, width, x, y } = element.getBoundingClientRect();
6
+ return {
7
+ height: Math.round(height),
8
+ width: Math.round(width),
9
+ x: Math.round(x),
10
+ y: Math.round(y),
11
+ };
12
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getBoundingClientRect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBoundingClientRect.test.d.ts","sourceRoot":"","sources":["../../src/clientSideScripts/getBoundingClientRect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ // @vitest-environment jsdom
2
+ import { describe, it, expect } from 'vitest';
3
+ import { getBoundingClientRect } from './getBoundingClientRect.js';
4
+ describe('getBoundingClientRect', () => {
5
+ it('should return rounded values of the bounding client rect', () => {
6
+ const element = document.createElement('div');
7
+ Object.defineProperty(element, 'getBoundingClientRect', {
8
+ value: () => ({
9
+ x: 10.7,
10
+ y: 20.4,
11
+ width: 100.9,
12
+ height: 200.3,
13
+ top: 20.4,
14
+ left: 10.7,
15
+ bottom: 220.7,
16
+ right: 110.9,
17
+ toJSON: () => { },
18
+ }),
19
+ });
20
+ const result = getBoundingClientRect(element);
21
+ expect(result).toEqual({
22
+ x: 11,
23
+ y: 20,
24
+ width: 101,
25
+ height: 200,
26
+ });
27
+ });
28
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Get the document scroll height, this means the actual height of the page from the top to the bottom of the DOM
3
+ */
4
+ export default function getDocumentScrollHeight(): number;
5
+ //# sourceMappingURL=getDocumentScrollHeight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDocumentScrollHeight.d.ts","sourceRoot":"","sources":["../../src/clientSideScripts/getDocumentScrollHeight.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,uBAAuB,IAAI,MAAM,CAoDxD"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Get the document scroll height, this means the actual height of the page from the top to the bottom of the DOM
3
+ */
4
+ export default function getDocumentScrollHeight() {
5
+ const viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
6
+ const scrollHeight = document.documentElement.scrollHeight;
7
+ const bodyScrollHeight = document.body.scrollHeight;
8
+ // In some situations the default scrollheight can be equal to the viewport height
9
+ // but the body scroll height can be different, then return that one
10
+ if (viewPortHeight === scrollHeight && bodyScrollHeight > scrollHeight) {
11
+ return bodyScrollHeight;
12
+ }
13
+ // In some cases we can have a challenge determining the height of the page
14
+ // due to for example a `vh` property on the body element.
15
+ // If that is the case we need to walk over all the elements and determine the highest element
16
+ // this is a very time consuming thing, so our last hope :(
17
+ let pageHeight = 0;
18
+ let largestNodeElement = document.querySelector('body');
19
+ if (bodyScrollHeight === scrollHeight && bodyScrollHeight === viewPortHeight) {
20
+ findHighestNode(document.documentElement.childNodes);
21
+ // There could be some elements above this largest element,
22
+ // add that on top
23
+ /* istanbul ignore next */
24
+ return pageHeight + largestNodeElement.getBoundingClientRect().top;
25
+ }
26
+ // The scrollHeight is good enough
27
+ return scrollHeight;
28
+ /**
29
+ * Find the largest html element on the page
30
+ * @param nodesList
31
+ */
32
+ function findHighestNode(nodesList) {
33
+ for (let i = nodesList.length - 1; i >= 0; i--) {
34
+ const currentNode = nodesList[i];
35
+ /* istanbul ignore next */
36
+ if (currentNode.scrollHeight && currentNode.clientHeight) {
37
+ const elHeight = Math.max(currentNode.scrollHeight, currentNode.clientHeight);
38
+ pageHeight = Math.max(elHeight, pageHeight);
39
+ if (elHeight === pageHeight) {
40
+ largestNodeElement = currentNode;
41
+ }
42
+ }
43
+ if (currentNode.childNodes.length) {
44
+ findHighestNode(currentNode.childNodes);
45
+ }
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getDocumentScrollHeight.test.d.ts.map