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
@@ -56,14 +56,10 @@ function removeTestOrSuite(testOrSuite) {
56
56
 
57
57
  async function addTestsFromStories(rootSuite, config, {
58
58
  browser,
59
- watch,
60
- debug
59
+ ...options
61
60
  }) {
62
61
  const mochaTestsById = new Map();
63
- const tests = await (0, _stories.loadTestsFromStories)([browser], listener => config.storiesProvider(config, {
64
- watch,
65
- debug
66
- }, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
62
+ const tests = await (0, _stories.loadTestsFromStories)([browser], listener => config.storiesProvider(config, options, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
67
63
  const oldTest = mochaTestsById.get(id);
68
64
  mochaTestsById.delete(id);
69
65
  if (oldTest) removeTestOrSuite(oldTest);
@@ -72,6 +72,7 @@ async function worker(config, options) {
72
72
  let retries = 0;
73
73
  let images = {};
74
74
  let error = undefined;
75
+ const screenshots = [];
75
76
  const testScope = [];
76
77
 
77
78
  function runHandler(failures) {
@@ -201,13 +202,23 @@ async function worker(config, options) {
201
202
 
202
203
  _chai.default.use((0, _chaiImage.default)(getExpected, config.diffOptions));
203
204
 
205
+ if ((await (0, _selenium.getBrowser)(config, options.browser)) == null) return;
204
206
  await (0, _helpers.addTestsFromStories)(mocha.suite, config, {
205
207
  browser: options.browser,
206
208
  watch: options.ui,
207
- debug: options.debug
209
+ debug: options.debug,
210
+ port: options.port
208
211
  });
209
- const browserConfig = config.browsers[options.browser];
210
- const browser = await (0, _selenium.getBrowser)(config, browserConfig);
212
+
213
+ try {
214
+ var _await$getBrowser;
215
+
216
+ await ((_await$getBrowser = await (0, _selenium.getBrowser)(config, options.browser)) === null || _await$getBrowser === void 0 ? void 0 : _await$getBrowser.getCurrentUrl());
217
+ } catch (_) {
218
+ await (0, _selenium.closeBrowser)();
219
+ }
220
+
221
+ const browser = await (0, _selenium.getBrowser)(config, options.browser);
211
222
  const sessionId = (_await$browser$getSes = await (browser === null || browser === void 0 ? void 0 : browser.getSession())) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
212
223
  if (browser == null) return;
213
224
  const interval = setInterval(() => void browser.getCurrentUrl().then(url => {
@@ -222,6 +233,7 @@ async function worker(config, options) {
222
233
  this.expect = _chai.default.expect;
223
234
  this.browserName = options.browser;
224
235
  this.testScope = testScope;
236
+ this.screenshots = screenshots;
225
237
  });
226
238
  mocha.suite.beforeEach(_selenium.switchStory);
227
239
  (0, _messages.subscribeOn)('test', message => {
package/lib/cjs/shared.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.denormalizeStoryParameters = exports.combineParameters = void 0;
6
+ exports.deserializeStory = exports.deserializeRawStories = exports.serializeRawStories = exports.deserializeRegExp = exports.serializeRegExp = exports.isSerializedRegExp = exports.denormalizeStoryParameters = exports.combineParameters = void 0;
7
7
 
8
8
  var _lodash = require("lodash");
9
9
 
@@ -24,12 +24,84 @@ const denormalizeStoryParameters = ({
24
24
  stories
25
25
  }) => {
26
26
  return (0, _lodash.mapValues)(stories, storyData => {
27
- var _kindParameters$story;
27
+ var _globalParameters$cre, _kindParameters$story, _kindParameters$story2;
28
28
 
29
- return { ...storyData,
30
- parameters: combineParameters(globalParameters, (_kindParameters$story = kindParameters[storyData.kind]) !== null && _kindParameters$story !== void 0 ? _kindParameters$story : {}, storyData.parameters)
31
- };
29
+ storyData.parameters.creevey = combineParameters((_globalParameters$cre = globalParameters.creevey) !== null && _globalParameters$cre !== void 0 ? _globalParameters$cre : {}, (_kindParameters$story = (_kindParameters$story2 = kindParameters[storyData.kind]) === null || _kindParameters$story2 === void 0 ? void 0 : _kindParameters$story2.creevey) !== null && _kindParameters$story !== void 0 ? _kindParameters$story : {}, storyData.parameters.creevey);
30
+ return storyData;
32
31
  });
33
32
  };
34
33
 
35
- exports.denormalizeStoryParameters = denormalizeStoryParameters;
34
+ exports.denormalizeStoryParameters = denormalizeStoryParameters;
35
+
36
+ const isSerializedRegExp = exp => {
37
+ return typeof exp === 'object' && exp !== null && Reflect.get(exp, '__regexp') === true;
38
+ };
39
+
40
+ exports.isSerializedRegExp = isSerializedRegExp;
41
+
42
+ const serializeRegExp = exp => {
43
+ const {
44
+ source,
45
+ flags
46
+ } = exp;
47
+ return {
48
+ __regexp: true,
49
+ source,
50
+ flags
51
+ };
52
+ };
53
+
54
+ exports.serializeRegExp = serializeRegExp;
55
+
56
+ const deserializeRegExp = ({
57
+ source,
58
+ flags
59
+ }) => {
60
+ return new RegExp(source, flags);
61
+ };
62
+
63
+ exports.deserializeRegExp = deserializeRegExp;
64
+
65
+ const serializeRawStories = stories => {
66
+ return (0, _lodash.mapValues)(stories, storyData => {
67
+ const creevey = storyData.parameters.creevey;
68
+
69
+ if ((creevey === null || creevey === void 0 ? void 0 : creevey.skip) !== undefined) {
70
+ creevey.skip = (0, _lodash.cloneDeepWith)(creevey.skip, value => {
71
+ if (value instanceof RegExp) {
72
+ return serializeRegExp(value);
73
+ }
74
+
75
+ return undefined;
76
+ });
77
+ }
78
+
79
+ return storyData;
80
+ });
81
+ };
82
+
83
+ exports.serializeRawStories = serializeRawStories;
84
+
85
+ const deserializeRawStories = stories => {
86
+ return (0, _lodash.mapValues)(stories, deserializeStory);
87
+ };
88
+
89
+ exports.deserializeRawStories = deserializeRawStories;
90
+
91
+ const deserializeStory = story => {
92
+ const creevey = story.parameters.creevey;
93
+
94
+ if ((creevey === null || creevey === void 0 ? void 0 : creevey.skip) !== undefined) {
95
+ creevey.skip = (0, _lodash.cloneDeepWith)(creevey.skip, value => {
96
+ if (isSerializedRegExp(value)) {
97
+ return deserializeRegExp(value);
98
+ }
99
+
100
+ return undefined;
101
+ });
102
+ }
103
+
104
+ return story;
105
+ };
106
+
107
+ exports.deserializeStory = deserializeStory;
package/lib/cjs/types.js CHANGED
@@ -12,6 +12,7 @@ exports.isFunction = isFunction;
12
12
  exports.isImageError = isImageError;
13
13
  exports.isProcessMessage = isProcessMessage;
14
14
  exports.isWorkerMessage = isWorkerMessage;
15
+ exports.isStoriesMessage = isStoriesMessage;
15
16
  exports.isTestMessage = isTestMessage;
16
17
  exports.isWebpackMessage = isWebpackMessage;
17
18
  exports.isDockerMessage = isDockerMessage;
@@ -56,6 +57,10 @@ function isWorkerMessage(message) {
56
57
  return isProcessMessage(message) && message.scope == 'worker';
57
58
  }
58
59
 
60
+ function isStoriesMessage(message) {
61
+ return isProcessMessage(message) && message.scope == 'stories';
62
+ }
63
+
59
64
  function isTestMessage(message) {
60
65
  return isProcessMessage(message) && message.scope == 'test';
61
66
  }
@@ -230,7 +230,6 @@ export var CreeveyManager = /*#__PURE__*/function () {
230
230
  });
231
231
 
232
232
  _defineProperty(this, "onSetStories", function (data) {
233
- // TODO: Send PR to storybook to fix this
234
233
  var stories = data.v ? denormalizeStoryParameters(data) : data.stories;
235
234
  _this.stories = stories;
236
235
  });
@@ -47,6 +47,7 @@ export function managerWebpack(config, options) {
47
47
  DefinePlugin = _ref$DefinePlugin === void 0 ? FallbackDefinePlugin : _ref$DefinePlugin;
48
48
 
49
49
  (_config$plugins = config.plugins) === null || _config$plugins === void 0 ? void 0 : _config$plugins.push(new DefinePlugin({
50
+ __CREEVEY_SERVER_HOST__: options.creeveyHost,
50
51
  __CREEVEY_SERVER_PORT__: (_options$creeveyPort = options.creeveyPort) !== null && _options$creeveyPort !== void 0 ? _options$creeveyPort : 3000,
51
52
  __CREEVEY_CLIENT_PORT__: options.clientPort
52
53
  }));
@@ -0,0 +1,5 @@
1
+ export function readyForCapture() {
2
+ var _window$__CREEVEY_SET, _window;
3
+
4
+ (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
5
+ }
@@ -1,3 +1,23 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+
5
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
6
+
7
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
+
9
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
10
+
11
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12
+
13
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
14
+
15
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
16
+
17
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
18
+
19
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
20
+
1
21
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
22
 
3
23
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
@@ -6,8 +26,11 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
6
26
 
7
27
  import * as Events from '@storybook/core-events';
8
28
  import * as polyfill from 'event-source-polyfill';
29
+ import { buildQueries, within } from '@storybook/testing-library';
9
30
  import { addons, makeDecorator } from '@storybook/addons';
10
31
  import { isObject, noop } from '../../types';
32
+ import { denormalizeStoryParameters, serializeRawStories } from '../../shared';
33
+ import { getConnectionUrl } from '../shared/helpers';
11
34
 
12
35
  if ((typeof process === "undefined" ? "undefined" : _typeof(process)) != 'object' || typeof process.version != 'string') {
13
36
  // NOTE If you don't use babel-polyfill or any other polyfills that add EventSource for IE11
@@ -27,10 +50,10 @@ function resetCurrentStory(_x) {
27
50
  }
28
51
 
29
52
  function _resetCurrentStory() {
30
- _resetCurrentStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(channel) {
31
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
53
+ _resetCurrentStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(channel) {
54
+ return regeneratorRuntime.wrap(function _callee4$(_context4) {
32
55
  while (1) {
33
- switch (_context3.prev = _context3.next) {
56
+ switch (_context4.prev = _context4.next) {
34
57
  case 0:
35
58
  setTimeout(function () {
36
59
  return channel.emit(Events.SET_CURRENT_STORY, {
@@ -39,16 +62,16 @@ function _resetCurrentStory() {
39
62
  kind: ''
40
63
  });
41
64
  }, 0);
42
- return _context3.abrupt("return", new Promise(function (resolve) {
65
+ return _context4.abrupt("return", new Promise(function (resolve) {
43
66
  return channel.once(Events.STORY_MISSING, resolve);
44
67
  }));
45
68
 
46
69
  case 2:
47
70
  case "end":
48
- return _context3.stop();
71
+ return _context4.stop();
49
72
  }
50
73
  }
51
- }, _callee3);
74
+ }, _callee4);
52
75
  }));
53
76
  return _resetCurrentStory.apply(this, arguments);
54
77
  }
@@ -122,9 +145,39 @@ function waitForFontsLoaded() {
122
145
  }
123
146
  }
124
147
 
148
+ function waitForCaptureCall() {
149
+ return new Promise(function (resolve) {
150
+ return captureResolver = resolve;
151
+ });
152
+ }
153
+
154
+ function initCreeveyState() {
155
+ var _window$localStorage$;
156
+
157
+ var prevState = JSON.parse((_window$localStorage$ = window.localStorage.getItem('Creevey_Tests')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '{}');
158
+ if (prevState.creeveyHost) window.__CREEVEY_SERVER_HOST__ = prevState.creeveyHost;
159
+ if (prevState.creeveyPort) window.__CREEVEY_SERVER_PORT__ = prevState.creeveyPort;
160
+ if (prevState.setStoriesCounter) setStoriesCounter = prevState.setStoriesCounter;
161
+ if (prevState.isTestBrowser) isTestBrowser = prevState.isTestBrowser;
162
+ window.addEventListener('beforeunload', function () {
163
+ window.localStorage.setItem('Creevey_Tests', JSON.stringify({
164
+ creeveyHost: window.__CREEVEY_SERVER_HOST__,
165
+ creeveyPort: window.__CREEVEY_SERVER_PORT__,
166
+ setStoriesCounter: setStoriesCounter,
167
+ isTestBrowser: isTestBrowser
168
+ }));
169
+ });
170
+ }
171
+
172
+ var isTestBrowser = false;
173
+ var captureResolver;
174
+ var waitForCreevey;
175
+ var creeveyReady;
176
+ var setStoriesCounter = 0;
125
177
  export function withCreevey() {
126
178
  var currentStory = '';
127
179
  var isAnimationDisabled = false;
180
+ initCreeveyState();
128
181
 
129
182
  function disableAnimation() {
130
183
  isAnimationDisabled = true;
@@ -135,42 +188,129 @@ export function withCreevey() {
135
188
  document.head.appendChild(style);
136
189
  }
137
190
 
191
+ function getStories() {
192
+ return _getStories.apply(this, arguments);
193
+ }
194
+
195
+ function _getStories() {
196
+ _getStories = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
197
+ var _window$__STORYBOOK_S;
198
+
199
+ var storiesPromise, store;
200
+ return regeneratorRuntime.wrap(function _callee$(_context) {
201
+ while (1) {
202
+ switch (_context.prev = _context.next) {
203
+ case 0:
204
+ storiesPromise = new Promise(function (resolve) {
205
+ return addons.getChannel().once(Events.SET_STORIES, function (data) {
206
+ return resolve(serializeRawStories(denormalizeStoryParameters(data)));
207
+ });
208
+ });
209
+ store = (_window$__STORYBOOK_S = window.__STORYBOOK_STORY_STORE__) !== null && _window$__STORYBOOK_S !== void 0 ? _window$__STORYBOOK_S : {}; // @ts-expect-error `pushToManager` exists only in Storybook 6.0 - 6.3
210
+
211
+ if (!store.pushToManager) {
212
+ _context.next = 6;
213
+ break;
214
+ }
215
+
216
+ // @ts-expect-error `pushToManager` exists only in Storybook 6.0 - 6.3
217
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
218
+ store.pushToManager();
219
+ _context.next = 13;
220
+ break;
221
+
222
+ case 6:
223
+ if (!store.cacheAllCSFFiles) {
224
+ _context.next = 12;
225
+ break;
226
+ }
227
+
228
+ _context.next = 9;
229
+ return store.cacheAllCSFFiles();
230
+
231
+ case 9:
232
+ addons.getChannel().emit(Events.SET_STORIES, store.getSetStoriesPayload());
233
+ _context.next = 13;
234
+ break;
235
+
236
+ case 12:
237
+ return _context.abrupt("return");
238
+
239
+ case 13:
240
+ addons.getChannel().on(Events.SET_STORIES, function (data) {
241
+ // TODO Figure out how to get only updated stories
242
+ // TODO Subscribe on hmr? like use dummy-hmr
243
+ setStoriesCounter += 1;
244
+ var stories = serializeRawStories(denormalizeStoryParameters(data));
245
+ var storiesByFiles = new Map();
246
+ Object.values(stories).forEach(function (story) {
247
+ var storiesFromFile = storiesByFiles.get(story.parameters.fileName);
248
+ if (storiesFromFile) storiesFromFile.push(story);else storiesByFiles.set(story.parameters.fileName, [story]);
249
+ });
250
+ void fetch("http://".concat(getConnectionUrl(), "/stories"), {
251
+ method: 'POST',
252
+ headers: {
253
+ 'Content-Type': 'application/json'
254
+ },
255
+ body: JSON.stringify({
256
+ setStoriesCounter: setStoriesCounter,
257
+ stories: _toConsumableArray(storiesByFiles.entries())
258
+ })
259
+ });
260
+ });
261
+ return _context.abrupt("return", storiesPromise);
262
+
263
+ case 15:
264
+ case "end":
265
+ return _context.stop();
266
+ }
267
+ }
268
+ }, _callee);
269
+ }));
270
+ return _getStories.apply(this, arguments);
271
+ }
272
+
138
273
  function selectStory(_x2, _x3, _x4, _x5, _x6) {
139
274
  return _selectStory.apply(this, arguments);
140
275
  }
141
276
 
142
277
  function _selectStory() {
143
- _selectStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(storyId, kind, name, shouldWaitForReady, callback) {
144
- var channel, waitForReady, renderPromise, errorPromise, _reason$stack, errorMessage;
278
+ _selectStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(storyId, kind, name, shouldWaitForReady, callback) {
279
+ var channel, waitForReady, isCaptureCalled, renderPromise, errorPromise, capturePromise, _reason$stack, errorMessage;
145
280
 
146
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
281
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
147
282
  while (1) {
148
- switch (_context2.prev = _context2.next) {
283
+ switch (_context3.prev = _context3.next) {
149
284
  case 0:
150
285
  if (!isAnimationDisabled) disableAnimation();
286
+ isTestBrowser = true;
151
287
  channel = addons.getChannel();
152
288
  waitForReady = shouldWaitForReady ? new Promise(function (resolve) {
153
289
  return window.__CREEVEY_SET_READY_FOR_CAPTURE__ = resolve;
154
290
  }) : Promise.resolve();
155
291
 
156
292
  if (!(storyId == currentStory)) {
157
- _context2.next = 8;
293
+ _context3.next = 9;
158
294
  break;
159
295
  }
160
296
 
161
- _context2.next = 6;
297
+ _context3.next = 7;
162
298
  return resetCurrentStory(channel);
163
299
 
164
- case 6:
165
- _context2.next = 9;
300
+ case 7:
301
+ _context3.next = 10;
166
302
  break;
167
303
 
168
- case 8:
304
+ case 9:
169
305
  currentStory = storyId;
170
306
 
171
- case 9:
307
+ case 10:
308
+ isCaptureCalled = false;
172
309
  renderPromise = waitForStoryRendered(channel);
173
310
  errorPromise = catchRenderError(channel);
311
+ capturePromise = waitForCaptureCall().then(function () {
312
+ return isCaptureCalled = true;
313
+ });
174
314
  setTimeout(function () {
175
315
  return channel.emit(Events.SET_CURRENT_STORY, {
176
316
  storyId: storyId,
@@ -178,57 +318,57 @@ export function withCreevey() {
178
318
  kind: kind
179
319
  });
180
320
  }, 0);
181
- _context2.prev = 12;
182
- _context2.next = 15;
183
- return Promise.race([_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
184
- return regeneratorRuntime.wrap(function _callee$(_context) {
321
+ _context3.prev = 15;
322
+ _context3.next = 18;
323
+ return Promise.race([_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
324
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
185
325
  while (1) {
186
- switch (_context.prev = _context.next) {
326
+ switch (_context2.prev = _context2.next) {
187
327
  case 0:
188
- _context.next = 2;
189
- return renderPromise;
328
+ _context2.next = 2;
329
+ return Promise.race([renderPromise, capturePromise]);
190
330
 
191
331
  case 2:
192
- _context.next = 4;
332
+ _context2.next = 4;
193
333
  return waitForFontsLoaded();
194
334
 
195
335
  case 4:
196
- _context.next = 6;
336
+ _context2.next = 6;
197
337
  return waitForReady;
198
338
 
199
339
  case 6:
200
340
  case "end":
201
- return _context.stop();
341
+ return _context2.stop();
202
342
  }
203
343
  }
204
- }, _callee);
344
+ }, _callee2);
205
345
  }))(), errorPromise]);
206
346
 
207
- case 15:
208
- callback();
209
- _context2.next = 22;
347
+ case 18:
348
+ callback([null, isCaptureCalled]);
349
+ _context3.next = 25;
210
350
  break;
211
351
 
212
- case 18:
213
- _context2.prev = 18;
214
- _context2.t0 = _context2["catch"](12);
352
+ case 21:
353
+ _context3.prev = 21;
354
+ _context3.t0 = _context3["catch"](15);
215
355
  // NOTE Event `STORY_THREW_EXCEPTION` triggered only in react and vue frameworks and return Error instance
216
356
  // NOTE Event `STORY_ERRORED` return error-like object without `name` field
217
- errorMessage = _context2.t0 instanceof Error ? (_reason$stack = _context2.t0.stack) !== null && _reason$stack !== void 0 ? _reason$stack : _context2.t0.message : isObject(_context2.t0) ? "".concat(_context2.t0.message, "\n ").concat(_context2.t0.stack) : _context2.t0;
218
- callback(errorMessage);
357
+ errorMessage = _context3.t0 instanceof Error ? (_reason$stack = _context3.t0.stack) !== null && _reason$stack !== void 0 ? _reason$stack : _context3.t0.message : isObject(_context3.t0) ? "".concat(_context3.t0.message, "\n ").concat(_context3.t0.stack) : _context3.t0;
358
+ callback([errorMessage]);
219
359
 
220
- case 22:
221
- _context2.prev = 22;
360
+ case 25:
361
+ _context3.prev = 25;
222
362
  renderPromise.cancel();
223
363
  errorPromise.cancel();
224
- return _context2.finish(22);
364
+ return _context3.finish(25);
225
365
 
226
- case 26:
366
+ case 29:
227
367
  case "end":
228
- return _context2.stop();
368
+ return _context3.stop();
229
369
  }
230
370
  }
231
- }, _callee2, null, [[12, 18, 22, 26]]);
371
+ }, _callee3, null, [[15, 21, 25, 29]]);
232
372
  }));
233
373
  return _selectStory.apply(this, arguments);
234
374
  }
@@ -255,16 +395,138 @@ export function withCreevey() {
255
395
  (_ignoreStyles$parentN = ignoreStyles.parentNode) === null || _ignoreStyles$parentN === void 0 ? void 0 : _ignoreStyles$parentN.removeChild(ignoreStyles);
256
396
  }
257
397
 
398
+ function hasPlayCompletedYet(callback) {
399
+ creeveyReady();
400
+ var isCaptureCalled = false;
401
+ var isPlayCompleted = false;
402
+ var channel = addons.getChannel();
403
+ void waitForStoryRendered(channel).then(function () {
404
+ if (isCaptureCalled) return;
405
+ isPlayCompleted = true;
406
+ callback(true);
407
+ });
408
+ void waitForCaptureCall().then(function () {
409
+ if (isPlayCompleted) return;
410
+ isCaptureCalled = true;
411
+ callback(false);
412
+ });
413
+ }
414
+
415
+ window.__CREEVEY_GET_STORIES__ = getStories;
258
416
  window.__CREEVEY_SELECT_STORY__ = selectStory;
259
417
  window.__CREEVEY_UPDATE_GLOBALS__ = updateGlobals;
260
418
  window.__CREEVEY_INSERT_IGNORE_STYLES__ = insertIgnoreStyles;
261
419
  window.__CREEVEY_REMOVE_IGNORE_STYLES__ = removeIgnoreStyles;
420
+ window.__CREEVEY_HAS_PLAY_COMPLETED_YET__ = hasPlayCompletedYet;
262
421
  window.__CREEVEY_SET_READY_FOR_CAPTURE__ = noop;
422
+
423
+ var queryAllByQuery = function queryAllByQuery(container, query) {
424
+ return _toConsumableArray(container.querySelectorAll(query)).filter(function (e) {
425
+ return e instanceof HTMLElement;
426
+ });
427
+ };
428
+
429
+ var getMultipleError = function getMultipleError(_, query) {
430
+ return "Found multiple elements by query: ".concat(query);
431
+ };
432
+
433
+ var getMissingError = function getMissingError(_, query) {
434
+ return "Unable to find an element by query: ".concat(query);
435
+ };
436
+
437
+ var _buildQueries = buildQueries(queryAllByQuery, getMultipleError, getMissingError),
438
+ _buildQueries2 = _slicedToArray(_buildQueries, 5),
439
+ queryByQuery = _buildQueries2[0],
440
+ getAllByQuery = _buildQueries2[1],
441
+ getByQuery = _buildQueries2[2],
442
+ findAllByQuery = _buildQueries2[3],
443
+ findByQuery = _buildQueries2[4];
444
+
445
+ var queries = {
446
+ queryByQuery: queryByQuery,
447
+ getAllByQuery: getAllByQuery,
448
+ getByQuery: getByQuery,
449
+ findAllByQuery: findAllByQuery,
450
+ findByQuery: findByQuery
451
+ };
263
452
  return makeDecorator({
264
453
  name: 'withCreevey',
265
454
  parameterName: 'creevey',
266
455
  wrapper: function wrapper(getStory, context) {
456
+ var _ref2;
457
+
458
+ // TODO Define proper types, like captureElement is a promise
459
+ var _context$parameters$c = context.parameters.creevey = (_ref2 = context.parameters.creevey) !== null && _ref2 !== void 0 ? _ref2 : {},
460
+ captureElement = _context$parameters$c.captureElement;
461
+
462
+ Object.defineProperty(context.parameters.creevey, 'captureElement', {
463
+ get: function get() {
464
+ switch (true) {
465
+ case captureElement === undefined:
466
+ return Promise.resolve(context.canvasElement);
467
+
468
+ case captureElement === null:
469
+ return Promise.resolve(document.documentElement);
470
+
471
+ case typeof captureElement == 'string':
472
+ return within(context.canvasElement, queries).findByQuery(captureElement);
473
+
474
+ case typeof captureElement == 'function':
475
+ // TODO Define type for it
476
+ return Promise.resolve(captureElement(context));
477
+ }
478
+ },
479
+ enumerable: true,
480
+ configurable: true
481
+ });
267
482
  return getStory(context);
268
483
  }
269
484
  });
485
+ }
486
+ export function capture(_x7) {
487
+ return _capture.apply(this, arguments);
488
+ }
489
+
490
+ function _capture() {
491
+ _capture = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(options) {
492
+ return regeneratorRuntime.wrap(function _callee5$(_context5) {
493
+ while (1) {
494
+ switch (_context5.prev = _context5.next) {
495
+ case 0:
496
+ if (isTestBrowser) {
497
+ _context5.next = 2;
498
+ break;
499
+ }
500
+
501
+ return _context5.abrupt("return");
502
+
503
+ case 2:
504
+ captureResolver();
505
+ waitForCreevey = new Promise(function (resolve) {
506
+ return creeveyReady = resolve;
507
+ });
508
+ _context5.next = 6;
509
+ return fetch("http://".concat(getConnectionUrl(), "/capture"), {
510
+ method: 'POST',
511
+ headers: {
512
+ 'Content-Type': 'application/json'
513
+ },
514
+ body: JSON.stringify({
515
+ workerId: window.__CREEVEY_WORKER_ID__,
516
+ options: options
517
+ })
518
+ });
519
+
520
+ case 6:
521
+ _context5.next = 8;
522
+ return waitForCreevey;
523
+
524
+ case 8:
525
+ case "end":
526
+ return _context5.stop();
527
+ }
528
+ }
529
+ }, _callee5);
530
+ }));
531
+ return _capture.apply(this, arguments);
270
532
  }