@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,900 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ vi.mock('node:fs', async () => {
5
+ const actual = await vi.importActual('node:fs');
6
+ return {
7
+ ...actual,
8
+ existsSync: vi.fn(),
9
+ mkdirSync: vi.fn(),
10
+ };
11
+ });
12
+ import logger from '@wdio/logger';
13
+ import { buildBaseExecuteCompareOptions, buildFolderOptions, calculateDprData, canUseBidiScreenshot, checkAndroidChromeDriverScreenshot, checkAndroidNativeWebScreenshot, checkTestInBrowser, checkTestInMobileBrowser, createConditionalProperty, executeNativeClick, extractCommonCheckVariables, formatFileName, getAddressBarShadowPadding, getAndCreatePath, getBase64ScreenshotSize, getBooleanOption, getDevicePixelRatio, getIosBezelImageNames, getMethodOrWicOption, getMobileScreenSize, getMobileViewPortPosition, getToolBarShadowPadding, hasResizeDimensions, isObject, isStorybook, loadBase64Html, logAllDeprecatedCompareOptions, updateVisualBaseline, } from './utils.js';
14
+ import { IMAGE_STRING } from '../mocks/image.js';
15
+ import { DEVICE_RECTANGLES } from './constants.js';
16
+ import { getMobileWebviewClickAndDimensions } from '../clientSideScripts/getMobileWebviewClickAndDimensions.js';
17
+ import { checkMetaTag } from '../clientSideScripts/checkMetaTag.js';
18
+ vi.mock('../clientSideScripts/injectWebviewOverlay.js', () => ({
19
+ injectWebviewOverlay: Symbol('injectWebviewOverlay'),
20
+ }));
21
+ vi.mock('../clientSideScripts/getMobileWebviewClickAndDimensions.js', () => ({
22
+ getMobileWebviewClickAndDimensions: Symbol('getMobileWebviewClickAndDimensions'),
23
+ }));
24
+ vi.mock('../clientSideScripts/checkMetaTag.js', () => ({
25
+ checkMetaTag: Symbol('checkMetaTag'),
26
+ }));
27
+ const log = logger('test');
28
+ vi.mock('@wdio/logger', () => import(join(process.cwd(), '__mocks__', '@wdio/logger')));
29
+ vi.mock('@wdio/globals', () => ({
30
+ browser: {
31
+ execute: vi.fn(),
32
+ browsingContextCaptureScreenshot: vi.fn(),
33
+ getWindowHandle: vi.fn(),
34
+ }
35
+ }));
36
+ describe('utils', () => {
37
+ const createMockBrowserInstance = () => {
38
+ return {
39
+ execute: vi.fn(),
40
+ browsingContextCaptureScreenshot: vi.fn(),
41
+ getWindowHandle: vi.fn(),
42
+ isBidi: true,
43
+ getOrientation: vi.fn().mockResolvedValue('PORTRAIT'),
44
+ getWindowSize: vi.fn().mockResolvedValue({ width: 375, height: 667 }),
45
+ getUrl: vi.fn().mockResolvedValue('http://example.com'),
46
+ url: vi.fn(),
47
+ };
48
+ };
49
+ describe('getAndCreatePath', () => {
50
+ const folder = join(process.cwd(), '/.tmp/utils');
51
+ beforeEach(() => {
52
+ vi.mocked(existsSync).mockClear();
53
+ });
54
+ it('should create the folder and return the folder name for a device that needs to have its own folder', () => {
55
+ const options = {
56
+ browserName: '',
57
+ deviceName: 'deviceName',
58
+ isMobile: true,
59
+ savePerInstance: true,
60
+ };
61
+ const expectedFolderName = join(folder, options.deviceName);
62
+ vi.mocked(existsSync).mockReturnValueOnce(false);
63
+ expect(existsSync(expectedFolderName)).toMatchSnapshot();
64
+ vi.mocked(existsSync).mockReturnValue(true);
65
+ expect(getAndCreatePath(folder, options)).toEqual(expectedFolderName);
66
+ expect(existsSync(expectedFolderName)).toMatchSnapshot();
67
+ });
68
+ it('should create the folder and return the folder name for a browser that needs to have its own folder', () => {
69
+ const options = {
70
+ browserName: 'browser',
71
+ deviceName: '',
72
+ isMobile: false,
73
+ savePerInstance: true,
74
+ };
75
+ const expectedFolderName = join(folder, `desktop_${options.browserName}`);
76
+ vi.mocked(existsSync).mockReturnValueOnce(false);
77
+ expect(existsSync(expectedFolderName)).toMatchSnapshot();
78
+ vi.mocked(existsSync).mockReturnValue(true);
79
+ expect(getAndCreatePath(folder, options)).toEqual(expectedFolderName);
80
+ expect(existsSync(expectedFolderName)).toMatchSnapshot();
81
+ });
82
+ it('should create the folder and return the folder name for a browser', () => {
83
+ const options = {
84
+ browserName: 'browser',
85
+ deviceName: '',
86
+ isMobile: false,
87
+ savePerInstance: false,
88
+ };
89
+ vi.mocked(existsSync).mockReturnValueOnce(false);
90
+ expect(existsSync(folder)).toMatchSnapshot();
91
+ vi.mocked(existsSync).mockReturnValue(true);
92
+ expect(getAndCreatePath(folder, options)).toEqual(folder);
93
+ expect(existsSync(folder)).toMatchSnapshot();
94
+ });
95
+ });
96
+ describe('formatFileName', () => {
97
+ const formatFileOptions = {
98
+ browserName: '',
99
+ browserVersion: '',
100
+ deviceName: '',
101
+ devicePixelRatio: 2,
102
+ formatImageName: '',
103
+ isMobile: false,
104
+ isTestInBrowser: true,
105
+ logName: '',
106
+ name: '',
107
+ outerHeight: 768,
108
+ outerWidth: 1366,
109
+ platformName: '',
110
+ platformVersion: '',
111
+ screenHeight: 900,
112
+ screenWidth: 1400,
113
+ tag: 'theTag',
114
+ };
115
+ it('should format a string with all options provided', () => {
116
+ formatFileOptions.formatImageName =
117
+ 'browser.{browserName}-{browserVersion}-platform.{platformName}-{platformVersion}-dpr.{dpr}-{height}-{logName}-{name}-{tag}-{width}';
118
+ formatFileOptions.browserName = 'chrome';
119
+ formatFileOptions.browserVersion = '74';
120
+ formatFileOptions.logName = 'chrome-latest';
121
+ formatFileOptions.name = 'chrome-name';
122
+ formatFileOptions.platformName = 'osx';
123
+ formatFileOptions.platformVersion = '12';
124
+ expect(formatFileName(formatFileOptions)).toMatchSnapshot();
125
+ });
126
+ it('should format a string for mobile app', () => {
127
+ formatFileOptions.formatImageName = '{tag}-{mobile}-{dpr}-{width}x{height}';
128
+ formatFileOptions.deviceName = 'iPhoneX';
129
+ formatFileOptions.isMobile = true;
130
+ formatFileOptions.isTestInBrowser = false;
131
+ expect(formatFileName(formatFileOptions)).toMatchSnapshot();
132
+ });
133
+ it('should format a string for mobile browser', () => {
134
+ formatFileOptions.formatImageName = '{tag}-{mobile}-{dpr}-{width}x{height}';
135
+ formatFileOptions.browserName = 'chrome';
136
+ formatFileOptions.deviceName = 'iPhoneX';
137
+ formatFileOptions.isMobile = true;
138
+ formatFileOptions.isTestInBrowser = true;
139
+ expect(formatFileName(formatFileOptions)).toMatchSnapshot();
140
+ });
141
+ });
142
+ describe('checkTestInBrowser', () => {
143
+ const testCases = [
144
+ { browserName: 'chrome', expected: true },
145
+ { browserName: '', expected: false },
146
+ ];
147
+ testCases.forEach(({ browserName, expected }) => {
148
+ it(`should return ${expected} for browserName:'${browserName}'`, () => {
149
+ expect(checkTestInBrowser(browserName)).toMatchSnapshot();
150
+ });
151
+ });
152
+ });
153
+ describe('checkTestInMobileBrowser', () => {
154
+ const testCases = [
155
+ { isMobile: false, browserName: 'chrome', expected: false },
156
+ { isMobile: true, browserName: '', expected: false },
157
+ { isMobile: true, browserName: 'chrome', expected: true },
158
+ ];
159
+ testCases.forEach(({ isMobile, browserName, expected }) => {
160
+ it(`should return ${expected} for isMobile:'${isMobile}' and browserName:'${browserName}'`, () => {
161
+ expect(checkTestInMobileBrowser(isMobile, browserName)).toMatchSnapshot();
162
+ });
163
+ });
164
+ });
165
+ describe('checkAndroidNativeWebScreenshot', () => {
166
+ const testCases = [
167
+ { isAndroid: false, nativeWeb: false, expected: false },
168
+ { isAndroid: true, nativeWeb: true, expected: true },
169
+ { isAndroid: true, nativeWeb: false, expected: false },
170
+ ];
171
+ testCases.forEach(({ isAndroid, nativeWeb, expected }) => {
172
+ it(`should return ${expected} for isAndroid:'${isAndroid}' and nativeWeb:${nativeWeb}`, () => {
173
+ expect(checkAndroidNativeWebScreenshot(isAndroid, nativeWeb)).toMatchSnapshot();
174
+ });
175
+ });
176
+ });
177
+ describe('checkAndroidChromeDriverScreenshot', () => {
178
+ const testCases = [
179
+ { isAndroid: false, nativeWeb: false, expected: false },
180
+ { isAndroid: true, nativeWeb: true, expected: false },
181
+ { isAndroid: true, nativeWeb: false, expected: true },
182
+ ];
183
+ testCases.forEach(({ isAndroid, nativeWeb, expected }) => {
184
+ it(`should return ${expected} for isAndroid:'${isAndroid}' and nativeWeb:${nativeWeb}`, () => {
185
+ expect(checkAndroidChromeDriverScreenshot(isAndroid, nativeWeb)).toMatchSnapshot();
186
+ });
187
+ });
188
+ });
189
+ describe('getAddressBarShadowPadding', () => {
190
+ const baseOptions = {
191
+ isAndroid: false,
192
+ isIOS: false,
193
+ isMobile: false,
194
+ browserName: '',
195
+ nativeWebScreenshot: false,
196
+ addressBarShadowPadding: 6,
197
+ addShadowPadding: false,
198
+ };
199
+ const testCases = [
200
+ { ...baseOptions, browserName: 'chrome', description: 'desktop browser', expected: 0 },
201
+ { ...baseOptions, isAndroid: true, description: 'Android app', expected: 0 },
202
+ { ...baseOptions, isIOS: true, description: 'iOS app', expected: 0 },
203
+ { ...baseOptions, isAndroid: true, nativeWebScreenshot: true, description: 'Android native web without shadow padding', expected: 0 },
204
+ { ...baseOptions, isAndroid: true, nativeWebScreenshot: true, addShadowPadding: true, description: 'Android native web with shadow padding', expected: 6 },
205
+ { ...baseOptions, isIOS: true, addShadowPadding: true, description: 'iOS with shadow padding', expected: 6 },
206
+ ];
207
+ testCases.forEach(({ description, expected, ...options }) => {
208
+ it(`should return ${expected} for ${description}`, () => {
209
+ expect(getAddressBarShadowPadding(options)).toMatchSnapshot();
210
+ });
211
+ });
212
+ });
213
+ describe('getToolBarShadowPadding', () => {
214
+ const baseOptions = {
215
+ isAndroid: false,
216
+ isIOS: false,
217
+ isMobile: false,
218
+ browserName: '',
219
+ nativeWebScreenshot: false,
220
+ toolBarShadowPadding: 6,
221
+ addShadowPadding: false,
222
+ };
223
+ const testCases = [
224
+ { ...baseOptions, browserName: 'chrome', description: 'desktop browser', expected: 0 },
225
+ { ...baseOptions, isAndroid: true, isMobile: true, description: 'Android app', expected: 0 },
226
+ { ...baseOptions, isIOS: true, isMobile: true, description: 'iOS app', expected: 0 },
227
+ { ...baseOptions, isAndroid: true, isMobile: true, addShadowPadding: true, description: 'Android app with shadow padding', expected: 0 },
228
+ { ...baseOptions, isAndroid: true, isMobile: true, browserName: 'chrome', addShadowPadding: true, description: 'Android browser with shadow padding', expected: 6 },
229
+ { ...baseOptions, isIOS: true, isMobile: true, browserName: 'safari', addShadowPadding: true, description: 'iOS with shadow padding', expected: 15 },
230
+ ];
231
+ testCases.forEach(({ description, expected, ...options }) => {
232
+ it(`should return ${expected} for ${description}`, () => {
233
+ expect(getToolBarShadowPadding(options)).toMatchSnapshot();
234
+ });
235
+ });
236
+ });
237
+ describe('calculateDprData', () => {
238
+ it('should multiply all number values by the dpr value', () => {
239
+ const data = {
240
+ a: 1,
241
+ b: 2,
242
+ 1: 3,
243
+ a1: 9,
244
+ bool: true,
245
+ string: 'string',
246
+ };
247
+ expect(calculateDprData(data, 2)).toMatchSnapshot();
248
+ });
249
+ });
250
+ describe('getBase64ScreenshotSize', () => {
251
+ const testCases = [
252
+ { dpr: undefined, description: 'default DPR' },
253
+ { dpr: 2, description: 'DPR 2' },
254
+ ];
255
+ testCases.forEach(({ dpr, description }) => {
256
+ it(`should get the screenshot size with ${description}`, () => {
257
+ expect(getBase64ScreenshotSize(IMAGE_STRING, dpr)).toMatchSnapshot();
258
+ });
259
+ });
260
+ });
261
+ describe('getDevicePixelRatio', () => {
262
+ const testCases = [
263
+ { deviceSize: { width: 32, height: 64 }, expected: 1, description: 'equal width' },
264
+ { deviceSize: { width: 16, height: 32 }, expected: 2, description: 'double width' },
265
+ { deviceSize: { width: 17, height: 32 }, expected: 'rounded', description: 'rounded result' },
266
+ ];
267
+ testCases.forEach(({ deviceSize, description }) => {
268
+ it(`should return correct ratio for ${description}`, () => {
269
+ expect(getDevicePixelRatio(IMAGE_STRING, deviceSize)).toMatchSnapshot();
270
+ });
271
+ });
272
+ });
273
+ describe('getIosBezelImageNames', () => {
274
+ const supportedDevices = [
275
+ 'iphonex', 'iphonexs', 'iphonexsmax', 'iphonexr', 'iphone11', 'iphone11pro', 'iphone11promax',
276
+ 'iphone12', 'iphone12mini', 'iphone12pro', 'iphone12promax', 'iphone13', 'iphone13mini',
277
+ 'iphone13pro', 'iphone13promax', 'iphone14', 'iphone14plus', 'iphone14pro', 'iphone14promax',
278
+ 'iphone15', 'ipadmini', 'ipadair', 'ipadpro11', 'ipadpro129',
279
+ ];
280
+ supportedDevices.forEach((device) => {
281
+ it(`should return bezel image names for "${device}"`, () => {
282
+ expect(getIosBezelImageNames(device)).toMatchSnapshot();
283
+ });
284
+ });
285
+ it('should throw an error for unsupported device names', () => {
286
+ expect(() => getIosBezelImageNames('unsupportedDevice')).toThrowErrorMatchingSnapshot();
287
+ });
288
+ });
289
+ describe('isObject', () => {
290
+ const testCases = [
291
+ { value: {}, expected: true, description: 'plain object' },
292
+ { value: () => { }, expected: true, description: 'function' },
293
+ { value: [], expected: true, description: 'array' },
294
+ { value: null, expected: false, description: 'null' },
295
+ { value: undefined, expected: false, description: 'undefined' },
296
+ { value: 'string', expected: false, description: 'string' },
297
+ { value: 123, expected: false, description: 'number' },
298
+ { value: true, expected: false, description: 'boolean' },
299
+ ];
300
+ testCases.forEach(({ value, expected, description }) => {
301
+ it(`should return ${expected} for ${description}`, () => {
302
+ expect(isObject(value)).toBe(expected);
303
+ });
304
+ });
305
+ });
306
+ describe('process.argv dependent functions', () => {
307
+ const originalArgv = [...process.argv];
308
+ const processArgvTests = [
309
+ { functionName: 'isStorybook', testFunction: isStorybook, flag: '--storybook' },
310
+ { functionName: 'updateVisualBaseline', testFunction: updateVisualBaseline, flag: '--update-visual-baseline' },
311
+ ];
312
+ afterEach(() => {
313
+ process.argv = [...originalArgv];
314
+ });
315
+ processArgvTests.forEach(({ functionName, testFunction, flag }) => {
316
+ describe(functionName, () => {
317
+ it(`should return true when "${flag}" is in process.argv`, () => {
318
+ process.argv.push(flag);
319
+ expect(testFunction()).toBe(true);
320
+ });
321
+ it(`should return false when "${flag}" is not in process.argv`, () => {
322
+ process.argv = originalArgv.filter(arg => arg !== flag);
323
+ expect(testFunction()).toBe(false);
324
+ });
325
+ });
326
+ });
327
+ });
328
+ describe('getMobileScreenSize', () => {
329
+ let mockBrowserInstance;
330
+ beforeEach(() => {
331
+ mockBrowserInstance = createMockBrowserInstance();
332
+ });
333
+ const testCases = [
334
+ {
335
+ description: 'iOS in portrait',
336
+ isIOS: true,
337
+ orientation: 'PORTRAIT',
338
+ mockResponse: { screenSize: { width: 390, height: 844 } },
339
+ expected: { width: 390, height: 844 }
340
+ },
341
+ {
342
+ description: 'iOS in landscape',
343
+ isIOS: true,
344
+ orientation: 'LANDSCAPE',
345
+ mockResponse: { screenSize: { width: 390, height: 844 } },
346
+ expected: { width: 844, height: 390 }
347
+ },
348
+ {
349
+ description: 'Android in portrait',
350
+ isIOS: false,
351
+ orientation: 'PORTRAIT',
352
+ mockResponse: { realDisplaySize: '1080x2400' },
353
+ expected: { width: 1080, height: 2400 }
354
+ }
355
+ ];
356
+ testCases.forEach(({ description, isIOS, orientation, mockResponse, expected }) => {
357
+ it(`should return correct screen size for ${description}`, async () => {
358
+ vi.mocked(mockBrowserInstance.getOrientation).mockResolvedValue(orientation);
359
+ vi.mocked(mockBrowserInstance.execute).mockResolvedValue(mockResponse);
360
+ const result = await getMobileScreenSize({
361
+ browserInstance: mockBrowserInstance,
362
+ isIOS,
363
+ isNativeContext: true
364
+ });
365
+ expect(result).toEqual(expected);
366
+ });
367
+ });
368
+ it('should fall back to web context for iOS', async () => {
369
+ vi.mocked(mockBrowserInstance.execute)
370
+ .mockRejectedValueOnce(new Error('Missing screenSize'))
371
+ .mockResolvedValueOnce({ width: 800, height: 1200 });
372
+ vi.mocked(mockBrowserInstance.getOrientation).mockResolvedValue('PORTRAIT');
373
+ const result = await getMobileScreenSize({
374
+ browserInstance: mockBrowserInstance,
375
+ isIOS: true,
376
+ isNativeContext: false
377
+ });
378
+ expect(result).toEqual({ width: 800, height: 1200 });
379
+ });
380
+ it('should fall back to getWindowSize in native context', async () => {
381
+ vi.mocked(mockBrowserInstance.execute).mockRejectedValue(new Error('Boom'));
382
+ vi.mocked(mockBrowserInstance.getOrientation).mockResolvedValue('PORTRAIT');
383
+ vi.mocked(mockBrowserInstance.getWindowSize).mockResolvedValue({ width: 123, height: 456 });
384
+ const result = await getMobileScreenSize({
385
+ browserInstance: mockBrowserInstance,
386
+ isIOS: true,
387
+ isNativeContext: true
388
+ });
389
+ expect(result).toEqual({ width: 123, height: 456 });
390
+ });
391
+ });
392
+ describe('loadBase64Html', () => {
393
+ let mockBrowserInstance;
394
+ beforeEach(() => {
395
+ mockBrowserInstance = createMockBrowserInstance();
396
+ });
397
+ it('should call browserInstance.execute with blob URL creation for all platforms', async () => {
398
+ await loadBase64Html({ browserInstance: mockBrowserInstance, isIOS: false });
399
+ expect(mockBrowserInstance.execute).toHaveBeenCalledTimes(1);
400
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith(expect.any(Function), expect.any(String));
401
+ });
402
+ it('should call browserInstance.execute with blob URL creation and checkMetaTag for iOS', async () => {
403
+ await loadBase64Html({ browserInstance: mockBrowserInstance, isIOS: true });
404
+ expect(mockBrowserInstance.execute).toHaveBeenCalledTimes(2);
405
+ expect(mockBrowserInstance.execute).toHaveBeenNthCalledWith(1, expect.any(Function), expect.any(String));
406
+ expect(mockBrowserInstance.execute).toHaveBeenNthCalledWith(2, checkMetaTag);
407
+ });
408
+ });
409
+ describe('executeNativeClick', () => {
410
+ let mockBrowserInstance;
411
+ const coords = { x: 100, y: 200 };
412
+ beforeEach(() => {
413
+ mockBrowserInstance = createMockBrowserInstance();
414
+ });
415
+ it('should call browserInstance.execute with "mobile: tap" on iOS', async () => {
416
+ await executeNativeClick({ browserInstance: mockBrowserInstance, isIOS: true, ...coords });
417
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith('mobile: tap', coords);
418
+ });
419
+ it('should call browserInstance.execute with "mobile: clickGesture" on Android (Appium 2)', async () => {
420
+ await executeNativeClick({ browserInstance: mockBrowserInstance, isIOS: false, ...coords });
421
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith('mobile: clickGesture', coords);
422
+ });
423
+ it('should fall back to "doubleClickGesture" when clickGesture fails (Appium 1)', async () => {
424
+ vi.mocked(mockBrowserInstance.execute)
425
+ .mockRejectedValueOnce(new Error('WebDriverError: Unknown mobile command: clickGesture'))
426
+ .mockResolvedValueOnce(undefined);
427
+ await executeNativeClick({ browserInstance: mockBrowserInstance, isIOS: false, ...coords });
428
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith('mobile: clickGesture', coords);
429
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith('mobile: doubleClickGesture', coords);
430
+ });
431
+ it('should throw the error if it\'s not a known Appium command error', async () => {
432
+ vi.mocked(mockBrowserInstance.execute).mockRejectedValue(new Error('Some unexpected error'));
433
+ await expect(executeNativeClick({ browserInstance: mockBrowserInstance, isIOS: false, ...coords }))
434
+ .rejects
435
+ .toThrowError('Some unexpected error');
436
+ });
437
+ });
438
+ describe('getMobileViewPortPosition', () => {
439
+ let mockBrowserInstance;
440
+ const baseOptions = {
441
+ isAndroid: false,
442
+ isIOS: true,
443
+ isNativeContext: false,
444
+ nativeWebScreenshot: true,
445
+ screenHeight: 800,
446
+ screenWidth: 400,
447
+ initialDeviceRectangles: DEVICE_RECTANGLES,
448
+ };
449
+ beforeEach(() => {
450
+ mockBrowserInstance = createMockBrowserInstance();
451
+ });
452
+ it('should return correct device rectangles for iOS WebView flow', async () => {
453
+ vi.mocked(mockBrowserInstance.execute)
454
+ .mockResolvedValueOnce(undefined) // loadBase64Html
455
+ .mockResolvedValueOnce(undefined) // checkMetaTag
456
+ .mockResolvedValueOnce(undefined) // injectWebviewOverlay
457
+ .mockResolvedValueOnce(undefined) // executeNativeClick
458
+ .mockResolvedValueOnce({ x: 150, y: 300, width: 100, height: 100 }); // getMobileWebviewClickAndDimensions
459
+ const result = await getMobileViewPortPosition({
460
+ browserInstance: mockBrowserInstance,
461
+ ...baseOptions,
462
+ });
463
+ expect(mockBrowserInstance.getUrl).toHaveBeenCalled();
464
+ expect(mockBrowserInstance.url).toHaveBeenCalledWith('http://example.com');
465
+ expect(mockBrowserInstance.execute).toHaveBeenCalledWith(getMobileWebviewClickAndDimensions, '[data-test="ics-overlay"]');
466
+ expect(result).toMatchSnapshot();
467
+ });
468
+ it('should return initialDeviceRectangles if not WebView (native context)', async () => {
469
+ const result = await getMobileViewPortPosition({
470
+ browserInstance: mockBrowserInstance,
471
+ ...baseOptions,
472
+ isNativeContext: true,
473
+ });
474
+ expect(result).toEqual(DEVICE_RECTANGLES);
475
+ expect(mockBrowserInstance.execute).not.toHaveBeenCalled();
476
+ });
477
+ it('should return initialDeviceRectangles if Android + not nativeWebScreenshot', async () => {
478
+ const result = await getMobileViewPortPosition({
479
+ browserInstance: mockBrowserInstance,
480
+ ...baseOptions,
481
+ isAndroid: true,
482
+ isIOS: false,
483
+ nativeWebScreenshot: false,
484
+ });
485
+ expect(result).toEqual(DEVICE_RECTANGLES);
486
+ expect(mockBrowserInstance.getUrl).not.toHaveBeenCalled();
487
+ });
488
+ });
489
+ describe('canUseBidiScreenshot', () => {
490
+ it('should return true when both required methods are functions', () => {
491
+ const mockBrowserInstance = createMockBrowserInstance();
492
+ expect(canUseBidiScreenshot(mockBrowserInstance)).toBe(true);
493
+ });
494
+ it('should return false if browsingContextCaptureScreenshot is missing', () => {
495
+ const mockBrowserInstance = createMockBrowserInstance();
496
+ delete mockBrowserInstance.browsingContextCaptureScreenshot;
497
+ expect(canUseBidiScreenshot(mockBrowserInstance)).toBe(false);
498
+ });
499
+ it('should return false if getWindowHandle is missing', () => {
500
+ const mockBrowserInstance = createMockBrowserInstance();
501
+ delete mockBrowserInstance.getWindowHandle;
502
+ expect(canUseBidiScreenshot(mockBrowserInstance)).toBe(false);
503
+ });
504
+ it('should return false if either is not a function', () => {
505
+ const mockBrowserInstance = createMockBrowserInstance();
506
+ mockBrowserInstance.browsingContextCaptureScreenshot = 'notAFunction';
507
+ expect(canUseBidiScreenshot(mockBrowserInstance)).toBe(false);
508
+ });
509
+ });
510
+ describe('logAllDeprecatedCompareOptions', () => {
511
+ const allDeprecatedOptions = {
512
+ blockOutSideBar: true,
513
+ blockOutStatusBar: true,
514
+ blockOutToolBar: true,
515
+ createJsonReportFiles: true,
516
+ diffPixelBoundingBoxProximity: 5,
517
+ ignoreAlpha: true,
518
+ ignoreAntialiasing: true,
519
+ ignoreColors: true,
520
+ ignoreLess: true,
521
+ ignoreNothing: true,
522
+ rawMisMatchPercentage: true,
523
+ returnAllCompareData: true,
524
+ saveAboveTolerance: 100,
525
+ scaleImagesToSameSize: true,
526
+ };
527
+ it('should log a deprecation warning for each deprecated key', () => {
528
+ const warnSpy = vi.spyOn(log, 'warn').mockImplementation(() => { });
529
+ logAllDeprecatedCompareOptions(allDeprecatedOptions);
530
+ expect(warnSpy).toHaveBeenCalledTimes(1);
531
+ expect(warnSpy.mock.calls[0][0]).toMatchSnapshot();
532
+ });
533
+ it('should return a subset of CompareOptions with deprecated keys only', () => {
534
+ const result = logAllDeprecatedCompareOptions(allDeprecatedOptions);
535
+ expect(result).toMatchSnapshot();
536
+ });
537
+ });
538
+ describe('getMethodOrWicOption', () => {
539
+ const defaultOptions = { foo: 'bar', count: 42, isEnabled: true };
540
+ const testCases = [
541
+ { method: { foo: 'baz' }, key: 'foo', expected: 'baz', description: 'value from method if defined' },
542
+ { method: undefined, key: 'count', expected: 42, description: 'value from wic if method is undefined' },
543
+ { method: { foo: undefined }, key: 'foo', expected: 'bar', description: 'value from wic if key in method is undefined' },
544
+ { method: { isEnabled: false }, key: 'isEnabled', expected: false, description: 'boolean value from method if defined' },
545
+ { method: {}, key: 'count', expected: 42, description: 'value from wic for missing key in method' },
546
+ ];
547
+ testCases.forEach(({ method, key, expected, description }) => {
548
+ it(`should return ${description}`, () => {
549
+ const result = getMethodOrWicOption(method, defaultOptions, key);
550
+ expect(result).toBe(expected);
551
+ });
552
+ });
553
+ });
554
+ describe('getBooleanOption', () => {
555
+ const testCases = [
556
+ { options: { autoElementScroll: true }, key: 'autoElementScroll', defaultValue: false, expected: true, description: 'boolean value when property exists' },
557
+ { options: {}, key: 'disableBlinkingCursor', defaultValue: true, expected: true, description: 'default value when property does not exist' },
558
+ { options: { autoElementScroll: 'truthy' }, key: 'autoElementScroll', defaultValue: false, expected: true, description: 'truthy values to true' },
559
+ { options: { autoElementScroll: 0 }, key: 'autoElementScroll', defaultValue: true, expected: false, description: 'falsy values to false' },
560
+ { options: { autoElementScroll: undefined }, key: 'autoElementScroll', defaultValue: true, expected: true, description: 'default when property is undefined' },
561
+ { options: { autoElementScroll: null }, key: 'autoElementScroll', defaultValue: false, expected: false, description: 'default when property is null' },
562
+ ];
563
+ testCases.forEach(({ options, key, defaultValue, expected, description }) => {
564
+ it(`should return ${description}`, () => {
565
+ const result = getBooleanOption(options, key, defaultValue);
566
+ expect(result).toBe(expected);
567
+ });
568
+ });
569
+ });
570
+ describe('createConditionalProperty', () => {
571
+ const testCases = [
572
+ { condition: true, key: 'testKey', value: 'testValue', expected: { testKey: 'testValue' }, description: 'object with property when condition is true' },
573
+ { condition: false, key: 'testKey', value: 'testValue', expected: {}, description: 'empty object when condition is false' },
574
+ { condition: true, key: 'number', value: 42, expected: { number: 42 }, description: 'number value' },
575
+ { condition: true, key: 'boolean', value: false, expected: { boolean: false }, description: 'boolean value' },
576
+ { condition: true, key: 'object', value: { nested: 'value' }, expected: { object: { nested: 'value' } }, description: 'object value' },
577
+ { condition: true, key: 'undefined', value: undefined, expected: { undefined: undefined }, description: 'undefined value' },
578
+ { condition: true, key: 'null', value: null, expected: { null: null }, description: 'null value' },
579
+ ];
580
+ testCases.forEach(({ condition, key, value, expected, description }) => {
581
+ it(`should return ${description}`, () => {
582
+ const result = createConditionalProperty(condition, key, value);
583
+ expect(result).toEqual(expected);
584
+ });
585
+ });
586
+ it('should always return empty object when condition is false regardless of value', () => {
587
+ const values = ['value', null, undefined, { complex: 'object' }];
588
+ values.forEach(value => {
589
+ expect(createConditionalProperty(false, 'key', value)).toEqual({});
590
+ });
591
+ });
592
+ });
593
+ describe('hasResizeDimensions', () => {
594
+ it('should return true when any value is non-zero', () => {
595
+ expect(hasResizeDimensions({ top: 10, right: 0, bottom: 0, left: 0 })).toBe(true);
596
+ expect(hasResizeDimensions({ top: 0, right: 0, bottom: 0, left: -5 })).toBe(true);
597
+ });
598
+ it('should return false when all values are zero', () => {
599
+ expect(hasResizeDimensions({ top: 0, right: 0, bottom: 0, left: 0 })).toBe(false);
600
+ });
601
+ it('should return falsy when input is falsy', () => {
602
+ expect(hasResizeDimensions(null)).toBe(null);
603
+ expect(hasResizeDimensions(undefined)).toBe(undefined);
604
+ expect(hasResizeDimensions(false)).toBe(false);
605
+ });
606
+ it('should return false for empty object', () => {
607
+ expect(hasResizeDimensions({})).toBe(false);
608
+ });
609
+ });
610
+ describe('extractCommonCheckVariables', () => {
611
+ const baseFolders = {
612
+ actualFolder: '/path/to/actual',
613
+ baselineFolder: '/path/to/baseline',
614
+ diffFolder: '/path/to/diff',
615
+ };
616
+ const baseInstanceData = {
617
+ browserName: 'chrome',
618
+ deviceName: 'iPhone 12',
619
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
620
+ isAndroid: false,
621
+ isMobile: true,
622
+ nativeWebScreenshot: true,
623
+ };
624
+ const baseWicOptions = {
625
+ autoSaveBaseline: true,
626
+ savePerInstance: false,
627
+ };
628
+ it('should extract all required common variables', () => {
629
+ const options = {
630
+ folders: baseFolders,
631
+ instanceData: baseInstanceData,
632
+ wicOptions: baseWicOptions,
633
+ };
634
+ const result = extractCommonCheckVariables(options);
635
+ expect(result).toEqual({
636
+ actualFolder: '/path/to/actual',
637
+ baselineFolder: '/path/to/baseline',
638
+ diffFolder: '/path/to/diff',
639
+ browserName: 'chrome',
640
+ deviceName: 'iPhone 12',
641
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
642
+ isAndroid: false,
643
+ isMobile: true,
644
+ isAndroidNativeWebScreenshot: true,
645
+ autoSaveBaseline: true,
646
+ savePerInstance: false,
647
+ });
648
+ });
649
+ it('should include optional fields when they exist', () => {
650
+ const options = {
651
+ folders: baseFolders,
652
+ instanceData: {
653
+ ...baseInstanceData,
654
+ platformName: 'iOS',
655
+ isIOS: true,
656
+ },
657
+ wicOptions: {
658
+ ...baseWicOptions,
659
+ isHybridApp: true,
660
+ },
661
+ };
662
+ const result = extractCommonCheckVariables(options);
663
+ expect(result).toEqual({
664
+ actualFolder: '/path/to/actual',
665
+ baselineFolder: '/path/to/baseline',
666
+ diffFolder: '/path/to/diff',
667
+ browserName: 'chrome',
668
+ deviceName: 'iPhone 12',
669
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
670
+ isAndroid: false,
671
+ isMobile: true,
672
+ isAndroidNativeWebScreenshot: true,
673
+ platformName: 'iOS',
674
+ isIOS: true,
675
+ autoSaveBaseline: true,
676
+ savePerInstance: false,
677
+ isHybridApp: true,
678
+ });
679
+ });
680
+ it('should exclude optional fields when they are falsy or undefined', () => {
681
+ const options = {
682
+ folders: baseFolders,
683
+ instanceData: {
684
+ ...baseInstanceData,
685
+ platformName: null,
686
+ isIOS: undefined,
687
+ },
688
+ wicOptions: {
689
+ ...baseWicOptions,
690
+ isHybridApp: undefined,
691
+ },
692
+ };
693
+ const result = extractCommonCheckVariables(options);
694
+ expect(result).toEqual({
695
+ actualFolder: '/path/to/actual',
696
+ baselineFolder: '/path/to/baseline',
697
+ diffFolder: '/path/to/diff',
698
+ browserName: 'chrome',
699
+ deviceName: 'iPhone 12',
700
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
701
+ isAndroid: false,
702
+ isMobile: true,
703
+ isAndroidNativeWebScreenshot: true,
704
+ autoSaveBaseline: true,
705
+ savePerInstance: false,
706
+ });
707
+ });
708
+ it('should handle partial optional fields correctly', () => {
709
+ const options = {
710
+ folders: baseFolders,
711
+ instanceData: {
712
+ ...baseInstanceData,
713
+ platformName: 'Android',
714
+ isIOS: false,
715
+ },
716
+ wicOptions: baseWicOptions,
717
+ };
718
+ const result = extractCommonCheckVariables(options);
719
+ expect(result).toEqual({
720
+ actualFolder: '/path/to/actual',
721
+ baselineFolder: '/path/to/baseline',
722
+ diffFolder: '/path/to/diff',
723
+ browserName: 'chrome',
724
+ deviceName: 'iPhone 12',
725
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
726
+ isAndroid: false,
727
+ isMobile: true,
728
+ isAndroidNativeWebScreenshot: true,
729
+ platformName: 'Android',
730
+ isIOS: false,
731
+ autoSaveBaseline: true,
732
+ savePerInstance: false,
733
+ });
734
+ });
735
+ it('should handle Android device correctly', () => {
736
+ const options = {
737
+ folders: baseFolders,
738
+ instanceData: {
739
+ browserName: 'chromium',
740
+ deviceName: 'Pixel 4',
741
+ deviceRectangles: { screenSize: { width: 412, height: 869 } },
742
+ isAndroid: true,
743
+ isMobile: true,
744
+ nativeWebScreenshot: false,
745
+ },
746
+ wicOptions: baseWicOptions,
747
+ };
748
+ const result = extractCommonCheckVariables(options);
749
+ expect(result.isAndroid).toBe(true);
750
+ expect(result.isAndroidNativeWebScreenshot).toBe(false);
751
+ expect(result.browserName).toBe('chromium');
752
+ expect(result.deviceName).toBe('Pixel 4');
753
+ });
754
+ });
755
+ describe('buildFolderOptions', () => {
756
+ it('should build folder options from common check variables', () => {
757
+ const commonCheckVariables = {
758
+ actualFolder: '/path/to/actual',
759
+ baselineFolder: '/path/to/baseline',
760
+ diffFolder: '/path/to/diff',
761
+ browserName: 'chrome',
762
+ deviceName: 'iPhone 12',
763
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
764
+ isAndroid: false,
765
+ isMobile: true,
766
+ isAndroidNativeWebScreenshot: true,
767
+ autoSaveBaseline: true,
768
+ savePerInstance: false,
769
+ };
770
+ const result = buildFolderOptions({ commonCheckVariables });
771
+ expect(result).toMatchSnapshot();
772
+ });
773
+ it('should handle all properties correctly', () => {
774
+ const commonCheckVariables = {
775
+ actualFolder: '/test/actual',
776
+ baselineFolder: '/test/baseline',
777
+ diffFolder: '/test/diff',
778
+ browserName: 'firefox',
779
+ deviceName: 'Desktop',
780
+ deviceRectangles: { screenSize: { width: 1920, height: 1080 } },
781
+ isAndroid: true,
782
+ isMobile: false,
783
+ isAndroidNativeWebScreenshot: false,
784
+ autoSaveBaseline: false,
785
+ savePerInstance: true,
786
+ platformName: 'Android',
787
+ isIOS: false,
788
+ isHybridApp: true,
789
+ };
790
+ const result = buildFolderOptions({ commonCheckVariables });
791
+ expect(result).toMatchSnapshot();
792
+ });
793
+ });
794
+ describe('buildBaseExecuteCompareOptions', () => {
795
+ const baseCommonCheckVariables = {
796
+ actualFolder: '/path/to/actual',
797
+ baselineFolder: '/path/to/baseline',
798
+ diffFolder: '/path/to/diff',
799
+ browserName: 'chrome',
800
+ deviceName: 'iPhone 12',
801
+ deviceRectangles: { screenSize: { width: 390, height: 844 } },
802
+ isAndroid: false,
803
+ isMobile: true,
804
+ isAndroidNativeWebScreenshot: true,
805
+ autoSaveBaseline: true,
806
+ savePerInstance: false,
807
+ };
808
+ const baseWicCompareOptions = {
809
+ ignoreAlpha: false,
810
+ ignoreAntialiasing: false,
811
+ blockOutSideBar: true,
812
+ blockOutStatusBar: true,
813
+ blockOutToolBar: true,
814
+ };
815
+ const baseMethodCompareOptions = {
816
+ ignoreColors: false,
817
+ scaleImagesToSameSize: false,
818
+ };
819
+ it('should build base execute compare options', () => {
820
+ const result = buildBaseExecuteCompareOptions({
821
+ commonCheckVariables: baseCommonCheckVariables,
822
+ wicCompareOptions: baseWicCompareOptions,
823
+ methodCompareOptions: baseMethodCompareOptions,
824
+ devicePixelRatio: 2,
825
+ fileName: 'test-screenshot.png',
826
+ });
827
+ expect(result).toMatchSnapshot();
828
+ });
829
+ it('should handle element screenshot correctly (blockOut options set to false)', () => {
830
+ const result = buildBaseExecuteCompareOptions({
831
+ commonCheckVariables: baseCommonCheckVariables,
832
+ wicCompareOptions: baseWicCompareOptions,
833
+ methodCompareOptions: baseMethodCompareOptions,
834
+ devicePixelRatio: 2,
835
+ fileName: 'test-element.png',
836
+ isElementScreenshot: true,
837
+ });
838
+ expect(result.compareOptions.wic.blockOutSideBar).toBe(false);
839
+ expect(result.compareOptions.wic.blockOutStatusBar).toBe(false);
840
+ expect(result.compareOptions.wic.blockOutToolBar).toBe(false);
841
+ expect(result).toMatchSnapshot();
842
+ });
843
+ it('should include optional properties from commonCheckVariables', () => {
844
+ const commonCheckVariablesWithOptional = {
845
+ ...baseCommonCheckVariables,
846
+ platformName: 'iOS',
847
+ isIOS: true,
848
+ isHybridApp: true,
849
+ };
850
+ const result = buildBaseExecuteCompareOptions({
851
+ commonCheckVariables: commonCheckVariablesWithOptional,
852
+ wicCompareOptions: baseWicCompareOptions,
853
+ methodCompareOptions: baseMethodCompareOptions,
854
+ devicePixelRatio: 2,
855
+ fileName: 'test-screenshot.png',
856
+ });
857
+ expect(result.platformName).toBe('iOS');
858
+ expect(result.isIOS).toBe(true);
859
+ expect(result.isHybridApp).toBe(true);
860
+ expect(result).toMatchSnapshot();
861
+ });
862
+ it('should add additional properties correctly', () => {
863
+ const additionalProperties = {
864
+ ignoreRegions: [{ x: 0, y: 0, width: 100, height: 100 }],
865
+ customProperty: 'test-value',
866
+ };
867
+ const result = buildBaseExecuteCompareOptions({
868
+ commonCheckVariables: baseCommonCheckVariables,
869
+ wicCompareOptions: baseWicCompareOptions,
870
+ methodCompareOptions: baseMethodCompareOptions,
871
+ devicePixelRatio: 2,
872
+ fileName: 'test-screenshot.png',
873
+ additionalProperties,
874
+ });
875
+ expect(result.ignoreRegions).toEqual([{ x: 0, y: 0, width: 100, height: 100 }]);
876
+ expect(result.customProperty).toBe('test-value');
877
+ expect(result).toMatchSnapshot();
878
+ });
879
+ it('should handle Android device correctly', () => {
880
+ const androidCommonCheckVariables = {
881
+ ...baseCommonCheckVariables,
882
+ isAndroid: true,
883
+ isMobile: true,
884
+ isAndroidNativeWebScreenshot: false,
885
+ platformName: 'Android',
886
+ };
887
+ const result = buildBaseExecuteCompareOptions({
888
+ commonCheckVariables: androidCommonCheckVariables,
889
+ wicCompareOptions: baseWicCompareOptions,
890
+ methodCompareOptions: baseMethodCompareOptions,
891
+ devicePixelRatio: 1.5,
892
+ fileName: 'test-android.png',
893
+ });
894
+ expect(result.isAndroid).toBe(true);
895
+ expect(result.isAndroidNativeWebScreenshot).toBe(false);
896
+ expect(result.platformName).toBe('Android');
897
+ expect(result).toMatchSnapshot();
898
+ });
899
+ });
900
+ });