creevey 0.8.0-beta.0 → 0.9.0-beta.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 (149) hide show
  1. package/CHANGELOG.md +5 -9
  2. package/lib/cjs/client/addon/Manager.js +0 -1
  3. package/lib/cjs/client/addon/preset.js +1 -0
  4. package/lib/cjs/client/addon/readyForCapture.js +12 -0
  5. package/lib/cjs/client/addon/withCreevey.js +313 -41
  6. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +3 -3
  7. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +3 -3
  8. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +4 -3
  9. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +3 -3
  10. package/lib/cjs/client/shared/helpers.js +1 -1
  11. package/lib/cjs/client/web/main.js +6 -6
  12. package/lib/cjs/index.js +27 -9
  13. package/lib/cjs/server/config.js +7 -3
  14. package/lib/cjs/server/extract.js +11 -4
  15. package/lib/cjs/server/index.js +2 -4
  16. package/lib/cjs/server/master/index.js +3 -9
  17. package/lib/cjs/server/master/master.js +1 -0
  18. package/lib/cjs/server/master/pool.js +29 -29
  19. package/lib/cjs/server/master/server.js +75 -3
  20. package/lib/cjs/server/messages.js +124 -12
  21. package/lib/cjs/server/parser.js +85 -0
  22. package/lib/cjs/server/selenium/browser.js +119 -21
  23. package/lib/cjs/server/stories.js +49 -46
  24. package/lib/cjs/server/storybook/providers/browser.js +78 -0
  25. package/lib/cjs/server/storybook/providers/hybrid.js +79 -0
  26. package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +32 -13
  27. package/lib/cjs/server/utils.js +7 -0
  28. package/lib/cjs/server/worker/helpers.js +2 -6
  29. package/lib/cjs/server/worker/worker.js +15 -3
  30. package/lib/cjs/shared.js +78 -6
  31. package/lib/cjs/types.js +5 -0
  32. package/lib/esm/client/addon/Manager.js +0 -1
  33. package/lib/esm/client/addon/preset.js +1 -0
  34. package/lib/esm/client/addon/readyForCapture.js +5 -0
  35. package/lib/esm/client/addon/withCreevey.js +303 -41
  36. package/lib/esm/client/shared/components/ImagesView/BlendView.js +2 -3
  37. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +2 -3
  38. package/lib/esm/client/shared/components/ImagesView/SlideView.js +3 -3
  39. package/lib/esm/client/shared/components/ImagesView/SwapView.js +2 -3
  40. package/lib/esm/client/shared/helpers.js +1 -1
  41. package/lib/esm/index.js +6 -3
  42. package/lib/esm/server/config.js +7 -5
  43. package/lib/esm/server/extract.js +8 -4
  44. package/lib/esm/server/index.js +2 -3
  45. package/lib/esm/server/master/index.js +4 -10
  46. package/lib/esm/server/master/master.js +1 -0
  47. package/lib/esm/server/master/pool.js +31 -31
  48. package/lib/esm/server/master/server.js +73 -5
  49. package/lib/esm/server/messages.js +118 -12
  50. package/lib/esm/server/parser.js +63 -0
  51. package/lib/esm/server/selenium/browser.js +116 -23
  52. package/lib/esm/server/stories.js +50 -46
  53. package/lib/esm/server/storybook/providers/browser.js +61 -0
  54. package/lib/esm/server/storybook/providers/hybrid.js +63 -0
  55. package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +30 -13
  56. package/lib/esm/server/utils.js +6 -1
  57. package/lib/esm/server/worker/helpers.js +2 -6
  58. package/lib/esm/server/worker/worker.js +16 -4
  59. package/lib/esm/shared.js +59 -5
  60. package/lib/esm/types.js +3 -0
  61. package/lib/types/cli.d.ts +1 -1
  62. package/lib/types/client/addon/Manager.d.ts +37 -37
  63. package/lib/types/client/addon/components/Addon.d.ts +8 -8
  64. package/lib/types/client/addon/components/Icons.d.ts +7 -7
  65. package/lib/types/client/addon/components/Panel.d.ts +9 -9
  66. package/lib/types/client/addon/components/TestSelect.d.ts +9 -9
  67. package/lib/types/client/addon/components/Tools.d.ts +6 -6
  68. package/lib/types/client/addon/decorator.d.ts +1 -1
  69. package/lib/types/client/addon/preset.d.ts +24 -22
  70. package/lib/types/client/addon/readyForCapture.d.ts +6 -0
  71. package/lib/types/client/addon/register.d.ts +3 -3
  72. package/lib/types/client/addon/utils.d.ts +2 -2
  73. package/lib/types/client/addon/withCreevey.d.ts +24 -13
  74. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -3
  75. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +25 -25
  76. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -3
  77. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -3
  78. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -3
  79. package/lib/types/client/shared/components/ImagesView/index.d.ts +5 -5
  80. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +9 -9
  81. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +8 -8
  82. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +12 -12
  83. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +17 -17
  84. package/lib/types/client/shared/components/ResultsPage.d.ts +18 -18
  85. package/lib/types/client/shared/creeveyClientApi.d.ts +9 -9
  86. package/lib/types/client/shared/helpers.d.ts +46 -46
  87. package/lib/types/client/shared/viewMode.d.ts +4 -4
  88. package/lib/types/client/web/CreeveyApp.d.ts +12 -12
  89. package/lib/types/client/web/CreeveyContext.d.ts +11 -11
  90. package/lib/types/client/web/CreeveyLoader.d.ts +3 -3
  91. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +19 -19
  92. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  93. package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  94. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +13 -13
  95. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +33 -33
  96. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +8 -8
  97. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +10 -10
  98. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +9 -9
  99. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  100. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +1 -1
  101. package/lib/types/client/web/KeyboardEventsContext.d.ts +13 -13
  102. package/lib/types/client/web/index.d.ts +4 -4
  103. package/lib/types/creevey.d.ts +1 -1
  104. package/lib/types/index.d.ts +2 -1
  105. package/lib/types/server/config.d.ts +4 -4
  106. package/lib/types/server/docker.d.ts +7 -7
  107. package/lib/types/server/extract.d.ts +2 -2
  108. package/lib/types/server/index.d.ts +2 -2
  109. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +1 -1
  110. package/lib/types/server/loaders/babel/helpers.d.ts +19 -19
  111. package/lib/types/server/loaders/babel/register.d.ts +5 -5
  112. package/lib/types/server/loaders/hooks/mdx.d.ts +1 -1
  113. package/lib/types/server/loaders/hooks/svelte.d.ts +1 -1
  114. package/lib/types/server/loaders/webpack/compile.d.ts +2 -2
  115. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +2 -2
  116. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +10 -10
  117. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +6 -6
  118. package/lib/types/server/loaders/webpack/start.d.ts +1 -1
  119. package/lib/types/server/logger.d.ts +6 -6
  120. package/lib/types/server/master/api.d.ts +7 -7
  121. package/lib/types/server/master/index.d.ts +3 -3
  122. package/lib/types/server/master/master.d.ts +7 -6
  123. package/lib/types/server/master/pool.d.ts +31 -30
  124. package/lib/types/server/master/runner.d.ts +26 -26
  125. package/lib/types/server/master/server.d.ts +2 -2
  126. package/lib/types/server/messages.d.ts +28 -18
  127. package/lib/types/server/parser.d.ts +12 -0
  128. package/lib/types/server/selenium/browser.d.ts +17 -14
  129. package/lib/types/server/selenium/index.d.ts +2 -2
  130. package/lib/types/server/selenium/selenoid.d.ts +3 -3
  131. package/lib/types/server/stories.d.ts +8 -8
  132. package/lib/types/server/storybook/entry.d.ts +18 -18
  133. package/lib/types/server/storybook/helpers.d.ts +24 -24
  134. package/lib/types/server/storybook/providers/browser.d.ts +4 -0
  135. package/lib/types/server/storybook/providers/hybrid.d.ts +4 -0
  136. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
  137. package/lib/types/server/update.d.ts +2 -2
  138. package/lib/types/server/utils.d.ts +20 -19
  139. package/lib/types/server/worker/chai-image.d.ts +6 -6
  140. package/lib/types/server/worker/helpers.d.ts +8 -7
  141. package/lib/types/server/worker/index.d.ts +1 -1
  142. package/lib/types/server/worker/reporter.d.ts +8 -8
  143. package/lib/types/server/worker/worker.d.ts +4 -4
  144. package/lib/types/shared.d.ts +16 -4
  145. package/lib/types/types.d.ts +488 -459
  146. package/package.json +12 -6
  147. package/storybook-static/stories.json +21 -0
  148. package/types/mocha.d.ts +1 -0
  149. package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
