creevey 0.10.0-beta.8 → 0.10.0-rc.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 (350) hide show
  1. package/AUTHORS +2 -0
  2. package/CHANGELOG.md +281 -0
  3. package/README.md +19 -41
  4. package/dist/client/addon/components/Addon.js +18 -8
  5. package/dist/client/addon/components/Addon.js.map +1 -1
  6. package/dist/client/addon/components/Panel.js +4 -4
  7. package/dist/client/addon/components/Panel.js.map +1 -1
  8. package/dist/client/addon/components/TestSelect.js +2 -2
  9. package/dist/client/addon/components/TestSelect.js.map +1 -1
  10. package/dist/client/addon/components/Tools.js +19 -9
  11. package/dist/client/addon/components/Tools.js.map +1 -1
  12. package/dist/client/addon/controller.d.ts +1 -1
  13. package/dist/client/addon/controller.js +3 -3
  14. package/dist/client/addon/controller.js.map +1 -1
  15. package/dist/client/addon/decorator.d.ts +1 -1
  16. package/dist/client/addon/makeDecorator.d.ts +9 -0
  17. package/dist/client/addon/makeDecorator.js +48 -0
  18. package/dist/client/addon/makeDecorator.js.map +1 -0
  19. package/dist/client/addon/manager.js +38 -39
  20. package/dist/client/addon/manager.js.map +1 -1
  21. package/dist/client/addon/preset.d.ts +0 -1
  22. package/dist/client/addon/preset.js +3 -2
  23. package/dist/client/addon/preset.js.map +1 -1
  24. package/dist/client/addon/preview.d.ts +1 -1
  25. package/dist/client/addon/withCreevey.d.ts +5 -3
  26. package/dist/client/addon/withCreevey.js +14 -21
  27. package/dist/client/addon/withCreevey.js.map +1 -1
  28. package/dist/client/shared/components/ImagesView/BlendView.d.ts +2 -2
  29. package/dist/client/shared/components/ImagesView/BlendView.js +18 -8
  30. package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
  31. package/dist/client/shared/components/ImagesView/ImagesView.js +1 -1
  32. package/dist/client/shared/components/ImagesView/ImagesView.js.map +1 -1
  33. package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +2 -2
  34. package/dist/client/shared/components/ImagesView/SideBySideView.js +19 -9
  35. package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
  36. package/dist/client/shared/components/ImagesView/SlideView.d.ts +2 -2
  37. package/dist/client/shared/components/ImagesView/SlideView.js +19 -9
  38. package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
  39. package/dist/client/shared/components/ImagesView/SwapView.d.ts +2 -2
  40. package/dist/client/shared/components/ImagesView/SwapView.js +31 -9
  41. package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
  42. package/dist/client/shared/components/ImagesView/common.d.ts +1 -1
  43. package/dist/client/shared/components/PageFooter/PageFooter.js +1 -1
  44. package/dist/client/shared/components/PageFooter/PageFooter.js.map +1 -1
  45. package/dist/client/shared/components/PageFooter/Paging.js +1 -1
  46. package/dist/client/shared/components/PageFooter/Paging.js.map +1 -1
  47. package/dist/client/shared/components/PageHeader/ImagePreview.d.ts +2 -2
  48. package/dist/client/shared/components/PageHeader/ImagePreview.js +2 -1
  49. package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
  50. package/dist/client/shared/components/PageHeader/PageHeader.js +34 -13
  51. package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
  52. package/dist/client/shared/components/ResultsPage.d.ts +2 -2
  53. package/dist/client/shared/components/ResultsPage.js +45 -15
  54. package/dist/client/shared/components/ResultsPage.js.map +1 -1
  55. package/dist/client/shared/creeveyClientApi.js +18 -1
  56. package/dist/client/shared/creeveyClientApi.js.map +1 -1
  57. package/dist/client/shared/helpers.d.ts +1 -3
  58. package/dist/client/shared/helpers.js +4 -19
  59. package/dist/client/shared/helpers.js.map +1 -1
  60. package/dist/client/web/CreeveyApp.d.ts +1 -0
  61. package/dist/client/web/CreeveyApp.js +44 -15
  62. package/dist/client/web/CreeveyApp.js.map +1 -1
  63. package/dist/client/web/CreeveyContext.d.ts +6 -0
  64. package/dist/client/web/CreeveyContext.js +21 -7
  65. package/dist/client/web/CreeveyContext.js.map +1 -1
  66. package/dist/client/web/CreeveyLoader.d.ts +1 -1
  67. package/dist/client/web/CreeveyLoader.js +3 -3
  68. package/dist/client/web/CreeveyLoader.js.map +1 -1
  69. package/dist/client/web/CreeveyView/SideBar/Checkbox.d.ts +4 -4
  70. package/dist/client/web/CreeveyView/SideBar/Checkbox.js +36 -6
  71. package/dist/client/web/CreeveyView/SideBar/Checkbox.js.map +1 -1
  72. package/dist/client/web/CreeveyView/SideBar/Search.js +20 -10
  73. package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
  74. package/dist/client/web/CreeveyView/SideBar/SideBar.js +26 -12
  75. package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
  76. package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +67 -13
  77. package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
  78. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +32 -12
  79. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
  80. package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
  81. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +20 -13
  82. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
  83. package/dist/client/web/CreeveyView/SideBar/TestLink.js +20 -13
  84. package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
  85. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +2 -2
  86. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js +2 -2
  87. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js.map +1 -1
  88. package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +2 -2
  89. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js +3 -2
  90. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js.map +1 -1
  91. package/dist/client/web/CreeveyView/SideBar/Toggle.js +1 -1
  92. package/dist/client/web/CreeveyView/SideBar/Toggle.js.map +1 -1
  93. package/dist/client/web/KeyboardEventsContext.d.ts +1 -8
  94. package/dist/client/web/KeyboardEventsContext.js +79 -64
  95. package/dist/client/web/KeyboardEventsContext.js.map +1 -1
  96. package/dist/client/web/assets/index-CtSq3IhG.js +518 -0
  97. package/dist/client/web/index.html +1 -1
  98. package/dist/client/web/index.js +26 -11
  99. package/dist/client/web/index.js.map +1 -1
  100. package/dist/client/web/themes.d.ts +2 -0
  101. package/dist/client/web/themes.js +22 -0
  102. package/dist/client/web/themes.js.map +1 -0
  103. package/dist/creevey.d.ts +1 -1
  104. package/dist/creevey.js +122 -41
  105. package/dist/creevey.js.map +1 -1
  106. package/dist/index.d.ts +1 -0
  107. package/dist/playwright/generator.d.ts +25 -0
  108. package/dist/playwright/generator.js +243 -0
  109. package/dist/playwright/generator.js.map +1 -0
  110. package/dist/playwright/helpers.d.ts +2 -0
  111. package/dist/playwright/helpers.js +29 -0
  112. package/dist/playwright/helpers.js.map +1 -0
  113. package/dist/playwright/reporter.d.ts +83 -0
  114. package/dist/playwright/reporter.js +334 -0
  115. package/dist/playwright/reporter.js.map +1 -0
  116. package/dist/playwright/setup.d.ts +3 -0
  117. package/dist/playwright/setup.js +72 -0
  118. package/dist/playwright/setup.js.map +1 -0
  119. package/dist/playwright.d.ts +1 -0
  120. package/dist/playwright.js +3 -1
  121. package/dist/playwright.js.map +1 -1
  122. package/dist/server/compare.d.ts +18 -0
  123. package/dist/server/compare.js +182 -0
  124. package/dist/server/compare.js.map +1 -0
  125. package/dist/server/config.d.ts +3 -3
  126. package/dist/server/config.js +75 -8
  127. package/dist/server/config.js.map +1 -1
  128. package/dist/server/connection.d.ts +3 -0
  129. package/dist/server/connection.js +28 -0
  130. package/dist/server/connection.js.map +1 -0
  131. package/dist/server/docker.d.ts +1 -1
  132. package/dist/server/docker.js +54 -32
  133. package/dist/server/docker.js.map +1 -1
  134. package/dist/server/index.d.ts +2 -2
  135. package/dist/server/index.js +165 -64
  136. package/dist/server/index.js.map +1 -1
  137. package/dist/server/master/api.d.ts +11 -6
  138. package/dist/server/master/api.js +88 -25
  139. package/dist/server/master/api.js.map +1 -1
  140. package/dist/server/master/handlers/capture-handler.d.ts +5 -0
  141. package/dist/server/master/handlers/capture-handler.js +25 -0
  142. package/dist/server/master/handlers/capture-handler.js.map +1 -0
  143. package/dist/server/master/handlers/index.d.ts +4 -0
  144. package/dist/server/master/handlers/index.js +21 -0
  145. package/dist/server/master/handlers/index.js.map +1 -0
  146. package/dist/server/master/handlers/ping-handler.d.ts +2 -0
  147. package/dist/server/master/handlers/ping-handler.js +8 -0
  148. package/dist/server/master/handlers/ping-handler.js.map +1 -0
  149. package/dist/server/master/handlers/static-handler.d.ts +1 -0
  150. package/dist/server/master/handlers/static-handler.js +20 -0
  151. package/dist/server/master/handlers/static-handler.js.map +1 -0
  152. package/dist/server/master/handlers/stories-handler.d.ts +4 -0
  153. package/dist/server/master/handlers/stories-handler.js +24 -0
  154. package/dist/server/master/handlers/stories-handler.js.map +1 -0
  155. package/dist/server/master/master.js +7 -24
  156. package/dist/server/master/master.js.map +1 -1
  157. package/dist/server/master/pool.d.ts +1 -0
  158. package/dist/server/master/pool.js +5 -3
  159. package/dist/server/master/pool.js.map +1 -1
  160. package/dist/server/master/queue.d.ts +1 -1
  161. package/dist/server/master/queue.js +14 -6
  162. package/dist/server/master/queue.js.map +1 -1
  163. package/dist/server/master/runner.d.ts +6 -6
  164. package/dist/server/master/runner.js +98 -130
  165. package/dist/server/master/runner.js.map +1 -1
  166. package/dist/server/master/server.d.ts +1 -1
  167. package/dist/server/master/server.js +193 -88
  168. package/dist/server/master/server.js.map +1 -1
  169. package/dist/server/master/start.d.ts +1 -2
  170. package/dist/server/master/start.js +13 -29
  171. package/dist/server/master/start.js.map +1 -1
  172. package/dist/server/master/testsManager.d.ts +81 -0
  173. package/dist/server/master/testsManager.js +282 -0
  174. package/dist/server/master/testsManager.js.map +1 -0
  175. package/dist/server/playwright/docker-file.d.ts +1 -1
  176. package/dist/server/playwright/docker-file.js +17 -8
  177. package/dist/server/playwright/docker-file.js.map +1 -1
  178. package/dist/server/playwright/docker.d.ts +2 -1
  179. package/dist/server/playwright/docker.js +10 -2
  180. package/dist/server/playwright/docker.js.map +1 -1
  181. package/dist/server/playwright/index-source.mjs +16 -0
  182. package/dist/server/playwright/internal.d.ts +7 -7
  183. package/dist/server/playwright/internal.js +144 -84
  184. package/dist/server/playwright/internal.js.map +1 -1
  185. package/dist/server/playwright/webdriver.d.ts +3 -3
  186. package/dist/server/playwright/webdriver.js +0 -6
  187. package/dist/server/playwright/webdriver.js.map +1 -1
  188. package/dist/server/providers/browser.js +4 -3
  189. package/dist/server/providers/browser.js.map +1 -1
  190. package/dist/server/providers/hybrid.js +2 -2
  191. package/dist/server/providers/hybrid.js.map +1 -1
  192. package/dist/server/report.d.ts +10 -0
  193. package/dist/server/report.js +45 -0
  194. package/dist/server/report.js.map +1 -0
  195. package/dist/server/reporters/creevey.d.ts +7 -0
  196. package/dist/server/reporters/creevey.js +63 -0
  197. package/dist/server/reporters/creevey.js.map +1 -0
  198. package/dist/server/reporters/index.d.ts +2 -0
  199. package/dist/server/reporters/index.js +16 -0
  200. package/dist/server/reporters/index.js.map +1 -0
  201. package/dist/server/reporters/junit.d.ts +16 -0
  202. package/dist/server/reporters/junit.js +167 -0
  203. package/dist/server/reporters/junit.js.map +1 -0
  204. package/dist/server/reporters/teamcity.d.ts +7 -0
  205. package/dist/server/reporters/teamcity.js +60 -0
  206. package/dist/server/reporters/teamcity.js.map +1 -0
  207. package/dist/server/selenium/internal.d.ts +4 -4
  208. package/dist/server/selenium/internal.js +56 -40
  209. package/dist/server/selenium/internal.js.map +1 -1
  210. package/dist/server/selenium/selenoid.js +12 -6
  211. package/dist/server/selenium/selenoid.js.map +1 -1
  212. package/dist/server/selenium/webdriver.d.ts +3 -3
  213. package/dist/server/selenium/webdriver.js +4 -8
  214. package/dist/server/selenium/webdriver.js.map +1 -1
  215. package/dist/server/shutdown.d.ts +1 -0
  216. package/dist/server/shutdown.js +23 -0
  217. package/dist/server/shutdown.js.map +1 -0
  218. package/dist/server/stories.d.ts +0 -1
  219. package/dist/server/stories.js +0 -12
  220. package/dist/server/stories.js.map +1 -1
  221. package/dist/server/telemetry.js +3 -3
  222. package/dist/server/telemetry.js.map +1 -1
  223. package/dist/server/testsFiles/parser.js +45 -5
  224. package/dist/server/testsFiles/parser.js.map +1 -1
  225. package/dist/server/utils.d.ts +23 -0
  226. package/dist/server/utils.js +114 -15
  227. package/dist/server/utils.js.map +1 -1
  228. package/dist/server/webdriver.d.ts +1 -1
  229. package/dist/server/worker/context.d.ts +3 -0
  230. package/dist/server/worker/context.js +15 -0
  231. package/dist/server/worker/context.js.map +1 -0
  232. package/dist/server/worker/match-image.d.ts +8 -12
  233. package/dist/server/worker/match-image.js +11 -178
  234. package/dist/server/worker/match-image.js.map +1 -1
  235. package/dist/server/worker/start.d.ts +2 -2
  236. package/dist/server/worker/start.js +41 -64
  237. package/dist/server/worker/start.js.map +1 -1
  238. package/dist/shared/index.d.ts +1 -1
  239. package/dist/shared/index.js +9 -7
  240. package/dist/shared/index.js.map +1 -1
  241. package/dist/types.d.ts +84 -43
  242. package/dist/types.js +65 -1
  243. package/dist/types.js.map +1 -1
  244. package/docs/cli.md +80 -0
  245. package/docs/config.md +179 -165
  246. package/docs/examples/playwright-reporer/playwright.config.ts +37 -0
  247. package/docs/migration-0.9-to-0.10.md +144 -0
  248. package/docs/playwright-reporter.md +357 -0
  249. package/docs/storybook.md +60 -0
  250. package/docs/tests.md +50 -45
  251. package/package.json +78 -83
  252. package/playwright.config.mts +46 -0
  253. package/src/client/addon/components/Addon.tsx +1 -1
  254. package/src/client/addon/components/Panel.tsx +4 -4
  255. package/src/client/addon/components/TestSelect.tsx +2 -2
  256. package/src/client/addon/components/Tools.tsx +2 -2
  257. package/src/client/addon/controller.ts +4 -4
  258. package/src/client/addon/makeDecorator.ts +69 -0
  259. package/src/client/addon/manager.ts +38 -37
  260. package/src/client/addon/preset.ts +2 -1
  261. package/src/client/addon/withCreevey.ts +16 -19
  262. package/src/client/shared/components/ImagesView/BlendView.tsx +1 -1
  263. package/src/client/shared/components/ImagesView/ImagesView.tsx +1 -1
  264. package/src/client/shared/components/ImagesView/SideBySideView.tsx +2 -2
  265. package/src/client/shared/components/ImagesView/SlideView.tsx +2 -2
  266. package/src/client/shared/components/ImagesView/SwapView.tsx +20 -2
  267. package/src/client/shared/components/ImagesView/common.ts +1 -1
  268. package/src/client/shared/components/PageFooter/PageFooter.tsx +1 -1
  269. package/src/client/shared/components/PageFooter/Paging.tsx +1 -1
  270. package/src/client/shared/components/PageHeader/ImagePreview.tsx +2 -1
  271. package/src/client/shared/components/PageHeader/PageHeader.tsx +23 -7
  272. package/src/client/shared/components/ResultsPage.tsx +33 -10
  273. package/src/client/shared/creeveyClientApi.ts +19 -1
  274. package/src/client/shared/helpers.ts +4 -24
  275. package/src/client/web/CreeveyApp.tsx +30 -9
  276. package/src/client/web/CreeveyContext.tsx +11 -0
  277. package/src/client/web/CreeveyLoader.tsx +2 -2
  278. package/src/client/web/CreeveyView/SideBar/Checkbox.tsx +3 -3
  279. package/src/client/web/CreeveyView/SideBar/Search.tsx +4 -4
  280. package/src/client/web/CreeveyView/SideBar/SideBar.tsx +11 -6
  281. package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +48 -15
  282. package/src/client/web/CreeveyView/SideBar/SideBarHeader.tsx +20 -5
  283. package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +12 -12
  284. package/src/client/web/CreeveyView/SideBar/TestLink.tsx +10 -10
  285. package/src/client/web/CreeveyView/SideBar/TestStatusIcon.tsx +2 -2
  286. package/src/client/web/CreeveyView/SideBar/TestsStatus.tsx +3 -2
  287. package/src/client/web/CreeveyView/SideBar/Toggle.tsx +1 -1
  288. package/src/client/web/KeyboardEventsContext.tsx +61 -73
  289. package/src/client/web/index.tsx +10 -5
  290. package/src/client/web/themes.ts +24 -0
  291. package/src/creevey.ts +92 -38
  292. package/src/playwright/generator.ts +322 -0
  293. package/src/playwright/helpers.ts +31 -0
  294. package/src/playwright/reporter.ts +381 -0
  295. package/src/playwright/setup.ts +84 -0
  296. package/src/playwright.ts +1 -0
  297. package/src/server/compare.ts +260 -0
  298. package/src/server/config.ts +52 -9
  299. package/src/server/connection.ts +26 -0
  300. package/src/server/docker.ts +62 -34
  301. package/src/server/index.ts +166 -79
  302. package/src/server/master/api.ts +94 -28
  303. package/src/server/master/handlers/capture-handler.ts +20 -0
  304. package/src/server/master/handlers/index.ts +4 -0
  305. package/src/server/master/handlers/ping-handler.ts +6 -0
  306. package/src/server/master/handlers/static-handler.ts +16 -0
  307. package/src/server/master/handlers/stories-handler.ts +20 -0
  308. package/src/server/master/master.ts +10 -27
  309. package/src/server/master/pool.ts +7 -3
  310. package/src/server/master/queue.ts +21 -7
  311. package/src/server/master/runner.ts +123 -134
  312. package/src/server/master/server.ts +214 -101
  313. package/src/server/master/start.ts +19 -41
  314. package/src/server/master/testsManager.ts +316 -0
  315. package/src/server/playwright/docker-file.ts +20 -8
  316. package/src/server/playwright/docker.ts +16 -3
  317. package/src/server/playwright/index-source.mjs +16 -0
  318. package/src/server/playwright/internal.ts +176 -103
  319. package/src/server/playwright/webdriver.ts +4 -10
  320. package/src/server/providers/browser.ts +4 -3
  321. package/src/server/providers/hybrid.ts +2 -3
  322. package/src/server/report.ts +51 -0
  323. package/src/server/reporters/creevey.ts +71 -0
  324. package/src/server/reporters/index.ts +11 -0
  325. package/src/server/reporters/junit.ts +207 -0
  326. package/src/server/reporters/teamcity.ts +74 -0
  327. package/src/server/selenium/internal.ts +70 -53
  328. package/src/server/selenium/selenoid.ts +13 -6
  329. package/src/server/selenium/webdriver.ts +8 -12
  330. package/src/server/shutdown.ts +19 -0
  331. package/src/server/stories.ts +1 -12
  332. package/src/server/telemetry.ts +3 -3
  333. package/src/server/testsFiles/parser.ts +52 -4
  334. package/src/server/utils.ts +124 -16
  335. package/src/server/webdriver.ts +1 -1
  336. package/src/server/worker/context.ts +14 -0
  337. package/src/server/worker/match-image.ts +16 -248
  338. package/src/server/worker/start.ts +49 -79
  339. package/src/shared/index.ts +10 -8
  340. package/src/types.ts +91 -58
  341. package/types/global.d.ts +1 -0
  342. package/dist/client/web/assets/index-DB8lHlJw.js +0 -591
  343. package/dist/server/reporter.d.ts +0 -26
  344. package/dist/server/reporter.js +0 -108
  345. package/dist/server/reporter.js.map +0 -1
  346. package/dist/server/update.d.ts +0 -2
  347. package/dist/server/update.js +0 -53
  348. package/dist/server/update.js.map +0 -1
  349. package/src/server/reporter.ts +0 -139
  350. package/src/server/update.ts +0 -74
