creevey 0.8.0-beta.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/CHANGELOG.md +30 -7
  2. package/README.md +9 -1
  3. package/addon/README.md +3 -0
  4. package/addon/package.json +4 -0
  5. package/docs/config.md +29 -26
  6. package/jest.config.js +6 -0
  7. package/lib/cjs/client/addon/Manager.js +122 -271
  8. package/lib/cjs/client/addon/components/Addon.js +17 -38
  9. package/lib/cjs/client/addon/components/Icons.js +11 -7
  10. package/lib/cjs/client/addon/components/Panel.js +17 -13
  11. package/lib/cjs/client/addon/components/TestSelect.js +11 -9
  12. package/lib/cjs/client/addon/components/Tools.js +21 -40
  13. package/lib/cjs/client/addon/decorator.js +1 -1
  14. package/lib/cjs/client/addon/index.js +31 -0
  15. package/lib/cjs/client/addon/preset.ie11.js +74 -0
  16. package/lib/cjs/client/addon/preset.js +13 -31
  17. package/lib/cjs/client/addon/readyForCapture.js +12 -0
  18. package/lib/cjs/client/addon/register.js +46 -70
  19. package/lib/cjs/client/addon/utils.js +6 -2
  20. package/lib/cjs/client/addon/withCreevey.js +221 -155
  21. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +26 -24
  22. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +22 -18
  23. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +44 -66
  24. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +38 -50
  25. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +26 -45
  26. package/lib/cjs/client/shared/components/ImagesView/index.js +9 -9
  27. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +12 -8
  28. package/lib/cjs/client/shared/components/PageFooter/Paging.js +14 -18
  29. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +22 -18
  30. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +42 -67
  31. package/lib/cjs/client/shared/components/ResultsPage.js +39 -69
  32. package/lib/cjs/client/shared/creeveyClientApi.js +55 -82
  33. package/lib/cjs/client/shared/helpers.js +140 -211
  34. package/lib/cjs/client/shared/viewMode.js +5 -5
  35. package/lib/cjs/client/web/142.js +2 -0
  36. package/lib/cjs/client/web/142.js.LICENSE.txt +12 -0
  37. package/lib/cjs/client/web/32.js +1 -0
  38. package/lib/cjs/client/web/551.js +1 -0
  39. package/lib/cjs/client/web/566.js +2 -0
  40. package/lib/cjs/client/web/566.js.LICENSE.txt +31 -0
  41. package/lib/cjs/client/web/691.js +2 -0
  42. package/lib/cjs/client/web/691.js.LICENSE.txt +8 -0
  43. package/lib/cjs/client/web/725.js +1 -0
  44. package/lib/cjs/client/web/main.js +2 -38
  45. package/lib/cjs/client/web/main.js.LICENSE.txt +49 -0
  46. package/lib/cjs/creevey.js +3 -5
  47. package/lib/cjs/index.js +10 -15
  48. package/lib/cjs/server/config.js +5 -4
  49. package/lib/cjs/server/docker.js +3 -7
  50. package/lib/cjs/server/extract.js +7 -4
  51. package/lib/cjs/server/index.js +3 -5
  52. package/lib/cjs/server/loaders/babel/creevey-plugin.js +1 -3
  53. package/lib/cjs/server/loaders/babel/helpers.js +13 -23
  54. package/lib/cjs/server/loaders/babel/register.js +2 -4
  55. package/lib/cjs/server/loaders/webpack/compile.js +34 -51
  56. package/lib/cjs/server/loaders/webpack/creevey-loader.js +20 -22
  57. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +2 -7
  58. package/lib/cjs/server/loaders/webpack/mdx-loader.js +2 -2
  59. package/lib/cjs/server/loaders/webpack/start.js +1 -1
  60. package/lib/cjs/server/logger.js +2 -1
  61. package/lib/cjs/server/master/index.js +4 -4
  62. package/lib/cjs/server/master/master.js +1 -0
  63. package/lib/cjs/server/master/pool.js +38 -47
  64. package/lib/cjs/server/master/runner.js +53 -66
  65. package/lib/cjs/server/master/server.js +78 -4
  66. package/lib/cjs/server/messages.js +128 -18
  67. package/lib/cjs/server/selenium/browser.js +129 -55
  68. package/lib/cjs/server/selenium/selenoid.js +5 -7
  69. package/lib/cjs/server/stories.js +58 -72
  70. package/lib/cjs/server/storybook/entry.js +7 -22
  71. package/lib/cjs/server/storybook/helpers.js +20 -27
  72. package/lib/cjs/server/storybook/providers/browser.js +74 -0
  73. package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +37 -20
  74. package/lib/cjs/server/update.js +1 -5
  75. package/lib/cjs/server/utils.js +26 -35
  76. package/lib/cjs/server/worker/helpers.js +2 -6
  77. package/lib/cjs/server/worker/reporter.js +8 -20
  78. package/lib/cjs/server/worker/worker.js +21 -19
  79. package/lib/cjs/shared/index.js +101 -0
  80. package/lib/cjs/shared/serializeRegExp.js +42 -0
  81. package/lib/cjs/types.js +11 -6
  82. package/lib/esm/client/addon/Manager.js +122 -271
  83. package/lib/esm/client/addon/components/Addon.js +15 -34
  84. package/lib/esm/client/addon/components/Icons.js +10 -6
  85. package/lib/esm/client/addon/components/Panel.js +17 -13
  86. package/lib/esm/client/addon/components/TestSelect.js +11 -9
  87. package/lib/esm/client/addon/components/Tools.js +19 -36
  88. package/lib/esm/client/addon/decorator.js +1 -1
  89. package/lib/esm/client/addon/index.js +2 -0
  90. package/lib/esm/client/addon/preset.ie11.js +59 -0
  91. package/lib/esm/client/addon/preset.js +12 -26
  92. package/lib/esm/client/addon/readyForCapture.js +5 -0
  93. package/lib/esm/client/addon/register.js +42 -66
  94. package/lib/esm/client/addon/utils.js +3 -2
  95. package/lib/esm/client/addon/withCreevey.js +209 -156
  96. package/lib/esm/client/shared/components/ImagesView/BlendView.js +23 -20
  97. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +21 -17
  98. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +42 -63
  99. package/lib/esm/client/shared/components/ImagesView/SlideView.js +36 -47
  100. package/lib/esm/client/shared/components/ImagesView/SwapView.js +24 -42
  101. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +12 -8
  102. package/lib/esm/client/shared/components/PageFooter/Paging.js +14 -18
  103. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +22 -18
  104. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +37 -60
  105. package/lib/esm/client/shared/components/ResultsPage.js +36 -64
  106. package/lib/esm/client/shared/creeveyClientApi.js +57 -84
  107. package/lib/esm/client/shared/helpers.js +124 -195
  108. package/lib/esm/client/shared/viewMode.js +4 -4
  109. package/lib/esm/creevey.js +3 -5
  110. package/lib/esm/index.js +2 -3
  111. package/lib/esm/server/config.js +4 -5
  112. package/lib/esm/server/docker.js +2 -2
  113. package/lib/esm/server/extract.js +6 -4
  114. package/lib/esm/server/index.js +3 -4
  115. package/lib/esm/server/loaders/babel/creevey-plugin.js +1 -3
  116. package/lib/esm/server/loaders/babel/helpers.js +12 -22
  117. package/lib/esm/server/loaders/babel/register.js +3 -5
  118. package/lib/esm/server/loaders/webpack/compile.js +35 -52
  119. package/lib/esm/server/loaders/webpack/creevey-loader.js +9 -10
  120. package/lib/esm/server/loaders/webpack/dummy-hmr.js +2 -6
  121. package/lib/esm/server/loaders/webpack/mdx-loader.js +2 -2
  122. package/lib/esm/server/loaders/webpack/start.js +1 -1
  123. package/lib/esm/server/master/index.js +4 -4
  124. package/lib/esm/server/master/master.js +1 -0
  125. package/lib/esm/server/master/pool.js +38 -49
  126. package/lib/esm/server/master/runner.js +53 -66
  127. package/lib/esm/server/master/server.js +76 -6
  128. package/lib/esm/server/messages.js +118 -14
  129. package/lib/esm/server/selenium/browser.js +126 -57
  130. package/lib/esm/server/selenium/selenoid.js +4 -6
  131. package/lib/esm/server/stories.js +58 -70
  132. package/lib/esm/server/storybook/entry.js +5 -22
  133. package/lib/esm/server/storybook/helpers.js +11 -20
  134. package/lib/esm/server/storybook/providers/browser.js +60 -0
  135. package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +35 -19
  136. package/lib/esm/server/update.js +1 -5
  137. package/lib/esm/server/utils.js +18 -31
  138. package/lib/esm/server/worker/helpers.js +2 -6
  139. package/lib/esm/server/worker/reporter.js +8 -20
  140. package/lib/esm/server/worker/worker.js +22 -20
  141. package/lib/esm/shared/index.js +78 -0
  142. package/lib/esm/shared/serializeRegExp.js +24 -0
  143. package/lib/esm/types.js +3 -0
  144. package/lib/types/client/addon/Manager.d.ts +2 -2
  145. package/lib/types/client/addon/components/TestSelect.d.ts +0 -1
  146. package/lib/types/client/addon/index.d.ts +2 -0
  147. package/lib/types/client/addon/preset.d.ts +2 -1
  148. package/lib/types/client/addon/preset.ie11.d.ts +10 -0
  149. package/lib/types/client/addon/readyForCapture.d.ts +6 -0
  150. package/lib/types/client/addon/utils.d.ts +1 -0
  151. package/lib/types/client/addon/withCreevey.d.ts +13 -2
  152. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +1 -1
  153. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +0 -1
  154. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +1 -1
  155. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +1 -1
  156. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +1 -1
  157. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +0 -1
  158. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +0 -1
  159. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +1 -1
  160. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +0 -1
  161. package/lib/types/client/shared/components/ResultsPage.d.ts +1 -1
  162. package/lib/types/client/web/CreeveyApp.d.ts +0 -1
  163. package/lib/types/client/web/CreeveyLoader.d.ts +1 -2
  164. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +1 -1
  165. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +0 -1
  166. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
  167. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +0 -1
  168. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +1 -1
  169. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +1 -1
  170. package/lib/types/index.d.ts +0 -1
  171. package/lib/types/server/loaders/babel/register.d.ts +1 -1
  172. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +4 -2
  173. package/lib/types/server/logger.d.ts +6 -2
  174. package/lib/types/server/master/master.d.ts +1 -0
  175. package/lib/types/server/master/pool.d.ts +1 -0
  176. package/lib/types/server/master/server.d.ts +1 -1
  177. package/lib/types/server/messages.d.ts +17 -6
  178. package/lib/types/server/selenium/browser.d.ts +5 -2
  179. package/lib/types/server/stories.d.ts +2 -2
  180. package/lib/types/server/storybook/entry.d.ts +2 -3
  181. package/lib/types/server/storybook/helpers.d.ts +1 -1
  182. package/lib/types/server/storybook/providers/browser.d.ts +4 -0
  183. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
  184. package/lib/types/server/utils.d.ts +5 -1
  185. package/lib/types/server/worker/helpers.d.ts +2 -1
  186. package/lib/types/shared/index.d.ts +7 -0
  187. package/lib/types/shared/serializeRegExp.d.ts +9 -0
  188. package/lib/types/types.d.ts +32 -5
  189. package/package.json +120 -103
  190. package/preset/ie11.js +5 -0
  191. package/{preset.js → preset/index.js} +2 -2
  192. package/types/mdx.d.ts +3 -2
  193. package/types/mocha.d.ts +1 -0
  194. package/lib/cjs/client/web/1.js +0 -13
  195. package/lib/cjs/client/web/2.js +0 -1
  196. package/lib/cjs/shared.js +0 -35
  197. package/lib/esm/shared.js +0 -22
  198. package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
  199. package/lib/types/shared.d.ts +0 -4
