creevey 0.9.0-non-webpack.2 → 0.9.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 (533) hide show
  1. package/.yarnrc.yml +1 -0
  2. package/AUTHORS +15 -15
  3. package/CHANGELOG.md +1326 -1275
  4. package/LICENSE +21 -21
  5. package/README.md +4 -3
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +5 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/client/addon/components/Addon.d.ts +8 -0
  10. package/dist/client/addon/components/Addon.js +57 -0
  11. package/dist/client/addon/components/Addon.js.map +1 -0
  12. package/{lib/types → dist}/client/addon/components/Icons.d.ts +7 -7
  13. package/dist/client/addon/components/Icons.js +18 -0
  14. package/dist/client/addon/components/Icons.js.map +1 -0
  15. package/{lib/types → dist}/client/addon/components/Panel.d.ts +9 -9
  16. package/dist/client/addon/components/Panel.js +32 -0
  17. package/dist/client/addon/components/Panel.js.map +1 -0
  18. package/{lib/types → dist}/client/addon/components/TestSelect.d.ts +8 -8
  19. package/dist/client/addon/components/TestSelect.js +33 -0
  20. package/dist/client/addon/components/TestSelect.js.map +1 -0
  21. package/dist/client/addon/components/Tools.d.ts +6 -0
  22. package/dist/client/addon/components/Tools.js +89 -0
  23. package/dist/client/addon/components/Tools.js.map +1 -0
  24. package/{lib/types/client/addon/Manager.d.ts → dist/client/addon/controller.d.ts} +38 -37
  25. package/dist/client/addon/controller.js +208 -0
  26. package/dist/client/addon/controller.js.map +1 -0
  27. package/dist/client/addon/decorator.d.ts +1 -0
  28. package/dist/client/addon/decorator.js +6 -0
  29. package/dist/client/addon/decorator.js.map +1 -0
  30. package/dist/client/addon/index.d.ts +2 -0
  31. package/dist/client/addon/index.js +19 -0
  32. package/dist/client/addon/index.js.map +1 -0
  33. package/dist/client/addon/manager.d.ts +1 -0
  34. package/dist/client/addon/manager.js +41 -0
  35. package/dist/client/addon/manager.js.map +1 -0
  36. package/dist/client/addon/preset.d.ts +2 -0
  37. package/dist/client/addon/preset.js +6 -0
  38. package/dist/client/addon/preset.js.map +1 -0
  39. package/dist/client/addon/preview.d.ts +4 -0
  40. package/dist/client/addon/preview.js +8 -0
  41. package/dist/client/addon/preview.js.map +1 -0
  42. package/{lib/types → dist}/client/addon/readyForCapture.d.ts +6 -6
  43. package/dist/client/addon/readyForCapture.js +7 -0
  44. package/dist/client/addon/readyForCapture.js.map +1 -0
  45. package/{lib/types → dist}/client/addon/utils.d.ts +3 -2
  46. package/dist/client/addon/utils.js +27 -0
  47. package/dist/client/addon/utils.js.map +1 -0
  48. package/{lib/types → dist}/client/addon/withCreevey.d.ts +25 -24
  49. package/dist/client/addon/withCreevey.js +286 -0
  50. package/dist/client/addon/withCreevey.js.map +1 -0
  51. package/dist/client/shared/components/ImagesView/BlendView.d.ts +5 -0
  52. package/dist/client/shared/components/ImagesView/BlendView.js +74 -0
  53. package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -0
  54. package/dist/client/shared/components/ImagesView/ImagesView.d.ts +9 -0
  55. package/dist/client/shared/components/ImagesView/ImagesView.js +46 -0
  56. package/dist/client/shared/components/ImagesView/ImagesView.js.map +1 -0
  57. package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +5 -0
  58. package/dist/client/shared/components/ImagesView/SideBySideView.js +121 -0
  59. package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -0
  60. package/dist/client/shared/components/ImagesView/SlideView.d.ts +5 -0
  61. package/dist/client/shared/components/ImagesView/SlideView.js +136 -0
  62. package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -0
  63. package/dist/client/shared/components/ImagesView/SwapView.d.ts +5 -0
  64. package/dist/client/shared/components/ImagesView/SwapView.js +72 -0
  65. package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -0
  66. package/{lib/types/client/shared/components/ImagesView/ImagesView.d.ts → dist/client/shared/components/ImagesView/common.d.ts} +15 -24
  67. package/dist/client/shared/components/ImagesView/common.js +14 -0
  68. package/dist/client/shared/components/ImagesView/common.js.map +1 -0
  69. package/dist/client/shared/components/ImagesView/index.d.ts +5 -0
  70. package/dist/client/shared/components/ImagesView/index.js +14 -0
  71. package/dist/client/shared/components/ImagesView/index.js.map +1 -0
  72. package/{lib/types → dist}/client/shared/components/PageFooter/PageFooter.d.ts +8 -8
  73. package/dist/client/shared/components/PageFooter/PageFooter.js +25 -0
  74. package/dist/client/shared/components/PageFooter/PageFooter.js.map +1 -0
  75. package/{lib/types → dist}/client/shared/components/PageFooter/Paging.d.ts +7 -7
  76. package/dist/client/shared/components/PageFooter/Paging.js +68 -0
  77. package/dist/client/shared/components/PageFooter/Paging.js.map +1 -0
  78. package/{lib/types → dist}/client/shared/components/PageHeader/ImagePreview.d.ts +14 -12
  79. package/dist/client/shared/components/PageHeader/ImagePreview.js +61 -0
  80. package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -0
  81. package/{lib/types → dist}/client/shared/components/PageHeader/PageHeader.d.ts +14 -16
  82. package/dist/client/shared/components/PageHeader/PageHeader.js +86 -0
  83. package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -0
  84. package/{lib/types → dist}/client/shared/components/ResultsPage.d.ts +18 -18
  85. package/dist/client/shared/components/ResultsPage.js +95 -0
  86. package/dist/client/shared/components/ResultsPage.js.map +1 -0
  87. package/{lib/types → dist}/client/shared/creeveyClientApi.d.ts +9 -9
  88. package/dist/client/shared/creeveyClientApi.js +53 -0
  89. package/dist/client/shared/creeveyClientApi.js.map +1 -0
  90. package/{lib/types → dist}/client/shared/helpers.d.ts +46 -46
  91. package/dist/client/shared/helpers.js +381 -0
  92. package/dist/client/shared/helpers.js.map +1 -0
  93. package/{lib/types → dist}/client/shared/viewMode.d.ts +4 -4
  94. package/dist/client/shared/viewMode.js +11 -0
  95. package/dist/client/shared/viewMode.js.map +1 -0
  96. package/dist/client/web/202.js +1 -0
  97. package/dist/client/web/270.js +43 -0
  98. package/dist/client/web/752.js +1 -0
  99. package/{lib/types → dist}/client/web/CreeveyApp.d.ts +11 -11
  100. package/dist/client/web/CreeveyApp.js +130 -0
  101. package/dist/client/web/CreeveyApp.js.map +1 -0
  102. package/{lib/types → dist}/client/web/CreeveyContext.d.ts +11 -11
  103. package/dist/client/web/CreeveyContext.js +17 -0
  104. package/dist/client/web/CreeveyContext.js.map +1 -0
  105. package/dist/client/web/CreeveyLoader.d.ts +3 -0
  106. package/dist/client/web/CreeveyLoader.js +52 -0
  107. package/dist/client/web/CreeveyLoader.js.map +1 -0
  108. package/{lib/types → dist}/client/web/CreeveyView/SideBar/Checkbox.d.ts +22 -19
  109. package/dist/client/web/CreeveyView/SideBar/Checkbox.js +86 -0
  110. package/dist/client/web/CreeveyView/SideBar/Checkbox.js.map +1 -0
  111. package/{lib/types → dist}/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  112. package/dist/client/web/CreeveyView/SideBar/Search.js +125 -0
  113. package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -0
  114. package/{lib/types → dist}/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  115. package/dist/client/web/CreeveyView/SideBar/SideBar.js +101 -0
  116. package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -0
  117. package/{lib/types → dist}/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +12 -12
  118. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +113 -0
  119. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -0
  120. package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +38 -0
  121. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +108 -0
  122. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -0
  123. package/{lib/types → dist}/client/web/CreeveyView/SideBar/TestLink.d.ts +7 -7
  124. package/dist/client/web/CreeveyView/SideBar/TestLink.js +63 -0
  125. package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -0
  126. package/{lib/types → dist}/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +12 -10
  127. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js +52 -0
  128. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js.map +1 -0
  129. package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +11 -0
  130. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js +74 -0
  131. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js.map +1 -0
  132. package/{lib/types → dist}/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  133. package/dist/client/web/CreeveyView/SideBar/Toggle.js +69 -0
  134. package/dist/client/web/CreeveyView/SideBar/Toggle.js.map +1 -0
  135. package/dist/client/web/CreeveyView/SideBar/index.d.ts +1 -0
  136. package/dist/client/web/CreeveyView/SideBar/index.js +6 -0
  137. package/dist/client/web/CreeveyView/SideBar/index.js.map +1 -0
  138. package/{lib/types → dist}/client/web/KeyboardEventsContext.d.ts +15 -13
  139. package/dist/client/web/KeyboardEventsContext.js +116 -0
  140. package/dist/client/web/KeyboardEventsContext.js.map +1 -0
  141. package/{lib/types → dist}/client/web/index.d.ts +4 -4
  142. package/{lib/cjs → dist}/client/web/index.html +28 -19
  143. package/dist/client/web/index.js +75 -0
  144. package/dist/client/web/index.js.map +1 -0
  145. package/dist/client/web/main.js +79 -0
  146. package/{lib/cjs → dist}/client/web/main.js.LICENSE.txt +0 -15
  147. package/{lib/types → dist}/creevey.d.ts +1 -1
  148. package/dist/creevey.js +52 -0
  149. package/dist/creevey.js.map +1 -0
  150. package/dist/index.d.ts +5 -0
  151. package/dist/index.js +24 -0
  152. package/dist/index.js.map +1 -0
  153. package/{lib/types → dist}/server/config.d.ts +4 -4
  154. package/dist/server/config.js +86 -0
  155. package/dist/server/config.js.map +1 -0
  156. package/{lib/types → dist}/server/docker.d.ts +7 -7
  157. package/dist/server/docker.js +122 -0
  158. package/dist/server/docker.js.map +1 -0
  159. package/{lib/types → dist}/server/index.d.ts +2 -2
  160. package/dist/server/index.js +47 -0
  161. package/dist/server/index.js.map +1 -0
  162. package/{lib/types → dist}/server/logger.d.ts +10 -10
  163. package/dist/server/logger.js +25 -0
  164. package/dist/server/logger.js.map +1 -0
  165. package/{lib/types → dist}/server/master/api.d.ts +7 -7
  166. package/dist/server/master/api.js +50 -0
  167. package/dist/server/master/api.js.map +1 -0
  168. package/dist/server/master/index.d.ts +3 -0
  169. package/dist/server/master/index.js +110 -0
  170. package/dist/server/master/index.js.map +1 -0
  171. package/{lib/types → dist}/server/master/master.d.ts +7 -7
  172. package/dist/server/master/master.js +40 -0
  173. package/dist/server/master/master.js.map +1 -0
  174. package/{lib/types → dist}/server/master/pool.d.ts +30 -31
  175. package/dist/server/master/pool.js +186 -0
  176. package/dist/server/master/pool.js.map +1 -0
  177. package/{lib/types → dist}/server/master/runner.d.ts +21 -26
  178. package/dist/server/master/runner.js +172 -0
  179. package/dist/server/master/runner.js.map +1 -0
  180. package/dist/server/master/server.d.ts +2 -0
  181. package/dist/server/master/server.js +114 -0
  182. package/dist/server/master/server.js.map +1 -0
  183. package/{lib/types → dist}/server/messages.d.ts +26 -27
  184. package/dist/server/messages.js +222 -0
  185. package/dist/server/messages.js.map +1 -0
  186. package/{lib/types → dist}/server/selenium/browser.d.ts +19 -17
  187. package/dist/server/selenium/browser.js +637 -0
  188. package/dist/server/selenium/browser.js.map +1 -0
  189. package/dist/server/selenium/index.d.ts +2 -0
  190. package/dist/server/selenium/index.js +19 -0
  191. package/dist/server/selenium/index.js.map +1 -0
  192. package/{lib/types → dist}/server/selenium/selenoid.d.ts +3 -3
  193. package/dist/server/selenium/selenoid.js +120 -0
  194. package/dist/server/selenium/selenoid.js.map +1 -0
  195. package/dist/server/stories.d.ts +3 -0
  196. package/dist/server/stories.js +92 -0
  197. package/dist/server/stories.js.map +1 -0
  198. package/dist/server/storybook/providers/browser.d.ts +2 -0
  199. package/dist/server/storybook/providers/browser.js +60 -0
  200. package/dist/server/storybook/providers/browser.js.map +1 -0
  201. package/dist/server/storybook/providers/hybrid.d.ts +2 -0
  202. package/dist/server/storybook/providers/hybrid.js +59 -0
  203. package/dist/server/storybook/providers/hybrid.js.map +1 -0
  204. package/dist/server/telemetry.d.ts +2 -0
  205. package/dist/server/telemetry.js +196 -0
  206. package/dist/server/telemetry.js.map +1 -0
  207. package/{lib/types → dist}/server/testsFiles/parser.d.ts +8 -12
  208. package/dist/server/testsFiles/parser.js +50 -0
  209. package/dist/server/testsFiles/parser.js.map +1 -0
  210. package/dist/server/update.d.ts +2 -0
  211. package/dist/server/update.js +53 -0
  212. package/dist/server/update.js.map +1 -0
  213. package/dist/server/utils.d.ts +25 -0
  214. package/dist/server/utils.js +157 -0
  215. package/dist/server/utils.js.map +1 -0
  216. package/{lib/types → dist}/server/worker/chai-image.d.ts +5 -6
  217. package/dist/server/worker/chai-image.js +113 -0
  218. package/dist/server/worker/chai-image.js.map +1 -0
  219. package/{lib/types → dist}/server/worker/helpers.d.ts +8 -8
  220. package/dist/server/worker/helpers.js +57 -0
  221. package/dist/server/worker/helpers.js.map +1 -0
  222. package/dist/server/worker/index.d.ts +1 -0
  223. package/dist/server/worker/index.js +6 -0
  224. package/dist/server/worker/index.js.map +1 -0
  225. package/{lib/types → dist}/server/worker/reporter.d.ts +8 -8
  226. package/dist/server/worker/reporter.js +130 -0
  227. package/dist/server/worker/reporter.js.map +1 -0
  228. package/dist/server/worker/worker.d.ts +4 -0
  229. package/dist/server/worker/worker.js +211 -0
  230. package/dist/server/worker/worker.js.map +1 -0
  231. package/{lib/types → dist}/shared/index.d.ts +7 -7
  232. package/dist/shared/index.js +77 -0
  233. package/dist/shared/index.js.map +1 -0
  234. package/{lib/types → dist}/shared/serializeRegExp.d.ts +9 -9
  235. package/dist/shared/serializeRegExp.js +25 -0
  236. package/dist/shared/serializeRegExp.js.map +1 -0
  237. package/{lib/types → dist}/types.d.ts +459 -490
  238. package/dist/types.js +61 -0
  239. package/dist/types.js.map +1 -0
  240. package/docs/config.md +212 -212
  241. package/docs/grid.md +10 -10
  242. package/docs/tests.md +63 -63
  243. package/manager/package.json +3 -0
  244. package/package.json +115 -156
  245. package/preset/README.md +3 -0
  246. package/preset/package.json +3 -0
  247. package/preview/README.md +3 -0
  248. package/preview/package.json +3 -0
  249. package/src/cli.ts +3 -0
  250. package/src/client/addon/components/Addon.tsx +53 -0
  251. package/src/client/addon/components/Icons.tsx +28 -0
  252. package/src/client/addon/components/Panel.tsx +53 -0
  253. package/src/client/addon/components/TestSelect.tsx +48 -0
  254. package/src/client/addon/components/Tools.tsx +93 -0
  255. package/src/client/addon/controller.ts +224 -0
  256. package/src/client/addon/decorator.ts +3 -0
  257. package/src/client/addon/index.ts +2 -0
  258. package/src/client/addon/manager.ts +44 -0
  259. package/src/client/addon/preset.ts +3 -0
  260. package/src/client/addon/preview.ts +7 -0
  261. package/src/client/addon/readyForCapture.ts +9 -0
  262. package/src/client/addon/utils.tsx +24 -0
  263. package/src/client/addon/withCreevey.ts +326 -0
  264. package/src/client/shared/components/ImagesView/BlendView.tsx +71 -0
  265. package/src/client/shared/components/ImagesView/ImagesView.tsx +70 -0
  266. package/src/client/shared/components/ImagesView/SideBySideView.tsx +139 -0
  267. package/src/client/shared/components/ImagesView/SlideView.tsx +146 -0
  268. package/src/client/shared/components/ImagesView/SwapView.tsx +81 -0
  269. package/src/client/shared/components/ImagesView/common.ts +23 -0
  270. package/src/client/shared/components/ImagesView/index.ts +5 -0
  271. package/src/client/shared/components/PageFooter/PageFooter.tsx +44 -0
  272. package/src/client/shared/components/PageFooter/Paging.tsx +105 -0
  273. package/src/client/shared/components/PageHeader/ImagePreview.tsx +82 -0
  274. package/src/client/shared/components/PageHeader/PageHeader.tsx +123 -0
  275. package/src/client/shared/components/ResultsPage.tsx +135 -0
  276. package/src/client/shared/creeveyClientApi.ts +64 -0
  277. package/src/client/shared/helpers.ts +422 -0
  278. package/src/client/shared/viewMode.ts +10 -0
  279. package/src/client/web/CreeveyApp.tsx +177 -0
  280. package/src/client/web/CreeveyContext.tsx +20 -0
  281. package/src/client/web/CreeveyLoader.tsx +56 -0
  282. package/src/client/web/CreeveyView/SideBar/Checkbox.tsx +118 -0
  283. package/src/client/web/CreeveyView/SideBar/Search.tsx +140 -0
  284. package/src/client/web/CreeveyView/SideBar/SideBar.tsx +125 -0
  285. package/src/client/web/CreeveyView/SideBar/SideBarHeader.tsx +138 -0
  286. package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +118 -0
  287. package/src/client/web/CreeveyView/SideBar/TestLink.tsx +67 -0
  288. package/src/client/web/CreeveyView/SideBar/TestStatusIcon.tsx +58 -0
  289. package/src/client/web/CreeveyView/SideBar/TestsStatus.tsx +105 -0
  290. package/src/client/web/CreeveyView/SideBar/Toggle.tsx +85 -0
  291. package/src/client/web/CreeveyView/SideBar/index.ts +1 -0
  292. package/src/client/web/KeyboardEventsContext.tsx +121 -0
  293. package/src/client/web/index.html +28 -0
  294. package/src/client/web/index.tsx +63 -0
  295. package/src/creevey.ts +47 -0
  296. package/src/index.ts +4 -0
  297. package/src/server/config.ts +83 -0
  298. package/src/server/docker.ts +136 -0
  299. package/src/server/index.ts +51 -0
  300. package/{lib/esm/server/logger.js → src/server/logger.ts} +8 -7
  301. package/src/server/master/api.ts +55 -0
  302. package/src/server/master/index.ts +111 -0
  303. package/src/server/master/master.ts +47 -0
  304. package/src/server/master/pool.ts +203 -0
  305. package/src/server/master/runner.ts +189 -0
  306. package/src/server/master/server.ts +124 -0
  307. package/src/server/messages.ts +273 -0
  308. package/src/server/selenium/browser.ts +837 -0
  309. package/src/server/selenium/index.ts +2 -0
  310. package/src/server/selenium/selenoid.ts +154 -0
  311. package/src/server/stories.ts +133 -0
  312. package/src/server/storybook/providers/browser.ts +58 -0
  313. package/src/server/storybook/providers/hybrid.ts +70 -0
  314. package/src/server/telemetry.ts +212 -0
  315. package/src/server/testsFiles/parser.ts +62 -0
  316. package/src/server/update.ts +74 -0
  317. package/src/server/utils.ts +206 -0
  318. package/src/server/worker/chai-image.ts +147 -0
  319. package/src/server/worker/helpers.ts +61 -0
  320. package/src/server/worker/index.ts +1 -0
  321. package/src/server/worker/reporter.ts +170 -0
  322. package/src/server/worker/worker.ts +239 -0
  323. package/src/shared/index.ts +76 -0
  324. package/src/shared/serializeRegExp.ts +26 -0
  325. package/src/types.ts +500 -0
  326. package/types/chai.d.ts +11 -12
  327. package/types/global.d.ts +5 -0
  328. package/types/mocha.d.ts +20 -20
  329. package/types/png.d.ts +4 -4
  330. package/addon/package.json +0 -4
  331. package/jest.config.js +0 -6
  332. package/lib/cjs/cli.js +0 -5
  333. package/lib/cjs/client/addon/Manager.js +0 -264
  334. package/lib/cjs/client/addon/components/Addon.js +0 -55
  335. package/lib/cjs/client/addon/components/Icons.js +0 -46
  336. package/lib/cjs/client/addon/components/Panel.js +0 -72
  337. package/lib/cjs/client/addon/components/TestSelect.js +0 -65
  338. package/lib/cjs/client/addon/components/Tools.js +0 -95
  339. package/lib/cjs/client/addon/decorator.js +0 -11
  340. package/lib/cjs/client/addon/index.js +0 -31
  341. package/lib/cjs/client/addon/preset.js +0 -62
  342. package/lib/cjs/client/addon/readyForCapture.js +0 -12
  343. package/lib/cjs/client/addon/register.js +0 -72
  344. package/lib/cjs/client/addon/utils.js +0 -38
  345. package/lib/cjs/client/addon/withCreevey.js +0 -351
  346. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +0 -87
  347. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +0 -92
  348. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +0 -154
  349. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +0 -166
  350. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +0 -91
  351. package/lib/cjs/client/shared/components/ImagesView/index.js +0 -45
  352. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +0 -50
  353. package/lib/cjs/client/shared/components/PageFooter/Paging.js +0 -94
  354. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +0 -82
  355. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +0 -119
  356. package/lib/cjs/client/shared/components/ResultsPage.js +0 -143
  357. package/lib/cjs/client/shared/creeveyClientApi.js +0 -76
  358. package/lib/cjs/client/shared/helpers.js +0 -411
  359. package/lib/cjs/client/shared/viewMode.js +0 -17
  360. package/lib/cjs/client/web/142.js +0 -2
  361. package/lib/cjs/client/web/142.js.LICENSE.txt +0 -12
  362. package/lib/cjs/client/web/32.js +0 -1
  363. package/lib/cjs/client/web/551.js +0 -1
  364. package/lib/cjs/client/web/566.js +0 -2
  365. package/lib/cjs/client/web/566.js.LICENSE.txt +0 -31
  366. package/lib/cjs/client/web/691.js +0 -2
  367. package/lib/cjs/client/web/691.js.LICENSE.txt +0 -8
  368. package/lib/cjs/client/web/725.js +0 -1
  369. package/lib/cjs/client/web/main.js +0 -2
  370. package/lib/cjs/creevey.js +0 -69
  371. package/lib/cjs/index.js +0 -62
  372. package/lib/cjs/server/config.js +0 -96
  373. package/lib/cjs/server/docker.js +0 -146
  374. package/lib/cjs/server/extract.js +0 -50
  375. package/lib/cjs/server/index.js +0 -83
  376. package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -86
  377. package/lib/cjs/server/loaders/babel/helpers.js +0 -469
  378. package/lib/cjs/server/loaders/babel/register.js +0 -124
  379. package/lib/cjs/server/loaders/hooks/mdx.js +0 -30
  380. package/lib/cjs/server/loaders/hooks/svelte.js +0 -65
  381. package/lib/cjs/server/loaders/webpack/compile.js +0 -293
  382. package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -179
  383. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -39
  384. package/lib/cjs/server/loaders/webpack/mdx-loader.js +0 -72
  385. package/lib/cjs/server/loaders/webpack/start.js +0 -41
  386. package/lib/cjs/server/logger.js +0 -48
  387. package/lib/cjs/server/master/api.js +0 -75
  388. package/lib/cjs/server/master/index.js +0 -146
  389. package/lib/cjs/server/master/master.js +0 -57
  390. package/lib/cjs/server/master/pool.js +0 -197
  391. package/lib/cjs/server/master/runner.js +0 -281
  392. package/lib/cjs/server/master/server.js +0 -129
  393. package/lib/cjs/server/messages.js +0 -264
  394. package/lib/cjs/server/selenium/browser.js +0 -672
  395. package/lib/cjs/server/selenium/index.js +0 -31
  396. package/lib/cjs/server/selenium/selenoid.js +0 -172
  397. package/lib/cjs/server/stories.js +0 -159
  398. package/lib/cjs/server/storybook/entry.js +0 -70
  399. package/lib/cjs/server/storybook/helpers.js +0 -159
  400. package/lib/cjs/server/storybook/providers/browser.js +0 -74
  401. package/lib/cjs/server/storybook/providers/hybrid.js +0 -84
  402. package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
  403. package/lib/cjs/server/testsFiles/parser.js +0 -72
  404. package/lib/cjs/server/testsFiles/register.js +0 -48
  405. package/lib/cjs/server/update.js +0 -79
  406. package/lib/cjs/server/utils.js +0 -183
  407. package/lib/cjs/server/worker/chai-image.js +0 -142
  408. package/lib/cjs/server/worker/helpers.js +0 -69
  409. package/lib/cjs/server/worker/index.js +0 -15
  410. package/lib/cjs/server/worker/reporter.js +0 -108
  411. package/lib/cjs/server/worker/worker.js +0 -268
  412. package/lib/cjs/shared/index.js +0 -101
  413. package/lib/cjs/shared/serializeRegExp.js +0 -42
  414. package/lib/cjs/types.js +0 -74
  415. package/lib/esm/cli.js +0 -4
  416. package/lib/esm/client/addon/Manager.js +0 -248
  417. package/lib/esm/client/addon/components/Addon.js +0 -39
  418. package/lib/esm/client/addon/components/Icons.js +0 -31
  419. package/lib/esm/client/addon/components/Panel.js +0 -53
  420. package/lib/esm/client/addon/components/TestSelect.js +0 -51
  421. package/lib/esm/client/addon/components/Tools.js +0 -74
  422. package/lib/esm/client/addon/decorator.js +0 -2
  423. package/lib/esm/client/addon/index.js +0 -2
  424. package/lib/esm/client/addon/preset.js +0 -41
  425. package/lib/esm/client/addon/readyForCapture.js +0 -5
  426. package/lib/esm/client/addon/register.js +0 -51
  427. package/lib/esm/client/addon/utils.js +0 -31
  428. package/lib/esm/client/addon/withCreevey.js +0 -325
  429. package/lib/esm/client/shared/components/ImagesView/BlendView.js +0 -67
  430. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +0 -69
  431. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +0 -131
  432. package/lib/esm/client/shared/components/ImagesView/SlideView.js +0 -143
  433. package/lib/esm/client/shared/components/ImagesView/SwapView.js +0 -71
  434. package/lib/esm/client/shared/components/ImagesView/index.js +0 -5
  435. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +0 -36
  436. package/lib/esm/client/shared/components/PageFooter/Paging.js +0 -80
  437. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +0 -68
  438. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +0 -97
  439. package/lib/esm/client/shared/components/ResultsPage.js +0 -115
  440. package/lib/esm/client/shared/creeveyClientApi.js +0 -67
  441. package/lib/esm/client/shared/helpers.js +0 -353
  442. package/lib/esm/client/shared/viewMode.js +0 -6
  443. package/lib/esm/creevey.js +0 -54
  444. package/lib/esm/index.js +0 -5
  445. package/lib/esm/server/config.js +0 -73
  446. package/lib/esm/server/docker.js +0 -123
  447. package/lib/esm/server/extract.js +0 -34
  448. package/lib/esm/server/index.js +0 -64
  449. package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -72
  450. package/lib/esm/server/loaders/babel/helpers.js +0 -452
  451. package/lib/esm/server/loaders/babel/register.js +0 -103
  452. package/lib/esm/server/loaders/hooks/mdx.js +0 -15
  453. package/lib/esm/server/loaders/hooks/svelte.js +0 -49
  454. package/lib/esm/server/loaders/webpack/compile.js +0 -270
  455. package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -158
  456. package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -32
  457. package/lib/esm/server/loaders/webpack/mdx-loader.js +0 -58
  458. package/lib/esm/server/loaders/webpack/start.js +0 -27
  459. package/lib/esm/server/master/api.js +0 -64
  460. package/lib/esm/server/master/index.js +0 -125
  461. package/lib/esm/server/master/master.js +0 -38
  462. package/lib/esm/server/master/pool.js +0 -176
  463. package/lib/esm/server/master/runner.js +0 -259
  464. package/lib/esm/server/master/server.js +0 -105
  465. package/lib/esm/server/messages.js +0 -232
  466. package/lib/esm/server/selenium/browser.js +0 -639
  467. package/lib/esm/server/selenium/index.js +0 -2
  468. package/lib/esm/server/selenium/selenoid.js +0 -149
  469. package/lib/esm/server/stories.js +0 -140
  470. package/lib/esm/server/storybook/entry.js +0 -46
  471. package/lib/esm/server/storybook/helpers.js +0 -98
  472. package/lib/esm/server/storybook/providers/browser.js +0 -60
  473. package/lib/esm/server/storybook/providers/hybrid.js +0 -64
  474. package/lib/esm/server/storybook/providers/nodejs.js +0 -217
  475. package/lib/esm/server/testsFiles/parser.js +0 -50
  476. package/lib/esm/server/testsFiles/register.js +0 -35
  477. package/lib/esm/server/update.js +0 -61
  478. package/lib/esm/server/utils.js +0 -142
  479. package/lib/esm/server/worker/chai-image.js +0 -130
  480. package/lib/esm/server/worker/helpers.js +0 -60
  481. package/lib/esm/server/worker/index.js +0 -1
  482. package/lib/esm/server/worker/reporter.js +0 -86
  483. package/lib/esm/server/worker/worker.js +0 -238
  484. package/lib/esm/shared/index.js +0 -78
  485. package/lib/esm/shared/serializeRegExp.js +0 -24
  486. package/lib/esm/types.js +0 -43
  487. package/lib/types/cli.d.ts +0 -1
  488. package/lib/types/client/addon/components/Addon.d.ts +0 -8
  489. package/lib/types/client/addon/components/Tools.d.ts +0 -6
  490. package/lib/types/client/addon/decorator.d.ts +0 -1
  491. package/lib/types/client/addon/index.d.ts +0 -2
  492. package/lib/types/client/addon/preset.d.ts +0 -23
  493. package/lib/types/client/addon/register.d.ts +0 -3
  494. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +0 -3
  495. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +0 -3
  496. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +0 -3
  497. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +0 -3
  498. package/lib/types/client/shared/components/ImagesView/index.d.ts +0 -5
  499. package/lib/types/client/web/CreeveyLoader.d.ts +0 -2
  500. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +0 -33
  501. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +0 -9
  502. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +0 -1
  503. package/lib/types/index.d.ts +0 -2
  504. package/lib/types/server/extract.d.ts +0 -2
  505. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +0 -1
  506. package/lib/types/server/loaders/babel/helpers.d.ts +0 -19
  507. package/lib/types/server/loaders/babel/register.d.ts +0 -5
  508. package/lib/types/server/loaders/hooks/mdx.d.ts +0 -1
  509. package/lib/types/server/loaders/hooks/svelte.d.ts +0 -1
  510. package/lib/types/server/loaders/webpack/compile.d.ts +0 -2
  511. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +0 -4
  512. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +0 -10
  513. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +0 -6
  514. package/lib/types/server/loaders/webpack/start.d.ts +0 -1
  515. package/lib/types/server/master/index.d.ts +0 -3
  516. package/lib/types/server/master/server.d.ts +0 -2
  517. package/lib/types/server/selenium/index.d.ts +0 -2
  518. package/lib/types/server/stories.d.ts +0 -8
  519. package/lib/types/server/storybook/entry.d.ts +0 -18
  520. package/lib/types/server/storybook/helpers.d.ts +0 -24
  521. package/lib/types/server/storybook/providers/browser.d.ts +0 -4
  522. package/lib/types/server/storybook/providers/hybrid.d.ts +0 -4
  523. package/lib/types/server/storybook/providers/nodejs.d.ts +0 -9
  524. package/lib/types/server/testsFiles/register.d.ts +0 -2
  525. package/lib/types/server/update.d.ts +0 -2
  526. package/lib/types/server/utils.d.ts +0 -20
  527. package/lib/types/server/worker/index.d.ts +0 -1
  528. package/lib/types/server/worker/worker.d.ts +0 -4
  529. package/preset.js +0 -9
  530. package/types/babel__register.d.ts +0 -1
  531. package/types/event-source-polyfill.d.ts +0 -6
  532. package/types/mdx.d.ts +0 -7
  533. /package/{addon → manager}/README.md +0 -0
