creevey 0.8.0-beta.0 → 0.8.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 (199) hide show
  1. package/CHANGELOG.md +30 -7
  2. package/README.md +9 -1
  3. package/addon/README.md +3 -0
  4. package/addon/package.json +4 -0
  5. package/docs/config.md +29 -26
  6. package/jest.config.js +6 -0
  7. package/lib/cjs/client/addon/Manager.js +122 -271
  8. package/lib/cjs/client/addon/components/Addon.js +17 -38
  9. package/lib/cjs/client/addon/components/Icons.js +11 -7
  10. package/lib/cjs/client/addon/components/Panel.js +17 -13
  11. package/lib/cjs/client/addon/components/TestSelect.js +11 -9
  12. package/lib/cjs/client/addon/components/Tools.js +21 -40
  13. package/lib/cjs/client/addon/decorator.js +1 -1
  14. package/lib/cjs/client/addon/index.js +31 -0
  15. package/lib/cjs/client/addon/preset.ie11.js +74 -0
  16. package/lib/cjs/client/addon/preset.js +13 -31
  17. package/lib/cjs/client/addon/readyForCapture.js +12 -0
  18. package/lib/cjs/client/addon/register.js +46 -70
  19. package/lib/cjs/client/addon/utils.js +6 -2
  20. package/lib/cjs/client/addon/withCreevey.js +221 -155
  21. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +26 -24
  22. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +22 -18
  23. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +44 -66
  24. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +38 -50
  25. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +26 -45
  26. package/lib/cjs/client/shared/components/ImagesView/index.js +9 -9
  27. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +12 -8
  28. package/lib/cjs/client/shared/components/PageFooter/Paging.js +14 -18
  29. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +22 -18
  30. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +42 -67
  31. package/lib/cjs/client/shared/components/ResultsPage.js +39 -69
  32. package/lib/cjs/client/shared/creeveyClientApi.js +55 -82
  33. package/lib/cjs/client/shared/helpers.js +140 -211
  34. package/lib/cjs/client/shared/viewMode.js +5 -5
  35. package/lib/cjs/client/web/142.js +2 -0
  36. package/lib/cjs/client/web/142.js.LICENSE.txt +12 -0
  37. package/lib/cjs/client/web/32.js +1 -0
  38. package/lib/cjs/client/web/551.js +1 -0
  39. package/lib/cjs/client/web/566.js +2 -0
  40. package/lib/cjs/client/web/566.js.LICENSE.txt +31 -0
  41. package/lib/cjs/client/web/691.js +2 -0
  42. package/lib/cjs/client/web/691.js.LICENSE.txt +8 -0
  43. package/lib/cjs/client/web/725.js +1 -0
  44. package/lib/cjs/client/web/main.js +2 -38
  45. package/lib/cjs/client/web/main.js.LICENSE.txt +49 -0
  46. package/lib/cjs/creevey.js +3 -5
  47. package/lib/cjs/index.js +10 -15
  48. package/lib/cjs/server/config.js +5 -4
  49. package/lib/cjs/server/docker.js +3 -7
  50. package/lib/cjs/server/extract.js +7 -4
  51. package/lib/cjs/server/index.js +3 -5
  52. package/lib/cjs/server/loaders/babel/creevey-plugin.js +1 -3
  53. package/lib/cjs/server/loaders/babel/helpers.js +13 -23
  54. package/lib/cjs/server/loaders/babel/register.js +2 -4
  55. package/lib/cjs/server/loaders/webpack/compile.js +34 -51
  56. package/lib/cjs/server/loaders/webpack/creevey-loader.js +20 -22
  57. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +2 -7
  58. package/lib/cjs/server/loaders/webpack/mdx-loader.js +2 -2
  59. package/lib/cjs/server/loaders/webpack/start.js +1 -1
  60. package/lib/cjs/server/logger.js +2 -1
  61. package/lib/cjs/server/master/index.js +4 -4
  62. package/lib/cjs/server/master/master.js +1 -0
  63. package/lib/cjs/server/master/pool.js +38 -47
  64. package/lib/cjs/server/master/runner.js +53 -66
  65. package/lib/cjs/server/master/server.js +78 -4
  66. package/lib/cjs/server/messages.js +128 -18
  67. package/lib/cjs/server/selenium/browser.js +129 -55
  68. package/lib/cjs/server/selenium/selenoid.js +5 -7
  69. package/lib/cjs/server/stories.js +58 -72
  70. package/lib/cjs/server/storybook/entry.js +7 -22
  71. package/lib/cjs/server/storybook/helpers.js +20 -27
  72. package/lib/cjs/server/storybook/providers/browser.js +74 -0
  73. package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +37 -20
  74. package/lib/cjs/server/update.js +1 -5
  75. package/lib/cjs/server/utils.js +26 -35
  76. package/lib/cjs/server/worker/helpers.js +2 -6
  77. package/lib/cjs/server/worker/reporter.js +8 -20
  78. package/lib/cjs/server/worker/worker.js +21 -19
  79. package/lib/cjs/shared/index.js +101 -0
  80. package/lib/cjs/shared/serializeRegExp.js +42 -0
  81. package/lib/cjs/types.js +11 -6
  82. package/lib/esm/client/addon/Manager.js +122 -271
  83. package/lib/esm/client/addon/components/Addon.js +15 -34
  84. package/lib/esm/client/addon/components/Icons.js +10 -6
  85. package/lib/esm/client/addon/components/Panel.js +17 -13
  86. package/lib/esm/client/addon/components/TestSelect.js +11 -9
  87. package/lib/esm/client/addon/components/Tools.js +19 -36
  88. package/lib/esm/client/addon/decorator.js +1 -1
  89. package/lib/esm/client/addon/index.js +2 -0
  90. package/lib/esm/client/addon/preset.ie11.js +59 -0
  91. package/lib/esm/client/addon/preset.js +12 -26
  92. package/lib/esm/client/addon/readyForCapture.js +5 -0
  93. package/lib/esm/client/addon/register.js +42 -66
  94. package/lib/esm/client/addon/utils.js +3 -2
  95. package/lib/esm/client/addon/withCreevey.js +209 -156
  96. package/lib/esm/client/shared/components/ImagesView/BlendView.js +23 -20
  97. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +21 -17
  98. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +42 -63
  99. package/lib/esm/client/shared/components/ImagesView/SlideView.js +36 -47
  100. package/lib/esm/client/shared/components/ImagesView/SwapView.js +24 -42
  101. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +12 -8
  102. package/lib/esm/client/shared/components/PageFooter/Paging.js +14 -18
  103. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +22 -18
  104. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +37 -60
  105. package/lib/esm/client/shared/components/ResultsPage.js +36 -64
  106. package/lib/esm/client/shared/creeveyClientApi.js +57 -84
  107. package/lib/esm/client/shared/helpers.js +124 -195
  108. package/lib/esm/client/shared/viewMode.js +4 -4
  109. package/lib/esm/creevey.js +3 -5
  110. package/lib/esm/index.js +2 -3
  111. package/lib/esm/server/config.js +4 -5
  112. package/lib/esm/server/docker.js +2 -2
  113. package/lib/esm/server/extract.js +6 -4
  114. package/lib/esm/server/index.js +3 -4
  115. package/lib/esm/server/loaders/babel/creevey-plugin.js +1 -3
  116. package/lib/esm/server/loaders/babel/helpers.js +12 -22
  117. package/lib/esm/server/loaders/babel/register.js +3 -5
  118. package/lib/esm/server/loaders/webpack/compile.js +35 -52
  119. package/lib/esm/server/loaders/webpack/creevey-loader.js +9 -10
  120. package/lib/esm/server/loaders/webpack/dummy-hmr.js +2 -6
  121. package/lib/esm/server/loaders/webpack/mdx-loader.js +2 -2
  122. package/lib/esm/server/loaders/webpack/start.js +1 -1
  123. package/lib/esm/server/master/index.js +4 -4
  124. package/lib/esm/server/master/master.js +1 -0
  125. package/lib/esm/server/master/pool.js +38 -49
  126. package/lib/esm/server/master/runner.js +53 -66
  127. package/lib/esm/server/master/server.js +76 -6
  128. package/lib/esm/server/messages.js +118 -14
  129. package/lib/esm/server/selenium/browser.js +126 -57
  130. package/lib/esm/server/selenium/selenoid.js +4 -6
  131. package/lib/esm/server/stories.js +58 -70
  132. package/lib/esm/server/storybook/entry.js +5 -22
  133. package/lib/esm/server/storybook/helpers.js +11 -20
  134. package/lib/esm/server/storybook/providers/browser.js +60 -0
  135. package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +35 -19
  136. package/lib/esm/server/update.js +1 -5
  137. package/lib/esm/server/utils.js +18 -31
  138. package/lib/esm/server/worker/helpers.js +2 -6
  139. package/lib/esm/server/worker/reporter.js +8 -20
  140. package/lib/esm/server/worker/worker.js +22 -20
  141. package/lib/esm/shared/index.js +78 -0
  142. package/lib/esm/shared/serializeRegExp.js +24 -0
  143. package/lib/esm/types.js +3 -0
  144. package/lib/types/client/addon/Manager.d.ts +2 -2
  145. package/lib/types/client/addon/components/TestSelect.d.ts +0 -1
  146. package/lib/types/client/addon/index.d.ts +2 -0
  147. package/lib/types/client/addon/preset.d.ts +2 -1
  148. package/lib/types/client/addon/preset.ie11.d.ts +10 -0
  149. package/lib/types/client/addon/readyForCapture.d.ts +6 -0
  150. package/lib/types/client/addon/utils.d.ts +1 -0
  151. package/lib/types/client/addon/withCreevey.d.ts +13 -2
  152. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +1 -1
  153. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +0 -1
  154. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +1 -1
  155. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +1 -1
  156. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +1 -1
  157. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +0 -1
  158. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +0 -1
  159. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +1 -1
  160. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +0 -1
  161. package/lib/types/client/shared/components/ResultsPage.d.ts +1 -1
  162. package/lib/types/client/web/CreeveyApp.d.ts +0 -1
  163. package/lib/types/client/web/CreeveyLoader.d.ts +1 -2
  164. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +1 -1
  165. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +0 -1
  166. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
  167. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +0 -1
  168. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +1 -1
  169. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +1 -1
  170. package/lib/types/index.d.ts +0 -1
  171. package/lib/types/server/loaders/babel/register.d.ts +1 -1
  172. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +4 -2
  173. package/lib/types/server/logger.d.ts +6 -2
  174. package/lib/types/server/master/master.d.ts +1 -0
  175. package/lib/types/server/master/pool.d.ts +1 -0
  176. package/lib/types/server/master/server.d.ts +1 -1
  177. package/lib/types/server/messages.d.ts +17 -6
  178. package/lib/types/server/selenium/browser.d.ts +5 -2
  179. package/lib/types/server/stories.d.ts +2 -2
  180. package/lib/types/server/storybook/entry.d.ts +2 -3
  181. package/lib/types/server/storybook/helpers.d.ts +1 -1
  182. package/lib/types/server/storybook/providers/browser.d.ts +4 -0
  183. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
  184. package/lib/types/server/utils.d.ts +5 -1
  185. package/lib/types/server/worker/helpers.d.ts +2 -1
  186. package/lib/types/shared/index.d.ts +7 -0
  187. package/lib/types/shared/serializeRegExp.d.ts +9 -0
  188. package/lib/types/types.d.ts +32 -5
  189. package/package.json +120 -103
  190. package/preset/ie11.js +5 -0
  191. package/{preset.js → preset/index.js} +2 -2
  192. package/types/mdx.d.ts +3 -2
  193. package/types/mocha.d.ts +1 -0
  194. package/lib/cjs/client/web/1.js +0 -13
  195. package/lib/cjs/client/web/2.js +0 -1
  196. package/lib/cjs/shared.js +0 -35
  197. package/lib/esm/shared.js +0 -22
  198. package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
  199. package/lib/types/shared.d.ts +0 -4