@@ -1,67 +1,45 @@
1
- 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
-
3
- 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); }); }; }
4
-
5
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
6
-
7
1
  import * as Events from '@storybook/core-events';
8
2
  import * as polyfill from 'event-source-polyfill';
3
+ import { buildQueries, within } from '@storybook/testing-library';
9
4
  import { addons, makeDecorator } from '@storybook/addons';
10
5
  import { isObject, noop } from '../../types';
6
+ import { denormalizeStoryParameters, serializeRawStories } from '../../shared';
7
+ import { getConnectionUrl } from '../shared/helpers';
8
+ import { isInternetExplorer } from './utils';
11
9
 
12
- if ((typeof process === "undefined" ? "undefined" : _typeof(process)) != 'object' || typeof process.version != 'string') {
10
+ if (typeof process != 'object' || typeof process.version != 'string') {
13
11
  // NOTE If you don't use babel-polyfill or any other polyfills that add EventSource for IE11
14
12
  // You don't get hot reload in IE11. So put polyfill for that to better UX
15
13
  // Don't load in nodejs environment
16
14
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
17
- var NativeEventSource = polyfill.NativeEventSource,
18
- EventSourcePolyfill = polyfill.EventSourcePolyfill; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
15
+ const {
16
+ NativeEventSource,
17
+ EventSourcePolyfill
18
+ } = polyfill; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
19
 
20
20
  window.EventSource = NativeEventSource || EventSourcePolyfill;
21
21
  }
22
22
 
23
- var disableAnimationsStyles = "\n*,\n*:hover,\n*::before,\n*::after {\n animation-delay: -0.0001ms !important;\n animation-duration: 0s !important;\n animation-play-state: paused !important;\n cursor: none !important;\n caret-color: transparent !important;\n transition: 0s !important;\n}\n";
24
-
25
- function resetCurrentStory(_x) {
26
- return _resetCurrentStory.apply(this, arguments);
27
- }
23
+ const disableAnimationsStyles = "\n*,\n*:hover,\n*::before,\n*::after {\n animation-delay: -0.0001ms !important;\n animation-duration: 0s !important;\n animation-play-state: paused !important;\n cursor: none !important;\n caret-color: transparent !important;\n transition: 0s !important;\n}\n";
28
24
 
29
- function _resetCurrentStory() {
30
- _resetCurrentStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(channel) {
31
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
32
- while (1) {
33
- switch (_context3.prev = _context3.next) {
34
- case 0:
35
- setTimeout(function () {
36
- return channel.emit(Events.SET_CURRENT_STORY, {
37
- storyId: true,
38
- name: '',
39
- kind: ''
40
- });
41
- }, 0);
42
- return _context3.abrupt("return", new Promise(function (resolve) {
43
- return channel.once(Events.STORY_MISSING, resolve);
44
- }));
45
-
46
- case 2:
47
- case "end":
48
- return _context3.stop();
49
- }
50
- }
51
- }, _callee3);
52
- }));
53
- return _resetCurrentStory.apply(this, arguments);
25
+ async function resetCurrentStory(channel) {
26
+ setTimeout(() => channel.emit(Events.SET_CURRENT_STORY, {
27
+ storyId: true,
28
+ name: '',
29
+ kind: ''
30
+ }), 0);
31
+ return new Promise(resolve => channel.once(Events.STORY_MISSING, resolve));
54
32
  }
