creevey 0.9.0-beta.13 → 0.9.0-beta.14

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 (216) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/.yarnrc.yml +1 -0
  3. package/lib/cjs/cli.js +1 -0
  4. package/lib/cjs/client/addon/Manager.js +151 -223
  5. package/lib/cjs/client/addon/components/Addon.js +2 -9
  6. package/lib/cjs/client/addon/components/Icons.js +1 -7
  7. package/lib/cjs/client/addon/components/Panel.js +5 -18
  8. package/lib/cjs/client/addon/components/TestSelect.js +12 -25
  9. package/lib/cjs/client/addon/components/Tools.js +17 -28
  10. package/lib/cjs/client/addon/decorator.js +1 -4
  11. package/lib/cjs/client/addon/index.js +0 -4
  12. package/lib/cjs/client/addon/preset.js +3 -12
  13. package/lib/cjs/client/addon/preview.js +1 -4
  14. package/lib/cjs/client/addon/readyForCapture.js +1 -4
  15. package/lib/cjs/client/addon/register.js +11 -26
  16. package/lib/cjs/client/addon/utils.js +1 -9
  17. package/lib/cjs/client/addon/withCreevey.js +55 -134
  18. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +5 -17
  19. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +8 -24
  20. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +7 -23
  21. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +7 -22
  22. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +5 -17
  23. package/lib/cjs/client/shared/components/ImagesView/index.js +0 -5
  24. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +1 -8
  25. package/lib/cjs/client/shared/components/PageFooter/Paging.js +2 -19
  26. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +21 -17
  27. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +5 -24
  28. package/lib/cjs/client/shared/components/ResultsPage.js +9 -37
  29. package/lib/cjs/client/shared/creeveyClientApi.js +3 -13
  30. package/lib/cjs/client/shared/helpers.js +21 -75
  31. package/lib/cjs/client/shared/viewMode.js +2 -6
  32. package/lib/cjs/client/web/192.js +1 -0
  33. package/lib/cjs/client/web/632.js +43 -0
  34. package/lib/cjs/client/web/794.js +1 -0
  35. package/lib/cjs/client/web/main.js +78 -1
  36. package/lib/cjs/client/web/main.js.LICENSE.txt +0 -15
  37. package/lib/cjs/creevey.js +5 -21
  38. package/lib/cjs/index.js +0 -15
  39. package/lib/cjs/server/config.js +13 -33
  40. package/lib/cjs/server/docker.js +5 -27
  41. package/lib/cjs/server/index.js +8 -33
  42. package/lib/cjs/server/logger.js +5 -19
  43. package/lib/cjs/server/master/api.js +1 -14
  44. package/lib/cjs/server/master/index.js +15 -46
  45. package/lib/cjs/server/master/master.js +6 -21
  46. package/lib/cjs/server/master/pool.js +2 -37
  47. package/lib/cjs/server/master/runner.js +15 -42
  48. package/lib/cjs/server/master/server.js +5 -27
  49. package/lib/cjs/server/messages.js +7 -53
  50. package/lib/cjs/server/selenium/browser.js +51 -136
  51. package/lib/cjs/server/selenium/index.js +0 -4
  52. package/lib/cjs/server/selenium/selenoid.js +7 -33
  53. package/lib/cjs/server/stories.js +25 -30
  54. package/lib/cjs/server/storybook/providers/browser.js +5 -18
  55. package/lib/cjs/server/storybook/providers/hybrid.js +9 -29
  56. package/lib/cjs/server/testsFiles/parser.js +3 -19
  57. package/lib/cjs/server/testsFiles/register.js +7 -9
  58. package/lib/cjs/server/update.js +3 -20
  59. package/lib/cjs/server/utils.js +9 -41
  60. package/lib/cjs/server/worker/chai-image.js +1 -27
  61. package/lib/cjs/server/worker/helpers.js +2 -12
  62. package/lib/cjs/server/worker/index.js +1 -3
  63. package/lib/cjs/server/worker/reporter.js +8 -24
  64. package/lib/cjs/server/worker/worker.js +5 -49
  65. package/lib/cjs/shared/index.js +22 -36
  66. package/lib/cjs/shared/serializeRegExp.js +0 -8
  67. package/lib/cjs/types.js +4 -14
  68. package/lib/esm/cli.js +1 -1
  69. package/lib/esm/client/addon/Manager.js +151 -214
  70. package/lib/esm/client/addon/components/Panel.js +4 -6
  71. package/lib/esm/client/addon/components/TestSelect.js +11 -17
  72. package/lib/esm/client/addon/components/Tools.js +15 -14
  73. package/lib/esm/client/addon/preset.js +2 -8
  74. package/lib/esm/client/addon/readyForCapture.js +1 -3
  75. package/lib/esm/client/addon/register.js +6 -8
  76. package/lib/esm/client/addon/utils.js +0 -5
  77. package/lib/esm/client/addon/withCreevey.js +54 -116
  78. package/lib/esm/client/shared/components/ImagesView/BlendView.js +1 -1
  79. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +6 -8
  80. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +3 -4
  81. package/lib/esm/client/shared/components/ImagesView/SlideView.js +3 -3
  82. package/lib/esm/client/shared/components/ImagesView/SwapView.js +1 -1
  83. package/lib/esm/client/shared/components/PageFooter/Paging.js +1 -11
  84. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +18 -7
  85. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +3 -8
  86. package/lib/esm/client/shared/components/ResultsPage.js +6 -15
  87. package/lib/esm/client/shared/creeveyClientApi.js +3 -10
  88. package/lib/esm/client/shared/helpers.js +21 -47
  89. package/lib/esm/client/web/192.js +1 -0
  90. package/lib/esm/client/web/632.js +43 -0
  91. package/lib/esm/client/web/794.js +1 -0
  92. package/lib/esm/client/web/index.html +19 -0
  93. package/lib/esm/client/web/main.js +79 -0
  94. package/lib/esm/client/web/main.js.LICENSE.txt +34 -0
  95. package/lib/esm/creevey.js +4 -8
  96. package/lib/esm/index.js +0 -1
  97. package/lib/esm/server/config.js +7 -14
  98. package/lib/esm/server/docker.js +4 -12
  99. package/lib/esm/server/index.js +7 -21
  100. package/lib/esm/server/logger.js +0 -1
  101. package/lib/esm/server/master/api.js +0 -9
  102. package/lib/esm/server/master/index.js +15 -32
  103. package/lib/esm/server/master/master.js +2 -7
  104. package/lib/esm/server/master/pool.js +0 -23
  105. package/lib/esm/server/master/runner.js +14 -27
  106. package/lib/esm/server/master/server.js +4 -9
  107. package/lib/esm/server/messages.js +6 -38
  108. package/lib/esm/server/selenium/browser.js +50 -114
  109. package/lib/esm/server/selenium/selenoid.js +6 -17
  110. package/lib/esm/server/stories.js +24 -20
  111. package/lib/esm/server/storybook/providers/browser.js +4 -8
  112. package/lib/esm/server/storybook/providers/hybrid.js +6 -14
  113. package/lib/esm/server/testsFiles/parser.js +0 -6
  114. package/lib/esm/server/testsFiles/register.js +5 -2
  115. package/lib/esm/server/update.js +0 -8
  116. package/lib/esm/server/utils.js +3 -11
  117. package/lib/esm/server/worker/chai-image.js +0 -21
  118. package/lib/esm/server/worker/helpers.js +2 -9
  119. package/lib/esm/server/worker/reporter.js +7 -10
  120. package/lib/esm/server/worker/worker.js +4 -25
  121. package/lib/esm/shared/index.js +24 -25
  122. package/lib/esm/types.js +4 -1
  123. package/lib/types/client/addon/Manager.d.ts +1 -1
  124. package/lib/types/client/addon/components/Addon.d.ts +1 -0
  125. package/lib/types/client/addon/components/Icons.d.ts +1 -0
  126. package/lib/types/client/addon/components/Panel.d.ts +1 -0
  127. package/lib/types/client/addon/components/TestSelect.d.ts +1 -0
  128. package/lib/types/client/addon/components/Tools.d.ts +1 -0
  129. package/lib/types/client/addon/decorator.d.ts +1 -1
  130. package/lib/types/client/addon/preset.d.ts +2 -2
  131. package/lib/types/client/addon/preview.d.ts +1 -1
  132. package/lib/types/client/addon/withCreevey.d.ts +3 -2
  133. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -1
  134. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +1 -0
  135. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -1
  136. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -1
  137. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -1
  138. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +1 -0
  139. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +1 -0
  140. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +3 -1
  141. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +1 -0
  142. package/lib/types/client/shared/components/ResultsPage.d.ts +3 -1
  143. package/lib/types/client/web/CreeveyApp.d.ts +1 -0
  144. package/lib/types/client/web/CreeveyLoader.d.ts +2 -1
  145. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +4 -1
  146. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +1 -0
  147. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +1 -0
  148. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +19 -14
  149. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +1 -0
  150. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +3 -1
  151. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +3 -1
  152. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +1 -0
  153. package/lib/types/shared/index.d.ts +1 -1
  154. package/lib/types/types.d.ts +7 -28
  155. package/package.json +60 -78
  156. package/lib/cjs/client/addon/preset.ie11.js +0 -74
  157. package/lib/cjs/client/addon/preset.sb7.js +0 -19
  158. package/lib/cjs/client/web/142.js +0 -2
  159. package/lib/cjs/client/web/142.js.LICENSE.txt +0 -12
  160. package/lib/cjs/client/web/32.js +0 -1
  161. package/lib/cjs/client/web/551.js +0 -1
  162. package/lib/cjs/client/web/566.js +0 -2
  163. package/lib/cjs/client/web/566.js.LICENSE.txt +0 -31
  164. package/lib/cjs/client/web/691.js +0 -2
  165. package/lib/cjs/client/web/691.js.LICENSE.txt +0 -8
  166. package/lib/cjs/client/web/725.js +0 -1
  167. package/lib/cjs/server/extract.js +0 -46
  168. package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -86
  169. package/lib/cjs/server/loaders/babel/helpers.js +0 -469
  170. package/lib/cjs/server/loaders/babel/register.js +0 -124
  171. package/lib/cjs/server/loaders/hooks/mdx.js +0 -30
  172. package/lib/cjs/server/loaders/hooks/svelte.js +0 -65
  173. package/lib/cjs/server/loaders/webpack/compile.js +0 -269
  174. package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -172
  175. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -39
  176. package/lib/cjs/server/loaders/webpack/mdx-loader.js +0 -72
  177. package/lib/cjs/server/loaders/webpack/start.js +0 -41
  178. package/lib/cjs/server/storybook/entry.js +0 -53
  179. package/lib/cjs/server/storybook/helpers.js +0 -158
  180. package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
  181. package/lib/esm/client/addon/preset.ie11.js +0 -59
  182. package/lib/esm/client/addon/preset.sb7.js +0 -8
  183. package/lib/esm/server/extract.js +0 -32
  184. package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -72
  185. package/lib/esm/server/loaders/babel/helpers.js +0 -452
  186. package/lib/esm/server/loaders/babel/register.js +0 -103
  187. package/lib/esm/server/loaders/hooks/mdx.js +0 -15
  188. package/lib/esm/server/loaders/hooks/svelte.js +0 -49
  189. package/lib/esm/server/loaders/webpack/compile.js +0 -246
  190. package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -152
  191. package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -32
  192. package/lib/esm/server/loaders/webpack/mdx-loader.js +0 -58
  193. package/lib/esm/server/loaders/webpack/start.js +0 -27
  194. package/lib/esm/server/storybook/entry.js +0 -27
  195. package/lib/esm/server/storybook/helpers.js +0 -97
  196. package/lib/esm/server/storybook/providers/nodejs.js +0 -216
  197. package/lib/types/client/addon/preset.ie11.d.ts +0 -10
  198. package/lib/types/client/addon/preset.sb7.d.ts +0 -2
  199. package/lib/types/server/extract.d.ts +0 -2
  200. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +0 -1
  201. package/lib/types/server/loaders/babel/helpers.d.ts +0 -19
  202. package/lib/types/server/loaders/babel/register.d.ts +0 -5
  203. package/lib/types/server/loaders/hooks/mdx.d.ts +0 -1
  204. package/lib/types/server/loaders/hooks/svelte.d.ts +0 -1
  205. package/lib/types/server/loaders/webpack/compile.d.ts +0 -2
  206. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +0 -4
  207. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +0 -10
  208. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +0 -6
  209. package/lib/types/server/loaders/webpack/start.d.ts +0 -1
  210. package/lib/types/server/storybook/entry.d.ts +0 -17
  211. package/lib/types/server/storybook/helpers.d.ts +0 -24
  212. package/lib/types/server/storybook/providers/nodejs.d.ts +0 -9
  213. package/preset/ie11.js +0 -5
  214. package/preset/index.js +0 -9
  215. package/preset/sb7.js +0 -5
  216. package/types/mdx.d.ts +0 -7