package/lib/cjs/index.js CHANGED
@@ -4,12 +4,26 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  var _exportNames = {
7
- nodejsStoriesProvider: true
7
+ browserStoriesProvider: true,
8
+ nodejsStoriesProvider: true,
9
+ hybridStoriesProvider: true
8
10
  };
11
+ Object.defineProperty(exports, "browserStoriesProvider", {
12
+ enumerable: true,
13
+ get: function () {
14
+ return _browser.loadStories;
15
+ }
16
+ });
9
17
  Object.defineProperty(exports, "nodejsStoriesProvider", {
10
18
  enumerable: true,
11
19
  get: function () {
12
- return _nodejsProvider.loadStories;
20
+ return _nodejs.loadStories;
21
+ }
22
+ });
23
+ Object.defineProperty(exports, "hybridStoriesProvider", {
24
+ enumerable: true,
25
+ get: function () {
26
+ return _hybrid.loadStories;
13
27
  }
14
28
  });
15
29
 
@@ -27,18 +41,22 @@ Object.keys(_types).forEach(function (key) {
27
41
  });
28
42
  });
29
43
 
30
- var _withCreevey = require("./client/addon/withCreevey");
44
+ var _browser = require("./server/storybook/providers/browser");
45
+
46
+ var _nodejs = require("./server/storybook/providers/nodejs");
47
+
48
+ var _hybrid = require("./server/storybook/providers/hybrid");
31
49
 
