creevey 0.9.0-beta.13 → 0.9.0-beta.15

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