@@ -1,3 +1,4 @@
1
+ import { SET_GLOBALS, UPDATE_STORY_ARGS, STORY_RENDERED } from '@storybook/core-events';
1
2
  import chalk from 'chalk';
2
3
  import http from 'http';
3
4
  import https from 'https';
@@ -10,15 +11,13 @@ import { PageLoadStrategy } from 'selenium-webdriver/lib/capabilities';
10
11
  import { isDefined, noop } from '../../types';
11
12
  import { colors, logger } from '../logger';
12
13
  import { emitStoriesMessage, subscribeOn } from '../messages';
13
- import { importStorybookCoreEvents, isStorybookVersionLessThan } from '../storybook/helpers';
14
14
  import { isShuttingDown, LOCALHOST_REGEXP, runSequence } from '../utils';
15
- const storybookRootID = isStorybookVersionLessThan(7) ? 'root' : 'storybook-root';
15
+ const storybookRootID = 'storybook-root';
16
16
  const DOCKER_INTERNAL = 'host.docker.internal';
17
17
  let browserLogger = logger;
18
18
  let browserName = '';
19
19
  let browser = null;
20
20
  let creeveyServerHost = null;
21
-
22
21
  function getSessionData(grid, sessionId = '') {
23
22
  const gridUrl = new URL(grid);
24
23
  gridUrl.pathname = `/host/${sessionId}`;
@@ -26,7 +25,6 @@ function getSessionData(grid, sessionId = '') {
26
25
  if (res.statusCode !== 200) {
27
26
  return reject(new Error(`Couldn't get session data for ${sessionId}. Status code: ${res.statusCode ?? 'Unknown'}`));
28
27
  }
29
-
30
28
  let data = '';
31
29
  res.setEncoding('utf8');
32
30
  res.on('data', chunk => data += chunk);
@@ -39,44 +37,36 @@ function getSessionData(grid, sessionId = '') {
39
37
  });
40
38
  }));