32
- Object.keys(_withCreevey).forEach(function (key) {
50
+ var _parser = require("./server/parser");
51
+
52
+ Object.keys(_parser).forEach(function (key) {
33
53
  if (key === "default" || key === "__esModule") return;
34
54
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
35
- if (key in exports && exports[key] === _withCreevey[key]) return;
55
+ if (key in exports && exports[key] === _parser[key]) return;
36
56
  Object.defineProperty(exports, key, {
37
57
  enumerable: true,
38
58
  get: function () {
39
- return _withCreevey[key];
59
+ return _parser[key];
40
60
  }
41
61
  });
42
- });
43
-
44
- var _nodejsProvider = require("./server/storybook/nodejs-provider");
62
+ });
@@ -12,7 +12,9 @@ var _path = _interopRequireDefault(require("path"));
12
12
 
13
13
  var _helpers = require("./storybook/helpers");
14
14
 
15
- var _nodejsProvider = require("./storybook/nodejs-provider");
15
+ var _nodejs = require("./storybook/providers/nodejs");
16
+
17
+ var _browser = require("./storybook/providers/browser");
16
18
 
17
19
  var _types = require("../types");
18
20
 
@@ -44,7 +46,8 @@ const defaultConfig = {
44
46
  [defaultBrowser]: true
45
47
  },
46
48
  hooks: {},
47
- babelOptions: _ => _
49
+ babelOptions: _ => _,
50
+ testRegex: /.creevey.(t|j)s$/
48
51
  };
49
52
  exports.defaultConfig = defaultConfig;
50
53
 