@@ -0,0 +1,837 @@
1
+ import { Args } from '@storybook/csf';
2
+ import { SET_GLOBALS, UPDATE_STORY_ARGS, STORY_RENDERED } from '@storybook/core-events';
3
+ import chalk from 'chalk';
4
+ import http from 'http';
5
+ import https from 'https';
6
+ import Logger from 'loglevel';
7
+ import prefix from 'loglevel-plugin-prefix';
8
+ import { Context, Suite, Test } from 'mocha';
9
+ import { networkInterfaces } from 'os';
10
+ import { PNG } from 'pngjs';
11
+ import { Builder, By, Capabilities, Origin, WebDriver, WebElement, logging } from 'selenium-webdriver';
12
+ // import { Options as IeOptions } from 'selenium-webdriver/ie';
13
+ // import { Options as EdgeOptions } from 'selenium-webdriver/edge';
14
+ // import { Options as ChromeOptions } from 'selenium-webdriver/chrome';
15
+ // import { Options as SafariOptions } from 'selenium-webdriver/safari';
16
+ // import { Options as FirefoxOptions } from 'selenium-webdriver/firefox';
17
+ import { PageLoadStrategy } from 'selenium-webdriver/lib/capabilities.js';
18
+ import {
19
+ BrowserConfig,
20
+ Config,
21
+ CreeveyStoryParams,
22
+ isDefined,
23
+ noop,
24
+ StorybookGlobals,
25
+ StoryInput,
26
+ StoriesRaw,
27
+ Options,
28
+ } from '../../types.js';
29
+ import { colors, logger } from '../logger.js';
30
+ import { emitStoriesMessage, subscribeOn } from '../messages.js';
31
+ import { isShuttingDown, LOCALHOST_REGEXP, runSequence } from '../utils.js';
32
+
33
+ interface ElementRect {
34
+ top: number;
35
+ left: number;
36
+ width: number;
37
+ height: number;
38
+ }
39
+
40
+ declare global {
41
+ interface Window {
42
+ __CREEVEY_RESTORE_SCROLL__?: () => void;
43
+ __CREEVEY_UPDATE_GLOBALS__: (globals: StorybookGlobals) => void;
44
+ __CREEVEY_INSERT_IGNORE_STYLES__: (ignoreElements: string[]) => HTMLStyleElement;
45
+ __CREEVEY_REMOVE_IGNORE_STYLES__: (ignoreStyles: HTMLStyleElement) => void;
46
+ }
47
+ }
48
+
49
+ // type UnPromise<P> = P extends Promise<infer T> ? T : never;
50
+
51
+ const storybookRootID = 'storybook-root';
52
+ const DOCKER_INTERNAL = 'host.docker.internal';
53
+ let browserLogger = logger;
54
+ let browserName = '';
55
+ let browser: WebDriver | null = null;
56
+ // let context: UnPromise<ReturnType<typeof BrowsingContext>> | null = null;
57
+ let creeveyServerHost: string | null = null;
58
+
59
+ function getSessionData(grid: string, sessionId = ''): Promise<Record<string, unknown>> {
60
+ const gridUrl = new URL(grid);
61
+ gridUrl.pathname = `/host/${sessionId}`;
62
+
63
+ return new Promise((resolve, reject) =>
64
+ (gridUrl.protocol == 'https:' ? https : http).get(gridUrl.toString(), (res) => {
65
+ if (res.statusCode !== 200) {
66
+ reject(new Error(`Couldn't get session data for ${sessionId}. Status code: ${res.statusCode ?? 'Unknown'}`));
67
+ return;
68
+ }
69
+
70
+ let data = '';
71
+
72
+ res.setEncoding('utf-8');
73
+ res.on('data', (chunk: string) => (data += chunk));
74
+ res.on('end', () => {
75
+ try {
76
+ resolve(JSON.parse(data) as Record<string, unknown>);
77
+ } catch (error) {
78
+ reject(
79
+ new Error(
80
+ `Couldn't get session data for ${sessionId}. ${
81
+ error instanceof Error ? (error.stack ?? error.message) : (error as string)
82
+ }`,
83
+ ),
84
+ );
85
+ }
86
+ });
87
+ }),
88
+ );
89
+ }
90
+
91
+ function getAddresses(): string[] {
92
+ // TODO Check if docker is used
93
+ return [DOCKER_INTERNAL].concat(
94
+ ...Object.values(networkInterfaces())
95
+ .filter(isDefined)
96
+ .map((network) => network.filter((info) => info.family == 'IPv4').map((info) => info.address)),
97
+ );
98
+ }
99
+
100
+ async function resolveStorybookUrl(storybookUrl: string, checkUrl: (url: string) => Promise<boolean>): Promise<string> {
101
+ browserLogger.debug('Resolving storybook url');
102
+ const addresses = getAddresses();
103
+ for (const ip of addresses) {
104
+ const resolvedUrl = storybookUrl.replace(LOCALHOST_REGEXP, ip);
105
+ browserLogger.debug(`Checking storybook availability on ${chalk.magenta(resolvedUrl)}`);
106
+ if (await checkUrl(resolvedUrl)) {
107
+ browserLogger.debug(`Resolved storybook url ${chalk.magenta(resolvedUrl)}`);
108
+ return resolvedUrl;
109
+ }
110
+ }
111
+ const error = new Error('Please specify `storybookUrl` with IP address that accessible from remote browser');
112
+ error.name = 'ResolveUrlError';
113
+ throw error;
114
+ }
115
+
116
+ async function openUrlAndWaitForPageSource(
117
+ browser: WebDriver,
118
+ url: string,
119
+ predicate: (source: string) => boolean,
120
+ ): Promise<string> {
121
+ let source = '';
122
+ await browser.get(url);
123
+ do {
124
+ try {
125
+ source = await browser.getPageSource();
126
+ } catch {
127
+ // NOTE: Firefox can raise exception "curContainer.frame.document.documentElement is null"
128
+ }
129
+ } while (predicate(source));
130
+ return source;
131
+ }
132
+
133
+ function getUrlChecker(browser: WebDriver): (url: string) => Promise<boolean> {
134
+ return async (url: string): Promise<boolean> => {
135
+ try {
136
+ // NOTE: Before trying a new url, reset the current one
137
+ browserLogger.debug(`Opening ${chalk.magenta('about:blank')} page`);
138
+ await openUrlAndWaitForPageSource(browser, 'about:blank', (source: string) => !source.includes('<body></body>'));
139
+ browserLogger.debug(`Opening ${chalk.magenta(url)} and checking the page source`);
140
+ const source = await openUrlAndWaitForPageSource(
141
+ browser,
142
+ url,
143
+ // NOTE: IE11 can return only `head` without body
144
+ (source: string) => source.length == 0 || !/<body([^>]*>).+<\/body>/s.test(source),
145
+ );
146
+ // NOTE: This is the most optimal way to check if we in storybook or not
147
+ // We don't use any page load strategies except `NONE`
148
+ // because other add significant delay and some of them don't work in earlier chrome versions
149
+ // Browsers always load page successful even it's failed
150
+ // So we just check `root` element
151
+ browserLogger.debug(`Checking ${chalk.cyan(`#${storybookRootID}`)} existence on ${chalk.magenta(url)}`);
152
+ return source.includes(`id="${storybookRootID}"`);
153
+ } catch {
154
+ return false;
155
+ }
156
+ };
157
+ }
158
+
159
+ async function waitForStorybook(browser: WebDriver): Promise<void> {
160
+ browserLogger.debug('Waiting for `setStories` event to make sure that storybook is initiated');
161
+
162
+ const isTimeout = await Promise.race([
163
+ new Promise<boolean>((resolve) => {
164
+ setTimeout(() => {
165
+ resolve(true);
166
+ }, 60000);
167
+ }),
168
+ (async () => {
169
+ let wait = true;
170
+ do {
171
+ try {
172
+ wait = await browser.executeScript<boolean>(function (SET_GLOBALS: string): boolean {
173
+ if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined') return true;
174
+ if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined) return true;
175
+ return false;
176
+ }, SET_GLOBALS);
177
+ } catch (e: unknown) {
178
+ browserLogger.debug('An error has been caught during the script:', e);
179
+ }
180
+ } while (wait);
181
+ return false;
182
+ })(),
183
+ ]);
184
+
185
+ // TODO Change the message to describe a reason why it might happen
186
+ if (isTimeout) throw new Error('Failed to wait `setStories` event');
187
+ }
188
+
189
+ async function resetMousePosition(browser: WebDriver): Promise<void> {
190
+ browserLogger.debug('Resetting mouse position to the top-left corner');
191
+ const browserName = (await browser.getCapabilities()).getBrowserName();
192
+ const [browserVersion] =
193
+ (await browser.getCapabilities()).getBrowserVersion()?.split('.') ??
194
+ ((await browser.getCapabilities()).get('version') as string | undefined)?.split('.') ??
195
+ [];
196
+
197
+ // NOTE Reset mouse position to support keweb selenium grid browser versions
198
+ if (browserName == 'chrome' && browserVersion == '70') {
199
+ const { top, left, width, height } = await browser.executeScript<ElementRect>(function (): ElementRect {
200
+ const bodyRect = document.body.getBoundingClientRect();
201
+
202
+ return {
203
+ top: bodyRect.top,
204
+ left: bodyRect.left,
205
+ width: bodyRect.width,
206
+ height: bodyRect.height,
207
+ };
208
+ });
209
+ // NOTE Bridge mode doesn't support `Origin.VIEWPORT`, move mouse relative
210
+ await browser
211
+ .actions({ bridge: true })
212
+ .move({
213
+ origin: browser.findElement(By.css('body')),
214
+ x: Math.ceil((-1 * width) / 2) - left,
215
+ y: Math.ceil((-1 * height) / 2) - top,
216
+ })
217
+ .perform();
218
+ } else if (browserName == 'firefox' && browserVersion == '61') {
219
+ // NOTE Firefox for some reason moving by 0 x 0 move cursor in bottom left corner :sad:
220
+ await browser.actions().move({ origin: Origin.VIEWPORT, x: 0, y: 1 }).perform();
221
+ } else {
222
+ // NOTE IE don't emit move events until force window focus or connect by RDP on virtual machine
223
+ await browser.actions().move({ origin: Origin.VIEWPORT, x: 0, y: 0 }).perform();
224
+ }
225
+ }
226
+
227
+ async function resizeViewport(browser: WebDriver, viewport: { width: number; height: number }): Promise<void> {
228
+ const windowRect = await browser.manage().window().getRect();
229
+ const { innerWidth, innerHeight } = await browser.executeScript<{ innerWidth: number; innerHeight: number }>(
230
+ function () {
231
+ return {
232
+ innerWidth: window.innerWidth,
233
+ innerHeight: window.innerHeight,
234
+ };
235
+ },
236
+ );
237
+
238
+ browserLogger.debug(`Resizing viewport from ${innerWidth}x${innerHeight} to ${viewport.width}x${viewport.height}`);
239
+
240
+ const dWidth = windowRect.width - innerWidth;
241
+ const dHeight = windowRect.height - innerHeight;
242
+ await browser
243
+ .manage()
244
+ .window()
245
+ .setRect({
246
+ width: viewport.width + dWidth,
247
+ height: viewport.height + dHeight,
248
+ });
249
+ }
250
+
251
+ const getScrollBarWidth: (browser: WebDriver) => Promise<number> = (() => {
252
+ let scrollBarWidth: number | null = null;
253
+
254
+ return async (browser: WebDriver): Promise<number> => {
255
+ if (scrollBarWidth != null) return Promise.resolve(scrollBarWidth);
256
+ scrollBarWidth = await browser.executeScript<number>(function () {
257
+ // eslint-disable-next-line no-var
258
+ var div = document.createElement('div');
259
+ div.innerHTML = 'a'; // NOTE: In IE clientWidth is 0 if this div is empty.
260
+ div.style.overflowY = 'scroll';
261
+ document.body.appendChild(div);
262
+ // eslint-disable-next-line no-var
263
+ var widthDiff = div.offsetWidth - div.clientWidth;
264
+ document.body.removeChild(div);
265
+
266
+ return widthDiff;
267
+ });
268
+ return scrollBarWidth;
269
+ };
270
+ })();
271
+
272
+ // NOTE Firefox and Safari take viewport screenshot without scrollbars
273
+ async function hasScrollBar(browser: WebDriver): Promise<boolean> {
274
+ const browserName = (await browser.getCapabilities()).getBrowserName();
275
+ const [browserVersion] = (await browser.getCapabilities()).getBrowserVersion()?.split('.') ?? [];
276
+
277
+ return (
278
+ browserName != 'Safari' &&
279
+ // NOTE This need to work with keweb selenium grid
280
+ !(browserName == 'firefox' && browserVersion == '61')
281
+ );
282
+ }
283
+
284
+ async function takeCompositeScreenshot(
285
+ browser: WebDriver,
286
+ windowRect: ElementRect,
287
+ elementRect: ElementRect,
288
+ ): Promise<string> {
289
+ const screens = [];
290
+ const isScreenshotWithoutScrollBar = !(await hasScrollBar(browser));
291
+ const scrollBarWidth = await getScrollBarWidth(browser);
292
+ // NOTE Sometimes viewport has been scrolled somewhere
293
+ const normalizedElementRect = {
294
+ left: elementRect.left - windowRect.left,
295
+ right: elementRect.left + elementRect.width - windowRect.left,
296
+ top: elementRect.top - windowRect.top,
297
+ bottom: elementRect.top + elementRect.height - windowRect.top,
298
+ };
299
+ const isFitHorizontally = windowRect.width >= elementRect.width + normalizedElementRect.left;
300
+ const isFitVertically = windowRect.height >= elementRect.height + normalizedElementRect.top;
301
+ const viewportWidth = windowRect.width - (isFitVertically ? 0 : scrollBarWidth);
302
+ const viewportHeight = windowRect.height - (isFitHorizontally ? 0 : scrollBarWidth);
303
+ const cols = Math.ceil(elementRect.width / viewportWidth);
304
+ const rows = Math.ceil(elementRect.height / viewportHeight);
305
+ const xOffset = Math.round(
306
+ isFitHorizontally ? normalizedElementRect.left : Math.max(0, cols * viewportWidth - elementRect.width),
307
+ );
308
+ const yOffset = Math.round(
309
+ isFitVertically ? normalizedElementRect.top : Math.max(0, rows * viewportHeight - elementRect.height),
310
+ );
311
+
312
+ for (let row = 0; row < rows; row += 1) {
313
+ for (let col = 0; col < cols; col += 1) {
314
+ const dx = Math.min(
315
+ viewportWidth * col + normalizedElementRect.left,
316
+ Math.max(0, normalizedElementRect.right - viewportWidth),
317
+ );
318
+ const dy = Math.min(
319
+ viewportHeight * row + normalizedElementRect.top,
320
+ Math.max(0, normalizedElementRect.bottom - viewportHeight),
321
+ );
322
+ await browser.executeScript(
323
+ function (x: number, y: number) {
324
+ window.scrollTo(x, y);
325
+ },
326
+ dx,
327
+ dy,
328
+ );
329
+ screens.push(await browser.takeScreenshot());
330
+ }
331
+ }
332
+
333
+ const images = screens.map((s) => Buffer.from(s, 'base64')).map((b) => PNG.sync.read(b));
334
+ const compositeImage = new PNG({ width: Math.round(elementRect.width), height: Math.round(elementRect.height) });
335
+
336
+ for (let y = 0; y < compositeImage.height; y += 1) {
337
+ for (let x = 0; x < compositeImage.width; x += 1) {
338
+ const col = Math.floor(x / viewportWidth);
339
+ const row = Math.floor(y / viewportHeight);
340
+ const isLastCol = cols - col == 1;
341
+ const isLastRow = rows - row == 1;
342
+ const scrollOffset = isFitVertically || isScreenshotWithoutScrollBar ? 0 : scrollBarWidth;
343
+ const i = (y * compositeImage.width + x) * 4;
344
+ const j =
345
+ // NOTE compositeImage(x, y) => image(x, y)
346
+ ((y % viewportHeight) * (viewportWidth + scrollOffset) + (x % viewportWidth)) * 4 +
347
+ // NOTE Offset for last row/col image
348
+ (isLastRow ? yOffset * (viewportWidth + scrollOffset) * 4 : 0) +
349
+ (isLastCol ? xOffset * 4 : 0);
350
+ const image = images[row * cols + col];
351
+ compositeImage.data[i + 0] = image.data[j + 0];
352
+ compositeImage.data[i + 1] = image.data[j + 1];
353
+ compositeImage.data[i + 2] = image.data[j + 2];
354
+ compositeImage.data[i + 3] = image.data[j + 3];
355
+ }
356
+ }
357
+ return PNG.sync.write(compositeImage).toString('base64');
358
+ }
359
+
360
+ export async function takeScreenshot(
361
+ browser: WebDriver,
362
+ captureElement?: string | null,
363
+ ignoreElements?: string | string[] | null,
364
+ ): Promise<string> {
365
+ let screenshot: string;
366
+
367
+ const ignoreStyles = await insertIgnoreStyles(browser, ignoreElements);
368
+
369
+ if (browserLogger.getLevel() <= Logger.levels.DEBUG) {
370
+ const { innerWidth, innerHeight } = await browser.executeScript<{ innerWidth: number; innerHeight: number }>(
371
+ function () {
372
+ return {
373
+ innerWidth: window.innerWidth,
374
+ innerHeight: window.innerHeight,
375
+ };
376
+ },
377
+ );
378
+ browserLogger.debug(`Viewport size is: ${innerWidth}x${innerHeight}`);
379
+ }
380
+
381
+ try {
382
+ if (!captureElement) {
383
+ browserLogger.debug('Capturing viewport screenshot');
384
+ screenshot = await browser.takeScreenshot();
385
+ browserLogger.debug('Viewport screenshot is captured');
386
+ } else {
387
+ browserLogger.debug(`Checking is element ${chalk.cyan(captureElement)} fit into viewport`);
388
+ const rects = await browser.executeScript<{ elementRect: ElementRect; windowRect: ElementRect } | undefined>(
389
+ function (selector: string): { elementRect: ElementRect; windowRect: ElementRect } | undefined {
390
+ window.scrollTo(0, 0); // TODO Maybe we should remove same code from `resetMousePosition`
391
+ // eslint-disable-next-line no-var
392
+ var element = document.querySelector(selector);
393
+ if (!element) return;
394
+
395
+ // eslint-disable-next-line no-var
396
+ var elementRect = element.getBoundingClientRect();
397
+
398
+ return {
399
+ elementRect: {
400
+ top: elementRect.top,
401
+ left: elementRect.left,
402
+ width: elementRect.width,
403
+ height: elementRect.height,
404
+ },
405
+ // NOTE page_Offset is used only for IE9-11
406
+ windowRect: {
407
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
408
+ top: Math.round(window.scrollY || window.pageYOffset),
409
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
410
+ left: Math.round(window.scrollX || window.pageXOffset),
411
+ width: window.innerWidth,
412
+ height: window.innerHeight,
413
+ },
414
+ };
415
+ },
416
+ captureElement,
417
+ );
418
+ const { elementRect, windowRect } = rects ?? {};
419
+
420
+ if (!elementRect || !windowRect) throw new Error(`Couldn't find element with selector: '${captureElement}'`);
421
+
422
+ const isFitIntoViewport =
423
+ elementRect.width + elementRect.left <= windowRect.width &&
424
+ elementRect.height + elementRect.top <= windowRect.height;
425
+
426
+ if (isFitIntoViewport) {
427
+ browserLogger.debug(
428
+ `Capturing ${chalk.cyan(captureElement)} with size: ${elementRect.width}x${elementRect.height}`,
429
+ );
430
+ } else
431
+ browserLogger.debug(
432
+ `Capturing composite screenshot image of ${chalk.cyan(captureElement)} with size: ${elementRect.width}x${elementRect.height}`,
433
+ );
434
+
435
+ // const element = await browser.findElement(By.css(captureElement));
436
+ // screenshot = isFitIntoViewport
437
+ // ? context
438
+ // ? await context.captureElementScreenshot(await element.getId())
439
+ // : await browser.findElement(By.css(captureElement)).takeScreenshot()
440
+ // : // TODO pointer-events: none, need to research
441
+ // await takeCompositeScreenshot(browser, windowRect, elementRect);
442
+ screenshot = isFitIntoViewport
443
+ ? await browser.findElement(By.css(captureElement)).takeScreenshot()
444
+ : // TODO pointer-events: none, need to research
445
+ await takeCompositeScreenshot(browser, windowRect, elementRect);
446
+
447
+ browserLogger.debug(`${chalk.cyan(captureElement)} is captured`);
448
+ }
449
+ } finally {
450
+ await removeIgnoreStyles(browser, ignoreStyles);
451
+ }
452
+
453
+ return screenshot;
454
+ }
455
+
456
+ async function selectStory(browser: WebDriver, storyId: string, waitForReady = false): Promise<boolean> {
457
+ browserLogger.debug(`Triggering 'SetCurrentStory' event with storyId ${chalk.magenta(storyId)}`);
458
+
459
+ const result = await browser.executeAsyncScript<[error?: string | null, isCaptureCalled?: boolean] | null>(
460
+ function (
461
+ id: string,
462
+ shouldWaitForReady: boolean,
463
+ callback: (response: [error?: string | null, isCaptureCalled?: boolean]) => void,
464
+ ) {
465
+ if (typeof window.__CREEVEY_SELECT_STORY__ == 'undefined') {
466
+ callback([
467
+ "Creevey can't switch story. This may happened if forget to add `creevey` addon to your storybook config, or storybook not loaded in browser due syntax error.",
468
+ ]);
469
+ return;
470
+ }
471
+ void window.__CREEVEY_SELECT_STORY__(id, shouldWaitForReady, callback);
472
+ },
473
+ storyId,
474
+ waitForReady,
475
+ );
476
+
477
+ const [errorMessage, isCaptureCalled = false] = result ?? [];
478
+
479
+ if (errorMessage) throw new Error(errorMessage);
480
+
481
+ return isCaptureCalled;
482
+ }
483
+
484
+ export async function updateStorybookGlobals(browser: WebDriver, globals: StorybookGlobals): Promise<void> {
485
+ browserLogger.debug('Applying storybook globals');
486
+ await browser.executeScript(function (globals: StorybookGlobals) {
487
+ window.__CREEVEY_UPDATE_GLOBALS__(globals);
488
+ }, globals);
489
+ }
490
+
491
+ function appendIframePath(url: string): string {
492
+ return `${url.replace(/\/$/, '')}/iframe.html`;
493
+ }
494
+
495
+ async function openStorybookPage(
496
+ browser: WebDriver,
497
+ storybookUrl: string,
498
+ resolver?: () => Promise<string>,
499
+ ): Promise<void> {
500
+ if (!LOCALHOST_REGEXP.test(storybookUrl)) {
501
+ return browser.get(appendIframePath(storybookUrl));
502
+ }
503
+
504
+ try {
505
+ if (resolver) {
506
+ browserLogger.debug('Resolving storybook url with custom resolver');
507
+
508
+ const resolvedUrl = await resolver();
509
+
510
+ browserLogger.debug(`Resolver storybook url ${resolvedUrl}`);
511
+
512
+ await browser.get(appendIframePath(resolvedUrl));
513
+ } else {
514
+ // NOTE: getUrlChecker already calls `browser.get` so we don't need another one
515
+ await resolveStorybookUrl(appendIframePath(storybookUrl), getUrlChecker(browser));
516
+ }
517
+ } catch (error) {
518
+ browserLogger.error('Failed to resolve storybook URL', error instanceof Error ? error.message : '');
519
+ throw error;
520
+ }
521
+ }
522
+
523
+ async function resolveCreeveyHost(browser: WebDriver, port: number): Promise<string> {
524
+ if (creeveyServerHost != null) return creeveyServerHost;
525
+
526
+ const addresses = getAddresses();
527
+
528
+ creeveyServerHost = await browser.executeAsyncScript(
529
+ function (hosts: string[], port: number, callback: (host?: string | null) => void) {
530
+ void Promise.all(
531
+ hosts.map(function (host) {
532
+ return Promise.race([
533
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
534
+ fetch('http://' + host + ':' + port + '/ping').then(function (response) {
535
+ return response.text();
536
+ }),
537
+ new Promise((_resolve, reject) => {
538
+ setTimeout(reject, 5000);
539
+ }),
540
+ ])
541
+ .then(function (pong) {
542
+ return pong == 'pong' ? host : null;
543
+ })
544
+ .catch(function () {
545
+ return null;
546
+ });
547
+ }),
548
+ ).then(function (hosts) {
549
+ callback(
550
+ hosts.find(function (host) {
551
+ return host != null;
552
+ }),
553
+ );
554
+ });
555
+ },
556
+ addresses,
557
+ port,
558
+ );
559
+
560
+ if (creeveyServerHost == null) throw new Error("Can't reach creevey server from a browser");
561
+
562
+ return creeveyServerHost;
563
+ }
564
+
565
+ export async function loadStoriesFromBrowser(): Promise<StoriesRaw> {
566
+ if (!browser) throw new Error("Can't get stories from browser if webdriver isn't connected");
567
+
568
+ const stories = await browser.executeAsyncScript<StoriesRaw | undefined>(function (
569
+ callback: (stories: StoriesRaw | undefined) => void,
570
+ ) {
571
+ void window.__CREEVEY_GET_STORIES__().then(callback);
572
+ });
573
+
574
+ if (!stories) throw new Error("Can't get stories, it seems creevey or storybook API isn't available");
575
+
576
+ return stories;
577
+ }
578
+
579
+ export async function getBrowser(config: Config, options: Options & { browser: string }): Promise<WebDriver | null> {
580
+ if (browser) return browser;
581
+
582
+ browserName = options.browser;
583
+ const browserConfig = config.browsers[browserName] as BrowserConfig;
584
+ const {
585
+ gridUrl = config.gridUrl,
586
+ storybookUrl: address = config.storybookUrl,
587
+ limit,
588
+ viewport,
589
+ _storybookGlobals,
590
+ ...userCapabilities
591
+ } = browserConfig;
592
+ void limit;
593
+ const realAddress = address;
594
+
595
+ // TODO Define some capabilities explicitly and define typings
596
+ const capabilities = new Capabilities({ ...userCapabilities, pageLoadStrategy: PageLoadStrategy.EAGER });
597
+
598
+ subscribeOn('shutdown', () => {
599
+ void browser?.quit().finally(() => process.exit());
600
+ browser = null;
601
+ });
602
+
603
+ try {
604
+ const url = new URL(gridUrl);
605
+ url.username = url.username ? '********' : '';
606
+ url.password = url.password ? '********' : '';
607
+ browserLogger.debug(`(${browserName}) Connecting to Selenium ${chalk.magenta(url.toString())}`);
608
+
609
+ const prefs = new logging.Preferences();
610
+
611
+ if (options.trace) {
612
+ for (const type of Object.values(logging.Type)) {
613
+ prefs.setLevel(type as string, logging.Level.ALL);
614
+ }
615
+ }
616
+
617
+ // const ie = new IeOptions();
618
+ // const edge = new EdgeOptions();
619
+ // const chrome = new ChromeOptions();
620
+ // const safari = new SafariOptions();
621
+ // const firefox = new FirefoxOptions();
622
+ // edge.enableBidi();
623
+ // chrome.enableBidi();
624
+ // firefox.enableBidi();
625
+
626
+ browser = await new Builder()
627
+ // .setIeOptions(ie)
628
+ // .setEdgeOptions(edge)
629
+ // .setChromeOptions(chrome)
630
+ // .setSafariOptions(safari)
631
+ // .setFirefoxOptions(firefox)
632
+ .usingServer(gridUrl)
633
+ .withCapabilities(capabilities)
634
+ .setLoggingPrefs(prefs) // NOTE: Should go last
635
+ .build();
636
+
637
+ // const id = await browser.getWindowHandle();
638
+ // context = await BrowsingContext(browser, { browsingContextId: id });
639
+
640
+ const sessionId = (await browser.getSession()).getId();
641
+ let browserHost = '';
642
+
643
+ try {
644
+ const { Name } = await getSessionData(gridUrl, sessionId);
645
+ if (typeof Name == 'string') browserHost = Name;
646
+ } catch {
647
+ /* noop */
648
+ }
649
+
650
+ browserLogger.debug(
651
+ `(${browserName}) Connected successful with ${[chalk.green(browserHost), chalk.magenta(sessionId)]
652
+ .filter(Boolean)
653
+ .join(':')}`,
654
+ );
655
+
656
+ browserLogger = Logger.getLogger(sessionId);
657
+
658
+ prefix.apply(browserLogger, {
659
+ format(level) {
660
+ const levelColor = colors[level.toUpperCase() as keyof typeof colors];
661
+ return `[${browserName}:${chalk.gray(sessionId)}] ${levelColor(level)} =>`;
662
+ },
663
+ });
664
+
665
+ await runSequence(
666
+ [
667
+ () => browser?.manage().setTimeouts({ pageLoad: 10000, script: 60000 }),
668
+ () => browser && openStorybookPage(browser, realAddress, config.resolveStorybookUrl),
669
+ () => browser && waitForStorybook(browser),
670
+ // NOTE: Selenium draws automation toolbar with some delay after webdriver initialization
671
+ // NOTE: So if we resize window right after getting webdriver instance we might get situation
672
+ // NOTE: When the toolbar appears after resize and final viewport size become smaller than we set
673
+ () => viewport && browser && resizeViewport(browser, viewport),
674
+ ],
675
+ () => !isShuttingDown.current,
676
+ );
677
+ } catch (originalError) {
678
+ if (isShuttingDown.current) {
679
+ browser?.quit().catch(noop);
680
+ browser = null;
681
+ return null;
682
+ }
683
+ if (originalError instanceof Error && originalError.name == 'ResolveUrlError') throw originalError;
684
+ const error = new Error(`Can't load storybook root page by URL ${(await browser?.getCurrentUrl()) ?? realAddress}`);
685
+ if (originalError instanceof Error) error.stack = originalError.stack;
686
+ throw error;
687
+ }
688
+
689
+ if (_storybookGlobals) {
690
+ await updateStorybookGlobals(browser, _storybookGlobals);
691
+ }
692
+
693
+ const creeveyHost = await resolveCreeveyHost(browser, options.port);
694
+
695
+ await browser.executeScript(
696
+ function (workerId: number, creeveyHost: string, creeveyPort: number) {
697
+ window.__CREEVEY_WORKER_ID__ = workerId;
698
+ window.__CREEVEY_SERVER_HOST__ = creeveyHost;
699
+ window.__CREEVEY_SERVER_PORT__ = creeveyPort;
700
+ },
701
+ process.pid,
702
+ creeveyHost,
703
+ options.port,
704
+ );
705
+
706
+ return browser;
707
+ }
708
+
709
+ async function updateStoryArgs(browser: WebDriver, story: StoryInput, updatedArgs: Args): Promise<void> {
710
+ await browser.executeAsyncScript<undefined>(
711
+ function (
712
+ storyId: string,
713
+ updatedArgs: Args,
714
+ UPDATE_STORY_ARGS: string,
715
+ STORY_RENDERED: string,
716
+ callback: () => void,
717
+ ) {
718
+ window.__STORYBOOK_ADDONS_CHANNEL__.once(STORY_RENDERED, callback);
719
+ window.__STORYBOOK_ADDONS_CHANNEL__.emit(UPDATE_STORY_ARGS, {
720
+ storyId,
721
+ updatedArgs,
722
+ });
723
+ },
724
+ story.id,
725
+ updatedArgs,
726
+ UPDATE_STORY_ARGS,
727
+ STORY_RENDERED,
728
+ );
729
+ }
730
+
731
+ export async function closeBrowser(): Promise<void> {
732
+ if (!browser) return;
733
+ try {
734
+ await browser.quit();
735
+ } finally {
736
+ browser = null;
737
+ }
738
+ }
739
+
740
+ export async function switchStory(this: Context): Promise<void> {
741
+ let testOrSuite: Test | Suite | undefined = this.currentTest;
742
+
743
+ if (!testOrSuite) throw new Error("Can't switch story, because test context doesn't have 'currentTest' field");
744
+
745
+ this.testScope.length = 0;
746
+ this.screenshots.length = 0;
747
+ this.testScope.push(this.browserName);
748
+ while (testOrSuite?.title) {
749
+ this.testScope.push(testOrSuite.title);
750
+ testOrSuite = testOrSuite.parent;
751
+ }
752
+ const story = this.currentTest?.ctx?.story as StoryInput | undefined;
753
+
754
+ if (!story) throw new Error(`Current test '${this.testScope.join('/')}' context doesn't have 'story' field`);
755
+
756
+ const { id, title, name, parameters } = story;
757
+ const {
758
+ captureElement = `#${storybookRootID}`,
759
+ waitForReady,
760
+ ignoreElements,
761
+ } = (parameters.creevey ?? {}) as CreeveyStoryParams;
762
+
763
+ browserLogger.debug(`Switching to story ${chalk.cyan(title)}/${chalk.cyan(name)} by id ${chalk.magenta(id)}`);
764
+
765
+ if (captureElement)
766
+ Object.defineProperty(this, 'captureElement', {
767
+ enumerable: true,
768
+ configurable: true,
769
+ get: () => this.browser.findElement(By.css(captureElement)),
770
+ });
771
+ else Reflect.deleteProperty(this, 'captureElement');
772
+
773
+ this.takeScreenshot = () => takeScreenshot(this.browser, captureElement, ignoreElements);
774
+ this.updateStoryArgs = (updatedArgs: Args) => updateStoryArgs(this.browser, story, updatedArgs);
775
+
776
+ this.testScope.reverse();
777
+
778
+ let storyPlayResolver: (isCompleted: boolean) => void;
779
+ let waitForComplete = new Promise<boolean>((resolve) => (storyPlayResolver = resolve));
780
+ const unsubscribe = subscribeOn('stories', (message) => {
781
+ if (message.type != 'capture') return;
782
+ const { payload = {}, payload: { imageName } = {} } = message;
783
+ void takeScreenshot(
784
+ this.browser,
785
+ payload.captureElement ?? captureElement,
786
+ payload.ignoreElements ?? ignoreElements,
787
+ ).then((screenshot) => {
788
+ this.screenshots.push({ imageName, screenshot });
789
+
790
+ void this.browser
791
+ .executeAsyncScript<boolean>(function (callback: (isCompleted: boolean) => void) {
792
+ window.__CREEVEY_HAS_PLAY_COMPLETED_YET__(callback);
793
+ })
794
+ .then((isCompleted) => {
795
+ storyPlayResolver(isCompleted);
796
+ });
797
+
798
+ emitStoriesMessage({ type: 'capture' });
799
+ });
800
+ });
801
+
802
+ await resetMousePosition(this.browser);
803
+ const isCaptureCalled = await selectStory(this.browser, id, waitForReady);
804
+
805
+ if (isCaptureCalled) {
806
+ while (!(await waitForComplete)) {
807
+ waitForComplete = new Promise<boolean>((resolve) => (storyPlayResolver = resolve));
808
+ }
809
+ }
810
+
811
+ unsubscribe();
812
+
813
+ browserLogger.debug(`Story ${chalk.magenta(id)} ready for capturing`);
814
+ }
815
+
816
+ async function insertIgnoreStyles(
817
+ browser: WebDriver,
818
+ ignoreElements?: string | string[] | null,
819
+ ): Promise<WebElement | null> {
820
+ const ignoreSelectors = Array.prototype.concat(ignoreElements).filter(Boolean);
821
+ if (!ignoreSelectors.length) return null;
822
+
823
+ browserLogger.debug('Hiding ignored elements before capturing');
824
+
825
+ return await browser.executeScript(function (ignoreSelectors: string[]) {
826
+ return window.__CREEVEY_INSERT_IGNORE_STYLES__(ignoreSelectors);
827
+ }, ignoreSelectors);
828
+ }
829
+
830
+ async function removeIgnoreStyles(browser: WebDriver, ignoreStyles: WebElement | null): Promise<void> {
831
+ if (ignoreStyles) {
832
+ browserLogger.debug('Revert hiding ignored elements');
833
+ await browser.executeScript(function (ignoreStyles: HTMLStyleElement) {
834
+ window.__CREEVEY_REMOVE_IGNORE_STYLES__(ignoreStyles);
835
+ }, ignoreStyles);
836
+ }
837
+ }