41
39
  }
42
-
43
40
  function getAddresses() {
44
41
  return [DOCKER_INTERNAL].concat(...Object.values(networkInterfaces()).filter(isDefined).map(network => network.filter(info => info.family == 'IPv4').map(info => info.address)));
45
42
  }
46
-
47
43
  async function resolveStorybookUrl(storybookUrl, checkUrl) {
48
44
  browserLogger.debug('Resolving storybook url');
49
45
  const addresses = getAddresses();
50
-
51
46
  for (const ip of addresses) {
52
47
  const resolvedUrl = storybookUrl.replace(LOCALHOST_REGEXP, ip);
53
48
  browserLogger.debug(`Checking storybook availability on ${chalk.magenta(resolvedUrl)}`);
54
-
55
49
  if (await checkUrl(resolvedUrl)) {
56
50
  browserLogger.debug(`Resolved storybook url ${chalk.magenta(resolvedUrl)}`);
57
51
  return resolvedUrl;
58
52
  }
59
53
  }
60
-
61
54
  const error = new Error('Please specify `storybookUrl` with IP address that accessible from remote browser');
62
55
  error.name = 'ResolveUrlError';
63
56
  throw error;
64
57
  }
65
-
66
58
  async function openUrlAndWaitForPageSource(browser, url, predicate) {
67
59
  let source = '';
68
60
  await browser.get(url);
69
-
70
61
  do {
71
62
  try {
72
63
  source = await browser.getPageSource();
73
- } catch (_) {// NOTE: Firefox can raise exception "curContainer.frame.document.documentElement is null"
64
+ } catch (_) {
65
+ // NOTE: Firefox can raise exception "curContainer.frame.document.documentElement is null"
74
66
  }
75
67
  } while (predicate(source));
76
-
77
68
  return source;
78
69
  }