@@ -0,0 +1,357 @@
1
+ # Playwright Reporter for Creevey
2
+
3
+ Creevey provides a Playwright-compatible reporter that allows you to use Creevey's image comparison, reporting, and UI features with Playwright tests.
4
+
5
+ ## Installation
6
+
7
+ The reporter is included with the Creevey package. Install Playwright and Creevey in your project:
8
+
9
+ ```bash
10
+ npm install --save-dev @playwright/test creevey
11
+ ```
12
+
13
+ ## Configuration
14
+
15
+ Add the Creevey reporter to your Playwright configuration file:
16
+
17
+ ```typescript
18
+ // playwright.config.ts
19
+ import { defineConfig } from '@playwright/test';
20
+
21
+ export default defineConfig({
22
+ reporter: [
23
+ ['list'], // Standard Playwright reporter for console output
24
+ [
25
+ 'creevey/playwright-reporter',
26
+ {
27
+ // Optional configuration options
28
+ reportDir: './report', // Directory for report output
29
+ screenDir: './images', // Directory for reference images
30
+ port: 3000, // Port for Creevey UI server
31
+ debug: false, // Enable debug logging
32
+ },
33
+ ],
34
+ ],
35
+ // Other Playwright configuration...
36
+ });
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Taking Screenshots for Comparison
42
+
43
+ The reporter automatically collects screenshots taken during Playwright tests. You can use Playwright's built-in screenshot capabilities:
44
+
45
+ #### Using `page.screenshot()`
46
+
47
+ ```typescript
48
+ import { test, expect } from '@playwright/test';
49
+
50
+ test('capture screenshot with page.screenshot', async ({ page }) => {
51
+ await page.goto('https://example.com');
52
+
53
+ // Take a screenshot and attach it to the test result
54
+ const screenshot = await page.screenshot();
55
+ await test.info().attach('example-screenshot', {
56
+ body: screenshot,
57
+ contentType: 'image/png',
58
+ });
59
+ });
60
+ ```
61
+
62
+ #### Using Playwright's expect().toHaveScreenshot()
63
+
64
+ ```typescript
65
+ import { test, expect } from '@playwright/test';
66
+
67
+ test('capture screenshot with toHaveScreenshot', async ({ page }) => {
68
+ await page.goto('https://example.com');
69
+
70
+ // This will automatically be picked up by the Creevey reporter
71
+ await expect(page).toHaveScreenshot('example-screenshot.png');
72
+ });
73
+ ```
74
+
75
+ ### Adding Creevey Metadata
76
+
77
+ You can add metadata to your tests to better organize them in the Creevey UI:
78
+
79
+ ```typescript
80
+ import { test } from '@playwright/test';
81
+
82
+ test.describe('Homepage', () => {
83
+ test('header elements @creevey{"storyPath": ["Website", "HomePage"], "browser": "chromium"}', async ({ page }) => {
84
+ await page.goto('https://example.com');
85
+ // Test code...
86
+ await page.screenshot({ path: 'header.png' });
87
+ });
88
+ });
89
+ ```
90
+
91
+ The `@creevey` annotation accepts a JSON object with the following properties:
92
+
93
+ - `storyPath`: Array of strings defining the hierarchy in the Creevey UI
94
+ - `browser`: Browser name (chromium, firefox, webkit)
95
+ - `testName`: Custom test name (defaults to the test title)
96
+
97
+ ### Viewing Results
98
+
99
+ After running your tests, you can view the results in the Creevey UI:
100
+
101
+ 1. Open your browser and navigate to `http://localhost:3000` (or the port you configured)
102
+ 2. Browse test results, view image comparisons, and approve changes
103
+
104
+ Run your tests with Playwright:
105
+
106
+ ```bash
107
+ npx playwright test
108
+ ```
109
+
110
+ The Creevey server will automatically start during the test run, and you'll see a message with the URL once tests complete.
111
+
112
+ ### Approving Screenshots
113
+
114
+ You can approve screenshots directly from the Creevey UI by:
115
+
116
+ 1. Selecting the test with the failed comparison
117
+ 2. Reviewing the differences between expected and actual images
118
+ 3. Clicking the "Approve" button to update the reference image
119
+
120
+ ## Advanced Usage
121
+
122
+ ### Custom Screenshot Names
123
+
124
+ You can customize screenshot names to better organize your visual tests:
125
+
126
+ ```typescript
127
+ test('product page layout', async ({ page }) => {
128
+ await page.goto('https://example.com/products/1');
129
+
130
+ // Take multiple screenshots in a single test
131
+ await test.info().attach('product-header', {
132
+ body: await page.locator('.product-header').screenshot(),
133
+ contentType: 'image/png',
134
+ });
135
+
136
+ await test.info().attach('product-details', {
137
+ body: await page.locator('.product-details').screenshot(),
138
+ contentType: 'image/png',
139
+ });
140
+ });
141
+ ```
142
+
143
+ ### Multiple Screenshots in One Test
144
+
145
+ You can capture multiple screenshots in a single test:
146
+
147
+ ```typescript
148
+ test('responsive design checks', async ({ page }) => {
149
+ await page.goto('https://example.com');
150
+
151
+ // Mobile view
152
+ await page.setViewportSize({ width: 375, height: 667 });
153
+ await test.info().attach('mobile-view', {
154
+ body: await page.screenshot(),
155
+ contentType: 'image/png',
156
+ });
157
+
158
+ // Tablet view
159
+ await page.setViewportSize({ width: 768, height: 1024 });
160
+ await test.info().attach('tablet-view', {
161
+ body: await page.screenshot(),
162
+ contentType: 'image/png',
163
+ });
164
+
165
+ // Desktop view
166
+ await page.setViewportSize({ width: 1280, height: 800 });
167
+ await test.info().attach('desktop-view', {
168
+ body: await page.screenshot(),
169
+ contentType: 'image/png',
170
+ });
171
+ });
172
+ ```
173
+
174
+ ### Custom Test Names
175
+
176
+ By default, the reporter will use the Playwright test title as the test name. You can customize how tests are named by setting meta data:
177
+
178
+ ```typescript
179
+ test('home page visual test', async ({ page }) => {
180
+ test.info().annotations.push({
181
+ type: 'creevey',
182
+ description: JSON.stringify({
183
+ testName: 'custom-test-name',
184
+ browser: 'chrome', // Optional, to override browser name
185
+ }),
186
+ });
187
+
188
+ // Test implementation...
189
+ });
190
+ ```
191
+
192
+ ### Integration with Existing Creevey Configuration
193
+
194
+ If you're already using Creevey for other tests, you can share configuration:
195
+
196
+ ```typescript
197
+ import { defineConfig } from '@playwright/test';
198
+ import creeveyConfig from './creevey.config.js';
199
+
200
+ export default defineConfig({
201
+ reporter: [
202
+ ['list'],
203
+ [
204
+ 'creevey/playwright-reporter',
205
+ {
206
+ reportDir: creeveyConfig.reportDir,
207
+ screenDir: creeveyConfig.screenDir,
208
+ port: 3001, // Use a different port to avoid conflicts
209
+ },
210
+ ],
211
+ ],
212
+ });
213
+ ```
214
+
215
+ ### Test Steps Integration
216
+
217
+ The reporter supports Playwright's test steps, capturing screenshots at each step:
218
+
219
+ ```typescript
220
+ test('multi-step test', async ({ page }) => {
221
+ await test.step('Step 1: Navigate to home', async () => {
222
+ await page.goto('/');
223
+ // Screenshot captured from this step will be associated with "Step 1"
224
+ await test.info().attach('step1', {
225
+ body: await page.screenshot(),
226
+ contentType: 'image/png',
227
+ });
228
+ });
229
+
230
+ await test.step('Step 2: Click button', async () => {
231
+ await page.click('.button');
232
+ // This screenshot will be associated with "Step 2"
233
+ await test.info().attach('step2', {
234
+ body: await page.screenshot(),
235
+ contentType: 'image/png',
236
+ });
237
+ });
238
+ });
239
+ ```
240
+
241
+ ### Integration with Existing Creevey Server
242
+
243
+ If you're already running a Creevey server, you can configure the reporter to use it:
244
+
245
+ ```typescript
246
+ [
247
+ CreeveyPlaywrightReporter,
248
+ {
249
+ useExistingServer: true, // Don't start a new server
250
+ port: 3000, // Port of the existing server
251
+ },
252
+ ];
253
+ ```
254
+
255
+ ### Performance Optimization
256
+
257
+ For large test suites with many screenshots, you can enable performance optimizations:
258
+
259
+ ```typescript
260
+ [
261
+ CreeveyPlaywrightReporter,
262
+ {
263
+ batchProcessing: true, // Process screenshots in batches
264
+ maxConcurrency: 4, // Maximum concurrent screenshot processing
265
+ lazyInit: true, // Initialize components on demand
266
+ },
267
+ ];
268
+ ```
269
+
270
+ ## API Reference
271
+
272
+ ### Reporter Options
273
+
274
+ | Option | Type | Default | Description |
275
+ | ------------------------- | ------- | ------------ | ----------------------------------------------------- |
276
+ | `reportDir` | string | `'./report'` | Directory where Creevey will store reports |
277
+ | `screenDir` | string | `'./images'` | Directory where reference images are stored |
278
+ | `port` | number | `3000` | Port number for the Creevey UI server |
279
+ | `debug` | boolean | `false` | Enable debug logging |
280
+ | `uiEnabled` | boolean | `true` | Enable or disable the UI server |
281
+ | `useExistingServer` | boolean | `false` | Use an existing Creevey server instance |
282
+ | `batchProcessing` | boolean | `false` | Process screenshots in batches for better performance |
283
+ | `maxConcurrency` | number | `2` | Maximum concurrent screenshot processing operations |
284
+ | `lazyInit` | boolean | `false` | Initialize components on demand for faster startup |
285
+ | `retainOrphanedImages` | boolean | `false` | Keep images not associated with current tests |
286
+ | `customComparisonOptions` | object | `undefined` | Custom options for image comparison |
287
+
288
+ ## Troubleshooting
289
+
290
+ ### Common Issues
291
+
292
+ - **Port conflicts**: If the Creevey server fails to start, it might be due to port conflicts. Change the port in the configuration.
293
+ - **Missing screenshots**: Ensure your tests are attaching screenshots with unique names or using `toHaveScreenshot()`.
294
+ - **Path issues**: If reference images aren't found, check that the `screenDir` path is correct and accessible.
295
+
296
+ If screenshots are not appearing in the Creevey UI:
297
+
298
+ 1. Ensure your screenshots are being properly attached to test results
299
+ 2. Check that the content type is set to 'image/png' when attaching
300
+ 3. Enable debug mode in the reporter configuration to see detailed logs
301
+
302
+ ### Server Issues
303
+
304
+ If the Creevey server fails to start:
305
+
306
+ 1. Check if the configured port is already in use
307
+ 2. Ensure the report directory is writable
308
+ 3. Look for error messages in the console output
309
+
310
+ ### Debug Mode
311
+
312
+ Enable debug logging for more detailed information:
313
+
314
+ ```typescript
315
+ [
316
+ CreeveyPlaywrightReporter,
317
+ {
318
+ debug: true,
319
+ // Other options...
320
+ },
321
+ ];
322
+ ```
323
+
324
+ ## Error Handling
325
+
326
+ The reporter is designed to handle errors gracefully:
327
+
328
+ - If the reporter fails to initialize, tests will still run and screenshots will be captured when possible
329
+ - If the server can't start, the reporter will continue to capture screenshots but the UI won't be available
330
+ - All errors are logged with appropriate severity levels and won't cause your tests to fail
331
+
332
+ ### Debugging Reporter Issues
333
+
334
+ For detailed debugging information, enable debug mode and check the logs:
335
+
336
+ ```typescript
337
+ [
338
+ CreeveyPlaywrightReporter,
339
+ {
340
+ debug: true,
341
+ },
342
+ ];
343
+ ```
344
+
345
+ You can also specify a custom log file for the reporter:
346
+
347
+ ```typescript
348
+ [
349
+ CreeveyPlaywrightReporter,
350
+ {
351
+ debug: true,
352
+ logFile: './creevey-reporter.log',
353
+ },
354
+ ];
355
+ ```
356
+
357
+ For more help, please check the main Creevey documentation or open an issue on GitHub.
@@ -0,0 +1,60 @@
1
+ ## Creevey Storybook Parameters
2
+
3
+ Creevey allows you to customize how stories will be captured. You could define parameters on `global`, `kind` or `story` levels. All these parameters are deeply merged by Storybook for each story.
4
+
5
+ ```ts
6
+ // .storybook/preview.tsx
7
+ export const parameters = {
8
+ creevey: {
9
+ // Global parameters are applied to all stories
10
+ captureElement: '#storybook-root',
11
+ },
12
+ };
13
+ ```
14
+
15
+ ```ts
16
+ // stories/MyModal.stories.tsx
17
+ import React from 'react';
18
+ import { Meta, StoryObj } from '@storybook/react';
19
+ import { CreeveyMeta, CreeveyStory } from 'creevey';
20
+ import MyModal from './src/components/MyModal';
21
+
22
+ const Kind: Meta<typeof MyModal> = {
23
+ title: 'MyModal',
24
+ component: MyModal,
25
+ parameters: {
26
+ creevey: {
27
+ // It's possible to add additional delay before capturing screenshot
28
+ delay: 1000,
29
+
30
+ // For capturing the whole browser viewport, you can define `null` instead of css selector.
31
+ captureElement: null,
32
+
33
+ // You can skip some stories from capturing, by defining `skip` option:
34
+ // skip: { "The reason why story is skipped": { in: 'chrome', stories: 'Loading' } }
35
+ // - `in` - browser name, regex or array of browser names, which are defined in the Creevey config
36
+ // - `stories` - story name, regex or array of story names
37
+ // - `tests` - test name, regex or array of test names
38
+ // NOTE: If you try to skip stories by story name, the storybook name format will be used
39
+ // For more info see [storybook-export-vs-name-handling](https://storybook.js.org/docs/formats/component-story-format/#storybook-export-vs-name-handling))
40
+ skip: {
41
+ "`MyModal` doesn't support ie11": { in: 'ie11' },
42
+ 'Loading stories are flaky in firefox': { in: 'firefox', stories: 'Loading' },
43
+ "`MyModal` hovering doesn't work correctly": {
44
+ in: ['firefox', 'chrome'],
45
+ tests: /.*hover$/,
46
+ },
47
+ },
48
+ },
49
+ },
50
+ };
51
+
52
+ export default Kind;
53
+
54
+ export const Basic: StoryObj<typeof MyModal> = {
55
+ creevey: {
56
+ // Lastly some elements can be ignored in capturing screenshot
57
+ ignoreElements: ['button', '.local-time'],
58
+ },
59
+ };
60
+ ```
package/docs/tests.md CHANGED
@@ -1,63 +1,68 @@
1
- ## Write tests
1
+ ## Write interactive screenshot tests
2
2
 
