creevey 0.7.39 → 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 (102) hide show
  1. package/CHANGELOG.md +12 -2
  2. package/README.md +1 -1
  3. package/docs/config.md +37 -5
  4. package/docs/grid.md +2 -1
  5. package/lib/cjs/client/addon/Manager.js +3 -2
  6. package/lib/cjs/client/addon/preset.js +1 -0
  7. package/lib/cjs/client/addon/readyForCapture.js +12 -0
  8. package/lib/cjs/client/addon/utils.js +1 -41
  9. package/lib/cjs/client/addon/withCreevey.js +313 -41
  10. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +3 -3
  11. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +3 -3
  12. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +4 -3
  13. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +3 -3
  14. package/lib/cjs/client/shared/helpers.js +1 -1
  15. package/lib/cjs/client/web/1.js +2 -2
  16. package/lib/cjs/client/web/2.js +1 -1
  17. package/lib/cjs/client/web/main.js +6 -6
  18. package/lib/cjs/index.js +27 -9
  19. package/lib/cjs/server/config.js +7 -3
  20. package/lib/cjs/server/extract.js +11 -4
  21. package/lib/cjs/server/index.js +2 -4
  22. package/lib/cjs/server/loaders/babel/register.js +2 -1
  23. package/lib/cjs/server/master/index.js +3 -9
  24. package/lib/cjs/server/master/master.js +1 -0
  25. package/lib/cjs/server/master/pool.js +29 -29
  26. package/lib/cjs/server/master/server.js +75 -3
  27. package/lib/cjs/server/messages.js +124 -12
  28. package/lib/cjs/server/parser.js +85 -0
  29. package/lib/cjs/server/selenium/browser.js +119 -21
  30. package/lib/cjs/server/selenium/selenoid.js +1 -1
  31. package/lib/cjs/server/stories.js +49 -58
  32. package/lib/cjs/server/storybook/entry.js +5 -4
  33. package/lib/cjs/server/storybook/helpers.js +11 -3
  34. package/lib/cjs/server/storybook/providers/browser.js +78 -0
  35. package/lib/cjs/server/storybook/providers/hybrid.js +79 -0
  36. package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +42 -18
  37. package/lib/cjs/server/utils.js +32 -2
  38. package/lib/cjs/server/worker/helpers.js +2 -6
  39. package/lib/cjs/server/worker/worker.js +15 -3
  40. package/lib/cjs/shared.js +107 -0
  41. package/lib/cjs/types.js +5 -0
  42. package/lib/esm/client/addon/Manager.js +3 -3
  43. package/lib/esm/client/addon/preset.js +1 -0
  44. package/lib/esm/client/addon/readyForCapture.js +5 -0
  45. package/lib/esm/client/addon/utils.js +1 -33
  46. package/lib/esm/client/addon/withCreevey.js +303 -41
  47. package/lib/esm/client/shared/components/ImagesView/BlendView.js +2 -3
  48. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +2 -3
  49. package/lib/esm/client/shared/components/ImagesView/SlideView.js +3 -3
  50. package/lib/esm/client/shared/components/ImagesView/SwapView.js +2 -3
  51. package/lib/esm/client/shared/helpers.js +1 -1
  52. package/lib/esm/index.js +6 -3
  53. package/lib/esm/server/config.js +7 -5
  54. package/lib/esm/server/extract.js +8 -4
  55. package/lib/esm/server/index.js +2 -3
  56. package/lib/esm/server/loaders/babel/register.js +3 -2
  57. package/lib/esm/server/master/index.js +4 -10
  58. package/lib/esm/server/master/master.js +1 -0
  59. package/lib/esm/server/master/pool.js +31 -31
  60. package/lib/esm/server/master/server.js +73 -5
  61. package/lib/esm/server/messages.js +118 -12
  62. package/lib/esm/server/parser.js +63 -0
  63. package/lib/esm/server/selenium/browser.js +116 -23
  64. package/lib/esm/server/selenium/selenoid.js +1 -1
  65. package/lib/esm/server/stories.js +51 -58
  66. package/lib/esm/server/storybook/entry.js +4 -4
  67. package/lib/esm/server/storybook/helpers.js +9 -3
  68. package/lib/esm/server/storybook/providers/browser.js +61 -0
  69. package/lib/esm/server/storybook/providers/hybrid.js +63 -0
  70. package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +40 -18
  71. package/lib/esm/server/utils.js +29 -2
  72. package/lib/esm/server/worker/helpers.js +2 -6
  73. package/lib/esm/server/worker/worker.js +16 -4
  74. package/lib/esm/shared.js +76 -0
  75. package/lib/esm/types.js +3 -0
  76. package/lib/types/client/addon/preset.d.ts +2 -0
  77. package/lib/types/client/addon/readyForCapture.d.ts +6 -0
  78. package/lib/types/client/addon/utils.d.ts +1 -5
  79. package/lib/types/client/addon/withCreevey.d.ts +13 -2
  80. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +2 -2
  81. package/lib/types/index.d.ts +2 -1
  82. package/lib/types/server/config.d.ts +1 -1
  83. package/lib/types/server/master/master.d.ts +1 -0
  84. package/lib/types/server/master/pool.d.ts +1 -0
  85. package/lib/types/server/master/server.d.ts +1 -1
  86. package/lib/types/server/messages.d.ts +12 -2
  87. package/lib/types/server/parser.d.ts +12 -0
  88. package/lib/types/server/selenium/browser.d.ts +5 -2
  89. package/lib/types/server/stories.d.ts +1 -2
  90. package/lib/types/server/storybook/entry.d.ts +13 -9
  91. package/lib/types/server/storybook/helpers.d.ts +1 -0
  92. package/lib/types/server/storybook/providers/browser.d.ts +4 -0
  93. package/lib/types/server/storybook/providers/hybrid.d.ts +4 -0
  94. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
  95. package/lib/types/server/utils.d.ts +2 -0
  96. package/lib/types/server/worker/helpers.d.ts +2 -1
  97. package/lib/types/shared.d.ts +16 -0
  98. package/lib/types/types.d.ts +33 -4
  99. package/package.json +28 -18
  100. package/storybook-static/stories.json +4 -513
  101. package/types/mocha.d.ts +1 -0
  102. package/lib/types/server/storybook/nodejs-provider.d.ts +0 -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
  }