79
-
80
70
  function getUrlChecker(browser) {
81
71
  return async url => {
82
72
  try {
@@ -84,13 +74,14 @@ function getUrlChecker(browser) {
84
74
  browserLogger.debug(`Opening ${chalk.magenta('about:blank')} page`);
85
75
  await openUrlAndWaitForPageSource(browser, 'about:blank', source => !source.includes('<body></body>'));
86
76
  browserLogger.debug(`Opening ${chalk.magenta(url)} and checking the page source`);
87
- const source = await openUrlAndWaitForPageSource(browser, url, // NOTE: IE11 can return only `head` without body
88
- source => source.length == 0 || !/<body([^>]*>).+<\/body>/s.test(source)); // NOTE: This is the most optimal way to check if we in storybook or not
77
+ const source = await openUrlAndWaitForPageSource(browser, url,
78
+ // NOTE: IE11 can return only `head` without body
79
+ source => source.length == 0 || !/<body([^>]*>).+<\/body>/s.test(source));
80
+ // NOTE: This is the most optimal way to check if we in storybook or not
89
81
  // We don't use any page load strategies except `NONE`
90
82
  // because other add significant delay and some of them don't work in earlier chrome versions
91
83
  // Browsers always load page successful even it's failed
92
84
  // So we just check `root` element
93
-
94
85
  browserLogger.debug(`Checking ${chalk.cyan(`#${storybookRootID}`)} existence on ${chalk.magenta(url)}`);
95
86
  return source.includes(`id="${storybookRootID}"`);
96
87
  } catch (error) {
@@ -98,49 +89,35 @@ function getUrlChecker(browser) {
98
89
  }
99
90
  };
100
91
  }
101
-
102
92
  async function waitForStorybook(browser) {
103
93
  browserLogger.debug('Waiting for `setStories` event to make sure that storybook is initiated');
104
94
  let wait = true;
105
95
  let isTimeout = false;
106
- const Events = await importStorybookCoreEvents();
107
96
  const initiateTimeout = setTimeout(() => {
108
97
  wait = false;
109
98
  isTimeout = true;
110
99
  }, 60000);
111
-
112
100
  while (wait !== false) {
113
- if (isStorybookVersionLessThan(7)) {
114
- wait = await browser.executeAsyncScript(function (SET_STORIES, callback) {
115
- if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined') return callback(true);
116
- if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_STORIES) == undefined) return callback(true);
117
- return callback(false);
118
- }, Events.SET_STORIES);
119
- } else {
120
- try {
121
- wait = await browser.executeScript(function (SET_GLOBALS) {
122
- if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined') return true;
123
- if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined) return true;
124
- return false;
125
- }, Events.SET_GLOBALS);
126
- } catch (e) {
127
- browserLogger.debug('An error has been catched during the script: ', e);
128
- }
101
+ try {
102
+ wait = await browser.executeScript(function (SET_GLOBALS) {
103
+ if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined') return true;
104
+ if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined) return true;
105
+ return false;
106
+ }, SET_GLOBALS);
107
+ } catch (e) {
108
+ browserLogger.debug('An error has been caught during the script: ', e);
129
109
  }
130
-
131
110
  if (!wait) clearTimeout(initiateTimeout);
132
111
  }
133
-
134
112
  if (isTimeout) throw new Error('Failed to wait `setStories` event');
135
113
  }
136
-
137
114
  async function resetMousePosition(browser) {
138
115
  var _await$browser$getCap, _await$browser$getCap2;
139
-
140
116
  browserLogger.debug('Resetting mouse position to the top-left corner');
141
117
  const browserName = (await browser.getCapabilities()).getBrowserName();
142
- 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
118
+ 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('.')) ?? [];
143
119
 
120
+ // NOTE Reset mouse position to support keweb selenium grid browser versions
144
121
  if (browserName == 'chrome' && browserVersion == '70') {
145
122
  const {
146
123
  top,
@@ -155,8 +132,8 @@ async function resetMousePosition(browser) {
155
132
  width: bodyRect.width,
156
133
  height: bodyRect.height
157
134
  };
158
- }); // NOTE Bridge mode doesn't support `Origin.VIEWPORT`, move mouse relative
159
-
135
+ });
136
+ // NOTE Bridge mode doesn't support `Origin.VIEWPORT`, move mouse relative
160
137
  await browser.actions({
161
138
  bridge: true
162
139
  }).move({
@@ -180,7 +157,6 @@ async function resetMousePosition(browser) {
180
157
  }).perform();
181
158
  }
182
159
  }
183
-
184
160
  async function resizeViewport(browser, viewport) {
185
161
  const windowRect = await browser.manage().window().getRect();
186
162
  const {
@@ -200,7 +176,6 @@ async function resizeViewport(browser, viewport) {
200
176
  height: viewport.height + dHeight
201
177
  });
202
178
  }
203
-
204
179
  const getScrollBarWidth = (() => {
205
180
  let scrollBarWidth = null;
206
181
  return async browser => {
@@ -209,33 +184,31 @@ const getScrollBarWidth = (() => {
209
184
  // eslint-disable-next-line no-var
210
185
  var div = document.createElement('div');
211
186
  div.innerHTML = 'a'; // NOTE: In IE clientWidth is 0 if this div is empty.
212
-
213
187
  div.style.overflowY = 'scroll';
214
- document.body.appendChild(div); // eslint-disable-next-line no-var
215
-
188
+ document.body.appendChild(div);
189
+ // eslint-disable-next-line no-var
216
190
  var widthDiff = div.offsetWidth - div.clientWidth;
217
191
  document.body.removeChild(div);
218
192
  return widthDiff;
219
193
  });
220
194
  return scrollBarWidth;
221
195
  };
222
- })(); // NOTE Firefox and Safari take viewport screenshot without scrollbars
223
-
196
+ })();
224
197
 
