creevey 0.9.0-beta.1 → 0.9.0-non-webpack.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 (267) hide show
  1. package/AUTHORS +15 -15
  2. package/CHANGELOG.md +1275 -1275
  3. package/LICENSE +21 -21
  4. package/README.md +7 -0
  5. package/addon/README.md +3 -0
  6. package/addon/package.json +4 -0
  7. package/docs/config.md +212 -212
  8. package/docs/grid.md +10 -10
  9. package/docs/tests.md +63 -63
  10. package/jest.config.js +6 -0
  11. package/lib/cjs/cli.js +5 -0
  12. package/lib/cjs/client/addon/Manager.js +418 -0
  13. package/lib/cjs/client/addon/components/Addon.js +76 -0
  14. package/lib/cjs/client/addon/components/Icons.js +42 -0
  15. package/lib/cjs/client/addon/components/Panel.js +68 -0
  16. package/lib/cjs/client/addon/components/TestSelect.js +63 -0
  17. package/lib/cjs/client/addon/components/Tools.js +114 -0
  18. package/lib/cjs/client/addon/decorator.js +11 -0
  19. package/lib/cjs/client/addon/index.js +31 -0
  20. package/lib/cjs/client/addon/preset.js +81 -0
  21. package/lib/cjs/client/addon/readyForCapture.js +12 -0
  22. package/lib/cjs/client/addon/register.js +100 -0
  23. package/lib/cjs/client/addon/utils.js +38 -0
  24. package/lib/cjs/client/addon/withCreevey.js +558 -0
  25. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +85 -0
  26. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +88 -0
  27. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +176 -0
  28. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +179 -0
  29. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +110 -0
  30. package/lib/cjs/client/shared/components/ImagesView/index.js +45 -0
  31. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +46 -0
  32. package/lib/cjs/client/shared/components/PageFooter/Paging.js +98 -0
  33. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +78 -0
  34. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +144 -0
  35. package/lib/cjs/client/shared/components/ResultsPage.js +173 -0
  36. package/lib/cjs/client/shared/creeveyClientApi.js +107 -0
  37. package/lib/cjs/client/shared/helpers.js +482 -0
  38. package/lib/cjs/client/shared/viewMode.js +17 -0
  39. package/lib/cjs/client/web/142.js +2 -0
  40. package/lib/cjs/client/web/142.js.LICENSE.txt +12 -0
  41. package/lib/cjs/client/web/32.js +1 -0
  42. package/lib/cjs/client/web/551.js +1 -0
  43. package/lib/cjs/client/web/566.js +2 -0
  44. package/lib/cjs/client/web/566.js.LICENSE.txt +31 -0
  45. package/lib/cjs/client/web/691.js +2 -0
  46. package/lib/cjs/client/web/691.js.LICENSE.txt +8 -0
  47. package/lib/cjs/client/web/725.js +1 -0
  48. package/lib/cjs/client/web/index.html +19 -0
  49. package/lib/cjs/client/web/main.js +2 -38
  50. package/lib/cjs/client/web/main.js.LICENSE.txt +49 -0
  51. package/lib/cjs/creevey.js +69 -0
  52. package/lib/cjs/index.js +62 -0
  53. package/lib/cjs/server/config.js +96 -0
  54. package/lib/cjs/server/docker.js +146 -0
  55. package/lib/cjs/server/extract.js +50 -0
  56. package/lib/cjs/server/index.js +83 -0
  57. package/lib/cjs/server/loaders/babel/creevey-plugin.js +86 -0
  58. package/lib/cjs/server/loaders/babel/helpers.js +469 -0
  59. package/lib/cjs/server/loaders/babel/register.js +124 -0
  60. package/lib/cjs/server/loaders/hooks/mdx.js +30 -0
  61. package/lib/cjs/server/loaders/hooks/svelte.js +65 -0
  62. package/lib/cjs/server/loaders/webpack/compile.js +293 -0
  63. package/lib/cjs/server/loaders/webpack/creevey-loader.js +179 -0
  64. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +39 -0
  65. package/lib/cjs/server/loaders/webpack/mdx-loader.js +72 -0
  66. package/lib/cjs/server/loaders/webpack/start.js +41 -0
  67. package/lib/cjs/server/logger.js +48 -0
  68. package/lib/cjs/server/master/api.js +71 -0
  69. package/lib/cjs/server/master/index.js +146 -0
  70. package/lib/cjs/server/master/master.js +57 -0
  71. package/lib/cjs/server/master/pool.js +197 -0
  72. package/lib/cjs/server/master/runner.js +281 -0
  73. package/lib/cjs/server/master/server.js +129 -0
  74. package/lib/cjs/server/messages.js +264 -0
  75. package/lib/cjs/server/selenium/browser.js +672 -0
  76. package/lib/cjs/server/selenium/index.js +31 -0
  77. package/lib/cjs/server/selenium/selenoid.js +172 -0
  78. package/lib/cjs/server/stories.js +159 -0
  79. package/lib/cjs/server/storybook/entry.js +70 -0
  80. package/lib/cjs/server/storybook/helpers.js +159 -0
  81. package/lib/cjs/server/storybook/providers/browser.js +74 -0
  82. package/lib/cjs/server/storybook/providers/hybrid.js +84 -0
  83. package/lib/cjs/server/storybook/providers/nodejs.js +239 -0
  84. package/lib/cjs/server/testsFiles/parser.js +72 -0
  85. package/lib/cjs/server/testsFiles/register.js +48 -0
  86. package/lib/cjs/server/update.js +79 -0
  87. package/lib/cjs/server/utils.js +183 -0
  88. package/lib/cjs/server/worker/chai-image.js +142 -0
  89. package/lib/cjs/server/worker/helpers.js +69 -0
  90. package/lib/cjs/server/worker/index.js +15 -0
  91. package/lib/cjs/server/worker/reporter.js +108 -0
  92. package/lib/cjs/server/worker/worker.js +268 -0
  93. package/lib/cjs/shared/index.js +89 -0
  94. package/lib/cjs/shared/serializeRegExp.js +41 -0
  95. package/lib/cjs/types.js +74 -0
  96. package/lib/esm/cli.js +4 -0
  97. package/lib/esm/client/addon/Manager.js +402 -0
  98. package/lib/esm/client/addon/components/Addon.js +58 -0
  99. package/lib/esm/client/addon/components/Icons.js +27 -0
  100. package/lib/esm/client/addon/components/Panel.js +49 -0
  101. package/lib/esm/client/addon/components/TestSelect.js +49 -0
  102. package/lib/esm/client/addon/components/Tools.js +91 -0
  103. package/lib/esm/client/addon/decorator.js +2 -0
  104. package/lib/esm/client/addon/index.js +2 -0
  105. package/lib/esm/client/addon/preset.js +56 -0
  106. package/lib/esm/client/addon/readyForCapture.js +5 -0
  107. package/lib/esm/client/addon/register.js +79 -0
  108. package/lib/esm/client/addon/utils.js +31 -0
  109. package/lib/esm/client/addon/withCreevey.js +534 -0
  110. package/lib/esm/client/shared/components/ImagesView/BlendView.js +63 -0
  111. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +65 -0
  112. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +151 -0
  113. package/lib/esm/client/shared/components/ImagesView/SlideView.js +154 -0
  114. package/lib/esm/client/shared/components/ImagesView/SwapView.js +88 -0
  115. package/lib/esm/client/shared/components/ImagesView/index.js +5 -0
  116. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +32 -0
  117. package/lib/esm/client/shared/components/PageFooter/Paging.js +84 -0
  118. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +64 -0
  119. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +120 -0
  120. package/lib/esm/client/shared/components/ResultsPage.js +143 -0
  121. package/lib/esm/client/shared/creeveyClientApi.js +98 -0
  122. package/lib/esm/client/shared/helpers.js +424 -0
  123. package/lib/esm/client/shared/viewMode.js +6 -0
  124. package/lib/esm/creevey.js +54 -0
  125. package/lib/esm/index.js +5 -0
  126. package/lib/esm/server/config.js +73 -0
  127. package/lib/esm/server/docker.js +123 -0
  128. package/lib/esm/server/extract.js +34 -0
  129. package/lib/esm/server/index.js +64 -0
  130. package/lib/esm/server/loaders/babel/creevey-plugin.js +72 -0
  131. package/lib/esm/server/loaders/babel/helpers.js +452 -0
  132. package/lib/esm/server/loaders/babel/register.js +103 -0
  133. package/lib/esm/server/loaders/hooks/mdx.js +15 -0
  134. package/lib/esm/server/loaders/hooks/svelte.js +49 -0
  135. package/lib/esm/server/loaders/webpack/compile.js +270 -0
  136. package/lib/esm/server/loaders/webpack/creevey-loader.js +158 -0
  137. package/lib/esm/server/loaders/webpack/dummy-hmr.js +32 -0
  138. package/lib/esm/server/loaders/webpack/mdx-loader.js +58 -0
  139. package/lib/esm/server/loaders/webpack/start.js +27 -0
  140. package/lib/esm/server/logger.js +20 -0
  141. package/lib/esm/server/master/api.js +60 -0
  142. package/lib/esm/server/master/index.js +125 -0
  143. package/lib/esm/server/master/master.js +38 -0
  144. package/lib/esm/server/master/pool.js +176 -0
  145. package/lib/esm/server/master/runner.js +259 -0
  146. package/lib/esm/server/master/server.js +105 -0
  147. package/lib/esm/server/messages.js +232 -0
  148. package/lib/esm/server/selenium/browser.js +639 -0
  149. package/lib/esm/server/selenium/index.js +2 -0
  150. package/lib/esm/server/selenium/selenoid.js +149 -0
  151. package/lib/esm/server/stories.js +140 -0
  152. package/lib/esm/server/storybook/entry.js +46 -0
  153. package/lib/esm/server/storybook/helpers.js +98 -0
  154. package/lib/esm/server/storybook/providers/browser.js +60 -0
  155. package/lib/esm/server/storybook/providers/hybrid.js +64 -0
  156. package/lib/esm/server/storybook/providers/nodejs.js +217 -0
  157. package/lib/esm/server/testsFiles/parser.js +50 -0
  158. package/lib/esm/server/testsFiles/register.js +35 -0
  159. package/lib/esm/server/update.js +61 -0
  160. package/lib/esm/server/utils.js +142 -0
  161. package/lib/esm/server/worker/chai-image.js +130 -0
  162. package/lib/esm/server/worker/helpers.js +60 -0
  163. package/lib/esm/server/worker/index.js +1 -0
  164. package/lib/esm/server/worker/reporter.js +86 -0
  165. package/lib/esm/server/worker/worker.js +238 -0
  166. package/lib/esm/shared/index.js +66 -0
  167. package/lib/esm/shared/serializeRegExp.js +23 -0
  168. package/lib/esm/types.js +43 -0
  169. package/lib/types/cli.d.ts +1 -1
  170. package/lib/types/client/addon/Manager.d.ts +37 -37
  171. package/lib/types/client/addon/components/Addon.d.ts +8 -8
  172. package/lib/types/client/addon/components/Icons.d.ts +7 -7
  173. package/lib/types/client/addon/components/Panel.d.ts +9 -9
  174. package/lib/types/client/addon/components/TestSelect.d.ts +8 -9
  175. package/lib/types/client/addon/components/Tools.d.ts +6 -6
  176. package/lib/types/client/addon/decorator.d.ts +1 -1
  177. package/lib/types/client/addon/index.d.ts +2 -0
  178. package/lib/types/client/addon/preset.d.ts +23 -24
  179. package/lib/types/client/addon/readyForCapture.d.ts +6 -6
  180. package/lib/types/client/addon/register.d.ts +3 -3
  181. package/lib/types/client/addon/utils.d.ts +2 -2
  182. package/lib/types/client/addon/withCreevey.d.ts +24 -24
  183. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -3
  184. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +24 -25
  185. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -3
  186. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -3
  187. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -3
  188. package/lib/types/client/shared/components/ImagesView/index.d.ts +5 -5
  189. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +8 -9
  190. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +7 -8
  191. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +12 -12
  192. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +16 -17
  193. package/lib/types/client/shared/components/ResultsPage.d.ts +18 -18
  194. package/lib/types/client/shared/creeveyClientApi.d.ts +9 -9
  195. package/lib/types/client/shared/helpers.d.ts +46 -46
  196. package/lib/types/client/shared/viewMode.d.ts +4 -4
  197. package/lib/types/client/web/CreeveyApp.d.ts +11 -12
  198. package/lib/types/client/web/CreeveyContext.d.ts +11 -11
  199. package/lib/types/client/web/CreeveyLoader.d.ts +2 -3
  200. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +19 -19
  201. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  202. package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  203. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +12 -13
  204. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +33 -33
  205. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +7 -8
  206. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +10 -10
  207. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +9 -9
  208. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  209. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +1 -1
  210. package/lib/types/client/web/KeyboardEventsContext.d.ts +13 -13
  211. package/lib/types/client/web/index.d.ts +4 -4
  212. package/lib/types/creevey.d.ts +1 -1
  213. package/lib/types/index.d.ts +1 -4
  214. package/lib/types/server/config.d.ts +4 -4
  215. package/lib/types/server/docker.d.ts +7 -7
  216. package/lib/types/server/extract.d.ts +2 -2
  217. package/lib/types/server/index.d.ts +2 -2
  218. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +1 -1
  219. package/lib/types/server/loaders/babel/helpers.d.ts +19 -19
  220. package/lib/types/server/loaders/babel/register.d.ts +5 -5
  221. package/lib/types/server/loaders/hooks/mdx.d.ts +1 -1
  222. package/lib/types/server/loaders/hooks/svelte.d.ts +1 -1
  223. package/lib/types/server/loaders/webpack/compile.d.ts +2 -2
  224. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +4 -2
  225. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +10 -10
  226. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +6 -6
  227. package/lib/types/server/loaders/webpack/start.d.ts +1 -1
  228. package/lib/types/server/logger.d.ts +10 -6
  229. package/lib/types/server/master/api.d.ts +7 -7
  230. package/lib/types/server/master/index.d.ts +3 -3
  231. package/lib/types/server/master/master.d.ts +7 -7
  232. package/lib/types/server/master/pool.d.ts +31 -31
  233. package/lib/types/server/master/runner.d.ts +26 -26
  234. package/lib/types/server/master/server.d.ts +2 -2
  235. package/lib/types/server/messages.d.ts +27 -27
  236. package/lib/types/server/selenium/browser.d.ts +17 -17
  237. package/lib/types/server/selenium/index.d.ts +2 -2
  238. package/lib/types/server/selenium/selenoid.d.ts +3 -3
  239. package/lib/types/server/stories.d.ts +8 -8
  240. package/lib/types/server/storybook/entry.d.ts +18 -18
  241. package/lib/types/server/storybook/helpers.d.ts +24 -24
  242. package/lib/types/server/storybook/providers/browser.d.ts +4 -4
  243. package/lib/types/server/storybook/providers/hybrid.d.ts +4 -4
  244. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -9
  245. package/lib/types/server/testsFiles/parser.d.ts +12 -12
  246. package/lib/types/server/testsFiles/register.d.ts +2 -2
  247. package/lib/types/server/update.d.ts +2 -2
  248. package/lib/types/server/utils.d.ts +20 -20
  249. package/lib/types/server/worker/chai-image.d.ts +6 -6
  250. package/lib/types/server/worker/helpers.d.ts +8 -8
  251. package/lib/types/server/worker/index.d.ts +1 -1
  252. package/lib/types/server/worker/reporter.d.ts +8 -8
  253. package/lib/types/server/worker/worker.d.ts +4 -4
  254. package/lib/types/{shared.d.ts → shared/index.d.ts} +7 -16
  255. package/lib/types/shared/serializeRegExp.d.ts +9 -0
  256. package/lib/types/types.d.ts +490 -489
  257. package/package.json +115 -102
  258. package/preset.js +9 -9
  259. package/types/babel__register.d.ts +1 -1
  260. package/types/chai.d.ts +12 -12
  261. package/types/event-source-polyfill.d.ts +6 -6
  262. package/types/mdx.d.ts +3 -2
  263. package/types/mocha.d.ts +20 -20
  264. package/types/png.d.ts +4 -4
  265. package/lib/cjs/client/web/1.js +0 -13
  266. package/lib/cjs/client/web/2.js +0 -1
  267. package/storybook-static/stories.json +0 -21
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _path = _interopRequireDefault(require("path"));
9
+
10
+ var _fs = require("fs");
11
+
12
+ var _util = require("util");
13
+
14
+ var _events = require("events");
15
+
16
+ var _types = require("../../types");
17
+
18
+ var _pool = _interopRequireDefault(require("./pool"));
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ const copyFileAsync = (0, _util.promisify)(_fs.copyFile);
23
+ const mkdirAsync = (0, _util.promisify)(_fs.mkdir);
24
+
25
+ class Runner extends _events.EventEmitter {
26
+ pools = {};
27
+ tests = {};
28
+
29
+ get isRunning() {
30
+ return Object.values(this.pools).some(pool => pool.isRunning);
31
+ }
32
+
33
+ constructor(config) {
34
+ super();
35
+ this.failFast = config.failFast;
36
+ this.screenDir = config.screenDir;
37
+ this.reportDir = config.reportDir;
38
+ this.browsers = Object.keys(config.browsers);
39
+ this.browsers.map(browser => this.pools[browser] = new _pool.default(config, browser)).map(pool => pool.on('test', this.handlePoolMessage));
40
+ }
41
+
42
+ handlePoolMessage = message => {
43
+ const {
44
+ id,
45
+ status,
46
+ result
47
+ } = message;
48
+ const test = this.tests[id];
49
+ if (!test) return;
50
+ const {
51
+ browser,
52
+ testName,
53
+ storyPath,
54
+ storyId
55
+ } = test; // TODO Handle 'retrying' status
56
+
57
+ test.status = status == 'retrying' ? 'failed' : status;
58
+
59
+ if (!result) {
60
+ this.sendUpdate({
61
+ tests: {
62
+ [id]: {
63
+ id,
64
+ browser,
65
+ testName,
66
+ storyPath,
67
+ status: test.status,
68
+ storyId
69
+ }
70
+ }
71
+ });
72
+ return;
73
+ }
74
+
75
+ if (!test.results) {
76
+ test.results = [];
77
+ }
78
+
79
+ test.results.push(result);
80
+ this.sendUpdate({
81
+ tests: {
82
+ [id]: {
83
+ id,
84
+ browser,
85
+ testName,
86
+ storyPath,
87
+ status: test.status,
88
+ results: [result],
89
+ storyId
90
+ }
91
+ }
92
+ });
93
+ if (this.failFast && status == 'failed') this.stop();
94
+ };
95
+ handlePoolStop = () => {
96
+ if (!this.isRunning) {
97
+ this.sendUpdate({
98
+ isRunning: false
99
+ });
100
+ this.emit('stop');
101
+ }
102
+ };
103
+
104
+ async init() {
105
+ await Promise.all(Object.values(this.pools).map(pool => pool.init()));
106
+ }
107
+
108
+ updateTests(testsDiff) {
109
+ const tests = {};
110
+ const removedTests = [];
111
+ Object.entries(testsDiff).forEach(([id, newTest]) => {
112
+ const oldTest = this.tests[id];
113
+
114
+ if (newTest) {
115
+ if (oldTest) {
116
+ this.tests[id] = { ...newTest,
117
+ retries: oldTest.retries,
118
+ results: oldTest.results,
119
+ approved: oldTest.approved
120
+ };
121
+ } else this.tests[id] = newTest; // eslint-disable-next-line @typescript-eslint/no-unused-vars
122
+
123
+
124
+ const {
125
+ story,
126
+ fn,
127
+ ...restTest
128
+ } = newTest;
129
+ tests[id] = { ...restTest,
130
+ status: 'unknown'
131
+ };
132
+ } else if (oldTest) {
133
+ const {
134
+ id,
135
+ browser,
136
+ testName,
137
+ storyPath,
138
+ storyId
139
+ } = oldTest;
140
+ removedTests.push({
141
+ id,
142
+ browser,
143
+ testName,
144
+ storyPath,
145
+ storyId
146
+ });
147
+ delete this.tests[id];
148
+ }
149
+ });
150
+ this.sendUpdate({
151
+ tests,
152
+ removedTests
153
+ });
154
+ }
155
+
156
+ start(ids) {
157
+ if (this.isRunning) return;
158
+ const testsToStart = ids.map(id => this.tests[id]).filter(_types.isDefined).filter(test => !test.skip);
159
+ if (testsToStart.length == 0) return;
160
+ this.sendUpdate({
161
+ isRunning: true,
162
+ tests: testsToStart.reduce((update, {
163
+ id,
164
+ storyId,
165
+ browser,
166
+ testName,
167
+ storyPath
168
+ }) => ({ ...update,
169
+ [id]: {
170
+ id,
171
+ browser,
172
+ testName,
173
+ storyPath,
174
+ status: 'pending',
175
+ storyId
176
+ }
177
+ }), {})
178
+ });
179
+ const testsByBrowser = testsToStart.reduce((tests, test) => {
180
+ const {
181
+ id,
182
+ browser,
183
+ testName,
184
+ storyPath
185
+ } = test;
186
+ const restPath = [...storyPath, testName].filter(_types.isDefined);
187
+ test.status = 'pending';
188
+ return { ...tests,
189
+ [browser]: [...(tests[browser] || []), {
190
+ id,
191
+ path: restPath
192
+ }]
193
+ };
194
+ }, {});
195
+ this.browsers.forEach(browser => {
196
+ const pool = this.pools[browser];
197
+ const tests = testsByBrowser[browser];
198
+
199
+ if (tests && tests.length > 0 && pool.start(tests)) {
200
+ pool.once('stop', this.handlePoolStop);
201
+ }
202
+ });
203
+ }
204
+
205
+ stop() {
206
+ if (!this.isRunning) return;
207
+ this.browsers.forEach(browser => this.pools[browser].stop());
208
+ }
209
+
210
+ get status() {
211
+ const tests = {};
212
+ Object.values(this.tests).filter(_types.isDefined) // eslint-disable-next-line @typescript-eslint/no-unused-vars
213
+ .forEach(({
214
+ story,
215
+ fn,
216
+ ...test
217
+ }) => tests[test.id] = test);
218
+ return {
219
+ isRunning: this.isRunning,
220
+ tests,
221
+ browsers: this.browsers
222
+ };
223
+ }
224
+
225
+ async approve({
226
+ id,
227
+ retry,
228
+ image
229
+ }) {
230
+ const test = this.tests[id];
231
+ if (!test || !test.results) return;
232
+ const result = test.results[retry];
233
+ if (!result || !result.images) return;
234
+ const images = result.images[image];
235
+ if (!images) return;
236
+
237
+ if (!test.approved) {
238
+ test.approved = {};
239
+ }
240
+
241
+ const {
242
+ browser,
243
+ testName,
244
+ storyPath
245
+ } = test;
246
+ const restPath = [...storyPath, testName].filter(_types.isDefined);
247
+
248
+ const testPath = _path.default.join(...restPath, image == browser ? '' : browser);
249
+
250
+ const srcImagePath = _path.default.join(this.reportDir, testPath, images.actual);
251
+
252
+ const dstImagePath = _path.default.join(this.screenDir, testPath, `${image}.png`);
253
+
254
+ await mkdirAsync(_path.default.join(this.screenDir, testPath), {
255
+ recursive: true
256
+ });
257
+ await copyFileAsync(srcImagePath, dstImagePath);
258
+ test.approved[image] = retry;
259
+ this.sendUpdate({
260
+ tests: {
261
+ [id]: {
262
+ id,
263
+ browser,
264
+ testName,
265
+ storyPath,
266
+ approved: {
267
+ [image]: retry
268
+ },
269
+ storyId: test.storyId
270
+ }
271
+ }
272
+ });
273
+ }
274
+
275
+ sendUpdate(data) {
276
+ this.emit('update', data);
277
+ }
278
+
279
+ }
280
+
281
+ exports.default = Runner;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = server;
7
+
8
+ var _path = _interopRequireDefault(require("path"));
9
+
10
+ var _http = _interopRequireDefault(require("http"));
11
+
12
+ var _cluster = _interopRequireDefault(require("cluster"));
13
+
14
+ var _koa = _interopRequireDefault(require("koa"));
15
+
16
+ var _cors = _interopRequireDefault(require("@koa/cors"));
17
+
18
+ var _koaStatic = _interopRequireDefault(require("koa-static"));
19
+
20
+ var _koaMount = _interopRequireDefault(require("koa-mount"));
21
+
22
+ var _koaBodyparser = _interopRequireDefault(require("koa-bodyparser"));
23
+
24
+ var _ws = _interopRequireDefault(require("ws"));
25
+
26
+ var _messages = require("../messages");
27
+
28
+ var _types = require("../../types");
29
+
30
+ var _logger = require("../logger");
31
+
32
+ var _shared = require("../../shared");
33
+
34
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
+
36
+ function server(reportDir, port, ui) {
37
+ let resolveApi = _types.noop;
38
+ let setStoriesCounter = 0;
39
+ const creeveyApi = new Promise(resolve => resolveApi = resolve);
40
+ const app = new _koa.default();
41
+
42
+ const server = _http.default.createServer(app.callback());
43
+
44
+ const wss = new _ws.default.Server({
45
+ server
46
+ });
47
+ app.use((0, _cors.default)());
48
+ app.use((0, _koaBodyparser.default)());
49
+ app.use(async (ctx, next) => {
50
+ if (ctx.method == 'GET' && ctx.path == '/ping') {
51
+ ctx.body = 'pong';
52
+ return;
53
+ }
54
+
55
+ await next();
56
+ });
57
+
58
+ if (ui) {
59
+ app.use(async (_, next) => {
60
+ await creeveyApi;
61
+ await next();
62
+ });
63
+ }
64
+
65
+ app.use(async (ctx, next) => {
66
+ if (ctx.method == 'POST' && ctx.path == '/stories') {
67
+ const {
68
+ setStoriesCounter: counter,
69
+ stories
70
+ } = ctx.request.body;
71
+ if (setStoriesCounter >= counter) return;
72
+ const deserializedStories = stories.map(([file, stories]) => [file, stories.map(_shared.deserializeStory)]);
73
+ setStoriesCounter = counter;
74
+ (0, _messages.emitStoriesMessage)({
75
+ type: 'update',
76
+ payload: deserializedStories
77
+ });
78
+ Object.values(_cluster.default.workers ?? {}).filter(_types.isDefined).filter(worker => worker.isConnected()).forEach(worker => (0, _messages.sendStoriesMessage)(worker, {
79
+ type: 'update',
80
+ payload: deserializedStories
81
+ }));
82
+ return;
83
+ }
84
+
85
+ await next();
86
+ });
87
+ app.use(async (ctx, next) => {
88
+ if (ctx.method == 'POST' && ctx.path == '/capture') {
89
+ const {
90
+ workerId,
91
+ options
92
+ } = ctx.request.body;
93
+ const worker = Object.values(_cluster.default.workers ?? {}).filter(_types.isDefined).find(worker => worker.process.pid == workerId); // NOTE: Hypothetical case when someone send to us capture req and we don't have a worker with browser session for it
94
+
95
+ if (!worker) return;
96
+ await new Promise(resolve => {
97
+ const unsubscribe = (0, _messages.subscribeOnWorker)(worker, 'stories', message => {
98
+ if (message.type != 'capture') return;
99
+ unsubscribe();
100
+ resolve();
101
+ });
102
+ (0, _messages.sendStoriesMessage)(worker, {
103
+ type: 'capture',
104
+ payload: options
105
+ });
106
+ }); // TODO Pass screenshot result to show it in inspector
107
+
108
+ ctx.body = 'Ok';
109
+ return;
110
+ }
111
+
112
+ await next();
113
+ });
114
+ app.use((0, _koaStatic.default)(_path.default.join(__dirname, '../../client/web')));
115
+ app.use((0, _koaMount.default)('/report', (0, _koaStatic.default)(reportDir)));
116
+ wss.on('error', error => _logger.logger.error(error));
117
+ server.listen(port);
118
+ (0, _messages.subscribeOn)('shutdown', () => {
119
+ server.close();
120
+ wss.close();
121
+ });
122
+ void creeveyApi.then(api => {
123
+ api.subscribe(wss);
124
+ wss.on('connection', ws => {
125
+ ws.on('message', message => api.handleMessage(ws, message));
126
+ });
127
+ });
128
+ return resolveApi;
129
+ }
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.emitDockerMessage = emitDockerMessage;
7
+ exports.emitShutdownMessage = emitShutdownMessage;
8
+ exports.emitStoriesMessage = emitStoriesMessage;
9
+ exports.emitTestMessage = emitTestMessage;
10
+ exports.emitWebpackMessage = emitWebpackMessage;
11
+ exports.emitWorkerMessage = emitWorkerMessage;
12
+ exports.sendDockerMessage = sendDockerMessage;
13
+ exports.sendShutdownMessage = sendShutdownMessage;
14
+ exports.sendStoriesMessage = sendStoriesMessage;
15
+ exports.sendTestMessage = sendTestMessage;
16
+ exports.subscribeOn = subscribeOn;
17
+ exports.subscribeOnWorker = subscribeOnWorker;
18
+
19
+ var _cluster = _interopRequireDefault(require("cluster"));
20
+
21
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
+
23
+ function emitMessage(message) {
24
+ var _process$send, _process;
25
+
26
+ if (_cluster.default.isWorker && !process.connected) return false;
27
+ return ((_process$send = (_process = process).send) === null || _process$send === void 0 ? void 0 : _process$send.call(_process, message)) ?? // @ts-expect-error: wrong typings `process.emit` return boolean
28
+ process.emit('message', message);
29
+ }
30
+
31
+ function emitWorkerMessage(message) {
32
+ return emitMessage({
33
+ scope: 'worker',
34
+ ...message
35
+ });
36
+ }
37
+
38
+ function emitStoriesMessage(message) {
39
+ return emitMessage({
40
+ scope: 'stories',
41
+ ...message
42
+ });
43
+ }
44
+
45
+ function emitTestMessage(message) {
46
+ return emitMessage({
47
+ scope: 'test',
48
+ ...message
49
+ });
50
+ }
51
+
52
+ function emitWebpackMessage(message) {
53
+ return emitMessage({
54
+ scope: 'webpack',
55
+ ...message
56
+ });
57
+ }
58
+
59
+ function emitDockerMessage(message) {
60
+ return emitMessage({
61
+ scope: 'docker',
62
+ ...message
63
+ });
64
+ }
65
+
66
+ function emitShutdownMessage() {
67
+ return emitMessage({
68
+ scope: 'shutdown'
69
+ });
70
+ }
71
+
72
+ function createHandlers() {
73
+ return Object.assign(Object.create(null), {
74
+ worker: new Set(),
75
+ stories: new Set(),
76
+ test: new Set(),
77
+ webpack: new Set(),
78
+ docker: new Set(),
79
+ shutdown: new Set()
80
+ });
81
+ }
82
+
83
+ const handlers = createHandlers();
84
+
85
+ const handler = message => {
86
+ switch (message.scope) {
87
+ case 'worker':
88
+ return handlers.worker.forEach(h => h(message));
89
+
90
+ case 'stories':
91
+ return handlers.stories.forEach(h => h(message));
92
+
93
+ case 'test':
94
+ return handlers.test.forEach(h => h(message));
95
+
96
+ case 'webpack':
97
+ return handlers.webpack.forEach(h => h(message));
98
+
99
+ case 'docker':
100
+ return handlers.docker.forEach(h => h(message));
101
+
102
+ case 'shutdown':
103
+ return handlers.shutdown.forEach(h => h(message));
104
+ }
105
+ };
106
+
107
+ process.on('message', handler);
108
+
109
+ function sendStoriesMessage(target, message) {
110
+ var _target$send;
111
+
112
+ (_target$send = target.send) === null || _target$send === void 0 ? void 0 : _target$send.call(target, {
113
+ scope: 'stories',
114
+ ...message
115
+ });
116
+ }
117
+
118
+ function sendTestMessage(target, message) {
119
+ var _target$send2;
120
+
121
+ (_target$send2 = target.send) === null || _target$send2 === void 0 ? void 0 : _target$send2.call(target, {
122
+ scope: 'test',
123
+ ...message
124
+ });
125
+ }
126
+
127
+ function sendDockerMessage(target, message) {
128
+ var _target$send3;
129
+
130
+ (_target$send3 = target.send) === null || _target$send3 === void 0 ? void 0 : _target$send3.call(target, {
131
+ scope: 'docker',
132
+ ...message
133
+ });
134
+ }
135
+
136
+ function sendShutdownMessage(target) {
137
+ var _target$send4;
138
+
139
+ (_target$send4 = target.send) === null || _target$send4 === void 0 ? void 0 : _target$send4.call(target, {
140
+ scope: 'shutdown'
141
+ });
142
+ }
143
+
144
+ function subscribeOn(scope, handler) {
145
+ switch (scope) {
146
+ case 'worker':
147
+ {
148
+ const workerHandler = handler;
149
+ handlers.worker.add(workerHandler);
150
+ return () => handlers.worker.delete(workerHandler);
151
+ }
152
+
153
+ case 'stories':
154
+ {
155
+ const storiesHandler = handler;
156
+ handlers.stories.add(storiesHandler);
157
+ return () => handlers.stories.delete(storiesHandler);
158
+ }
159
+
160
+ case 'test':
161
+ {
162
+ const testHandler = handler;
163
+ handlers.test.add(testHandler);
164
+ return () => handlers.test.delete(testHandler);
165
+ }
166
+
167
+ case 'webpack':
168
+ {
169
+ const webpackHandler = handler;
170
+ handlers.webpack.add(webpackHandler);
171
+ return () => handlers.webpack.delete(webpackHandler);
172
+ }
173
+
174
+ case 'docker':
175
+ {
176
+ const dockerHandler = handler;
177
+ handlers.docker.add(dockerHandler);
178
+ return () => handlers.docker.delete(dockerHandler);
179
+ }
180
+
181
+ case 'shutdown':
182
+ {
183
+ const shutdownHandler = handler;
184
+ handlers.shutdown.add(shutdownHandler);
185
+ return () => handlers.shutdown.delete(shutdownHandler);
186
+ }
187
+ }
188
+ }
189
+
190
+ const workers = new Map();
191
+
192
+ function subscribeOnWorker(worker, scope, handler) {
193
+ const workerHandlers = workers.get(worker) ?? createHandlers();
194
+
195
+ if (!workers.has(worker)) {
196
+ workers.set(worker, workerHandlers);
197
+ worker.once('exit', () => workers.delete(worker));
198
+ worker.on('message', message => {
199
+ switch (message.scope) {
200
+ case 'worker':
201
+ return workerHandlers.worker.forEach(h => h(message));
202
+
203
+ case 'stories':
204
+ return workerHandlers.stories.forEach(h => h(message));
205
+
206
+ case 'test':
207
+ return workerHandlers.test.forEach(h => h(message));
208
+
209
+ case 'webpack':
210
+ return workerHandlers.webpack.forEach(h => h(message));
211
+
212
+ case 'docker':
213
+ return workerHandlers.docker.forEach(h => h(message));
214
+
215
+ case 'shutdown':
216
+ return workerHandlers.shutdown.forEach(h => h(message));
217
+ }
218
+ });
219
+ }
220
+
221
+ switch (scope) {
222
+ case 'worker':
223
+ {
224
+ const workerHandler = handler;
225
+ workerHandlers.worker.add(workerHandler);
226
+ return () => workerHandlers.worker.delete(workerHandler);
227
+ }
228
+
229
+ case 'stories':
230
+ {
231
+ const storiesHandler = handler;
232
+ workerHandlers.stories.add(storiesHandler);
233
+ return () => workerHandlers.stories.delete(storiesHandler);
234
+ }
235
+
236
+ case 'test':
237
+ {
238
+ const testHandler = handler;
239
+ workerHandlers.test.add(testHandler);
240
+ return () => workerHandlers.test.delete(testHandler);
241
+ }
242
+
243
+ case 'webpack':
244
+ {
245
+ const webpackHandler = handler;
246
+ workerHandlers.webpack.add(webpackHandler);
247
+ return () => workerHandlers.webpack.delete(webpackHandler);
248
+ }
249
+
250
+ case 'docker':
251
+ {
252
+ const dockerHandler = handler;
253
+ workerHandlers.docker.add(dockerHandler);
254
+ return () => workerHandlers.docker.delete(dockerHandler);
255
+ }
256
+
257
+ case 'shutdown':
258
+ {
259
+ const shutdownHandler = handler;
260
+ workerHandlers.shutdown.add(shutdownHandler);
261
+ return () => workerHandlers.shutdown.delete(shutdownHandler);
262
+ }
263
+ }
264
+ }