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
@@ -9,20 +9,21 @@ import { Builder, By, Capabilities, Origin } from 'selenium-webdriver';
9
9
  import { PageLoadStrategy } from 'selenium-webdriver/lib/capabilities';
10
10
  import { isDefined, noop } from '../../types';
11
11
  import { colors, logger } from '../logger';
12
- import { subscribeOn } from '../messages';
13
- import { importStorybookCoreEvents, isStorybookVersionLessThan } from '../storybook/helpers';
12
+ import { emitStoriesMessage, subscribeOn } from '../messages';
13
+ import { importStorybookCoreEvents } from '../storybook/helpers';
14
14
  import { isShuttingDown, LOCALHOST_REGEXP, runSequence } from '../utils';
15
15
  const DOCKER_INTERNAL = 'host.docker.internal';
16
16
  let browserLogger = logger;
17
+ let browserName = '';
18
+ let browser = null;
19
+ let creeveyServerHost = null;
17
20
 
18
21
  function getSessionData(grid, sessionId = '') {
19
22
  const gridUrl = new URL(grid);
20
23
  gridUrl.pathname = `/host/${sessionId}`;
21
24
  return new Promise((resolve, reject) => (gridUrl.protocol == 'https:' ? https : http).get(gridUrl.toString(), res => {
22
25
  if (res.statusCode !== 200) {
23
- var _res$statusCode;
24
-
25
- return reject(new Error(`Couldn't get session data for ${sessionId}. Status code: ${(_res$statusCode = res.statusCode) !== null && _res$statusCode !== void 0 ? _res$statusCode : 'Unknown'}`));
26
+ return reject(new Error(`Couldn't get session data for ${sessionId}. Status code: ${res.statusCode ?? 'Unknown'}`));
26
27
  }
27
28
 
28
29
  let data = '';
@@ -32,17 +33,19 @@ function getSessionData(grid, sessionId = '') {
32
33
  try {
33
34
  resolve(JSON.parse(data));
34
35
  } catch (error) {
35
- var _error$stack;
36
-
37
- reject(new Error(`Couldn't get session data for ${sessionId}. ${error instanceof Error ? (_error$stack = error.stack) !== null && _error$stack !== void 0 ? _error$stack : error.message : error}`));
36
+ reject(new Error(`Couldn't get session data for ${sessionId}. ${error instanceof Error ? error.stack ?? error.message : error}`));
38
37
  }
39
38
  });
40
39
  }));
41
40
  }
42
41
 