198
+ // NOTE Firefox and Safari take viewport screenshot without scrollbars
225
199
  async function hasScrollBar(browser) {
226
200
  var _await$browser$getCap3;
227
-
228
201
  const browserName = (await browser.getCapabilities()).getBrowserName();
229
202
  const [browserVersion] = ((_await$browser$getCap3 = (await browser.getCapabilities()).getBrowserVersion()) === null || _await$browser$getCap3 === void 0 ? void 0 : _await$browser$getCap3.split('.')) ?? [];
230
- return browserName != 'Safari' && // NOTE This need to work with keweb selenium grid
203
+ return browserName != 'Safari' &&
204
+ // NOTE This need to work with keweb selenium grid
231
205
  !(browserName == 'firefox' && browserVersion == '61');
232
206
  }
233
-
234
207
  async function takeCompositeScreenshot(browser, windowRect, elementRect) {
235
208
  const screens = [];
236
209
  const isScreenshotWithoutScrollBar = !(await hasScrollBar(browser));
237
- const scrollBarWidth = await getScrollBarWidth(browser); // NOTE Sometimes viewport has been scrolled somewhere
238
-
210
+ const scrollBarWidth = await getScrollBarWidth(browser);
211
+ // NOTE Sometimes viewport has been scrolled somewhere
239
212
  const normalizedElementRect = {
240
213
  left: elementRect.left - windowRect.left,
241
214
  right: elementRect.left + elementRect.width - windowRect.left,
@@ -250,7 +223,6 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
250
223
  const rows = Math.ceil(elementRect.height / viewportHeight);
251
224
  const xOffset = Math.round(isFitHorizontally ? normalizedElementRect.left : Math.max(0, cols * viewportWidth - elementRect.width));
252
225
  const yOffset = Math.round(isFitVertically ? normalizedElementRect.top : Math.max(0, rows * viewportHeight - elementRect.height));
253
-
254
226
  for (let row = 0; row < rows; row += 1) {
255
227
  for (let col = 0; col < cols; col += 1) {
256
228
  const dx = Math.min(viewportWidth * col + normalizedElementRect.left, Math.max(0, normalizedElementRect.right - viewportWidth));
@@ -261,13 +233,11 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
261
233
  screens.push(await browser.takeScreenshot());
262
234
  }
263
235
  }
264
-
265
236
  const images = screens.map(s => Buffer.from(s, 'base64')).map(b => PNG.sync.read(b));
266
237
  const compositeImage = new PNG({
267
238
  width: Math.round(elementRect.width),
268
239
  height: Math.round(elementRect.height)
269
240
  });
270
-
271
241
  for (let y = 0; y < compositeImage.height; y += 1) {
272
242
  for (let x = 0; x < compositeImage.width; x += 1) {
273
243
  const col = Math.floor(x / viewportWidth);
@@ -276,8 +246,10 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
276
246
  const isLastRow = rows - row == 1;
277
247
  const scrollOffset = isFitVertically || isScreenshotWithoutScrollBar ? 0 : scrollBarWidth;
278
248
  const i = (y * compositeImage.width + x) * 4;
279
- const j = // NOTE compositeImage(x, y) => image(x, y)
280
- (y % viewportHeight * (viewportWidth + scrollOffset) + x % viewportWidth) * 4 + ( // NOTE Offset for last row/col image
249
+ const j =
250
+ // NOTE compositeImage(x, y) => image(x, y)
251
+ (y % viewportHeight * (viewportWidth + scrollOffset) + x % viewportWidth) * 4 + (
252
+ // NOTE Offset for last row/col image
281
253
  isLastRow ? yOffset * (viewportWidth + scrollOffset) * 4 : 0) + (isLastCol ? xOffset * 4 : 0);
282
254
  const image = images[row * cols + col];
283
255
  compositeImage.data[i + 0] = image.data[j + 0];
@@ -286,14 +258,11 @@ async function takeCompositeScreenshot(browser, windowRect, elementRect) {
286
258
  compositeImage.data[i + 3] = image.data[j + 3];
287
259
  }
288
260
  }
289
-
290
261
  return PNG.sync.write(compositeImage).toString('base64');
291
262
  }
292
-
293
263
  export async function takeScreenshot(browser, captureElement, ignoreElements) {
294
264
  let screenshot;
295
265
  const ignoreStyles = await insertIgnoreStyles(browser, ignoreElements);
296
-
297
266
  try {
298
267
  if (!captureElement) {
299
268
  browserLogger.debug('Capturing viewport screenshot');
@@ -304,10 +273,10 @@ export async function takeScreenshot(browser, captureElement, ignoreElements) {
304
273
  const rects = await browser.executeScript(function (selector) {
305
274
  window.scrollTo(0, 0); // TODO Maybe we should remove same code from `resetMousePosition`
306
275
  // eslint-disable-next-line no-var
307
-
308
276
  var element = document.querySelector(selector);
309
- if (!element) return; // eslint-disable-next-line no-var
277
+ if (!element) return;
310
278
 
279
+ // eslint-disable-next-line no-var
311
280
  var elementRect = element.getBoundingClientRect();
312
281
  return {
313
282
  elementRect: {
@@ -331,17 +300,16 @@ export async function takeScreenshot(browser, captureElement, ignoreElements) {
331
300
  if (!elementRect || !windowRect) throw new Error(`Couldn't find element with selector: '${captureElement}'`);
332
301
  const isFitIntoViewport = elementRect.width + elementRect.left <= windowRect.width && elementRect.height + elementRect.top <= windowRect.height;
333
302
  if (isFitIntoViewport) browserLogger.debug(`Capturing ${chalk.cyan(captureElement)}`);else browserLogger.debug(`Capturing composite screenshot image of ${chalk.cyan(captureElement)}`);
334
- screenshot = isFitIntoViewport ? await browser.findElement(By.css(captureElement)).takeScreenshot() : // TODO pointer-events: none, need to research
303
+ screenshot = isFitIntoViewport ? await browser.findElement(By.css(captureElement)).takeScreenshot() :
304
+ // TODO pointer-events: none, need to research
335
305
  await takeCompositeScreenshot(browser, windowRect, elementRect);
336
306
  browserLogger.debug(`${chalk.cyan(captureElement)} is captured`);
337
307
  }
338
308
  } finally {
339
309
  await removeIgnoreStyles(browser, ignoreStyles);
340
310
  }
341
-
342
311
  return screenshot;
343
312
  }
344
-
345
313
  async function selectStory(browser, {
346
314
  id,
347
315
  kind,
@@ -352,52 +320,46 @@ async function selectStory(browser, {
352
320
  if (typeof window.__CREEVEY_SELECT_STORY__ == 'undefined') {
353
321
  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."]);
354
322
  }
355
-
356
323
  void window.__CREEVEY_SELECT_STORY__(id, kind, name, shouldWaitForReady, callback);
357
324
  }, id, kind, name, waitForReady);
358
325
  const [errorMessage, isCaptureCalled = false] = result ?? [];
359
326
  if (errorMessage) throw new Error(errorMessage);
360
327
  return isCaptureCalled;
361
328
  }
362
-
363
329
  export async function updateStorybookGlobals(browser, globals) {
364
330
  browserLogger.debug('Applying storybook globals');
365
331
  await browser.executeScript(function (globals) {
366
332
  window.__CREEVEY_UPDATE_GLOBALS__(globals);
367
333
  }, globals);
368
334
  }
369
-
370
335
  function appendIframePath(url) {
371
336
  return `${url.replace(/\/$/, '')}/iframe.html`;
372
337
  }
373
-
374
338
  async function openStorybookPage(browser, storybookUrl, resolver) {
375
339
  if (!LOCALHOST_REGEXP.test(storybookUrl)) {
376
340
  return browser === null || browser === void 0 ? void 0 : browser.get(appendIframePath(storybookUrl));
377
341
  }
378
-
379
342
  try {
380
343
  if (resolver) {
381
344
  browserLogger.debug('Resolving storybook url with custom resolver');
382
345
  const resolvedUrl = await resolver();
383
346
  browserLogger.debug(`Resolver storybook url ${resolvedUrl}`);
384
347
  return browser.get(appendIframePath(resolvedUrl));
385
- } // NOTE: getUrlChecker already calls `browser.get` so we don't need another one
386
-
387
-
348
+ }
349
+ // NOTE: getUrlChecker already calls `browser.get` so we don't need another one
388
350
  return void (await resolveStorybookUrl(appendIframePath(storybookUrl), getUrlChecker(browser)));
389
351
  } catch (error) {
390
352
  browserLogger.error('Failed to resolve storybook URL', error instanceof Error ? error.message : '');
391
353
  throw error;
392
354
  }
393
355
  }
394
-
395
356
  async function resolveCreeveyHost(browser, port) {
396
357
  if (creeveyServerHost != null) return creeveyServerHost;
397
358
  const addresses = getAddresses();
398
359
  creeveyServerHost = await browser.executeAsyncScript(function (hosts, port, callback) {
399
360
  void Promise.all(hosts.map(function (host) {
400
- return Promise.race([// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
361
+ return Promise.race([
362
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
401
363
  fetch('http://' + host + ':' + port + '/ping').then(function (response) {
402
364
  return response.text();
403
365
  }), new Promise((_resolve, reject) => {
@@ -416,7 +378,6 @@ async function resolveCreeveyHost(browser, port) {
416
378
  if (creeveyServerHost == null) throw new Error("Can't reach creevey server from a browser");
417
379
  return creeveyServerHost;
418
380
  }
419
-
420
381
  export async function loadStoriesFromBrowser() {
421
382
  if (!browser) throw new Error("Can't get stories from browser if webdriver isn't connected");
422
383
  const stories = await browser.executeAsyncScript(function (callback) {
@@ -438,22 +399,22 @@ export async function getBrowser(config, options) {
438
399
  ...userCapabilities
439
400
  } = browserConfig;
440
401
  void limit;
441
- const realAddress = address; // TODO Define some capabilities explicitly and define typings
402
+ const realAddress = address;
442
403
 
443
- const capabilities = new Capabilities({ ...userCapabilities,
404
+ // TODO Define some capabilities explicitly and define typings
405
+ const capabilities = new Capabilities({
406
+ ...userCapabilities,
444
407
  pageLoadStrategy: PageLoadStrategy.NONE
445
408
  });
446
409
  subscribeOn('shutdown', () => {
447
410
  var _browser;
448
-
449
- (_browser = browser) === null || _browser === void 0 ? void 0 : _browser.quit().finally(() => // eslint-disable-next-line no-process-exit
411
+ (_browser = browser) === null || _browser === void 0 || _browser.quit().finally(() =>
412
+ // eslint-disable-next-line no-process-exit
450
413
  process.exit());
451
414
  browser = null;
452
415
  });
453
-
454
416
  try {
455
417
  var _await$browser$getSes;
456
-
457
418
  const url = new URL(gridUrl);
458
419
  url.username = url.username ? '********' : '';
459
420
  url.password = url.password ? '********' : '';
@@ -461,7 +422,6 @@ export async function getBrowser(config, options) {
461
422
  browser = await new Builder().usingServer(gridUrl).withCapabilities(capabilities).build();
462
423
  const sessionId = (_await$browser$getSes = await browser.getSession()) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
463
424
  let browserHost = '';
464
-
465
425
  try {
466
426
  const {
467
427
  Name
@@ -470,7 +430,6 @@ export async function getBrowser(config, options) {
470
430
  } catch (_) {
471
431
  /* noop */
472
432
  }
473
-
474
433
  browserLogger.debug(`(${browserName}) Connected successful with ${[chalk.green(browserHost), chalk.magenta(sessionId)].filter(Boolean).join(':')}`);
475
434
  browserLogger = getLogger(sessionId);
476
435
  prefix.apply(browserLogger, {
@@ -478,11 +437,9 @@ export async function getBrowser(config, options) {
478
437
  const levelColor = colors[level.toUpperCase()];
479
438
  return `[${browserName}:${chalk.gray(sessionId)}] ${levelColor(level)} =>`;
480
439
  }
481
-
482
440
  });
483
441
  await runSequence([() => {
484
442
  var _browser2;
485
-
486
443
  return (_browser2 = browser) === null || _browser2 === void 0 ? void 0 : _browser2.manage().setTimeouts({
487
444
  pageLoad: 5000,
488
445
  script: 60000
@@ -490,25 +447,20 @@ export async function getBrowser(config, options) {
490
447
  }, () => viewport && browser && resizeViewport(browser, viewport), () => browser && openStorybookPage(browser, realAddress, config.resolveStorybookUrl), () => browser && waitForStorybook(browser)], () => !isShuttingDown.current);
491
448
  } catch (originalError) {
492
449
  var _browser4;
493
-
494
450
  if (isShuttingDown.current) {
495
451
  var _browser3;
496
-
497
- (_browser3 = browser) === null || _browser3 === void 0 ? void 0 : _browser3.quit().catch(noop);
452
+ (_browser3 = browser) === null || _browser3 === void 0 || _browser3.quit().catch(noop);
498
453
  browser = null;
499
454
  return null;
500
455
  }
501
-
502
456
  if (originalError instanceof Error && originalError.name == 'ResolveUrlError') throw originalError;
503
457
  const error = new Error(`Can't load storybook root page by URL ${(await ((_browser4 = browser) === null || _browser4 === void 0 ? void 0 : _browser4.getCurrentUrl())) ?? realAddress}`);
504
458
  if (originalError instanceof Error) error.stack = originalError.stack;
505
459
  throw error;
506
460
  }
507
-
508
461
  if (_storybookGlobals) {
509
462
  await updateStorybookGlobals(browser, _storybookGlobals);
510
463
  }
511
-
512
464
  const creeveyHost = await resolveCreeveyHost(browser, options.port);
513
465
  await browser.executeScript(function (workerId, creeveyHost, creeveyPort) {
514
466
  window.__CREEVEY_WORKER_ID__ = workerId;
@@ -517,22 +469,17 @@ export async function getBrowser(config, options) {
517
469
  }, process.pid, creeveyHost, options.port);
518
470
  return browser;
519
471
  }
520
-
521
472
  async function updateStoryArgs(browser, story, updatedArgs) {
522
- const Events = await importStorybookCoreEvents();
523
473
  await browser.executeAsyncScript(function (storyId, updatedArgs, UPDATE_STORY_ARGS, STORY_RENDERED, callback) {
524
474
  window.__STORYBOOK_ADDONS_CHANNEL__.once(STORY_RENDERED, callback);
525
-
526
475
  window.__STORYBOOK_ADDONS_CHANNEL__.emit(UPDATE_STORY_ARGS, {
527
476
  storyId,
528
477
  updatedArgs
529
478
  });
530
- }, story.id, updatedArgs, Events.UPDATE_STORY_ARGS, Events.STORY_RENDERED);
479
+ }, story.id, updatedArgs, UPDATE_STORY_ARGS, STORY_RENDERED);
531
480
  }
532
-
533
481
  export async function closeBrowser() {
534
482
  if (!browser) return;
535
-
536
483
  try {
537
484
  await browser.quit();
538
485
  } finally {
@@ -540,22 +487,18 @@ export async function closeBrowser() {
540
487
  }
541
488
  }
542
489
  export async function switchStory() {
543
- var _this$currentTest, _this$currentTest$ctx;
544
-
490
+ var _this$currentTest;
545
491
  let testOrSuite = this.currentTest;
546
492
  if (!testOrSuite) throw new Error("Can't switch story, because test context doesn't have 'currentTest' field");
547
493
  this.testScope.length = 0;
548
494
  this.screenshots.length = 0;
549
495
  this.testScope.push(this.browserName);
550
-
551
496
  while ((_testOrSuite = testOrSuite) !== null && _testOrSuite !== void 0 && _testOrSuite.title) {
552
497
  var _testOrSuite;
553
-
554
498
  this.testScope.push(testOrSuite.title);
555
499
  testOrSuite = testOrSuite.parent;
556
500
  }
557
-
558
- const story = (_this$currentTest = this.currentTest) === null || _this$currentTest === void 0 ? void 0 : (_this$currentTest$ctx = _this$currentTest.ctx) === null || _this$currentTest$ctx === void 0 ? void 0 : _this$currentTest$ctx.story;
501
+ const story = (_this$currentTest = this.currentTest) === null || _this$currentTest === void 0 || (_this$currentTest = _this$currentTest.ctx) === null || _this$currentTest === void 0 ? void 0 : _this$currentTest.story;
559
502
  if (!story) throw new Error(`Current test '${this.testScope.join('/')}' context doesn't have 'story' field`);
560
503
  const {
561
504
  id,
@@ -574,11 +517,8 @@ export async function switchStory() {
574
517
  configurable: true,
575
518
  get: () => this.browser.findElement(By.css(captureElement))
576
519
  });else Reflect.deleteProperty(this, 'captureElement');
577
-
578
520
  this.takeScreenshot = () => takeScreenshot(this.browser, captureElement, ignoreElements);
579
-
580
521
  this.updateStoryArgs = updatedArgs => updateStoryArgs(this.browser, story, updatedArgs);
581
-
582
522
  this.testScope.reverse();
583
523
  let storyPlayResolver;
584
524
  let waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
@@ -609,17 +549,14 @@ export async function switchStory() {
609
549
  kind,
610
550
  name
611
551
  }, waitForReady);
612
-
613
552
  if (isCaptureCalled) {
614
553
  while (!(await waitForComplete)) {
615
554
  waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
616
555
  }
617
556
  }
618
-
619
557
  unsubscribe();
620
558
  browserLogger.debug(`Story ${chalk.magenta(id)} ready for capturing`);
621
559
  }
622
-
623
560
  async function insertIgnoreStyles(browser, ignoreElements) {
624
561
  const ignoreSelectors = Array.prototype.concat(ignoreElements).filter(Boolean);
625
562
  if (!ignoreSelectors.length) return null;
@@ -628,7 +565,6 @@ async function insertIgnoreStyles(browser, ignoreElements) {
628
565
  return window.__CREEVEY_INSERT_IGNORE_STYLES__(ignoreSelectors);
629
566
  }, ignoreSelectors);
630
567
  }
631
-
632
568
  async function removeIgnoreStyles(browser, ignoreStyles) {
633
569
  if (ignoreStyles) {
634
570
  browserLogger.debug('Revert hiding ignored elements');
@@ -10,7 +10,6 @@ import { chmod, exec } from 'shelljs';
10
10
  const mkdirAsync = promisify(mkdir);
11
11
  const writeFileAsync = promisify(writeFile);
12
12
  const copyFileAsync = promisify(copyFile);
13
-
14
13
  async function createSelenoidConfig(browsers, {
15
14
  useDocker
16
15
  }) {
@@ -39,7 +38,6 @@ async function createSelenoidConfig(browsers, {
39
38
  await writeFileAsync(path.join(selenoidConfigDir, 'browsers.json'), JSON.stringify(selenoidConfig));
40
39
  return selenoidConfigDir;
41
40
  }
42
-
43
41
  async function downloadSelenoidBinary(destination) {
44
42
  const platformNameMapping = {
45
43
  darwin: 'selenoid_darwin_amd64',
@@ -61,14 +59,11 @@ async function downloadSelenoidBinary(destination) {
61
59
  name
62
60
  }) => platformNameMapping[process.platform] == name) ?? {};
63
61
  if (existsSync(destination) && lstatSync(destination).size == binarySize) return;
64
-
65
62
  if (!downloadUrl) {
66
63
  throw new Error(`Couldn't get download url for selenoid binary. Please download it manually from "https://github.com/aerokube/selenoid/releases/latest" and define "selenoidPath" option in the Creevey config`);
67
64
  }
68
-
69
65
  return downloadBinary(downloadUrl, destination);
70
66
  }
71
-
72
67
  export async function startSelenoidStandalone(config, debug) {
73
68
  config.gridUrl = 'http://localhost:4444/wd/hub';
74
69
  if (cluster.isWorker) return;
@@ -77,32 +72,27 @@ export async function startSelenoidStandalone(config, debug) {
77
72
  useDocker: false
78
73
  });
79
74
  const binaryPath = path.join(selenoidConfigDir, process.platform == 'win32' ? 'selenoid.exe' : 'selenoid');
80
-
81
75
  if (config.selenoidPath) {
82
76
  await copyFileAsync(path.resolve(config.selenoidPath), binaryPath);
83
77
  } else {
84
78
  await downloadSelenoidBinary(binaryPath);
85
- } // TODO Download browser webdrivers
86
-
79
+ }
87
80
 
81
+ // TODO Download browser webdrivers
88
82
  try {
89
83
  if (process.platform != 'win32') chmod('+x', binaryPath);
90
84
  } catch (_) {
91
85
  /* noop */
92
86
  }
93
-
94
87
  const selenoidProcess = exec(`${binaryPath} -conf ./browsers.json -disable-docker`, {
95
88
  async: true,
96
89
  cwd: selenoidConfigDir
97
90
  });
98
-
99
91
  if (debug) {
100
92
  var _selenoidProcess$stdo, _selenoidProcess$stde;
101
-
102
- (_selenoidProcess$stdo = selenoidProcess.stdout) === null || _selenoidProcess$stdo === void 0 ? void 0 : _selenoidProcess$stdo.pipe(process.stdout);
103
- (_selenoidProcess$stde = selenoidProcess.stderr) === null || _selenoidProcess$stde === void 0 ? void 0 : _selenoidProcess$stde.pipe(process.stderr);
93
+ (_selenoidProcess$stdo = selenoidProcess.stdout) === null || _selenoidProcess$stdo === void 0 || _selenoidProcess$stdo.pipe(process.stdout);
94
+ (_selenoidProcess$stde = selenoidProcess.stderr) === null || _selenoidProcess$stde === void 0 || _selenoidProcess$stde.pipe(process.stderr);
104
95
  }
105
-
106
96
  subscribeOn('shutdown', () => selenoidProcess.kill());
107
97
  }
108
98
  export async function startSelenoidContainer(config, debug) {
@@ -123,13 +113,12 @@ export async function startSelenoidContainer(config, debug) {
123
113
  auth: config.dockerAuth,
124
114
  platform: config.dockerImagePlatform
125
115
  };
126
-
127
116
  if (config.pullImages) {
128
117
  await pullImages([selenoidImage], pullOptions);
129
118
  await pullImages(images, pullOptions);
130
- } // TODO Allow pass custom options
131
-
119
+ }
132
120
 
121
+ // TODO Allow pass custom options
133
122
  const selenoidOptions = {
134
123
  ExposedPorts: {
135
124
  '4444/tcp': {}