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
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = _default;
6
+ exports.default = loader;
7
7
 
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
 
@@ -19,19 +19,17 @@ var _traverse = _interopRequireDefault(require("@babel/traverse"));
19
19
 
20
20
  var _generator = _interopRequireDefault(require("@babel/generator"));
21
21
 
22
- var _helpers = require("../../storybook/helpers");
23
-
24
- var _helpers2 = require("../babel/helpers");
22
+ var _helpers = require("../babel/helpers");
25
23
 
26
24
  var _logger = require("../../logger");
27
25
 
28
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
27
 
30
28
  function transform(ast) {
31
- (0, _traverse.default)(ast, { ..._helpers2.commonVisitor,
32
- ...(fileType == _helpers2.FileType.Preview ? _helpers2.previewVisitor : undefined),
33
- ...(fileType == _helpers2.FileType.Story ? _helpers2.storyVisitor : undefined),
34
- ...(isMDX ? _helpers2.mdxVisitor : undefined)
29
+ (0, _traverse.default)(ast, { ..._helpers.commonVisitor,
30
+ ...(fileType == _helpers.FileType.Preview ? _helpers.previewVisitor : undefined),
31
+ ...(fileType == _helpers.FileType.Story ? _helpers.storyVisitor : undefined),
32
+ ...(isMDX ? _helpers.mdxVisitor : undefined)
35
33
  }, undefined, {
36
34
  resourcePath,
37
35
  fileType,
@@ -76,11 +74,6 @@ function isPreview(context, options) {
76
74
 
77
75
  const storybookDir = typeof options.storybookDir == 'string' ? toPosix(options.storybookDir) : '';
78
76
  const isConfigFile = resourceDir == storybookDir && (resourceName == 'preview' || resourceName == 'config');
79
-
80
- if ((0, _helpers.isStorybookVersionLessThan)(6)) {
81
- return isEntry(context) && isConfigFile;
82
- }
83
-
84
77
  const issuerResource = getIssuerResource(context);
85
78
  return Boolean(issuerResource && entries.has(issuerResource) && isConfigFile);
86
79
  }
@@ -105,39 +98,44 @@ const schema = {
105
98
  }
106
99
  }
107
100
  };
108
- let fileType = _helpers2.FileType.Invalid;
101
+ let fileType = _helpers.FileType.Invalid;
109
102
  let isMDX = false;
110
103
  let previewPath = '';
111
104
  let resourcePath = '';
112
105
  const entries = new Set();
113
106
  const stories = new Set();
114
107
  const reexportedStories = new Map();
115
- const isTest = process.env.__CREEVEY_ENV__ == 'test';
108
+
109
+ const isTest = () => process.env.__CREEVEY_ENV__ == 'test';
110
+
116
111
  const defaultOptions = {
117
- debug: isTest,
112
+ get debug() {
113
+ return isTest();
114
+ },
115
+
118
116
  storybookDir: process.cwd()
119
117
  };
120
118
 
121
- function _default(source) {
119
+ function loader(source) {
122
120
  const options = this ? (0, _loaderUtils.getOptions)(this) || defaultOptions : defaultOptions;
123
121
  (0, _schemaUtils.validate)(schema, options, {
124
122
  name: 'Creevey Stories Loader'
125
123
  });
126
- fileType = _helpers2.FileType.Invalid;
124
+ fileType = _helpers.FileType.Invalid;
127
125
 
128
126
  if (this) {
129
127
  const issuerResource = getIssuerResource(this);
130
128
  resourcePath = this.resourcePath;
131
129
 
132
130
  if (isStoryFile(this)) {
133
- fileType = _helpers2.FileType.Story;
131
+ fileType = _helpers.FileType.Story;
134
132
  isMDX = _path.default.parse(resourcePath).ext == '.mdx';
135
133
  stories.add(this.resourcePath);
136
134
  } else if (isPreview(this, options)) {
137
- fileType = _helpers2.FileType.Preview;
135
+ fileType = _helpers.FileType.Preview;
138
136
  previewPath = this.resourcePath;
139
137
  } else if (isEntry(this)) {
140
- fileType = _helpers2.FileType.Entry;
138
+ fileType = _helpers.FileType.Entry;
141
139
  entries.add(this.resourcePath);
142
140
  return source;
143
141
  } else if (issuerResource && stories.has(issuerResource) && options.debug) {
@@ -146,7 +144,7 @@ function _default(source) {
146
144
  }
147
145
  }
148
146
 
149
- if (isTest && !Number.isNaN(Number(process.env.CREEVEY_LOADER_FILE_TYPE))) {
147
+ if (isTest() && !Number.isNaN(Number(process.env.CREEVEY_LOADER_FILE_TYPE))) {
150
148
  fileType = Number(process.env.CREEVEY_LOADER_FILE_TYPE);
151
149
  }
152
150
 
@@ -4,19 +4,14 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
- var _global$__CREEVEY_HMR;
9
-
10
- global.__CREEVEY_HMR_DATA__ = (_global$__CREEVEY_HMR = global.__CREEVEY_HMR_DATA__) !== null && _global$__CREEVEY_HMR !== void 0 ? _global$__CREEVEY_HMR : {};
7
+ global.__CREEVEY_HMR_DATA__ = global.__CREEVEY_HMR_DATA__ ?? {};
11
8
  Object.entries(__webpack_require__.m).forEach(([key, moduleFn]) => {
12
9
  __webpack_require__.m[key] = new Proxy(moduleFn, {
13
10
  apply(target, thisArg, args) {
14
- var _global$__CREEVEY_HMR2;
15
-
16
11
  const [module] = args;
17
12
  const {
18
13
  data
19
- } = global.__CREEVEY_HMR_DATA__[module.i] = (_global$__CREEVEY_HMR2 = global.__CREEVEY_HMR_DATA__[module.i]) !== null && _global$__CREEVEY_HMR2 !== void 0 ? _global$__CREEVEY_HMR2 : {
14
+ } = global.__CREEVEY_HMR_DATA__[module.i] = global.__CREEVEY_HMR_DATA__[module.i] ?? {
20
15
  data: {}
21
16
  };
22
17
  Object.assign(module, {
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.webpack = webpack;
7
6
  exports.mdxOptions = exports.mdxLoaders = void 0;
7
+ exports.webpack = webpack;
8
8
 
9
9
  var _helpers = require("../../storybook/helpers");
10
10
 
@@ -58,7 +58,7 @@ function webpack(webpackConfig = {}, options = {}) {
58
58
  configureJSX = true
59
59
  } = options;
60
60
  exports.mdxLoaders = mdxLoaders = [{
61
- loader: (0, _helpers.isStorybookVersionLessThan)(6, 2) ? (0, _helpers.resolveFromStorybookCore)('babel-loader') : (0, _helpers.resolveFromStorybookBuilderWebpack4)('babel-loader'),
61
+ loader: (0, _helpers.resolveFromStorybookBuilderWebpack4)('babel-loader'),
62
62
  options: createBabelOptions({
63
63
  babelOptions,
64
64
  mdxBabelOptions,
@@ -23,7 +23,7 @@ function startWebpackCompiler() {
23
23
 
24
24
  webpackCompiler.on('message', message => {
25
25
  if (!(0, _types.isWebpackMessage)(message)) return;
26
- Object.values(_cluster.default.workers).filter(worker => worker != webpackCompiler).forEach(worker => worker === null || worker === void 0 ? void 0 : worker.send(message));
26
+ Object.values(_cluster.default.workers ?? {}).filter(worker => worker != webpackCompiler).forEach(worker => worker === null || worker === void 0 ? void 0 : worker.send(message));
27
27
 
28
28
  switch (message.type) {
29
29
  case 'success':
@@ -3,13 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.colors = void 0;
6
7
  Object.defineProperty(exports, "getLogger", {
7
8
  enumerable: true,
8
9
  get: function () {
9
10
  return _loglevel.getLogger;
10
11
  }
11
12
  });
12
- exports.logger = exports.colors = void 0;
13
+ exports.logger = void 0;
13
14
 
14
15
  var _chalk = _interopRequireDefault(require("chalk"));
15
16
 
@@ -105,9 +105,9 @@ async function _default(config, options, resolveApi) {
105
105
  });
106
106
  runner = await (0, _master.default)(config, {
107
107
  watch: options.ui,
108
- debug: options.debug
108
+ debug: options.debug,
109
+ port: options.port
109
110
  });
110
- await runner.init();
111
111
 
112
112
  if (options.saveReport) {
113
113
  await copyStatics(config.reportDir);
@@ -132,9 +132,9 @@ async function _default(config, options, resolveApi) {
132
132
  }
133
133
 
134
134
  runner.once('stop', () => {
135
- var _runner$status$tests, _runner6;
135
+ var _runner6;
136
136
 
137
- 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 : {});
137
+ const tests = Object.values(((_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) ?? {});
138
138
  const isSuccess = tests.filter(_types.isDefined).filter(({
139
139
  skip
140
140
  }) => !skip).every(({
@@ -46,6 +46,7 @@ async function master(config, options) {
46
46
  } catch (error) {// Ignore error
47
47
  }
48
48
 
49
+ await runner.init();
49
50
  const tests = await (0, _stories.loadTestsFromStories)(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
50
51
  runner.updateTests(testsDiff);
51
52
  (0, _stories.saveTestsJson)(runner.tests, config.reportDir);
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _cluster = _interopRequireDefault(require("cluster"));
8
+ var _cluster = _interopRequireWildcard(require("cluster"));
9
9
 
10
10
  var _events = require("events");
11
11
 
@@ -15,13 +15,17 @@ var _messages = require("../messages");
15
15
 
16
16
  var _utils = require("../utils");
17
17
 
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
19
 
20
- 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; }
20
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
21
 
22
22
  const FORK_RETRIES = 5;
23
23
 
24
24
  class Pool extends _events.EventEmitter {
25
+ workers = [];
26
+ queue = [];
27
+ forcedStop = false;
28
+
25
29
  get isRunning() {
26
30
  return this.workers.length !== this.freeWorkers.length;
27
31
  }
@@ -29,19 +33,6 @@ class Pool extends _events.EventEmitter {
29
33
  constructor(config, browser) {
30
34
  super();
31
35
  this.browser = browser;
32
-
33
- _defineProperty(this, "maxRetries", void 0);
34
-
35
- _defineProperty(this, "config", void 0);
36
-
37
- _defineProperty(this, "workers", []);
38
-
39
- _defineProperty(this, "queue", []);
40
-
41
- _defineProperty(this, "forcedStop", false);
42
-
43
- _defineProperty(this, "failFast", void 0);
44
-
45
36
  this.failFast = config.failFast;
46
37
  this.maxRetries = config.maxRetries;
47
38
  this.config = config.browsers[browser];
@@ -51,7 +42,7 @@ class Pool extends _events.EventEmitter {
51
42
  const poolSize = this.config.limit || 1;
52
43
  this.workers = (await Promise.all(Array.from({
53
44
  length: poolSize
54
- }).map(() => this.forkWorker()))).filter(workerOrError => workerOrError instanceof _cluster.default.Worker);
45
+ }).map(() => this.forkWorker()))).filter(workerOrError => workerOrError instanceof _cluster.Worker);
55
46
  if (this.workers.length != poolSize) throw new Error(`Can't instantiate workers for ${this.browser} due many errors`);
56
47
  this.workers.forEach(worker => this.exitHandler(worker));
57
48
  }
@@ -151,7 +142,7 @@ class Pool extends _events.EventEmitter {
151
142
  worker.once('exit', async () => {
152
143
  if (_utils.isShuttingDown.current) return;
153
144
  const workerOrError = await this.forkWorker();
154
- if (!(workerOrError instanceof _cluster.default.Worker)) throw new Error(`Can't instantiate worker for ${this.browser} due many errors`);
145
+ if (!(workerOrError instanceof _cluster.Worker)) throw new Error(`Can't instantiate worker for ${this.browser} due many errors`);
155
146
  this.exitHandler(workerOrError);
156
147
  this.workers[this.workers.indexOf(worker)] = workerOrError;
157
148
  this.process();
@@ -168,37 +159,37 @@ class Pool extends _events.EventEmitter {
168
159
  return test.retries < this.maxRetries && !this.forcedStop;
169
160
  }
170
161
 
162
+ handleTestResult(worker, test, result) {
163
+ const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
164
+
165
+ if (shouldRetry) {
166
+ test.retries += 1;
167
+ this.queue[this.failFast ? 'unshift' : 'push'](test);
168
+ }
169
+
170
+ this.sendStatus({
171
+ id: test.id,
172
+ status: shouldRetry ? 'retrying' : result.status,
173
+ result
174
+ });
175
+ worker.isRunning = false;
176
+ setImmediate(() => this.process());
177
+ }
178
+
171
179
  subscribe(worker, test) {
172
- worker.once('message', message => {
173
- if (!(0, _types.isWorkerMessage)(message) && !(0, _types.isTestMessage)(message)) return;
174
- if (message.type != 'end' && message.type != 'error') return;
175
- let result;
176
-
177
- if (message.type == 'error') {
178
- this.gracefullyKill(worker);
179
- result = {
180
- status: 'failed',
181
- ...message.payload
182
- };
183
- } else {
184
- result = message.payload;
185
- }
186
-
187
- const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
188
-
189
- if (shouldRetry) {
190
- test.retries += 1;
191
- this.queue[this.failFast ? 'unshift' : 'push'](test);
192
- }
193
-
194
- this.sendStatus({
195
- id: test.id,
196
- status: shouldRetry ? 'retrying' : result.status,
197
- result
180
+ const subscriptions = [(0, _messages.subscribeOnWorker)(worker, 'worker', message => {
181
+ if (message.type != 'error') return;
182
+ subscriptions.forEach(unsubscribe => unsubscribe());
183
+ this.gracefullyKill(worker);
184
+ this.handleTestResult(worker, test, {
185
+ status: 'failed',
186
+ ...message.payload
198
187
  });
199
- worker.isRunning = false;
200
- this.process();
201
- });
188
+ }), (0, _messages.subscribeOnWorker)(worker, 'test', message => {
189
+ if (message.type != 'end') return;
190
+ subscriptions.forEach(unsubscribe => unsubscribe());
191
+ this.handleTestResult(worker, test, message.payload);
192
+ })];
202
193
  }
203
194
 
204
195
  }
@@ -19,69 +19,44 @@ var _pool = _interopRequireDefault(require("./pool"));
19
19
 
20
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
21
 
22
- 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; }
23
-
24
22
  const copyFileAsync = (0, _util.promisify)(_fs.copyFile);
25
23
  const mkdirAsync = (0, _util.promisify)(_fs.mkdir);
26
24
 
27
25
  class Runner extends _events.EventEmitter {
26
+ pools = {};
27
+ tests = {};
28
+
28
29
  get isRunning() {
29
30
  return Object.values(this.pools).some(pool => pool.isRunning);
30
31
  }
31
32
 
32
33
  constructor(config) {
33
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
+ }
34
41
 
35
- _defineProperty(this, "failFast", void 0);
36
-
37
- _defineProperty(this, "screenDir", void 0);
38
-
39
- _defineProperty(this, "reportDir", void 0);
40
-
41
- _defineProperty(this, "browsers", void 0);
42
-
43
- _defineProperty(this, "pools", {});
44
-
45
- _defineProperty(this, "tests", {});
46
-
47
- _defineProperty(this, "handlePoolMessage", message => {
48
- const {
49
- id,
50
- status,
51
- result
52
- } = message;
53
- const test = this.tests[id];
54
- if (!test) return;
55
- const {
56
- browser,
57
- testName,
58
- storyPath,
59
- storyId
60
- } = test; // TODO Handle 'retrying' status
61
-
62
- test.status = status == 'retrying' ? 'failed' : status;
63
-
64
- if (!result) {
65
- this.sendUpdate({
66
- tests: {
67
- [id]: {
68
- id,
69
- browser,
70
- testName,
71
- storyPath,
72
- status: test.status,
73
- storyId
74
- }
75
- }
76
- });
77
- return;
78
- }
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
79
56
 
80
- if (!test.results) {
81
- test.results = [];
82
- }
57
+ test.status = status == 'retrying' ? 'failed' : status;
83
58
 
84
- test.results.push(result);
59
+ if (!result) {
85
60
  this.sendUpdate({
86
61
  tests: {
87
62
  [id]: {
@@ -90,29 +65,41 @@ class Runner extends _events.EventEmitter {
90
65
  testName,
91
66
  storyPath,
92
67
  status: test.status,
93
- results: [result],
94
68
  storyId
95
69
  }
96
70
  }
97
71
  });
98
- if (this.failFast && status == 'failed') this.stop();
99
- });
72
+ return;
73
+ }
100
74
 
101
- _defineProperty(this, "handlePoolStop", () => {
102
- if (!this.isRunning) {
103
- this.sendUpdate({
104
- isRunning: false
105
- });
106
- this.emit('stop');
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
+ }
107
91
  }
108
92
  });
109
-
110
- this.failFast = config.failFast;
111
- this.screenDir = config.screenDir;
112
- this.reportDir = config.reportDir;
113
- this.browsers = Object.keys(config.browsers);
114
- this.browsers.map(browser => this.pools[browser] = new _pool.default(config, browser)).map(pool => pool.on('test', this.handlePoolMessage));
115
- }
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
+ };
116
103
 
117
104
  async init() {
118
105
  await Promise.all(Object.values(this.pools).map(pool => pool.init()));
@@ -9,12 +9,18 @@ var _path = _interopRequireDefault(require("path"));
9
9
 
10
10
  var _http = _interopRequireDefault(require("http"));
11
11
 
12
+ var _cluster = _interopRequireDefault(require("cluster"));
13
+
12
14
  var _koa = _interopRequireDefault(require("koa"));
13
15
 
16
+ var _cors = _interopRequireDefault(require("@koa/cors"));
17
+
14
18
  var _koaStatic = _interopRequireDefault(require("koa-static"));
15
19
 
16
20
  var _koaMount = _interopRequireDefault(require("koa-mount"));
17
21
 
22
+ var _koaBodyparser = _interopRequireDefault(require("koa-bodyparser"));
23
+
18
24
  var _ws = _interopRequireDefault(require("ws"));
19
25
 
20
26
  var _messages = require("../messages");
@@ -23,10 +29,13 @@ var _types = require("../../types");
23
29
 
24
30
  var _logger = require("../logger");
25
31
 
32
+ var _shared = require("../../shared");
33
+
26
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
35
 
28
- function server(reportDir, port) {
36
+ function server(reportDir, port, ui) {
29
37
  let resolveApi = _types.noop;
38
+ let setStoriesCounter = 0;
30
39
  const creeveyApi = new Promise(resolve => resolveApi = resolve);
31
40
  const app = new _koa.default();
32
41
 
@@ -35,8 +44,71 @@ function server(reportDir, port) {
35
44
  const wss = new _ws.default.Server({
36
45
  server
37
46
  });
38
- app.use(async (_, next) => {
39
- await creeveyApi;
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
+
40
112
  await next();
41
113
  });
42
114
  app.use((0, _koaStatic.default)(_path.default.join(__dirname, '../../client/web')));
@@ -50,7 +122,9 @@ function server(reportDir, port) {
50
122
  void creeveyApi.then(api => {
51
123
  api.subscribe(wss);
52
124
  wss.on('connection', ws => {
53
- ws.on('message', message => api.handleMessage(ws, message));
125
+ ws.on('message', (message, isBinary) => {
126
+ api.handleMessage(ws, isBinary ? message : message.toString());
127
+ });
54
128
  });
55
129
  });
56
130
  return resolveApi;