3
- By default Creevey generate for each story very simple screenshot test. In most cases it would be enough to test your UI. But you may want to do some interactions and capture one or multiple screenshots with different states of your story. For this case you could write custom tests, like this
3
+ In most cases following Storybook's ideology of [writing stories](https://storybook.js.org/docs/get-started/whats-a-story) is enough to test your UI components. Where each component has a separate stories file with its different states. But sometimes you might have pretty complicated components with a lot of interactions and internal states. In this case, you can write tests for your stories.
4
4
 
5
- ```tsx
6
- import React from 'react';
7
- import { Story } from '@storybook/react';
8
- import { CreeveyStory } from 'creevey';
9
- import MyComponent from './src/components/MyComponent';
5
+ There are two different ways how to write interactive tests with Creevey:
10
6
 
11
- export default { title: 'MyComponent' };
7
+ ### Write tests in `*.creevey.ts` files
12
8
 
13
- export const Basic: Story & CreeveyStory = () => <MyComponent />;
14
- Basic.parameters = {
15
- creevey: {
16
- captureElement: '#storybook-root',
17
- tests: {
18
- async click() {
19
- await this.browser.actions().click(this.captureElement).perform();
9
+ It's the recommended way to write tests. It allows you to run these tests by Creevey itself and utilize webdriver benefits. The crucial part of it is webdriver action calls are more close to real user interactions and mitigate flakiness and false-negative results. Here is a simple example of how to write tests in `*.creevey.ts` files
20
10
 
21
- await this.expect(await this.takeScreenshot()).to.matchImage('clicked component');
22
- },
23
- },
24
- },
25
- };
11
+ ```ts
12
+ // stories/MyComponent.creevey.ts
13
+ import { kind, story, test } from 'creevey';
14
+
15
+ kind('MyComponent', () => {
16
+ story('Story', ({ setStoryParameters }) => {
17
+ // It's possible to pass Creevey parameters to story
18
+ setStoryParameters({
19
+ captureElement: 'span[data-test-id~="x"]',
20
+ ignoreElements: [],
21
+ });
22
+
23
+ test('idle', async (context) => {
24
+ await context.matchImage(await context.takeScreenshot());
25
+ });
26
+
27
+ test('input', async (context) => {
28
+ await context.webdriver.keyboard.press('Tab');
29
+ const focus = await context.takeScreenshot();
30
+ await context.webdriver.keyboard.type('Hello Creevey');
31
+ const input = await context.takeScreenshot();
32
+ await context.matchImages({ focus, input });
33
+ });
34
+ });
35
+ });
26
36
  ```
27
37
 
28
- NOTE: Here you define story parameters with simple test `click`. Where you setup capturing element `#storybook-root` then click on that element and taking screenshot to assert it. `this.browser` allow you to access to native selenium webdriver instance you could check [API here](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html).
38
+ In the example above, we used Playwright API to interact with the story. But Creevey also supports Selenium webdriver. And in that case `context.webdriver` will be an instance of Selenium webdriver. Obviously Selenium API is different from Playwright.
29
39
 