42
+ function getAddresses() {
43
+ return [DOCKER_INTERNAL].concat(...Object.values(networkInterfaces()).filter(isDefined).map(network => network.filter(info => info.family == 'IPv4').map(info => info.address)));
44
+ }
45
+
43
46
  async function resolveStorybookUrl(storybookUrl, checkUrl) {
44
47
  browserLogger.debug('Resolving storybook url');
45
- const addresses = [DOCKER_INTERNAL].concat(...Object.values(networkInterfaces()).filter(isDefined).map(network => network.filter(info => info.family == 'IPv4').map(info => info.address)));
48
+ const addresses = getAddresses();
46
49
 
47
50
  for (const ip of addresses) {
48
51
  const resolvedUrl = storybookUrl.replace(LOCALHOST_REGEXP, ip);
@@ -96,17 +99,6 @@ function getUrlChecker(browser) {
96
99
  }
97
100
 
98
101
  async function waitForStorybook(browser) {
99
- // NOTE: Storybook 5.x doesn't have the `last` method
100
- if (isStorybookVersionLessThan(6)) {
101
- browserLogger.debug('Waiting for `load` event to make sure that storybook is initiated');
102
- return browser.executeAsyncScript(function (callback) {
103
- if (document.readyState == 'complete') return callback();
104
- window.addEventListener('load', function () {
105
- callback();
106
- });
107
- });
108
- }
109
-
110
102
  browserLogger.debug('Waiting for `setStories` event to make sure that storybook is initiated');
111
103
  let wait = true;
112
104
  let isTimeout = false;
@@ -129,11 +121,11 @@ async function waitForStorybook(browser) {
129
121
  }
130
122
 
131
123
  async function resetMousePosition(browser) {
132
- var _ref, _await$browser$getCap, _await$browser$getCap2, _await$browser$getCap3;
124
+ var _await$browser$getCap, _await$browser$getCap2;
133
125
 
134
126
  browserLogger.debug('Resetting mouse position to the top-left corner');
135
127
  const browserName = (await browser.getCapabilities()).getBrowserName();
136
- const [browserVersion] = (_ref = (_await$browser$getCap = (_await$browser$getCap2 = (await browser.getCapabilities()).getBrowserVersion()) === null || _await$browser$getCap2 === void 0 ? void 0 : _await$browser$getCap2.split('.')) !== null && _await$browser$getCap !== void 0 ? _await$browser$getCap : (_await$browser$getCap3 = (await browser.getCapabilities()).get('version')) === null || _await$browser$getCap3 === void 0 ? void 0 : _await$browser$getCap3.split('.')) !== null && _ref !== void 0 ? _ref : []; // NOTE Reset mouse position to support keweb selenium grid browser versions
128
+ const [browserVersion] = ((_await$browser$getCap = (await browser.getCapabilities()).getBrowserVersion()) === null || _await$browser$getCap === void 0 ? void 0 : _await$browser$getCap.split('.')) ?? ((_await$browser$getCap2 = (await browser.getCapabilities()).get('version')) === null || _await$browser$getCap2 === void 0 ? void 0 : _await$browser$getCap2.split('.')) ?? []; // NOTE Reset mouse position to support keweb selenium grid browser versions
137
129
 
138
130
  if (browserName == 'chrome' && browserVersion == '70') {
139
131
  const {
@@ -217,10 +209,10 @@ const getScrollBarWidth = (() => {
217
209
 
218
210
 
219
211
  async function hasScrollBar(browser) {
220
- var _await$browser$getCap4, _await$browser$getCap5;
212
+ var _await$browser$getCap3;
221
213
 
222
214
  const browserName = (await browser.getCapabilities()).getBrowserName();
223
- const [browserVersion] = (_await$browser$getCap4 = (_await$browser$getCap5 = (await browser.getCapabilities()).getBrowserVersion()) === null || _await$browser$getCap5 === void 0 ? void 0 : _await$browser$getCap5.split('.')) !== null && _await$browser$getCap4 !== void 0 ? _await$browser$getCap4 : [];
215
+ const [browserVersion] = ((_await$browser$getCap3 = (await browser.getCapabilities()).getBrowserVersion()) === null || _await$browser$getCap3 === void 0 ? void 0 : _await$browser$getCap3.split('.')) ?? [];
224
216
  return browserName != 'Safari' && // NOTE This need to work with keweb selenium grid
225
217
  !(browserName == 'firefox' && browserVersion == '61');
226
218
  }
@@ -271,7 +263,8 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
271
263
  const scrollOffset = isFitVertically || isScreenshotWithoutScrollBar ? 0 : scrollBarWidth;
272
264
  const i = (y * compositeImage.width + x) * 4;
273
265
  const j = // NOTE compositeImage(x, y) => image(x, y)
274
- (y % viewportHeight * (viewportWidth + scrollOffset) + x % viewportWidth) * 4 + (isLastRow ? yOffset * (viewportWidth + scrollOffset) * 4 : 0) + (isLastCol ? xOffset * 4 : 0);
266
+ (y % viewportHeight * (viewportWidth + scrollOffset) + x % viewportWidth) * 4 + ( // NOTE Offset for last row/col image
267
+ isLastRow ? yOffset * (viewportWidth + scrollOffset) * 4 : 0) + (isLastCol ? xOffset * 4 : 0);
275
268
  const image = images[row * cols + col];
276
269
  compositeImage.data[i + 0] = image.data[j + 0];
277
270
  compositeImage.data[i + 1] = image.data[j + 1];
@@ -283,7 +276,7 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
283
276
  return PNG.sync.write(compositeImage).toString('base64');
284
277
  }
285
278
 
286
- async function takeScreenshot(browser, captureElement, ignoreElements) {
279
+ export async function takeScreenshot(browser, captureElement, ignoreElements) {
287
280
  let screenshot;
288
281
  const ignoreStyles = await insertIgnoreStyles(browser, ignoreElements);
289
282
 
@@ -320,7 +313,7 @@ async function takeScreenshot(browser, captureElement, ignoreElements) {
320
313
  const {
321
314
  elementRect,
322
315
  windowRect
323
- } = rects !== null && rects !== void 0 ? rects : {};
316
+ } = rects ?? {};
324
317
  if (!elementRect || !windowRect) throw new Error(`Couldn't find element with selector: '${captureElement}'`);
325
318
  const isFitIntoViewport = elementRect.width + elementRect.left <= windowRect.width && elementRect.height + elementRect.top <= windowRect.height;
326
319
  if (isFitIntoViewport) browserLogger.debug(`Capturing ${chalk.cyan(captureElement)}`);else browserLogger.debug(`Capturing composite screenshot image of ${chalk.cyan(captureElement)}`);
@@ -341,22 +334,19 @@ async function selectStory(browser, {
341
334
  name
342
335
  }, waitForReady = false) {
343
336
  browserLogger.debug(`Triggering 'SetCurrentStory' event with storyId ${chalk.magenta(id)}`);
344
- const errorMessage = await browser.executeAsyncScript(function (id, kind, name, shouldWaitForReady, callback) {
337
+ const result = await browser.executeAsyncScript(function (id, kind, name, shouldWaitForReady, callback) {
345
338
  if (typeof window.__CREEVEY_SELECT_STORY__ == 'undefined') {
346
- return callback("Creevey can't switch story. This may happened if forget to add `creevey` addon to your storybook config, or storybook not loaded in browser due syntax error.");
339
+ return callback(["Creevey can't switch story. This may happened if forget to add `creevey` addon to your storybook config, or storybook not loaded in browser due syntax error."]);
347
340
  }
348
341
 
349
- window.__CREEVEY_SELECT_STORY__(id, kind, name, shouldWaitForReady, callback);
342
+ void window.__CREEVEY_SELECT_STORY__(id, kind, name, shouldWaitForReady, callback);
350
343
  }, id, kind, name, waitForReady);
344
+ const [errorMessage, isCaptureCalled = false] = result ?? [];
351
345
  if (errorMessage) throw new Error(errorMessage);
346
+ return isCaptureCalled;
352
347
  }
353
348
 
354
349
  export async function updateStorybookGlobals(browser, globals) {
355
- if (isStorybookVersionLessThan(6)) {
356
- browserLogger.warn('Globals are not supported by Storybook versions less than 6');
357
- return;
358
- }
359
-
360
350
  browserLogger.debug('Applying storybook globals');
361
351
  await browser.executeScript(function (globals) {
362
352
  window.__CREEVEY_UPDATE_GLOBALS__(globals);
@@ -388,7 +378,44 @@ async function openStorybookPage(browser, storybookUrl, resolver) {
388
378
  }
389
379
  }
390
380
 
391
- export async function getBrowser(config, browserConfig) {
381
+ async function resolveCreeveyHost(browser, port) {
382
+ if (creeveyServerHost != null) return creeveyServerHost;
383
+ const addresses = getAddresses();
384
+ creeveyServerHost = await browser.executeAsyncScript(function (hosts, port, callback) {
385
+ void Promise.all(hosts.map(function (host) {
386
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
387
+ return fetch('http://' + host + ':' + port + '/ping').then(function (response) {
388
+ return response.text();
389
+ }).then(function (pong) {
390
+ return pong == 'pong' ? host : null;
391
+ }).catch(function () {
392
+ return null;
393
+ });
394
+ })).then(function (hosts) {
395
+ callback(hosts.find(function (host) {
396
+ return host != null;
397
+ }));
398
+ });
399
+ }, addresses, port);
400
+ if (creeveyServerHost == null) throw new Error("Can't reach creevey server from a browser");
401
+ return creeveyServerHost;
402
+ }
403
+
404
+ export async function loadStoriesFromBrowser(port) {
405
+ if (!browser) throw new Error("Can't get stories from browser if webdriver isn't connected");
406
+ const host = await resolveCreeveyHost(browser, port);
407
+ const stories = await browser.executeAsyncScript(function (creeveyHost, creeveyPort, callback) {
408
+ window.__CREEVEY_SERVER_HOST__ = creeveyHost;
409
+ window.__CREEVEY_SERVER_PORT__ = creeveyPort;
410
+ void window.__CREEVEY_GET_STORIES__().then(callback);
411
+ }, host, port);
412
+ if (!stories) throw new Error("Can't get stories, it seems creevey or storybook API isn't available");
413
+ return stories;
414
+ }
415
+ export async function getBrowser(config, name) {
416
+ if (browser) return browser;
417
+ browserName = name;
418
+ const browserConfig = config.browsers[browserName];
392
419
  const {
393
420
  gridUrl = config.gridUrl,
394
421
  storybookUrl: address = config.storybookUrl,
@@ -398,14 +425,11 @@ export async function getBrowser(config, browserConfig) {
398
425
  ...userCapabilities
399
426
  } = browserConfig;
400
427
  void limit;
401
- const {
402
- browserName
403
- } = userCapabilities;
404
- const realAddress = address;
405
- let browser = null; // TODO Define some capabilities explicitly and define typings
428
+ const realAddress = address; // TODO Define some capabilities explicitly and define typings
406
429
 
407
- const capabilities = new Capabilities(userCapabilities);
408
- capabilities.setPageLoadStrategy(PageLoadStrategy.NONE);
430
+ const capabilities = new Capabilities({ ...userCapabilities,
431
+ pageLoadStrategy: PageLoadStrategy.NONE
432
+ });
409
433
  subscribeOn('shutdown', () => {
410
434
  var _browser;
411
435
 
@@ -420,7 +444,7 @@ export async function getBrowser(config, browserConfig) {
420
444
  const url = new URL(gridUrl);
421
445
  url.username = url.username ? '********' : '';
422
446
  url.password = url.password ? '********' : '';
423
- browserLogger.debug(`(${browserName}) Connecting to Selenium ${chalk.magenta(url.toString())}`);
447
+ browserLogger.debug(`(${name}) Connecting to Selenium ${chalk.magenta(url.toString())}`);
424
448
  browser = await new Builder().usingServer(gridUrl).withCapabilities(capabilities).build();
425
449
  const sessionId = (_await$browser$getSes = await browser.getSession()) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
426
450
  let browserHost = '';
@@ -434,12 +458,12 @@ export async function getBrowser(config, browserConfig) {
434
458
  /* noop */
435
459
  }
436
460
 
437
- browserLogger.debug(`(${browserName}) Connected successful with ${[chalk.green(browserHost), chalk.magenta(sessionId)].filter(Boolean).join(':')}`);
461
+ browserLogger.debug(`(${name}) Connected successful with ${[chalk.green(browserHost), chalk.magenta(sessionId)].filter(Boolean).join(':')}`);
438
462
  browserLogger = getLogger(sessionId);
439
463
  prefix.apply(browserLogger, {
440
464
  format(level) {
441
465
  const levelColor = colors[level.toUpperCase()];
442
- return `[${browserName}:${chalk.gray(sessionId)}] ${levelColor(level)} =>`;
466
+ return `[${name}:${chalk.gray(sessionId)}] ${levelColor(level)} =>`;
443
467
  }
444
468
 
445
469
  });
@@ -452,17 +476,18 @@ export async function getBrowser(config, browserConfig) {
452
476
  });
453
477
  }, () => viewport && browser && resizeViewport(browser, viewport), () => browser && openStorybookPage(browser, realAddress, config.resolveStorybookUrl), () => browser && waitForStorybook(browser)], () => !isShuttingDown.current);
454
478
  } catch (originalError) {
455
- var _await$browser$getCur, _browser4;
479
+ var _browser4;
456
480
 
457
481
  if (isShuttingDown.current) {
458
482
  var _browser3;
459
483
 
460
484
  (_browser3 = browser) === null || _browser3 === void 0 ? void 0 : _browser3.quit().catch(noop);
485
+ browser = null;
461
486
  return null;
462
487
  }
463
488
 
464
489
  if (originalError instanceof Error && originalError.name == 'ResolveUrlError') throw originalError;
465
- const error = new Error(`Can't load storybook root page by URL ${(_await$browser$getCur = await ((_browser4 = browser) === null || _browser4 === void 0 ? void 0 : _browser4.getCurrentUrl())) !== null && _await$browser$getCur !== void 0 ? _await$browser$getCur : realAddress}`);
490
+ const error = new Error(`Can't load storybook root page by URL ${(await ((_browser4 = browser) === null || _browser4 === void 0 ? void 0 : _browser4.getCurrentUrl())) ?? realAddress}`);
466
491
  if (originalError instanceof Error) error.stack = originalError.stack;
467
492
  throw error;
468
493
  }
@@ -471,6 +496,9 @@ export async function getBrowser(config, browserConfig) {
471
496
  await updateStorybookGlobals(browser, _storybookGlobals);
472
497
  }
473
498
 
499
+ await browser.executeScript(function (workerId) {
500
+ window.__CREEVEY_WORKER_ID__ = workerId;
501
+ }, process.pid);
474
502
  return browser;
475
503
  }
476
504
 
@@ -486,12 +514,22 @@ async function updateStoryArgs(browser, story, updatedArgs) {
486
514
  }, story.id, updatedArgs, Events.UPDATE_STORY_ARGS, Events.STORY_RENDERED);
487
515
  }
488
516
 
517
+ export async function closeBrowser() {
518
+ if (!browser) return;
519
+
520
+ try {
521
+ await browser.quit();
522
+ } finally {
523
+ browser = null;
524
+ }
525
+ }
489
526
  export async function switchStory() {
490
- var _this$currentTest, _this$currentTest$ctx, _parameters$creevey;
527
+ var _this$currentTest, _this$currentTest$ctx;
491
528
 
492
529
  let testOrSuite = this.currentTest;
493
530
  if (!testOrSuite) throw new Error("Can't switch story, because test context doesn't have 'currentTest' field");
494
531
  this.testScope.length = 0;
532
+ this.screenshots.length = 0;
495
533
  this.testScope.push(this.browserName);
496
534
 
497
535
  while ((_testOrSuite = testOrSuite) !== null && _testOrSuite !== void 0 && _testOrSuite.title) {
@@ -513,15 +551,8 @@ export async function switchStory() {
513
551
  captureElement = '#root',
514
552
  waitForReady,
515
553
  ignoreElements
516
- } = (_parameters$creevey = parameters.creevey) !== null && _parameters$creevey !== void 0 ? _parameters$creevey : {};
554
+ } = parameters.creevey ?? {};
517
555
  browserLogger.debug(`Switching to story ${chalk.cyan(kind)}/${chalk.cyan(name)} by id ${chalk.magenta(id)}`);
518
- await resetMousePosition(this.browser);
519
- await selectStory(this.browser, {
520
- id,
521
- kind,
522
- name
523
- }, waitForReady);
524
- browserLogger.debug(`Story ${chalk.magenta(id)} ready for capturing`);
525
556
  if (captureElement) Object.defineProperty(this, 'captureElement', {
526
557
  enumerable: true,
527
558
  configurable: true,
@@ -533,6 +564,44 @@ export async function switchStory() {
533
564
  this.updateStoryArgs = updatedArgs => updateStoryArgs(this.browser, story, updatedArgs);
534
565
 
535
566
  this.testScope.reverse();
567
+ let storyPlayResolver;
568
+ let waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
569
+ const unsubscribe = subscribeOn('stories', message => {
570
+ if (message.type != 'capture') return;
571
+ const {
572
+ payload = {},
573
+ payload: {
574
+ imageName
575
+ } = {}
576
+ } = message;
577
+ void takeScreenshot(this.browser, payload.captureElement ?? captureElement, payload.ignoreElements ?? ignoreElements).then(screenshot => {
578
+ this.screenshots.push({
579
+ imageName,
580
+ screenshot
581
+ });
582
+ void this.browser.executeAsyncScript(function (callback) {
583
+ window.__CREEVEY_HAS_PLAY_COMPLETED_YET__(callback);
584
+ }).then(isCompleted => storyPlayResolver(isCompleted));
585
+ emitStoriesMessage({
586
+ type: 'capture'
587
+ });
588
+ });
589
+ });
590
+ await resetMousePosition(this.browser);
591
+ const isCaptureCalled = await selectStory(this.browser, {
592
+ id,
593
+ kind,
594
+ name
595
+ }, waitForReady);
596
+
597
+ if (isCaptureCalled) {
598
+ while (!(await waitForComplete)) {
599
+ waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
600
+ }
601
+ }
602
+
603
+ unsubscribe();
604
+ browserLogger.debug(`Story ${chalk.magenta(id)} ready for capturing`);
536
605
  }
537
606
 
538
607
  async function insertIgnoreStyles(browser, ignoreElements) {
@@ -5,7 +5,7 @@ import { downloadBinary, getCreeveyCache } from '../utils';
5
5
  import { pullImages, runImage } from '../docker';
6
6
  import { Octokit } from '@octokit/core';
7
7
  import { subscribeOn } from '../messages';
8
- import { isWorker } from 'cluster';
8
+ import cluster from 'cluster';
9
9
  import { chmod, exec } from 'shelljs';
10
10
  const mkdirAsync = promisify(mkdir);
11
11
  const writeFileAsync = promisify(writeFile);
@@ -41,8 +41,6 @@ async function createSelenoidConfig(browsers, {
41
41
  }
42
42
 
43
43
  async function downloadSelenoidBinary(destination) {
44
- var _assets$find;
45
-
46
44
  const platformNameMapping = {
47
45
  darwin: 'selenoid_darwin_amd64',
48
46
  linux: 'selenoid_linux_amd64',
@@ -59,9 +57,9 @@ async function downloadSelenoidBinary(destination) {
59
57
  const {
60
58
  browser_download_url: downloadUrl,
61
59
  size: binarySize
62
- } = (_assets$find = assets.find(({
60
+ } = assets.find(({
63
61
  name
64
- }) => platformNameMapping[process.platform] == name)) !== null && _assets$find !== void 0 ? _assets$find : {};
62
+ }) => platformNameMapping[process.platform] == name) ?? {};
65
63
  if (existsSync(destination) && lstatSync(destination).size == binarySize) return;
66
64
 
67
65
  if (!downloadUrl) {
@@ -73,7 +71,7 @@ async function downloadSelenoidBinary(destination) {
73
71
 
74
72
  export async function startSelenoidStandalone(config, debug) {
75
73
  config.gridUrl = 'http://localhost:4444/wd/hub';
76
- if (isWorker) return;
74
+ if (cluster.isWorker) return;
77
75
  const browsers = Object.values(config.browsers).filter(browser => !browser.gridUrl);
78
76
  const selenoidConfigDir = await createSelenoidConfig(browsers, {
79
77
  useDocker: false
@@ -4,15 +4,16 @@ import { createHash } from 'crypto';
4
4
  import { mapValues, pick } from 'lodash';
5
5
  import { isDefined, isFunction, isObject } from '../types';
6
6
  import { shouldSkip, removeProps } from './utils';
7
- import { isStorybookVersionGreaterThan, isStorybookVersionLessThan } from './storybook/helpers';
8
- import { denormalizeStoryParameters } from '../shared';
9
7
 
10
8
  function storyTestFabric(delay, testFn) {
11
9
  return async function storyTest() {
12
- var _testFn$call;
13
-
14
10
  delay ? await new Promise(resolve => setTimeout(resolve, delay)) : void 0;
15
- await ((_testFn$call = testFn === null || testFn === void 0 ? void 0 : testFn.call(this)) !== null && _testFn$call !== void 0 ? _testFn$call : this.expect(await this.takeScreenshot()).to.matchImage());
11
+ await (testFn ? testFn.call(this) : this.screenshots.length > 0 ? this.expect(this.screenshots.reduce((screenshots, {
12
+ imageName,
13
+ screenshot
14
+ }, index) => ({ ...screenshots,
15
+ [imageName ?? `screenshot_${index}`]: screenshot
16
+ }), {})).to.matchImages() : this.expect(await this.takeScreenshot()).to.matchImage());
16
17
  };
17
18
  }
18
19
 
@@ -38,42 +39,38 @@ function createCreeveyTest(browser, storyMeta, skipOptions, testName) {
38
39
  };
39
40
  }
40
41
 
41
- function convertStories(browsers, stories) {
42
+ function convertStories(browserName, stories) {
42
43
  const tests = {};
43
44
  (Array.isArray(stories) ? stories : Object.values(stories)).forEach(storyMeta => {
44
45
  // TODO Skip docsOnly stories for now
45
46
  if (storyMeta.parameters.docsOnly) return;
46
- browsers.forEach(browserName => {
47
- var _storyMeta$parameters;
48
-
49
- const {
50
- delay: delayParam,
51
- tests: storyTests,
52
- skip
53
- } = (_storyMeta$parameters = storyMeta.parameters.creevey) !== null && _storyMeta$parameters !== void 0 ? _storyMeta$parameters : {};
54
- const delay = typeof delayParam == 'number' ? delayParam : delayParam !== null && delayParam !== void 0 && delayParam.for.includes(browserName) ? delayParam.ms : 0; // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png]
55
- // typeof tests === "function" => rootSuite -> kindSuite -> storyTest -> browser -> [images.png]
56
- // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
57
- // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> browser -> [images.png]
58
-
59
- if (!storyTests) {
60
- const test = createCreeveyTest(browserName, storyMeta, skip);
61
- tests[test.id] = { ...test,
62
- storyId: storyMeta.id,
63
- story: storyMeta,
64
- fn: storyTestFabric(delay)
65
- };
66
- return;
67
- }
47
+ const {
48
+ delay: delayParam,
49
+ tests: storyTests,
50
+ skip
51
+ } = storyMeta.parameters.creevey ?? {};
52
+ const delay = typeof delayParam == 'number' ? delayParam : delayParam !== null && delayParam !== void 0 && delayParam.for.includes(browserName) ? delayParam.ms : 0; // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png]
53
+ // typeof tests === "function" => rootSuite -> kindSuite -> storyTest -> browser -> [images.png]
54
+ // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
55
+ // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> browser -> [images.png]
56
+
57
+ if (!storyTests) {
58
+ const test = createCreeveyTest(browserName, storyMeta, skip);
59
+ tests[test.id] = { ...test,
60
+ storyId: storyMeta.id,
61
+ story: storyMeta,
62
+ fn: storyTestFabric(delay)
63
+ };
64
+ return;
65
+ }
68
66
 
69
- Object.entries(storyTests).forEach(([testName, testFn]) => {
70
- const test = createCreeveyTest(browserName, storyMeta, skip, testName);
71
- tests[test.id] = { ...test,
72
- storyId: storyMeta.id,
73
- story: storyMeta,
74
- fn: storyTestFabric(delay, testFn)
75
- };
76
- });
67
+ Object.entries(storyTests).forEach(([testName, testFn]) => {
68
+ const test = createCreeveyTest(browserName, storyMeta, skip, testName);
69
+ tests[test.id] = { ...test,
70
+ storyId: storyMeta.id,
71
+ story: storyMeta,
72
+ fn: storyTestFabric(delay, testFn)
73
+ };
77
74
  });
78
75
  });
79
76
  return tests;
@@ -81,22 +78,24 @@ function convertStories(browsers, stories) {
81
78
 
82
79
  export async function loadTestsFromStories(browsers, provider, update) {
83
80
  const testIdsByFiles = new Map();
84
- const data = await provider(storiesByFiles => {
81
+ const stories = await provider(storiesByFiles => {
85
82
  const testsDiff = {};
86
- Array.from(storiesByFiles.entries()).forEach(([filename, stories]) => {
87
- var _testIdsByFiles$get$f, _testIdsByFiles$get;
88
-
89
- const tests = convertStories(browsers, stories);
90
- const changed = Object.keys(tests);
91
- const removed = (_testIdsByFiles$get$f = (_testIdsByFiles$get = testIdsByFiles.get(filename)) === null || _testIdsByFiles$get === void 0 ? void 0 : _testIdsByFiles$get.filter(testId => !tests[testId])) !== null && _testIdsByFiles$get$f !== void 0 ? _testIdsByFiles$get$f : [];
92
- if (changed.length == 0) testIdsByFiles.delete(filename);else testIdsByFiles.set(filename, changed);
93
- Object.assign(testsDiff, tests);
94
- removed.forEach(testId => testsDiff[testId] = undefined);
83
+ const tests = {};
84
+ browsers.forEach(browser => {
85
+ Array.from(storiesByFiles.entries()).forEach(([filename, stories]) => {
86
+ var _testIdsByFiles$get;
87
+
88
+ Object.assign(tests, convertStories(browser, stories));
89
+ const changed = Object.keys(tests);
90
+ const removed = ((_testIdsByFiles$get = testIdsByFiles.get(filename)) === null || _testIdsByFiles$get === void 0 ? void 0 : _testIdsByFiles$get.filter(testId => !tests[testId])) ?? [];
91
+ if (changed.length == 0) testIdsByFiles.delete(filename);else testIdsByFiles.set(filename, changed);
92
+ Object.assign(testsDiff, tests);
93
+ removed.forEach(testId => testsDiff[testId] = undefined);
94
+ });
95
95
  });
96
96
  update === null || update === void 0 ? void 0 : update(testsDiff);
97
97
  });
98
- const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
99
- const tests = convertStories(browsers, stories);
98
+ const tests = browsers.reduce((tests, browser) => Object.assign(tests, convertStories(browser, stories)), {});
100
99
  Object.values(tests).filter(isDefined).forEach(({
101
100
  id,
102
101
  story: {
@@ -104,35 +103,24 @@ export async function loadTestsFromStories(browsers, provider, update) {
104
103
  fileName
105
104
  }
106
105
  }
107
- }) => {
108
- var _testIdsByFiles$get2;
109
-
110
- return (// TODO Don't use filename as a key, due possible collisions if two require.context with same structure of modules are defined
111
- testIdsByFiles.set(fileName, [...((_testIdsByFiles$get2 = testIdsByFiles.get(fileName)) !== null && _testIdsByFiles$get2 !== void 0 ? _testIdsByFiles$get2 : []), id])
112
- );
113
- });
106
+ }) => // TODO Don't use filename as a key, due possible collisions if two require.context with same structure of modules are defined
107
+ testIdsByFiles.set(fileName, [...(testIdsByFiles.get(fileName) ?? []), id]));
114
108
  return tests;
115
109
  }
116
110
  export function saveStoriesJson(storiesData, extract) {
117
- var _storiesData$stories;
118
-
119
- const outputDir = typeof extract == 'boolean' ? 'storybook-static' : extract;
120
-
121
- if (!isStorybookVersionLessThan(6)) {
122
- // NOTE Copy-pasted from Storybook's `getStoriesJsonData` method
123
- const allowed = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory'];
124
- storiesData.globalParameters = pick(storiesData.globalParameters, allowed); // @ts-expect-error ignore error
111
+ const outputDir = typeof extract == 'boolean' ? 'storybook-static' : extract; // NOTE Copy-pasted from Storybook's `getStoriesJsonData` method
125
112
 
126
- storiesData.kindParameters = mapValues(storiesData.kindParameters, v => pick(v, allowed)); // @ts-expect-error ignore error
113
+ const allowed = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory'];
114
+ storiesData.globalParameters = pick(storiesData.globalParameters, allowed); // @ts-expect-error ignore error
127
115
 
128
- storiesData.stories = mapValues(storiesData.stories, v => ({ ...pick(v, ['id', 'name', 'kind', 'story']),
129
- parameters: pick(v.parameters, allowed)
130
- }));
131
- } // TODO Fix args stories
116
+ storiesData.kindParameters = mapValues(storiesData.kindParameters, v => pick(v, allowed)); // @ts-expect-error ignore error
132
117
 
118
+ storiesData.stories = mapValues(storiesData.stories, v => ({ ...pick(v, ['id', 'name', 'kind', 'story']),
119
+ parameters: pick(v.parameters, allowed)
120
+ })); // TODO Fix args stories
133
121
 
134
- removeProps(storiesData !== null && storiesData !== void 0 ? storiesData : {}, ['stories', () => true, 'parameters', '__isArgsStory']);
135
- Object.values((_storiesData$stories = storiesData === null || storiesData === void 0 ? void 0 : storiesData.stories) !== null && _storiesData$stories !== void 0 ? _storiesData$stories : {}).forEach(story => isObject(story) && 'parameters' in story && isObject(story.parameters) && delete story.parameters.__isArgsStory);
122
+ removeProps(storiesData ?? {}, ['stories', () => true, 'parameters', '__isArgsStory']);
123
+ Object.values((storiesData === null || storiesData === void 0 ? void 0 : storiesData.stories) ?? {}).forEach(story => isObject(story) && 'parameters' in story && isObject(story.parameters) && delete story.parameters.__isArgsStory);
136
124
  mkdirSync(outputDir, {
137
125
  recursive: true
138
126
  });
@@ -1,16 +1,12 @@
1
- var _api$channel, _api$context;
2
-
3
1
  import { addons } from '@storybook/addons';
4
- import { getStorybookFramework, isStorybookVersionLessThan, resolveFromStorybook } from './helpers';
2
+ import { getStorybookFramework, resolveFromStorybook } from './helpers';
5
3
  const framework = getStorybookFramework(); // eslint-disable-next-line @typescript-eslint/no-var-requires
6
4
 
7
- const core = require(resolveFromStorybook('@storybook/core')); //@ts-expect-error: 6.2 use named exports
8
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
9
-
5
+ const core = require(resolveFromStorybook('@storybook/core-client'));
10
6
 
11
- const start = isStorybookVersionLessThan(6, 2) ? core.default.start : core.start;
7
+ const start = core.start;
12
8
  const api = start(() => void 0);
13
- export const channel = isStorybookVersionLessThan(6, 4) ? (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel : addons.getChannel();
9
+ export const channel = addons.getChannel();
14
10
  export const clientApi = api.clientApi;
15
11
  export const forceReRender = api.forceReRender;
16
12
  export const storiesOf = (kind, m) => {
@@ -19,21 +15,8 @@ export const storiesOf = (kind, m) => {
19
15
  });
20
16
  };
21
17
  export const configure = (...args) => {
22
- if (isStorybookVersionLessThan(5, 2)) {
23
- //NOTE: Storybook <= 5.1 pass args as is
24
- //@ts-expect-error: ignore it
25
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
26
- return api.configApi.configure(...args);
27
- }
28
-
29
- if (isStorybookVersionLessThan(6)) {
30
- //NOTE: Storybook <= 5.3 pass `framework` as last argument
31
- //@ts-expect-error: ignore it
32
- return api.configure(...args, framework);
33
- } //NOTE Storybook 6.x pass `framework` as first argument
18
+ //NOTE Storybook 6.x pass `framework` as first argument
34
19
  //@ts-expect-error: ignore it
35
-
36
-
37
20
  return api.configure(framework, ...args);
38
21
  };
39
22
  export const addDecorator = clientApi.addDecorator;