55
33
 
56
34
  function catchRenderError(channel) {
57
- var rejectCallback;
58
- var promise = new Promise(function (_resolve, reject) {
59
- return rejectCallback = reject;
60
- });
35
+ let rejectCallback;
36
+ const promise = new Promise((_resolve, reject) => rejectCallback = reject);
61
37
 
62
38
  function errorHandler(_ref) {
63
- var title = _ref.title,
64
- description = _ref.description;
39
+ let {
40
+ title,
41
+ description
42
+ } = _ref;
65
43
  rejectCallback({
66
44
  message: title,
67
45
  stack: description
@@ -85,10 +63,8 @@ function catchRenderError(channel) {
85
63
  }
86
64
 
87
65
  function waitForStoryRendered(channel) {
88
- var resolveCallback;
89
- var promise = new Promise(function (resolve) {
90
- return resolveCallback = resolve;
91
- });
66
+ let resolveCallback;
67
+ const promise = new Promise(resolve => resolveCallback = resolve);
92
68
 
93
69
  function renderHandler() {
94
70
  resolveCallback();
@@ -106,13 +82,11 @@ function waitForStoryRendered(channel) {
106
82
 
107
83
  function waitForFontsLoaded() {
108
84
  if (!document.fonts) return;
109
- var areFontsLoading = Array.from(document.fonts).some(function (font) {
110
- return font.status == 'loading';
111
- });
85
+ const areFontsLoading = Array.from(document.fonts).some(font => font.status == 'loading');
112
86
 
113
87
  if (areFontsLoading) {
114
- return new Promise(function (resolve) {
115
- var fontsLoadedHandler = function fontsLoadedHandler() {
88
+ return new Promise(resolve => {
89
+ const fontsLoadedHandler = () => {
116
90
  document.fonts.removeEventListener('loadingdone', fontsLoadedHandler);
117
91
  resolve();
118
92
  };
@@ -122,128 +96,129 @@ function waitForFontsLoaded() {
122
96
  }
123
97
  }
124
98
 
99
+ function waitForCaptureCall() {
100
+ return new Promise(resolve => captureResolver = resolve);
101
+ }
102
+
103
+ function initCreeveyState() {
104
+ var _window$localStorage$;
105
+
106
+ const prevState = JSON.parse((_window$localStorage$ = window.localStorage.getItem('Creevey_Tests')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '{}');
107
+ if (prevState.creeveyHost) window.__CREEVEY_SERVER_HOST__ = prevState.creeveyHost;
108
+ if (prevState.creeveyPort) window.__CREEVEY_SERVER_PORT__ = prevState.creeveyPort;
109
+ if (prevState.setStoriesCounter) setStoriesCounter = prevState.setStoriesCounter;
110
+ if (prevState.isTestBrowser) isTestBrowser = prevState.isTestBrowser;
111
+ window.addEventListener('beforeunload', () => {
112
+ window.localStorage.setItem('Creevey_Tests', JSON.stringify({
113
+ creeveyHost: window.__CREEVEY_SERVER_HOST__,
114
+ creeveyPort: window.__CREEVEY_SERVER_PORT__,
115
+ setStoriesCounter,
116
+ isTestBrowser
117
+ }));
118
+ });
119
+ }
120
+
121
+ let isTestBrowser = false;
122
+ let captureResolver;
123
+ let waitForCreevey;
124
+ let creeveyReady;
125
+ let setStoriesCounter = 0;
125
126
  export function withCreevey() {
126
- var currentStory = '';
127
- var isAnimationDisabled = false;
127
+ let currentStory = '';
128
+ let isAnimationDisabled = false;
129
+ initCreeveyState();
128
130
 
129
131
  function disableAnimation() {
130
132
  isAnimationDisabled = true;
131
- var style = document.createElement('style');
132
- var textNode = document.createTextNode(disableAnimationsStyles);
133
+ const style = document.createElement('style');
134
+ const textNode = document.createTextNode(disableAnimationsStyles);
133
135
  style.setAttribute('type', 'text/css');
134
136
  style.appendChild(textNode);
135
137
  document.head.appendChild(style);
136
138
  }
137
139
 
138
- function selectStory(_x2, _x3, _x4, _x5, _x6) {
139
- return _selectStory.apply(this, arguments);
140
+ async function getStories() {
141
+ var _window$__STORYBOOK_S;
142
+
143
+ const storiesPromise = new Promise(resolve => addons.getChannel().once(Events.SET_STORIES, data => resolve(serializeRawStories(denormalizeStoryParameters(data)))));
144
+ const store = (_window$__STORYBOOK_S = window.__STORYBOOK_STORY_STORE__) !== null && _window$__STORYBOOK_S !== void 0 ? _window$__STORYBOOK_S : {};
145
+
146
+ if (store.cacheAllCSFFiles) {
147
+ await store.cacheAllCSFFiles();
148
+ addons.getChannel().emit(Events.SET_STORIES, store.getSetStoriesPayload());
149
+ } else return;
150
+
151
+ addons.getChannel().on(Events.SET_STORIES, data => {
152
+ // TODO Figure out how to get only updated stories
153
+ // TODO Subscribe on hmr? like use dummy-hmr
154
+ setStoriesCounter += 1;
155
+ const stories = serializeRawStories(denormalizeStoryParameters(data));
156
+ const storiesByFiles = new Map();
157
+ Object.values(stories).forEach(story => {
158
+ const storiesFromFile = storiesByFiles.get(story.parameters.fileName);
159
+ if (storiesFromFile) storiesFromFile.push(story);else storiesByFiles.set(story.parameters.fileName, [story]);
160
+ });
161
+ void fetch("http://".concat(getConnectionUrl(), "/stories"), {
162
+ method: 'POST',
163
+ headers: {
164
+ 'Content-Type': 'application/json'
165
+ },
166
+ body: JSON.stringify({
167
+ setStoriesCounter,
168
+ stories: [...storiesByFiles.entries()]
169
+ })
170
+ });
171
+ });
172
+ return storiesPromise;
140
173
  }
141
174
 
142
- function _selectStory() {
143
- _selectStory = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(storyId, kind, name, shouldWaitForReady, callback) {
144
- var channel, waitForReady, renderPromise, errorPromise, _reason$stack, errorMessage;
145
-
146
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
147
- while (1) {
148
- switch (_context2.prev = _context2.next) {
149
- case 0:
150
- if (!isAnimationDisabled) disableAnimation();
151
- channel = addons.getChannel();
152
- waitForReady = shouldWaitForReady ? new Promise(function (resolve) {
153
- return window.__CREEVEY_SET_READY_FOR_CAPTURE__ = resolve;
154
- }) : Promise.resolve();
155
-
156
- if (!(storyId == currentStory)) {
157
- _context2.next = 8;
158
- break;
159
- }
160
-
161
- _context2.next = 6;
162
- return resetCurrentStory(channel);
163
-
164
- case 6:
165
- _context2.next = 9;
166
- break;
167
-
168
- case 8:
169
- currentStory = storyId;
170
-
171
- case 9:
172
- renderPromise = waitForStoryRendered(channel);
173
- errorPromise = catchRenderError(channel);
174
- setTimeout(function () {
175
- return channel.emit(Events.SET_CURRENT_STORY, {
176
- storyId: storyId,
177
- name: name,
178
- kind: kind
179
- });
180
- }, 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) {
185
- while (1) {
186
- switch (_context.prev = _context.next) {
187
- case 0:
188
- _context.next = 2;
189
- return renderPromise;
190
-
191
- case 2:
192
- _context.next = 4;
193
- return waitForFontsLoaded();
194
-
195
- case 4:
196
- _context.next = 6;
197
- return waitForReady;
198
-
199
- case 6:
200
- case "end":
201
- return _context.stop();
202
- }
203
- }
204
- }, _callee);
205
- }))(), errorPromise]);
206
-
207
- case 15:
208
- callback();
209
- _context2.next = 22;
210
- break;
211
-
212
- case 18:
213
- _context2.prev = 18;
214
- _context2.t0 = _context2["catch"](12);
215
- // NOTE Event `STORY_THREW_EXCEPTION` triggered only in react and vue frameworks and return Error instance
216
- // 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);
219
-
220
- case 22:
221
- _context2.prev = 22;
222
- renderPromise.cancel();
223
- errorPromise.cancel();
224
- return _context2.finish(22);
225
-
226
- case 26:
227
- case "end":
228
- return _context2.stop();
229
- }
230
- }
231
- }, _callee2, null, [[12, 18, 22, 26]]);
232
- }));
233
- return _selectStory.apply(this, arguments);
175
+ async function selectStory(storyId, kind, name, shouldWaitForReady, callback) {
176
+ if (!isAnimationDisabled) disableAnimation();
177
+ isTestBrowser = true;
178
+ const channel = addons.getChannel();
179
+ const waitForReady = shouldWaitForReady ? new Promise(resolve => window.__CREEVEY_SET_READY_FOR_CAPTURE__ = resolve) : Promise.resolve();
180
+ if (storyId == currentStory) await resetCurrentStory(channel);else currentStory = storyId;
181
+ let isCaptureCalled = false;
182
+ const renderPromise = waitForStoryRendered(channel);
183
+ const errorPromise = catchRenderError(channel);
184
+ const capturePromise = waitForCaptureCall().then(() => isCaptureCalled = true);
185
+ setTimeout(() => channel.emit(Events.SET_CURRENT_STORY, {
186
+ storyId,
187
+ name,
188
+ kind
189
+ }), 0);
190
+
191
+ try {
192
+ await Promise.race([(async () => {
193
+ await Promise.race([renderPromise, capturePromise]);
194
+ await waitForFontsLoaded();
195
+ await waitForReady;
196
+ })(), errorPromise]);
197
+ callback([null, isCaptureCalled]);
198
+ } catch (reason) {
199
+ var _reason$stack;
200
+
201
+ // NOTE Event `STORY_THREW_EXCEPTION` triggered only in react and vue frameworks and return Error instance
202
+ // NOTE Event `STORY_ERRORED` return error-like object without `name` field
203
+ const errorMessage = reason instanceof Error ? (_reason$stack = reason.stack) !== null && _reason$stack !== void 0 ? _reason$stack : reason.message : isObject(reason) ? "".concat(reason.message, "\n ").concat(reason.stack) : reason;
204
+ callback([errorMessage]);
205
+ } finally {
206
+ renderPromise.cancel();
207
+ errorPromise.cancel();
208
+ }
234
209
  }
235
210
 
236
211
  function updateGlobals(globals) {
237
212
  addons.getChannel().emit(Events.UPDATE_GLOBALS, {
238
- globals: globals
213
+ globals
239
214
  });
240
215
  }
241
216
 
242
217
  function insertIgnoreStyles(ignoreSelectors) {
243
- var stylesElement = document.createElement('style');
218
+ const stylesElement = document.createElement('style');
244
219
  stylesElement.setAttribute('type', 'text/css');
245
220
  document.head.appendChild(stylesElement);
246
- ignoreSelectors.forEach(function (selector) {
221
+ ignoreSelectors.forEach(selector => {
247
222
  stylesElement.innerHTML += "\n ".concat(selector, " {\n background: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n outline: 0 !important;\n color: rgba(0,0,0,0) !important;\n }\n ").concat(selector, " *, ").concat(selector, "::before, ").concat(selector, "::after {\n visibility: hidden !important;\n }\n ");
248
223
  });
249
224
  return stylesElement;
@@ -255,16 +230,94 @@ export function withCreevey() {
255
230
  (_ignoreStyles$parentN = ignoreStyles.parentNode) === null || _ignoreStyles$parentN === void 0 ? void 0 : _ignoreStyles$parentN.removeChild(ignoreStyles);
256
231
  }
257
232
 
233
+ function hasPlayCompletedYet(callback) {
234
+ creeveyReady();
235
+ let isCaptureCalled = false;
236
+ let isPlayCompleted = false;
237
+ const channel = addons.getChannel();
238
+ void waitForStoryRendered(channel).then(() => {
239
+ if (isCaptureCalled) return;
240
+ isPlayCompleted = true;
241
+ callback(true);
242
+ });
243
+ void waitForCaptureCall().then(() => {
244
+ if (isPlayCompleted) return;
245
+ isCaptureCalled = true;
246
+ callback(false);
247
+ });
248
+ }
249
+
250
+ window.__CREEVEY_GET_STORIES__ = getStories;
258
251
  window.__CREEVEY_SELECT_STORY__ = selectStory;
259
252
  window.__CREEVEY_UPDATE_GLOBALS__ = updateGlobals;
260
253
  window.__CREEVEY_INSERT_IGNORE_STYLES__ = insertIgnoreStyles;
261
254
  window.__CREEVEY_REMOVE_IGNORE_STYLES__ = removeIgnoreStyles;
255
+ window.__CREEVEY_HAS_PLAY_COMPLETED_YET__ = hasPlayCompletedYet;
262
256
  window.__CREEVEY_SET_READY_FOR_CAPTURE__ = noop;
257
+
258
+ const queryAllByQuery = (container, query) => [...container.querySelectorAll(query)].filter(e => e instanceof HTMLElement);
259
+
260
+ const getMultipleError = (_, query) => "Found multiple elements by query: ".concat(query);
261
+
262
+ const getMissingError = (_, query) => "Unable to find an element by query: ".concat(query);
263
+
264
+ const [queryByQuery, getAllByQuery, getByQuery, findAllByQuery, findByQuery] = buildQueries(queryAllByQuery, getMultipleError, getMissingError);
265
+ const queries = {
266
+ queryByQuery,
267
+ getAllByQuery,
268
+ getByQuery,
269
+ findAllByQuery,
270
+ findByQuery
271
+ };
263
272
  return makeDecorator({
264
273
  name: 'withCreevey',
265
274
  parameterName: 'creevey',
266
- wrapper: function wrapper(getStory, context) {
275
+ wrapper: (getStory, context) => {
276
+ var _ref2;
277
+
278
+ // TODO Define proper types, like captureElement is a promise
279
+ const {
280
+ captureElement
281
+ } = context.parameters.creevey = (_ref2 = context.parameters.creevey) !== null && _ref2 !== void 0 ? _ref2 : {};
282
+ Object.defineProperty(context.parameters.creevey, 'captureElement', {
283
+ get() {
284
+ switch (true) {
285
+ case captureElement === undefined:
286
+ return Promise.resolve(context.canvasElement);
287
+
288
+ case captureElement === null:
289
+ return Promise.resolve(document.documentElement);
290
+
291
+ case typeof captureElement == 'string':
292
+ return isInternetExplorer // some code from testing-library makes IE hang
293
+ ? Promise.resolve(context.canvasElement.querySelector(captureElement)) : within(context.canvasElement, queries).findByQuery(captureElement);
294
+
295
+ case typeof captureElement == 'function':
296
+ // TODO Define type for it
297
+ return Promise.resolve(captureElement(context));
298
+ }
299
+ },
300
+
301
+ enumerable: true,
302
+ configurable: true
303
+ });
267
304
  return getStory(context);
268
305
  }
269
306
  });
307
+ }
308
+ export async function capture(options) {
309
+ if (!isTestBrowser) return;
310
+ captureResolver();
311
+ waitForCreevey = new Promise(resolve => creeveyReady = resolve);
312
+ await fetch("http://".concat(getConnectionUrl(), "/capture"), {
313
+ method: 'POST',
314
+ headers: {
315
+ 'Content-Type': 'application/json'
316
+ },
317
+ body: JSON.stringify({
318
+ workerId: window.__CREEVEY_WORKER_ID__,
319
+ options
320
+ })
321
+ });
322
+ await waitForCreevey;
270
323
  }
@@ -2,19 +2,22 @@ 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
- var Container = styled.div({
5
+ import { readyForCapture } from '../../../addon/readyForCapture';
6
+ const Container = styled.div({
6
7
  position: 'relative',
7
8
  display: 'flex',
8
9
  filter: 'invert(100%)'
9
10
  });
10
- var ImageContainer = styled.div({
11
+ const ImageContainer = styled.div({
11
12
  position: 'absolute',
12
13
  width: '100%',
13
14
  height: '100%',
14
15
  display: 'flex'
15
16
  });
16
- var Image = styled.img(function (_ref) {
17
- var borderColor = _ref.borderColor;
17
+ const Image = styled.img(_ref => {
18
+ let {
19
+ borderColor
20
+ } = _ref;
18
21
  return {
19
22
  boxSizing: 'border-box',
20
23
  border: "1px solid ".concat(borderColor),
@@ -22,28 +25,28 @@ var Image = styled.img(function (_ref) {
22
25
  filter: 'invert(100%)'
23
26
  };
24
27
  });
25
- var ActualImage = styled(Image)({
28
+ const ActualImage = styled(Image)({
26
29
  mixBlendMode: 'difference'
27
30
  });
28
- var DiffImage = styled(Image)({
31
+ const DiffImage = styled(Image)({
29
32
  opacity: '0'
30
33
  });
31
- export var BlendView = withTheme(function (_ref2) {
32
- var actual = _ref2.actual,
33
- diff = _ref2.diff,
34
- expect = _ref2.expect,
35
- theme = _ref2.theme;
36
- var expectImageRef = useRef(null);
37
- var diffImageRef = useRef(null);
38
- var actualImageRef = useRef(null);
39
- var loaded = useLoadImages(expect, diff, actual);
40
- var scale = useCalcScale(diffImageRef, loaded);
34
+ export const BlendView = withTheme(_ref2 => {
35
+ let {
36
+ actual,
37
+ diff,
38
+ expect,
39
+ theme
40
+ } = _ref2;
41
+ const expectImageRef = useRef(null);
42
+ const diffImageRef = useRef(null);
43
+ const actualImageRef = useRef(null);
44
+ const loaded = useLoadImages(expect, diff, actual);
45
+ const scale = useCalcScale(diffImageRef, loaded);
41
46
  useApplyScale(expectImageRef, scale, loaded);
42
47
  useApplyScale(actualImageRef, scale, loaded);
43
- 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);
48
+ useEffect(() => {
49
+ if (loaded) readyForCapture();
47
50
  }, [loaded]);
48
51
  return /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(ImageContainer, null, /*#__PURE__*/React.createElement(Image, {
49
52
  ref: expectImageRef,
@@ -4,26 +4,24 @@ import { SwapView } from './SwapView';
4
4
  import { SlideView } from './SlideView';
5
5
  import { BlendView } from './BlendView';
6
6
  import { styled, withTheme } from '@storybook/theming';
7
- export var themeBorderColors = {
7
+ export const themeBorderColors = {
8
8
  actual: 'negative',
9
9
  expect: 'positive',
10
10
  diff: 'secondary'
11
11
  };
12
12
 
13
- var isColor = function isColor(theme, color) {
14
- return color in theme.color;
15
- };
13
+ const isColor = (theme, color) => color in theme.color;
16
14
 
17
15
  export function getBorderColor(theme, color) {
18
16
  return isColor(theme, color) ? theme.color[color] : color;
19
17
  }
20
- var views = {
18
+ const views = {
21
19
  'side-by-side': SideBySideView,
22
20
  swap: SwapView,
23
21
  slide: SlideView,
24
22
  blend: BlendView
25
23
  };
26
- var Container = styled.div({
24
+ const Container = styled.div({
27
25
  height: '100%',
28
26
  display: 'flex',
29
27
  textAlign: 'center',
@@ -31,25 +29,31 @@ var Container = styled.div({
31
29
  justifyContent: 'center',
32
30
  padding: '0 20px'
33
31
  });
34
- var ImageLink = styled.a({
32
+ const ImageLink = styled.a({
35
33
  lineHeight: 0
36
34
  });
37
- var ActualImage = withTheme(styled.img(function (_ref) {
38
- var theme = _ref.theme;
35
+ const ActualImage = withTheme(styled.img(_ref => {
36
+ let {
37
+ theme
38
+ } = _ref;
39
39
  return {
40
40
  border: "1px solid ".concat(getBorderColor(theme, themeBorderColors.expect)),
41
41
  maxWidth: '100%'
42
42
  };
43
43
  }));
44
44
  export function ImagesView(_ref2) {
45
- var url = _ref2.url,
46
- image = _ref2.image,
47
- canApprove = _ref2.canApprove,
48
- mode = _ref2.mode;
49
- var ViewComponent = views[mode];
50
- var actual = image.actual,
51
- diff = image.diff,
52
- expect = image.expect;
45
+ let {
46
+ url,
47
+ image,
48
+ canApprove,
49
+ mode
50
+ } = _ref2;
51
+ const ViewComponent = views[mode];
52
+ const {
53
+ actual,
54
+ diff,
55
+ expect
56
+ } = image;
53
57
  return /*#__PURE__*/React.createElement(Container, null, canApprove && diff && expect ? /*#__PURE__*/React.createElement(ViewComponent, {
54
58
  actual: "".concat(url, "/").concat(actual),
55
59
  diff: "".concat(url, "/").concat(diff),