@@ -81,7 +84,8 @@ async function readConfig(options) {
81
84
  if ((0, _types.isDefined)(configPath)) Object.assign(userConfig, (await Promise.resolve(`${configPath}`).then(s => _interopRequireWildcard(require(s)))).default);
82
85
  _helpers.storybookDirRef.current = userConfig.storybookDir;
83
86
  if ((0, _helpers.isStorybookVersionLessThan)(6, 2)) userConfig.useWebpackToExtractTests = true;
84
- if (!userConfig.storiesProvider) userConfig.storiesProvider = (await (0, _helpers.isCSFv3Enabled)()) ? _nodejsProvider.loadStories : _nodejsProvider.loadStories;
87
+ if (!userConfig.storiesProvider) userConfig.storiesProvider = (await (0, _helpers.isCSFv3Enabled)()) && (0, _helpers.isStorybookVersionGreaterThan)(5) ? _browser.loadStories : _nodejs.loadStories;
88
+ if (userConfig.storiesProvider == _browser.loadStories && (0, _helpers.isStorybookVersionLessThan)(6)) throw new Error("Creevey browser stories provider doesn't support Storybook 5.x or older versions");
85
89
  if (options.failFast != undefined) userConfig.failFast = Boolean(options.failFast);
86
90
  if (options.reportDir) userConfig.reportDir = _path.default.resolve(options.reportDir);
87
91
  if (options.screenDir) userConfig.screenDir = _path.default.resolve(options.screenDir); // NOTE: Hack to pass typescript checking
@@ -5,10 +5,16 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = extract;
7
7
 
8
+ var _shared = require("../shared");
9
+
8
10
  var _messages = require("./messages");
9
11
 
10
12
  var _stories = require("./stories");
11
13
 
14
+ var _helpers = require("./storybook/helpers");
15
+
16
+ var _nodejs = require("./storybook/providers/nodejs");
17
+
12
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); }
13
19
 
14
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; }
@@ -29,12 +35,13 @@ async function extract(config, options) {
29
35
  });
30
36
  }
31
37
 