@@ -1,6 +1,5 @@
1
1
  import cluster from 'cluster';
2
2
  import { readConfig, defaultBrowser } from './config';
3
- import { noop } from '../types';
4
3
  import { logger } from './logger'; // NOTE: Impure function, mutate config by adding gridUrl prop
5
4
 
6
5
  async function startWebdriverServer(config, options) {
@@ -22,8 +21,7 @@ export default async function (options) {
22
21
  ui,
23
22
  port
24
23
  } = options;
25
- if (!config) return;
26
- const resolveApi = ui && cluster.isMaster ? (await import('./master/server')).default(config.reportDir, port) : noop; // NOTE: We don't need docker nor selenoid for webpack or update options
24
+ if (!config) return; // NOTE: We don't need docker nor selenoid for webpack or update options
27
25
 
28
26
  if (!(config.gridUrl || Object.values(config.browsers).every(({
29
27
  gridUrl
@@ -48,9 +46,10 @@ export default async function (options) {
48
46
  return (await import('./loaders/webpack/compile')).default(config, options);
49
47
  }
50
48
 
51
- case cluster.isMaster:
49
+ case cluster.isPrimary:
52
50
  {
53
51
  logger.info('Starting Master Process');
52
+ const resolveApi = (await import('./master/server')).default(config.reportDir, port, ui);
54
53
  return (await import('./master')).default(config, options, resolveApi);
55
54
  }
56
55
 
@@ -7,9 +7,7 @@ const reexportedStories = new Map();
7
7
  export default function () {
8
8
  return {
9
9
  pre() {
10
- var _this$opts$parents;
11
-
12
- const parents = (_this$opts$parents = this.opts.parents()) !== null && _this$opts$parents !== void 0 ? _this$opts$parents : [];
10
+ const parents = this.opts.parents() ?? [];
13
11
  const story = this.opts.story();
14
12
  this.resourcePath = this.filename;
15
13
  this.fileType = FileType.Invalid; // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -57,11 +57,9 @@ function getPropertyPath(path, name) {
57
57
 
58
58
  function getDeclaratorPath(path) {
59
59
  if (path !== null && path !== void 0 && path.isIdentifier()) {
60
- var _path$scope$getBindin;
61
-
62
60
  const {
63
61
  path: bindingPath
64
- } = (_path$scope$getBindin = path.scope.getBinding(path.node.name)) !== null && _path$scope$getBindin !== void 0 ? _path$scope$getBindin : {};
62
+ } = path.scope.getBinding(path.node.name) ?? {};
65
63
  if (bindingPath !== null && bindingPath !== void 0 && bindingPath.isVariableDeclarator() || bindingPath !== null && bindingPath !== void 0 && bindingPath.isFunctionDeclaration() || bindingPath !== null && bindingPath !== void 0 && bindingPath.isImportSpecifier()) return bindingPath;
66
64
  }
67
65
  }
@@ -100,7 +98,7 @@ function removeAllPropsExcept(path, propNames) {
100
98
  }
101
99
 
102
100
  function removeAllPropAssignsExcept(propAssigns, propNames) {
103
- for (const [assignPath, props] of propAssigns !== null && propAssigns !== void 0 ? propAssigns : []) {
101
+ for (const [assignPath, props] of propAssigns ?? []) {
104
102
  const restNames = props.reduce((subPropNames, prop) => {
105
103
  const propName = subPropNames.find(names => {
106
104
  const name = Array.isArray(names) ? names[0] : names;
@@ -138,13 +136,11 @@ function getAssignmentPathWithProps(refPath) {
138
136
  function getPropertyAssignmentPaths(idPaths) {
139
137
  const assignPaths = new Map();
140
138
  idPaths.forEach(idPath => {
141
- var _idPath$scope$getBind, _idPath$scope$getBind2;
139
+ var _idPath$scope$getBind;
142
140
 
143
- const referencePaths = (_idPath$scope$getBind = (_idPath$scope$getBind2 = idPath.scope.getBinding(idPath.node.name)) === null || _idPath$scope$getBind2 === void 0 ? void 0 : _idPath$scope$getBind2.referencePaths) !== null && _idPath$scope$getBind !== void 0 ? _idPath$scope$getBind : [];
141
+ const referencePaths = ((_idPath$scope$getBind = idPath.scope.getBinding(idPath.node.name)) === null || _idPath$scope$getBind === void 0 ? void 0 : _idPath$scope$getBind.referencePaths) ?? [];
144
142
  referencePaths.forEach(refPath => {
145
- var _getAssignmentPathWit;
146
-
147
- const [assignmentPath, props] = (_getAssignmentPathWit = getAssignmentPathWithProps(refPath)) !== null && _getAssignmentPathWit !== void 0 ? _getAssignmentPathWit : [];
143
+ const [assignmentPath, props] = getAssignmentPathWithProps(refPath) ?? [];
148
144
  if (assignmentPath && props) assignPaths.set(assignmentPath, props);
149
145
  });
150
146
  });
@@ -331,12 +327,12 @@ export const previewVisitor = {
331
327
  };
332
328
  export const mdxVisitor = {
333
329
  FunctionDeclaration(functionPath) {
334
- var _functionPath$get$nod, _rootPath$scope$getBi, _rootPath$scope$getBi2;
330
+ var _functionPath$get$nod, _rootPath$scope$getBi;
335
331
 
336
332
  const functionName = (_functionPath$get$nod = functionPath.get('id').node) === null || _functionPath$get$nod === void 0 ? void 0 : _functionPath$get$nod.name;
337
333
  if (functionName != 'MDXContent') return;
338
334
  const rootPath = findRootPath(functionPath);
339
- const refs = (_rootPath$scope$getBi = rootPath === null || rootPath === void 0 ? void 0 : (_rootPath$scope$getBi2 = rootPath.scope.getBinding(functionName)) === null || _rootPath$scope$getBi2 === void 0 ? void 0 : _rootPath$scope$getBi2.referencePaths) !== null && _rootPath$scope$getBi !== void 0 ? _rootPath$scope$getBi : [];
335
+ const refs = (rootPath === null || rootPath === void 0 ? void 0 : (_rootPath$scope$getBi = rootPath.scope.getBinding(functionName)) === null || _rootPath$scope$getBi === void 0 ? void 0 : _rootPath$scope$getBi.referencePaths) ?? [];
340
336
  refs.forEach(refPath => {
341
337
  var _findRootPath;
342
338
 
@@ -361,10 +357,8 @@ export const storyVisitor = {
361
357
  },
362
358
 
363
359
  ExportAllDeclaration(allPath) {
364
- var _this$reexportedStori;
365
-
366
360
  const request = allPath.get('source').node.value;
367
- this.reexportedStories.set(this.resourcePath, ((_this$reexportedStori = this.reexportedStories.get(this.resourcePath)) !== null && _this$reexportedStori !== void 0 ? _this$reexportedStori : new Set()).add(request));
361
+ this.reexportedStories.set(this.resourcePath, (this.reexportedStories.get(this.resourcePath) ?? new Set()).add(request));
368
362
  this.visitedTopPaths.add(allPath);
369
363
  },
370
364
 
@@ -398,9 +392,9 @@ export const storyVisitor = {
398
392
  const storiesIdPath = (_rootPath$get$find = rootPath.get('declarations').find(decl => decl.get('init') == rootCallPath)) === null || _rootPath$get$find === void 0 ? void 0 : _rootPath$get$find.get('id');
399
393
 
400
394
  if (storiesIdPath !== null && storiesIdPath !== void 0 && storiesIdPath.isIdentifier()) {
401
- var _storiesIdPath$scope$, _storiesIdPath$scope$2;
395
+ var _storiesIdPath$scope$;
402
396
 
403
- ((_storiesIdPath$scope$ = (_storiesIdPath$scope$2 = storiesIdPath.scope.getBinding(storiesIdPath.node.name)) === null || _storiesIdPath$scope$2 === void 0 ? void 0 : _storiesIdPath$scope$2.referencePaths) !== null && _storiesIdPath$scope$ !== void 0 ? _storiesIdPath$scope$ : []).forEach(cleanUpStoriesOfCallChain);
397
+ (((_storiesIdPath$scope$ = storiesIdPath.scope.getBinding(storiesIdPath.node.name)) === null || _storiesIdPath$scope$ === void 0 ? void 0 : _storiesIdPath$scope$.referencePaths) ?? []).forEach(cleanUpStoriesOfCallChain);
404
398
  }
405
399
  }
406
400
 
@@ -409,11 +403,9 @@ export const storyVisitor = {
409
403
 
410
404
  Identifier(identifierPath) {
411
405
  if (isExports(identifierPath)) {
412
- var _getAssignmentPathWit2;
413
-
414
406
  const rootPath = findRootPath(identifierPath);
415
407
  if (rootPath) this.visitedTopPaths.add(rootPath);
416
- const [assignmentPath, props] = (_getAssignmentPathWit2 = getAssignmentPathWithProps(identifierPath)) !== null && _getAssignmentPathWit2 !== void 0 ? _getAssignmentPathWit2 : [];
408
+ const [assignmentPath, props] = getAssignmentPathWithProps(identifierPath) ?? [];
417
409
 
418
410
  if (assignmentPath && props) {
419
411
  if (props.length == 1 && props[0] != 'default') {
@@ -433,11 +425,9 @@ export const storyVisitor = {
433
425
  }
434
426
 
435
427
  if (isModuleExports(identifierPath)) {
436
- var _getAssignmentPathWit3;
437
-
438
428
  const rootPath = findRootPath(identifierPath);
439
429
  if (rootPath) this.visitedTopPaths.add(rootPath);
440
- const [assignmentPath, props] = (_getAssignmentPathWit3 = getAssignmentPathWithProps(identifierPath)) !== null && _getAssignmentPathWit3 !== void 0 ? _getAssignmentPathWit3 : [];
430
+ const [assignmentPath, props] = getAssignmentPathWithProps(identifierPath) ?? [];
441
431
 
442
432
  if (assignmentPath && props) {
443
433
  if (props.length == 1 && props[0] == 'exports') {
@@ -5,7 +5,7 @@ import { addHook } from 'pirates';
5
5
  import { isDefined } from '../../../types';
6
6
  import { extensions } from '../../utils';
7
7
  import plugin from './creevey-plugin';
8
- import { hasDocsAddon, hasSvelteCSFAddon, isStorybookVersionLessThan } from '../../storybook/helpers';
8
+ import { hasDocsAddon, hasSvelteCSFAddon } from '../../storybook/helpers';
9
9
  let parents = null;
10
10
  let story = null; //@ts-expect-error private field doesn't have types
11
11
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
@@ -38,12 +38,10 @@ function getRequireContext(rootDir) {
38
38
  fs.readdirSync(dirPath, {
39
39
  withFileTypes: true
40
40
  }).forEach(dirent => {
41
- var _filter$test;
42
-
43
41
  const filename = dirent.name;
44
42
  const filePath = join(dirPath, filename);
45
43
  if (dirent.isDirectory() && deep) return traverse(filePath);
46
- if (dirent.isFile() && ((_filter$test = filter === null || filter === void 0 ? void 0 : filter.test(`./${relative(contextPath, filePath)}`)) !== null && _filter$test !== void 0 ? _filter$test : true)) return ids.push(filePath);
44
+ if (dirent.isFile() && ((filter === null || filter === void 0 ? void 0 : filter.test(`./${relative(contextPath, filePath)}`)) ?? true)) return ids.push(filePath);
47
45
  });
48
46
  };
49
47
 
@@ -69,7 +67,7 @@ function getRequireContext(rootDir) {
69
67
  }
70
68
 
71
69
  export default async function register(config, debug = false) {
72
- const rootDir = isStorybookVersionLessThan(6, 4) ? config.storybookDir : process.cwd();
70
+ const rootDir = process.cwd();
73
71
  const requireContext = getRequireContext(rootDir);
74
72
  const preview = resolve(config.storybookDir, 'preview');
75
73
  if (hasDocsAddon()) await (await import('../hooks/mdx')).addMDXHook(() => story);
@@ -3,7 +3,7 @@ import path from 'path';
3
3
  import webpack from 'webpack';
4
4
  import nodeExternals from 'webpack-node-externals';
5
5
  import { extensions as fallbackExtensions, getCreeveyCache } from '../../utils';
6
- import { getStorybookFramework, hasDocsAddon, importStorybookConfig, isStorybookVersionLessThan, resolveFromStorybook } from '../../storybook/helpers';
6
+ import { getStorybookFramework, hasDocsAddon, importStorybookConfig, resolveFromStorybook } from '../../storybook/helpers';
7
7
  import { noop } from '../../../types';
8
8
  import { emitWebpackMessage, subscribeOn } from '../../messages';
9
9
  import { logger } from '../../logger';
@@ -11,6 +11,8 @@ let isInitiated = false;
11
11
  let dumpStats = noop;
12
12
 
13
13
  function handleWebpackBuild(error, stats) {
14
+ var _stats$toJson$warning;
15
+
14
16
  dumpStats(stats);
15
17
 
16
18
  if (error || !stats || stats.hasErrors()) {
@@ -21,17 +23,16 @@ function handleWebpackBuild(error, stats) {
21
23
  if (error) return console.error(error.message);
22
24
 
23
25
  if (stats && (stats.hasErrors() || stats.hasWarnings())) {
24
- const {
25
- warnings,
26
- errors
27
- } = stats.toJson();
28
- errors.forEach(e => console.error(e));
29
- warnings.forEach(e => console.error(e));
26
+ var _statsJson$errors, _statsJson$warnings;
27
+
28
+ const statsJson = stats.toJson();
29
+ (_statsJson$errors = statsJson.errors) === null || _statsJson$errors === void 0 ? void 0 : _statsJson$errors.forEach(e => console.error(e));
30
+ (_statsJson$warnings = statsJson.warnings) === null || _statsJson$warnings === void 0 ? void 0 : _statsJson$warnings.forEach(e => console.error(e));
30
31
  return;
31
32
  }
32
33
  }
33
34
 
34
- stats.toJson().warnings.forEach(e => console.warn(e));
35
+ stats === null || stats === void 0 ? void 0 : (_stats$toJson$warning = stats.toJson().warnings) === null || _stats$toJson$warning === void 0 ? void 0 : _stats$toJson$warning.forEach(e => console.warn(e));
35
36
 
36
37
  if (!isInitiated) {
37
38
  isInitiated = true;
@@ -52,72 +53,48 @@ async function applyMdxLoader(config, areAddonsRemoved, loader) {
52
53
  mdxLoaders
53
54
  } = await import('./mdx-loader');
54
55
  mdxLoaders.splice(1, 0, loader);
55
- const mdxRegexps = isStorybookVersionLessThan(6, 2) ? [/\.(stories|story).mdx$/, /\.(stories|story)\.mdx$/] : [/(stories|story)\.mdx$/]; // NOTE replace md/mdx to null loader
56
+ const mdxRegexps = [/(stories|story)\.mdx$/]; // NOTE replace md/mdx to null loader
56
57
 
57
58
  const mdRegexps = [/\.md$/, /\.mdx$/];
58
59
 
59
60
  if (areAddonsRemoved) {
60
- var _config$module2;
61
+ var _config$module2, _config$module2$rules;
61
62
 
62
63
  mdRegexps.forEach(test => {
63
- var _config$module;
64
+ var _config$module, _config$module$rules;
64
65
 
65
- return (_config$module = config.module) === null || _config$module === void 0 ? void 0 : _config$module.rules.unshift({
66
+ return (_config$module = config.module) === null || _config$module === void 0 ? void 0 : (_config$module$rules = _config$module.rules) === null || _config$module$rules === void 0 ? void 0 : _config$module$rules.unshift({
66
67
  test,
67
68
  exclude: /(stories|story)\.mdx$/,
68
69
  use: require.resolve('null-loader')
69
70
  });
70
71
  });
71
- (_config$module2 = config.module) === null || _config$module2 === void 0 ? void 0 : _config$module2.rules.unshift({
72
+ (_config$module2 = config.module) === null || _config$module2 === void 0 ? void 0 : (_config$module2$rules = _config$module2.rules) === null || _config$module2$rules === void 0 ? void 0 : _config$module2$rules.unshift({
72
73
  test: /(stories|story)\.mdx$/,
73
74
  use: mdxLoaders
74
75
  });
75
76
  } else {
76
- var _config$module3, _config$module4, _config$module$rules$, _config$module5;
77
+ var _config$module3, _config$module3$rules, _config$module4, _config$module4$rules, _config$module5, _config$module5$rules;
77
78
 
78
79
  // NOTE Exclude addons' entry points
79
80
  config.entry = Array.isArray(config.entry) ? config.entry.filter(entry => !/@storybook(\/|\\)addon/.test(entry)) : config.entry;
80
- (_config$module3 = config.module) === null || _config$module3 === void 0 ? void 0 : _config$module3.rules.filter(rule => mdRegexps.some(test => {
81
+ (_config$module3 = config.module) === null || _config$module3 === void 0 ? void 0 : (_config$module3$rules = _config$module3.rules) === null || _config$module3$rules === void 0 ? void 0 : _config$module3$rules.flatMap(rule => typeof rule == 'object' && 'test' in rule ? rule : []).filter(rule => mdRegexps.some(test => {
81
82
  var _rule$test;
82
83
 
83
84
  return ((_rule$test = rule.test) === null || _rule$test === void 0 ? void 0 : _rule$test.toString()) == test.toString();
84
85
  })).forEach(rule => rule.use = require.resolve('null-loader'));
85
- (_config$module4 = config.module) === null || _config$module4 === void 0 ? void 0 : _config$module4.rules.filter(rule => mdxRegexps.some(test => {
86
+ (_config$module4 = config.module) === null || _config$module4 === void 0 ? void 0 : (_config$module4$rules = _config$module4.rules) === null || _config$module4$rules === void 0 ? void 0 : _config$module4$rules.flatMap(rule => typeof rule == 'object' && 'test' in rule ? rule : []).filter(rule => mdxRegexps.some(test => {
86
87
  var _rule$test2;
87
88
 
88
89
  return ((_rule$test2 = rule.test) === null || _rule$test2 === void 0 ? void 0 : _rule$test2.toString()) == test.toString();
89
90
  })).forEach(rule => rule.use = mdxLoaders); // NOTE Exclude source-loader
90
91
 
91
92
  config.module = { ...config.module,
92
- rules: (_config$module$rules$ = (_config$module5 = config.module) === null || _config$module5 === void 0 ? void 0 : _config$module5.rules.filter(rule => !(typeof rule.loader == 'string' && /@storybook(\/|\\)source-loader/.test(rule.loader)))) !== null && _config$module$rules$ !== void 0 ? _config$module$rules$ : []
93
+ rules: ((_config$module5 = config.module) === null || _config$module5 === void 0 ? void 0 : (_config$module5$rules = _config$module5.rules) === null || _config$module5$rules === void 0 ? void 0 : _config$module5$rules.flatMap(rule => typeof rule == 'object' && 'test' in rule ? rule : []).filter(rule => !(typeof rule.loader == 'string' && /@storybook(\/|\\)source-loader/.test(rule.loader)))) ?? []
93
94
  };
94
95
  }
95
96
  }
96
97
 
97
- async function getWebpackConfigForStorybook_pre6_2(framework, configDir, outputDir) {
98
- const {
99
- default: storybookFrameworkOptions
100
- } = await import(resolveFromStorybook(`@storybook/${framework}/dist/server/options`)); // eslint-disable-next-line node/no-missing-import, @typescript-eslint/no-unsafe-assignment, import/no-unresolved
101
-
102
- const {
103
- default: getConfig
104
- } = await import(resolveFromStorybook('@storybook/core/dist/server/config')); // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
105
-
106
- return getConfig({
107
- // NOTE: 6.1 storybook don't support quite any more. But we still have older versions
108
- quiet: true,
109
- configType: 'PRODUCTION',
110
- outputDir,
111
- cache: {},
112
- // eslint-disable-next-line node/no-missing-require
113
- corePresets: [resolveFromStorybook('@storybook/core/dist/server/preview/preview-preset')],
114
- overridePresets: [...(hasDocsAddon() ? [require.resolve('./mdx-loader')] : []), // eslint-disable-next-line node/no-missing-require
115
- resolveFromStorybook('@storybook/core/dist/server/preview/custom-webpack-preset')],
116
- ...storybookFrameworkOptions,
117
- configDir
118
- });
119
- }
120
-
121
98
  async function getWebpackConfigForStorybook_6_2(framework, configDir, outputDir) {
122
99
  const {
123
100
  default: storybookFrameworkOptions
@@ -182,7 +159,7 @@ export default async function compile(config, {
182
159
  debug,
183
160
  ui
184
161
  }) {
185
- var _storybookWebpackConf, _storybookWebpackConf2, _storybookWebpackConf3, _extensions$map, _storybookWebpackConf4, _storybookWebpackConf5, _storybookWebpackConf6;
162
+ var _storybookWebpackConf, _storybookWebpackConf2, _storybookWebpackConf3, _extensions$map, _storybookWebpackConf4, _storybookWebpackConf5;
186
163
 
187
164
  const storybookFramework = getStorybookFramework();
188
165
  const outputDir = path.join(getCreeveyCache(), 'storybook');
@@ -205,9 +182,9 @@ export default async function compile(config, {
205
182
  process.env.NODE_ENV = 'production'; // NOTE Remove addons by monkey patching, only for new config file (main.js)
206
183
 
207
184
  const areAddonsRemoved = await removeAddons();
208
- const getWebpackConfig = isStorybookVersionLessThan(6, 2) ? getWebpackConfigForStorybook_pre6_2 : getWebpackConfigForStorybook_6_2;
185
+ const getWebpackConfig = getWebpackConfigForStorybook_6_2;
209
186
  const storybookWebpackConfig = await getWebpackConfig(storybookFramework, config.storybookDir, outputDir);
210
- const extensions = (_storybookWebpackConf = (_storybookWebpackConf2 = storybookWebpackConfig.resolve) === null || _storybookWebpackConf2 === void 0 ? void 0 : _storybookWebpackConf2.extensions) !== null && _storybookWebpackConf !== void 0 ? _storybookWebpackConf : fallbackExtensions;
187
+ const extensions = ((_storybookWebpackConf = storybookWebpackConfig.resolve) === null || _storybookWebpackConf === void 0 ? void 0 : _storybookWebpackConf.extensions) ?? fallbackExtensions;
211
188
  delete storybookWebpackConfig.optimization;
212
189
  storybookWebpackConfig.devtool = false;
213
190
  storybookWebpackConfig.performance = false;
@@ -222,18 +199,21 @@ export default async function compile(config, {
222
199
 
223
200
  if (hasDocsAddon()) await applyMdxLoader(storybookWebpackConfig, areAddonsRemoved, creeveyLoader); // NOTE Add creevey-loader to cut off all unnecessary code except stories meta and tests
224
201
 
225
- (_storybookWebpackConf3 = storybookWebpackConfig.module) === null || _storybookWebpackConf3 === void 0 ? void 0 : _storybookWebpackConf3.rules.unshift({
202
+ (_storybookWebpackConf2 = storybookWebpackConfig.module) === null || _storybookWebpackConf2 === void 0 ? void 0 : (_storybookWebpackConf3 = _storybookWebpackConf2.rules) === null || _storybookWebpackConf3 === void 0 ? void 0 : _storybookWebpackConf3.unshift({
226
203
  enforce: 'pre',
227
204
  test: new RegExp(`\\.(${(_extensions$map = extensions.map(x => x.slice(1))) === null || _extensions$map === void 0 ? void 0 : _extensions$map.join('|')})$`),
228
205
  exclude: /node_modules/,
229
206
  use: creeveyLoader
230
207
  });
231
- const aliases = (_storybookWebpackConf4 = (_storybookWebpackConf5 = storybookWebpackConfig.resolve) === null || _storybookWebpackConf5 === void 0 ? void 0 : _storybookWebpackConf5.alias) !== null && _storybookWebpackConf4 !== void 0 ? _storybookWebpackConf4 : {};
208
+ const aliases = ((_storybookWebpackConf4 = storybookWebpackConfig.resolve) === null || _storybookWebpackConf4 === void 0 ? void 0 : _storybookWebpackConf4.alias) ?? {};
232
209
  const excluded = ['@storybook/addons', '@storybook/api', '@storybook/channel-postmessage', '@storybook/channels', '@storybook/client-api', '@storybook/client-logger', '@storybook/components', '@storybook/core-events', '@storybook/router', '@storybook/semver', '@storybook/theming']; // NOTE Exclude from bundle all modules from node_modules
233
210
 
234
- storybookWebpackConfig.externals = [...Object.entries(aliases).filter(([alias]) => excluded.includes(alias)).map(([, aliasPath]) => ({
235
- [aliasPath]: `commonjs ${aliasPath}`
236
- })), // NOTE Replace `@storybook/${framework}` to ../../storybook.ts
211
+ storybookWebpackConfig.externals = [...(Array.isArray(aliases) ? aliases.map(({
212
+ name,
213
+ alias
214
+ }) => [name, alias]) : Object.entries(aliases)).filter(([alias]) => excluded.includes(alias)).flatMap(([, aliasPath]) => aliasPath == false ? [] : (Array.isArray(aliasPath) ? aliasPath : [aliasPath]).map(x => ({
215
+ [x]: `commonjs ${x}`
216
+ }))), // NOTE Replace `@storybook/${framework}` to ../../storybook.ts
237
217
  {
238
218
  [`@storybook/${storybookFramework}`]: `commonjs ${require.resolve('../../storybook/entry')}`
239
219
  }, nodeExternals({
@@ -241,17 +221,20 @@ export default async function compile(config, {
241
221
  allowlist: /(webpack|dummy-hmr|generated-stories-entry|generated-config-entry|generated-other-entry)/
242
222
  }), // TODO Don't work well with monorepos
243
223
  nodeExternals({
244
- modulesDir: resolveFromStorybook('@storybook/core').split('@storybook')[0],
224
+ modulesDir: resolveFromStorybook('@storybook/core-client').split('@storybook')[0],
245
225
  includeAbsolutePaths: true,
246
226
  allowlist: /(webpack|dummy-hmr|generated-stories-entry|generated-config-entry|generated-other-entry)/
247
227
  })]; // NOTE Exclude some plugins
248
228
 
249
229
  const excludedPlugins = ['DocgenPlugin', 'ForkTsCheckerWebpackPlugin'];
250
- storybookWebpackConfig.plugins = (_storybookWebpackConf6 = storybookWebpackConfig.plugins) === null || _storybookWebpackConf6 === void 0 ? void 0 : _storybookWebpackConf6.filter(plugin => !excludedPlugins.includes(plugin.constructor.name));
230
+ storybookWebpackConfig.plugins = (_storybookWebpackConf5 = storybookWebpackConfig.plugins) === null || _storybookWebpackConf5 === void 0 ? void 0 : _storybookWebpackConf5.filter(plugin => !excludedPlugins.includes(plugin.constructor.name));
251
231
  const storybookWebpackCompiler = webpack(storybookWebpackConfig);
252
232
 
253
233
  if (debug) {
254
- dumpStats = stats => writeFile(path.join(config.reportDir, 'stats.json'), JSON.stringify(stats.toJson(), null, 2), noop);
234
+ dumpStats = stats => {
235
+ if (!stats) return;
236
+ writeFile(path.join(config.reportDir, 'stats.json'), JSON.stringify(stats.toJson(), null, 2), noop);
237
+ };
255
238
  }
256
239
 
257
240
  if (ui) {
@@ -5,7 +5,6 @@ import { validate } from 'schema-utils';
5
5
  import { parse } from '@babel/parser';
6
6
  import traverse from '@babel/traverse';
7
7
  import generate from '@babel/generator';
8
- import { isStorybookVersionLessThan } from '../../storybook/helpers';
9
8
  import { commonVisitor, mdxVisitor, previewVisitor, storyVisitor, FileType } from '../babel/helpers';
10
9
  import { logger } from '../../logger';
11
10
 
@@ -57,11 +56,6 @@ function isPreview(context, options) {
57
56
  } = path.posix.parse(toPosix(context.resourcePath));
58
57
  const storybookDir = typeof options.storybookDir == 'string' ? toPosix(options.storybookDir) : '';
59
58
  const isConfigFile = resourceDir == storybookDir && (resourceName == 'preview' || resourceName == 'config');
60
-
61
- if (isStorybookVersionLessThan(6)) {
62
- return isEntry(context) && isConfigFile;
63
- }
64
-
65
59
  const issuerResource = getIssuerResource(context);
66
60
  return Boolean(issuerResource && entries.has(issuerResource) && isConfigFile);
67
61
  }
@@ -93,12 +87,17 @@ let resourcePath = '';
93
87
  const entries = new Set();
94
88
  const stories = new Set();
95
89
  const reexportedStories = new Map();
96
- const isTest = process.env.__CREEVEY_ENV__ == 'test';
90
+
91
+ const isTest = () => process.env.__CREEVEY_ENV__ == 'test';
92
+
97
93
  const defaultOptions = {
98
- debug: isTest,
94
+ get debug() {
95
+ return isTest();
96
+ },
97
+
99
98
  storybookDir: process.cwd()
100
99
  };
101
- export default function (source) {
100
+ export default function loader(source) {
102
101
  const options = this ? getOptions(this) || defaultOptions : defaultOptions;
103
102
  validate(schema, options, {
104
103
  name: 'Creevey Stories Loader'
@@ -125,7 +124,7 @@ export default function (source) {
125
124
  }
126
125
  }
127
126
 
128
- if (isTest && !Number.isNaN(Number(process.env.CREEVEY_LOADER_FILE_TYPE))) {
127
+ if (isTest() && !Number.isNaN(Number(process.env.CREEVEY_LOADER_FILE_TYPE))) {
129
128
  fileType = Number(process.env.CREEVEY_LOADER_FILE_TYPE);
130
129
  }
131
130
 
@@ -1,15 +1,11 @@
1
- var _global$__CREEVEY_HMR;
2
-
3
- global.__CREEVEY_HMR_DATA__ = (_global$__CREEVEY_HMR = global.__CREEVEY_HMR_DATA__) !== null && _global$__CREEVEY_HMR !== void 0 ? _global$__CREEVEY_HMR : {};
1
+ global.__CREEVEY_HMR_DATA__ = global.__CREEVEY_HMR_DATA__ ?? {};
4
2
  Object.entries(__webpack_require__.m).forEach(([key, moduleFn]) => {
5
3
  __webpack_require__.m[key] = new Proxy(moduleFn, {
6
4
  apply(target, thisArg, args) {
7
- var _global$__CREEVEY_HMR2;
8
-
9
5
  const [module] = args;
10
6
  const {
11
7
  data
12
- } = global.__CREEVEY_HMR_DATA__[module.i] = (_global$__CREEVEY_HMR2 = global.__CREEVEY_HMR_DATA__[module.i]) !== null && _global$__CREEVEY_HMR2 !== void 0 ? _global$__CREEVEY_HMR2 : {
8
+ } = global.__CREEVEY_HMR_DATA__[module.i] = global.__CREEVEY_HMR_DATA__[module.i] ?? {
13
9
  data: {}
14
10
  };
15
11
  Object.assign(module, {
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable */
2
2
 
3
3
  /* Copy-paste from storybook/addons/docs/src/frameworks/common/preset.ts */
4
- import { isStorybookVersionLessThan, resolveFromStorybook, resolveFromStorybookAddonDocs, resolveFromStorybookBuilderWebpack4, resolveFromStorybookCore } from '../../storybook/helpers';
4
+ import { resolveFromStorybook, resolveFromStorybookAddonDocs, resolveFromStorybookBuilderWebpack4 } from '../../storybook/helpers';
5
5
  export let mdxLoaders = []; // for frameworks that are not working with react, we need to configure
6
6
  // the jsx to transpile mdx, for now there will be a flag for that
7
7
  // for more complex solutions we can find alone that we need to add '@babel/plugin-transform-react-jsx'
@@ -44,7 +44,7 @@ export function webpack(webpackConfig = {}, options = {}) {
44
44
  configureJSX = true
45
45
  } = options;
46
46
  mdxLoaders = [{
47
- loader: isStorybookVersionLessThan(6, 2) ? resolveFromStorybookCore('babel-loader') : resolveFromStorybookBuilderWebpack4('babel-loader'),
47
+ loader: resolveFromStorybookBuilderWebpack4('babel-loader'),
48
48
  options: createBabelOptions({
49
49
  babelOptions,
50
50
  mdxBabelOptions,
@@ -9,7 +9,7 @@ export function startWebpackCompiler() {
9
9
  const webpackCompiler = cluster.fork();
10
10
  webpackCompiler.on('message', message => {
11
11
  if (!isWebpackMessage(message)) return;
12
- Object.values(cluster.workers).filter(worker => worker != webpackCompiler).forEach(worker => worker === null || worker === void 0 ? void 0 : worker.send(message));
12
+ Object.values(cluster.workers ?? {}).filter(worker => worker != webpackCompiler).forEach(worker => worker === null || worker === void 0 ? void 0 : worker.send(message));
13
13
 
14
14
  switch (message.type) {
15
15
  case 'success':
@@ -86,9 +86,9 @@ export default async function (config, options, resolveApi) {
86
86
  });
87
87
  runner = await master(config, {
88
88
  watch: options.ui,
89
- debug: options.debug
89
+ debug: options.debug,
90
+ port: options.port
90
91
  });
91
- await runner.init();
92
92
 
93
93
  if (options.saveReport) {
94
94
  await copyStatics(config.reportDir);
@@ -111,9 +111,9 @@ export default async function (config, options, resolveApi) {
111
111
  }
112
112
 
113
113
  runner.once('stop', () => {
114
- var _runner$status$tests, _runner6;
114
+ var _runner6;
115
115
 
116
- const tests = Object.values((_runner$status$tests = (_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) !== null && _runner$status$tests !== void 0 ? _runner$status$tests : {});
116
+ const tests = Object.values(((_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) ?? {});
117
117
  const isSuccess = tests.filter(isDefined).filter(({
118
118
  skip
119
119
  }) => !skip).every(({
@@ -27,6 +27,7 @@ export default async function master(config, options) {
27
27
  } catch (error) {// Ignore error
28
28
  }
29
29
 
30
+ await runner.init();
30
31
  const tests = await loadTestsFromStories(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
31
32
  runner.updateTests(testsDiff);
32
33
  saveTestsJson(runner.tests, config.reportDir);
@@ -1,12 +1,14 @@
1
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
-
3
- import cluster from 'cluster';
1
+ import cluster, { Worker as ClusterWorker } from 'cluster';
4
2
  import { EventEmitter } from 'events';
5
- import { isWorkerMessage, isTestMessage } from '../../types';
6
- import { sendTestMessage, sendShutdownMessage } from '../messages';
3
+ import { isWorkerMessage } from '../../types';
4
+ import { sendTestMessage, sendShutdownMessage, subscribeOnWorker } from '../messages';
7
5
  import { isShuttingDown } from '../utils';
8
6
  const FORK_RETRIES = 5;
9
7
  export default class Pool extends EventEmitter {
8
+ workers = [];
9
+ queue = [];
10
+ forcedStop = false;
11
+
10
12
  get isRunning() {
11
13
  return this.workers.length !== this.freeWorkers.length;
12
14
  }
@@ -14,19 +16,6 @@ export default class Pool extends EventEmitter {
14
16
  constructor(config, browser) {
15
17
  super();
16
18
  this.browser = browser;
17
-
18
- _defineProperty(this, "maxRetries", void 0);
19
-
20
- _defineProperty(this, "config", void 0);
21
-
22
- _defineProperty(this, "workers", []);
23
-
24
- _defineProperty(this, "queue", []);
25
-
26
- _defineProperty(this, "forcedStop", false);
27
-
28
- _defineProperty(this, "failFast", void 0);
29
-
30
19
  this.failFast = config.failFast;
31
20
  this.maxRetries = config.maxRetries;
32
21
  this.config = config.browsers[browser];
@@ -36,7 +25,7 @@ export default class Pool extends EventEmitter {
36
25
  const poolSize = this.config.limit || 1;
37
26
  this.workers = (await Promise.all(Array.from({
38
27
  length: poolSize
39
- }).map(() => this.forkWorker()))).filter(workerOrError => workerOrError instanceof cluster.Worker);
28
+ }).map(() => this.forkWorker()))).filter(workerOrError => workerOrError instanceof ClusterWorker);
40
29
  if (this.workers.length != poolSize) throw new Error(`Can't instantiate workers for ${this.browser} due many errors`);
41
30
  this.workers.forEach(worker => this.exitHandler(worker));
42
31
  }
@@ -134,7 +123,7 @@ export default class Pool extends EventEmitter {
134
123
  worker.once('exit', async () => {
135
124
  if (isShuttingDown.current) return;
136
125
  const workerOrError = await this.forkWorker();
137
- if (!(workerOrError instanceof cluster.Worker)) throw new Error(`Can't instantiate worker for ${this.browser} due many errors`);
126
+ if (!(workerOrError instanceof ClusterWorker)) throw new Error(`Can't instantiate worker for ${this.browser} due many errors`);
138
127
  this.exitHandler(workerOrError);
139
128
  this.workers[this.workers.indexOf(worker)] = workerOrError;
140
129
  this.process();
@@ -151,37 +140,37 @@ export default class Pool extends EventEmitter {
151
140
  return test.retries < this.maxRetries && !this.forcedStop;
152
141
  }
153
142
 
143
+ handleTestResult(worker, test, result) {
144
+ const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
145
+
146
+ if (shouldRetry) {
147
+ test.retries += 1;
148
+ this.queue[this.failFast ? 'unshift' : 'push'](test);
149
+ }
150
+
151
+ this.sendStatus({
152
+ id: test.id,
153
+ status: shouldRetry ? 'retrying' : result.status,
154
+ result
155
+ });
156
+ worker.isRunning = false;
157
+ setImmediate(() => this.process());
158
+ }
159
+
154
160
  subscribe(worker, test) {
155
- worker.once('message', message => {
156
- if (!isWorkerMessage(message) && !isTestMessage(message)) return;
157
- if (message.type != 'end' && message.type != 'error') return;
158
- let result;
159
-
160
- if (message.type == 'error') {
161
- this.gracefullyKill(worker);
162
- result = {
163
- status: 'failed',
164
- ...message.payload
165
- };
166
- } else {
167
- result = message.payload;
168
- }
169
-
170
- const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
171
-
172
- if (shouldRetry) {
173
- test.retries += 1;
174
- this.queue[this.failFast ? 'unshift' : 'push'](test);
175
- }
176
-
177
- this.sendStatus({
178
- id: test.id,
179
- status: shouldRetry ? 'retrying' : result.status,
180
- result
161
+ const subscriptions = [subscribeOnWorker(worker, 'worker', message => {
162
+ if (message.type != 'error') return;
163
+ subscriptions.forEach(unsubscribe => unsubscribe());
164
+ this.gracefullyKill(worker);
165
+ this.handleTestResult(worker, test, {
166
+ status: 'failed',
167
+ ...message.payload
181
168
  });
182
- worker.isRunning = false;
183
- this.process();
184
- });
169
+ }), subscribeOnWorker(worker, 'test', message => {
170
+ if (message.type != 'end') return;
171
+ subscriptions.forEach(unsubscribe => unsubscribe());
172
+ this.handleTestResult(worker, test, message.payload);
173
+ })];
185
174
  }
186
175
 
187
176
  }