@@ -2,6 +2,7 @@ import React, { useEffect, useRef } from 'react';
2
2
  import { getBorderColor, themeBorderColors } from './ImagesView';
3
3
  import { styled, withTheme } from '@storybook/theming';
4
4
  import { useApplyScale, useCalcScale, useLoadImages } from '../../helpers';
5
+ import { readyForCapture } from '../../../addon/readyForCapture';
5
6
  var Container = styled.div({
6
7
  position: 'relative',
7
8
  display: 'flex',
@@ -41,9 +42,7 @@ export var BlendView = withTheme(function (_ref2) {
41
42
  useApplyScale(expectImageRef, scale, loaded);
42
43
  useApplyScale(actualImageRef, scale, loaded);
43
44
  useEffect(function () {
44
- var _window$__CREEVEY_SET, _window;
45
-
46
- if (loaded) (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
45
+ if (loaded) readyForCapture();
47
46
  }, [loaded]);
48
47
  return /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(ImageContainer, null, /*#__PURE__*/React.createElement(Image, {
49
48
  ref: expectImageRef,
@@ -15,6 +15,7 @@ import { getBorderColor, themeBorderColors } from './ImagesView';
15
15
  import { styled, withTheme } from '@storybook/theming';
16
16
  import { useApplyScale, useLoadImages, useResizeObserver, getBorderSize } from '../../helpers';
17
17
  import { Loader } from '@storybook/components';
18
+ import { readyForCapture } from '../../../addon/readyForCapture';
18
19
  var Container = styled.div({
19
20
  display: 'flex',
20
21
  flexWrap: 'nowrap',
@@ -111,9 +112,7 @@ export var SideBySideView = withTheme(function (_ref3) {
111
112
  useApplyScale(expectImageRef, scale);
112
113
  useApplyScale(actualImageRef, scale);
113
114
  useEffect(function () {
114
- var _window$__CREEVEY_SET, _window;
115
-
116
- if (loaded) (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
115
+ if (loaded) readyForCapture();
117
116
  }, [loaded]);
118
117
  return /*#__PURE__*/React.createElement(Container, {
119
118
  ref: containerRef
@@ -15,6 +15,7 @@ import { styled, withTheme } from '@storybook/theming';
15
15
  import { getBorderColor, themeBorderColors } from './ImagesView';
16
16
  import { useApplyScale, useCalcScale, useLoadImages } from '../../helpers';
17
17
  import { Loader } from '@storybook/components';
18
+ import { readyForCapture } from '../../../addon/readyForCapture';
18
19
  var Container = styled.div({
19
20
  position: 'relative',
20
21
  display: 'flex'
@@ -118,11 +119,10 @@ export var SlideView = withTheme(function (_ref3) {
118
119
  }
119
120
  }, [loaded]);
120
121
  useEffect(function () {
121
- var _window$__CREEVEY_SET, _window;
122
-
123
- if (loaded) (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
122
+ if (loaded) readyForCapture();
124
123
  }, [loaded]);
125
124
  return loaded ? /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(Input, {
125
+ "data-testid": "slider",
126
126
  type: "range",
127
127
  min: 0,
128
128
  max: 100,
@@ -15,6 +15,7 @@ import { getBorderColor, themeBorderColors } from './ImagesView';
15
15
  import { styled, withTheme } from '@storybook/theming';
16
16
  import { useApplyScale, useCalcScale, useLoadImages } from '../../helpers';
17
17
  import { Loader } from '@storybook/components';
18
+ import { readyForCapture } from '../../../addon/readyForCapture';
18
19
  var Container = styled.div({
19
20
  position: 'relative',
20
21
  display: 'flex'
@@ -60,9 +61,7 @@ export var SwapView = withTheme(function (_ref2) {
60
61
  });
61
62
  }, []);
62
63
  useEffect(function () {
63
- var _window$__CREEVEY_SET, _window;
64
-
65
- if (loaded) (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
64
+ if (loaded) readyForCapture();
66
65
  }, [loaded]);
67
66
  return loaded ? /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(Image, {
68
67
  ref: expectImageRef,
@@ -291,7 +291,7 @@ export function countTestsStatus(suite) {
291
291
  };
292
292
  }
293
293
  export function getConnectionUrl() {
294
- return [window.location.hostname, typeof __CREEVEY_SERVER_PORT__ == 'undefined' ? window.location.port : __CREEVEY_SERVER_PORT__].filter(Boolean).join(':');
294
+ return [typeof __CREEVEY_SERVER_HOST__ == 'undefined' ? window.location.hostname : __CREEVEY_SERVER_HOST__, typeof __CREEVEY_SERVER_PORT__ == 'undefined' ? window.location.port : __CREEVEY_SERVER_PORT__].filter(Boolean).join(':');
295
295
  }
296
296
  export function getImageUrl(path, imageName) {
297
297
  // path => [kind, story, test, browser]
package/lib/esm/index.js CHANGED
@@ -1,4 +1,7 @@
1
- export * from './types';
2
- export * from './client/addon/withCreevey'; // export { loadStories as browserStoriesProvider } from './server/storybook/browser-provider';
1
+ export * from './types'; // export * from './client/addon/withCreevey';
2
+ // export * from './client/addon/readyForCapture';
3
3
 
4
- export { loadStories as nodejsStoriesProvider } from './server/storybook/nodejs-provider';
4
+ export { loadStories as browserStoriesProvider } from './server/storybook/providers/browser';
5
+ export { loadStories as nodejsStoriesProvider } from './server/storybook/providers/nodejs';
6
+ export { loadStories as hybridStoriesProvider } from './server/storybook/providers/hybrid';
7
+ export * from './server/parser';
@@ -1,8 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { isCSFv3Enabled, isStorybookVersionLessThan, storybookDirRef } from './storybook/helpers';
4
- import { loadStories as nodejsStoriesProvider } from './storybook/nodejs-provider'; // import { loadStories as browserStoriesProvider } from './storybook/browser-provider';
5
-
3
+ import { isCSFv3Enabled, isStorybookVersionGreaterThan, isStorybookVersionLessThan, storybookDirRef } from './storybook/helpers';
4
+ import { loadStories as nodejsStoriesProvider } from './storybook/providers/nodejs';
5
+ import { loadStories as browserStoriesProvider } from './storybook/providers/browser';
6
6
  import { isDefined } from '../types';
7
7
  export const defaultBrowser = 'chrome';
8
8
  export const defaultConfig = {
@@ -25,7 +25,8 @@ export const defaultConfig = {
25
25
  [defaultBrowser]: true
26
26
  },
27
27
  hooks: {},
28
- babelOptions: _ => _
28
+ babelOptions: _ => _,
29
+ testRegex: /.creevey.(t|j)s$/
29
30
  };
30
31
 
31
32
  function normalizeBrowserConfig(name, config) {
@@ -60,7 +61,8 @@ export async function readConfig(options) {
60
61
  if (isDefined(configPath)) Object.assign(userConfig, (await import(configPath)).default);
61
62
  storybookDirRef.current = userConfig.storybookDir;
62
63
  if (isStorybookVersionLessThan(6, 2)) userConfig.useWebpackToExtractTests = true;
63
- if (!userConfig.storiesProvider) userConfig.storiesProvider = (await isCSFv3Enabled()) ? nodejsStoriesProvider : nodejsStoriesProvider;
64
+ if (!userConfig.storiesProvider) userConfig.storiesProvider = (await isCSFv3Enabled()) && isStorybookVersionGreaterThan(5) ? browserStoriesProvider : nodejsStoriesProvider;
65
+ if (userConfig.storiesProvider == browserStoriesProvider && isStorybookVersionLessThan(6)) throw new Error("Creevey browser stories provider doesn't support Storybook 5.x or older versions");
64
66
  if (options.failFast != undefined) userConfig.failFast = Boolean(options.failFast);
65
67
  if (options.reportDir) userConfig.reportDir = path.resolve(options.reportDir);
66
68
  if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir); // NOTE: Hack to pass typescript checking
@@ -1,5 +1,8 @@
1
+ import { denormalizeStoryParameters } from '../shared';
1
2
  import { subscribeOn } from './messages';
2
3
  import { loadTestsFromStories, saveStoriesJson, saveTestsJson } from './stories';
4
+ import { isStorybookVersionGreaterThan, isStorybookVersionLessThan } from './storybook/helpers';
5
+ import { extractStoriesData } from './storybook/providers/nodejs';
3
6
  export default async function extract(config, options) {
4
7
  if (config.useWebpackToExtractTests && process.env.__CREEVEY_ENV__ != 'test') {
5
8
  await new Promise((resolve, reject) => {
@@ -16,12 +19,13 @@ export default async function extract(config, options) {
16
19
  });
17
20
  }
18
21
 
19
- const tests = await loadTestsFromStories(Object.keys(config.browsers), async listener => {
20
- const stories = await config.storiesProvider(config, {
22
+ const tests = await loadTestsFromStories(Object.keys(config.browsers), async () => {
23
+ const data = await extractStoriesData(config, {
21
24
  watch: false,
22
25
  debug: options.debug
23
- }, listener);
24
- if (options.extract) saveStoriesJson(stories, options.extract);
26
+ });
27
+ const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
28
+ if (options.extract) saveStoriesJson(data, options.extract);
25
29
  return stories;
26
30
  });
27
31
  if (options.tests) saveTestsJson(tests); // eslint-disable-next-line no-process-exit
@@ -1,6 +1,5 @@
1
1
  import cluster from 'cluster';
2
2
  import { readConfig, defaultBrowser } from './config';
3
- import { noop } from '../types';
4
3
  import { logger } from './logger'; // NOTE: Impure function, mutate config by adding gridUrl prop
5
4
 
6
5
  async function startWebdriverServer(config, options) {
@@ -22,8 +21,7 @@ export default async function (options) {
22
21
  ui,
23
22
  port
24
23
  } = options;
25
- if (!config) return;
26
- const resolveApi = ui && cluster.isMaster ? (await import('./master/server')).default(config.reportDir, port) : noop; // NOTE: We don't need docker nor selenoid for webpack or update options
24
+ if (!config) return; // NOTE: We don't need docker nor selenoid for webpack or update options
27
25
 
28
26
  if (!(config.gridUrl || Object.values(config.browsers).every(({
29
27
  gridUrl
@@ -51,6 +49,7 @@ export default async function (options) {
51
49
  case cluster.isMaster:
52
50
  {
53
51
  logger.info('Starting Master Process');
52
+ const resolveApi = (await import('./master/server')).default(config.reportDir, port, ui);
54
53
  return (await import('./master')).default(config, options, resolveApi);
55
54
  }
56
55