32
- const tests = await (0, _stories.loadTestsFromStories)(Object.keys(config.browsers), async listener => {
33
- const stories = await config.storiesProvider(config, {
38
+ const tests = await (0, _stories.loadTestsFromStories)(Object.keys(config.browsers), async () => {
39
+ const data = await (0, _nodejs.extractStoriesData)(config, {
34
40
  watch: false,
35
41
  debug: options.debug
36
- }, listener);
37
- if (options.extract) (0, _stories.saveStoriesJson)(stories, options.extract);
42
+ });
43
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
44
+ if (options.extract) (0, _stories.saveStoriesJson)(data, options.extract);
38
45
  return stories;
39
46
  });
40
47
  if (options.tests) (0, _stories.saveTestsJson)(tests); // eslint-disable-next-line no-process-exit
@@ -9,8 +9,6 @@ var _cluster = _interopRequireDefault(require("cluster"));
9
9
 
10
10
  var _config = require("./config");
11
11
 
12
- var _types = require("../types");
13
-
14
12
  var _logger = require("./logger");
15
13
 
16
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -39,8 +37,7 @@ async function _default(options) {
39
37
  ui,
40
38
  port
41
39
  } = options;
42
- if (!config) return;
43
- const resolveApi = ui && _cluster.default.isMaster ? (await Promise.resolve().then(() => _interopRequireWildcard(require('./master/server')))).default(config.reportDir, port) : _types.noop; // NOTE: We don't need docker nor selenoid for webpack or update options
40
+ if (!config) return; // NOTE: We don't need docker nor selenoid for webpack or update options
44
41
 
45
42
  if (!(config.gridUrl || Object.values(config.browsers).every(({
46
43
  gridUrl
@@ -70,6 +67,7 @@ async function _default(options) {
70
67
  {
71
68
  _logger.logger.info('Starting Master Process');
72
69
 
70
+ const resolveApi = (await Promise.resolve().then(() => _interopRequireWildcard(require('./master/server')))).default(config.reportDir, port, ui);
73
71
  return (await Promise.resolve().then(() => _interopRequireWildcard(require('./master')))).default(config, options, resolveApi);
74
72
  }
75
73
 
@@ -56,15 +56,9 @@ function reportDataModule(data) {
56
56
  `;
57
57
  }
58
58
 
59
- function readDirRecursive(dirPath) {
60
- return [].concat(...(0, _fs.readdirSync)(dirPath, {
61
- withFileTypes: true
62
- }).map(dirent => dirent.isDirectory() ? readDirRecursive(`${dirPath}/${dirent.name}`) : [`${dirPath}/${dirent.name}`]));
63
- }
64
-
65
59
  function outputUnnecessaryImages(imagesDir, images) {
66
60
  if (!(0, _fs.existsSync)(imagesDir)) return;
67
- const unnecessaryImages = readDirRecursive(imagesDir).map(imagePath => _path.default.posix.relative(imagesDir, imagePath)).filter(imagePath => !images.has(imagePath));
61
+ const unnecessaryImages = (0, _utils.readDirRecursive)(imagesDir).map(imagePath => _path.default.posix.relative(imagesDir, imagePath)).filter(imagePath => !images.has(imagePath));
68
62
 
69
63
  if (unnecessaryImages.length > 0) {
70
64
  _logger.logger.warn('We found unnecessary screenshot images, those can be safely removed:\n', unnecessaryImages.join('\n'));
@@ -105,9 +99,9 @@ async function _default(config, options, resolveApi) {
105
99
  });
106
100
  runner = await (0, _master.default)(config, {
107
101
  watch: options.ui,
108
- debug: options.debug
102
+ debug: options.debug,
103
+ port: options.port
109
104
  });
110
- await runner.init();
111
105
 
112
106
  if (options.saveReport) {
113
107
  await copyStatics(config.reportDir);
@@ -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);
@@ -168,37 +168,37 @@ class Pool extends _events.EventEmitter {
168
168
  return test.retries < this.maxRetries && !this.forcedStop;
169
169
  }
170
170
 
171
+ handleTestResult(worker, test, result) {
172
+ const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
173
+
174
+ if (shouldRetry) {
175
+ test.retries += 1;
176
+ this.queue[this.failFast ? 'unshift' : 'push'](test);
177
+ }
178
+
179
+ this.sendStatus({
180
+ id: test.id,
181
+ status: shouldRetry ? 'retrying' : result.status,
182
+ result
183
+ });
184
+ worker.isRunning = false;
185
+ setImmediate(() => this.process());
186
+ }
187
+
171
188
  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
189
+ const subscriptions = [(0, _messages.subscribeOnWorker)(worker, 'worker', message => {
190
+ if (message.type != 'error') return;
191
+ subscriptions.forEach(unsubscribe => unsubscribe());
192
+ this.gracefullyKill(worker);
193
+ this.handleTestResult(worker, test, {
194
+ status: 'failed',
195
+ ...message.payload
198
196
  });
199
- worker.isRunning = false;
200
- this.process();
201
- });
197
+ }), (0, _messages.subscribeOnWorker)(worker, 'test', message => {
198
+ if (message.type != 'end') return;
199
+ subscriptions.forEach(unsubscribe => unsubscribe());
200
+ this.handleTestResult(worker, test, message.payload);
201
+ })];
202
202
  }
203
203
 
204
204
  }
@@ -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')));
@@ -4,14 +4,17 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.emitWorkerMessage = emitWorkerMessage;
7
+ exports.emitStoriesMessage = emitStoriesMessage;
7
8
  exports.emitTestMessage = emitTestMessage;
8
9
  exports.emitWebpackMessage = emitWebpackMessage;
9
10
  exports.emitDockerMessage = emitDockerMessage;
10
11
  exports.emitShutdownMessage = emitShutdownMessage;
12
+ exports.sendStoriesMessage = sendStoriesMessage;
11
13
  exports.sendTestMessage = sendTestMessage;
12
14
  exports.sendDockerMessage = sendDockerMessage;
13
15
  exports.sendShutdownMessage = sendShutdownMessage;
14
16
  exports.subscribeOn = subscribeOn;
17
+ exports.subscribeOnWorker = subscribeOnWorker;
15
18
 
16
19
  var _cluster = _interopRequireDefault(require("cluster"));
17
20
 
@@ -32,6 +35,13 @@ function emitWorkerMessage(message) {
32
35
  });
33
36
  }
34
37
 
38
+ function emitStoriesMessage(message) {
39
+ return emitMessage({
40
+ scope: 'stories',
41
+ ...message
42
+ });
43
+ }
44
+
35
45
  function emitTestMessage(message) {
36
46
  return emitMessage({
37
47
  scope: 'test',
@@ -59,19 +69,27 @@ function emitShutdownMessage() {
59
69
  });
60
70
  }
61
71
 
62
- const handlers = Object.assign(Object.create(null), {
63
- worker: new Set(),
64
- test: new Set(),
65
- webpack: new Set(),
66
- docker: new Set(),
67
- shutdown: new Set()
68
- });
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();
69
84
 
70
85
  const handler = message => {
71
86
  switch (message.scope) {
72
87
  case 'worker':
73
88
  return handlers.worker.forEach(h => h(message));
74
89
 
90
+ case 'stories':
91
+ return handlers.stories.forEach(h => h(message));
92
+
75
93
  case 'test':
76
94
  return handlers.test.forEach(h => h(message));
77
95
 
@@ -88,28 +106,37 @@ const handler = message => {
88
106
 
89
107
  process.on('message', handler);
90
108
 
91
- function sendTestMessage(target, message) {
109
+ function sendStoriesMessage(target, message) {
92
110
  var _target$send;
93
111
 
94
112
  (_target$send = target.send) === null || _target$send === void 0 ? void 0 : _target$send.call(target, {
95
- scope: 'test',
113
+ scope: 'stories',
96
114
  ...message
97
115
  });
98
116
  }
99
117
 
100
- function sendDockerMessage(target, message) {
118
+ function sendTestMessage(target, message) {
101
119
  var _target$send2;
102
120
 
103
121
  (_target$send2 = target.send) === null || _target$send2 === void 0 ? void 0 : _target$send2.call(target, {
104
- scope: 'docker',
122
+ scope: 'test',
105
123
  ...message
106
124
  });
107
125
  }
108
126
 
109
- function sendShutdownMessage(target) {
127
+ function sendDockerMessage(target, message) {
110
128
  var _target$send3;
111
129
 
112
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, {
113
140
  scope: 'shutdown'
114
141
  });
115
142
  }
@@ -123,6 +150,13 @@ function subscribeOn(scope, handler) {
123
150
  return () => handlers.worker.delete(workerHandler);
124
151
  }
125
152
 
153
+ case 'stories':
154
+ {
155
+ const storiesHandler = handler;
156
+ handlers.stories.add(storiesHandler);
157
+ return () => handlers.stories.delete(storiesHandler);
158
+ }
159
+
126
160
  case 'test':
127
161
  {
128
162
  const testHandler = handler;
@@ -151,4 +185,82 @@ function subscribeOn(scope, handler) {
151
185
  return () => handlers.shutdown.delete(shutdownHandler);
152
186
  }
153
187
  }
188
+ }
189
+
190
+ const workers = new Map();
191
+
192
+ function subscribeOnWorker(worker, scope, handler) {
193
+ var _workers$get;
194
+
195
+ const workerHandlers = (_workers$get = workers.get(worker)) !== null && _workers$get !== void 0 ? _workers$get : createHandlers();
196
+
197
+ if (!workers.has(worker)) {
198
+ workers.set(worker, workerHandlers);
199
+ worker.once('exit', () => workers.delete(worker));
200
+ worker.on('message', message => {
201
+ switch (message.scope) {
202
+ case 'worker':
203
+ return workerHandlers.worker.forEach(h => h(message));
204
+
205
+ case 'stories':
206
+ return workerHandlers.stories.forEach(h => h(message));
207
+
208
+ case 'test':
209
+ return workerHandlers.test.forEach(h => h(message));
210
+
211
+ case 'webpack':
212
+ return workerHandlers.webpack.forEach(h => h(message));
213
+
214
+ case 'docker':
215
+ return workerHandlers.docker.forEach(h => h(message));
216
+
217
+ case 'shutdown':
218
+ return workerHandlers.shutdown.forEach(h => h(message));
219
+ }
220
+ });
221
+ }
222
+
223
+ switch (scope) {
224
+ case 'worker':
225
+ {
226
+ const workerHandler = handler;
227
+ workerHandlers.worker.add(workerHandler);
228
+ return () => workerHandlers.worker.delete(workerHandler);
229
+ }
230
+
231
+ case 'stories':
232
+ {
233
+ const storiesHandler = handler;
234
+ workerHandlers.stories.add(storiesHandler);
235
+ return () => workerHandlers.stories.delete(storiesHandler);
236
+ }
237
+
238
+ case 'test':
239
+ {
240
+ const testHandler = handler;
241
+ workerHandlers.test.add(testHandler);
242
+ return () => workerHandlers.test.delete(testHandler);
243
+ }
244
+
245
+ case 'webpack':
246
+ {
247
+ const webpackHandler = handler;
248
+ workerHandlers.webpack.add(webpackHandler);
249
+ return () => workerHandlers.webpack.delete(webpackHandler);
250
+ }
251
+
252
+ case 'docker':
253
+ {
254
+ const dockerHandler = handler;
255
+ workerHandlers.docker.add(dockerHandler);
256
+ return () => workerHandlers.docker.delete(dockerHandler);
257
+ }
258
+
259
+ case 'shutdown':
260
+ {
261
+ const shutdownHandler = handler;
262
+ workerHandlers.shutdown.add(shutdownHandler);
263
+ return () => workerHandlers.shutdown.delete(shutdownHandler);
264
+ }
265
+ }
154
266
  }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = parse;
7
+ exports.test = exports.story = exports.kind = void 0;
8
+
9
+ var _csf = require("@storybook/csf");
10
+
11
+ 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); }
12
+
13
+ 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; }
14
+
15
+ async function parse(files) {
16
+ result = {}; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
17
+
18
+ (await Promise.resolve().then(() => _interopRequireWildcard(require('@babel/register')))).default({
19
+ babelrc: false,
20
+ rootMode: 'upward-optional',
21
+ ignore: [/node_modules/],
22
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
23
+ plugins: [['@babel/plugin-transform-runtime']],
24
+ presets: ['@babel/preset-typescript', ['@babel/preset-env', {
25
+ targets: {
26
+ node: '10'
27
+ }
28
+ }]]
29
+ });
30
+ await Promise.all(files.map(async file => Promise.resolve(`${file}`).then(s => _interopRequireWildcard(require(s)))));
31
+ return result;
32
+ }
33
+
34
+ let result = {};
35
+ let kindTitle = '';
36
+ let storyTitle = '';
37
+ let storyParams = null;
38
+
39
+ const setStoryParameters = params => {
40
+ storyParams = params;
41
+ };
42
+
43
+ const getStoryId = (kindTitle, storyTitle) => {
44
+ return (0, _csf.toId)(kindTitle, (0, _csf.storyNameFromExport)(storyTitle));
45
+ };
46
+
47
+ const kind = (title, kindFn) => {
48
+ kindTitle = title;
49
+ kindFn();
50
+ kindTitle = '';
51
+ };
52
+
53
+ exports.kind = kind;
54
+
55
+ const story = (title, storyFn) => {
56
+ var _result$storyId;
57
+
58
+ storyTitle = title;
59
+ storyParams = null;
60
+ storyFn({
61
+ setStoryParameters
62
+ });
63
+ const storyId = getStoryId(kindTitle, storyTitle);
64
+ result[storyId] = Object.assign({}, storyParams, {
65
+ tests: (_result$storyId = result[storyId]) === null || _result$storyId === void 0 ? void 0 : _result$storyId.tests
66
+ });
67
+ storyTitle = '';
68
+ storyParams = null;
69
+ };
70
+
71
+ exports.story = story;
72
+
73
+ const test = (title, testFn) => {
74
+ const storyId = getStoryId(kindTitle, storyTitle);
75
+
76
+ if (!result[storyId]) {
77
+ result[storyId] = {};
78
+ }
79
+
80
+ result[storyId].tests = Object.assign({}, result[storyId].tests, {
81
+ [title]: testFn
82
+ });
83
+ };
84
+
85
+ exports.test = test;