30
- You also could write more powerful tests with asserting multiple screenshots
40
+ ### Using Storybook's `play` function
31
41
 
32
- ```tsx
33
- import React from 'react';
34
- import { CSFStory } from 'creevey';
35
- import MyForm from './src/components/MyForm';
42
+ Storybook allows you to write tests in the story file itself by using [`play` function](https://storybook.js.org/docs/writing-tests/component-testing). It's a good way to write simple tests. But there are couple drawbacks of this approach:
36
43
 
37
- export default { title: 'MyForm' };
44
+ - You can have only one test per story. Which is not a big deal, but sometimes you might not want to have multiple stories with the same markup.
45
+ - Tests are running in browser environment and use https://testing-library.com API under the hood. It's good for unit tests, but might not be suitable for visual regression tests, because testing-library relies on DOM API and not even close to real user interactions. For example, you might have a button that could be visible for user, but it's covered by some other transparent element. With testing-library the button easily accessible and clickable, but the user can't interact with it.
38
46
 
39
- export const Basic: CSFStory<JSX.Element> = () => <MyForm />;
40
- Basic.story = {
41
- parameters: {
42
- creevey: {
43
- captureElement: '#storybook-root',
44
- delay: 1000,
45
- tests: {
46
- async submit() {
47
- const input = await this.browser.findElement({ css: '.my-input' });
47
+ Here is an example of how to write tests using Storybook's `play` function:
48
48
 
49
- const empty = await this.takeScreenshot();
49
+ ```tsx
50
+ // stories/MyComponent.stories.tsx
51
+ import React from 'react';
52
+ import { Meta, StoryObj } from '@storybook/react';
53
+ import { fireEvent, within } from '@storybook/test';
54
+ import MyComponent from './src/components/MyComponent';
50
55
 
51
- await this.browser.actions().click(input).sendKeys('Hello Creevey').sendKeys(this.keys.ENTER).perform();
56
+ export default {
57
+ title: 'MyComponent',
58
+ component: MyComponent,
59
+ };
52
60
 
53
- const submitted = await this.takeScreenshot();
61
+ export const Basic: StoryObj<typeof MyComponent> = {
62
+ play: async ({ canvasElement }) => {
63
+ const slider = await within(canvasElement).findByTestId('slider');
54
64
 
55
- await this.expect({ empty, submitted }).to.matchImages();
56
- },
57
- },
58
- },
65
+ await fireEvent.change(slider, { target: { value: 50 } });
59
66
  },
60
67
  };
61
68
  ```
62
-
63
- NOTE: In this example I fill some simple form and submit it. Also as you could see, I taking two different screenshots `empty` and `submitted` and assert these in the end.