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
@@ -0,0 +1,34 @@
1
+ /*
2
+ object-assign
3
+ (c) Sindre Sorhus
4
+ @license MIT
5
+ */
6
+
7
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
8
+
9
+ /** @license React v0.20.2
10
+ * scheduler.production.min.js
11
+ *
12
+ * Copyright (c) Facebook, Inc. and its affiliates.
13
+ *
14
+ * This source code is licensed under the MIT license found in the
15
+ * LICENSE file in the root directory of this source tree.
16
+ */
17
+
18
+ /** @license React v17.0.2
19
+ * react-dom.production.min.js
20
+ *
21
+ * Copyright (c) Facebook, Inc. and its affiliates.
22
+ *
23
+ * This source code is licensed under the MIT license found in the
24
+ * LICENSE file in the root directory of this source tree.
25
+ */
26
+
27
+ /** @license React v17.0.2
28
+ * react.production.min.js
29
+ *
30
+ * Copyright (c) Facebook, Inc. and its affiliates.
31
+ *
32
+ * This source code is licensed under the MIT license found in the
33
+ * LICENSE file in the root directory of this source tree.
34
+ */
@@ -6,7 +6,6 @@ import { emitWorkerMessage } from './server/messages';
6
6
  import { isShuttingDown, shutdown, shutdownWorkers } from './server/utils';
7
7
  import { setDefaultLevel, levels } from 'loglevel';
8
8
  import { logger } from './server/logger';
9
-
10
9
  function shutdownOnException(reason) {
11
10
  if (isShuttingDown.current) return;
12
11
  const error = reason instanceof Error ? reason.stack ?? reason.message : reason;
@@ -20,14 +19,13 @@ function shutdownOnException(reason) {
20
19
  });
21
20
  if (cluster.isPrimary && !isShuttingDown.current) void shutdownWorkers();
22
21
  }
23
-
24
22
  process.on('uncaughtException', shutdownOnException);
25
23
  process.on('unhandledRejection', shutdownOnException);
26
24
  if (cluster.isWorker) process.on('SIGINT', noop);
27
25
  if (cluster.isPrimary) process.on('SIGINT', shutdown);
28
26
  const argv = minimist(process.argv.slice(2), {
29
27
  string: ['browser', 'config', 'reporter', 'reportDir', 'screenDir'],
30
- boolean: ['debug', 'ui', 'saveReport', 'webpack', 'tests'],
28
+ boolean: ['debug', 'ui', 'saveReport', 'tests'],
31
29
  default: {
32
30
  port: 3000,
33
31
  saveReport: true
@@ -36,13 +34,12 @@ const argv = minimist(process.argv.slice(2), {
36
34
  port: 'p',
37
35
  config: 'c',
38
36
  debug: 'd',
39
- update: 'u',
40
- extract: 'e'
37
+ update: 'u'
41
38
  }
42
- }); // @ts-expect-error: define log level for storybook
39
+ });
43
40
 
41
+ // @ts-expect-error: define log level for storybook
44
42
  global.LOGLEVEL = argv.debug ? 'debug' : 'warn';
45
-
46
43
  if (argv.debug) {
47
44
  logger.setDefaultLevel(levels.DEBUG);
48
45
  setDefaultLevel(levels.DEBUG);
@@ -50,5 +47,4 @@ if (argv.debug) {
50
47
  logger.setDefaultLevel(levels.INFO);
51
48
  setDefaultLevel(levels.INFO);
52
49
  }
53
-
54
50
  void creevey(argv);
package/lib/esm/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './types';
2
2
  export { loadStories as browserStoriesProvider } from './server/storybook/providers/browser';
3
- export { loadStories as nodejsStoriesProvider } from './server/storybook/providers/nodejs';
4
3
  export { loadStories as hybridStoriesProvider } from './server/storybook/providers/hybrid';
5
4
  export * from './server/testsFiles/parser';
@@ -1,13 +1,10 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { isCSFv3Enabled, storybookDirRef } from './storybook/helpers';
4
- import { loadStories as nodejsStoriesProvider } from './storybook/providers/nodejs';
5
3
  import { loadStories as browserStoriesProvider } from './storybook/providers/browser';
6
4
  import { isDefined } from '../types';
7
5
  export const defaultBrowser = 'chrome';
8
6
  export const defaultConfig = {
9
7
  useDocker: true,
10
- useWebpackToExtractTests: false,
11
8
  dockerImage: 'aerokube/selenoid:latest-release',
12
9
  dockerImagePlatform: '',
13
10
  pullImages: true,
@@ -15,7 +12,6 @@ export const defaultConfig = {
15
12
  storybookUrl: 'http://localhost:6006',
16
13
  screenDir: path.resolve('images'),
17
14
  reportDir: path.resolve('report'),
18
- storybookDir: path.resolve('.storybook'),
19
15
  maxRetries: 0,
20
16
  diffOptions: {
21
17
  threshold: 0,
@@ -28,7 +24,6 @@ export const defaultConfig = {
28
24
  babelOptions: _ => _,
29
25
  testsRegex: /\.creevey\.(t|j)s$/
30
26
  };
31
-
32
27
  function normalizeBrowserConfig(name, config) {
33
28
  if (typeof config == 'boolean') return {
34
29
  browserName: name
@@ -38,33 +33,31 @@ function normalizeBrowserConfig(name, config) {
38
33
  };
39
34
  return config;
40
35
  }
41
-
42
36
  function resolveConfigPath(configPath) {
43
37
  const rootDir = process.cwd();
44
38
  const configDir = path.resolve('.creevey');
45
-
46
39
  if (isDefined(configPath)) {
47
40
  configPath = path.resolve(configPath);
48
41
  } else if (fs.existsSync(configDir)) {
49
- configPath = path.join(configDir, 'config'); // TODO We already find file with extension, why not use it?
42
+ configPath = path.join(configDir, 'config');
43
+ // TODO We already find file with extension, why not use it?
50
44
  } else if (fs.readdirSync(rootDir).find(filename => filename.startsWith('creevey.config'))) {
51
45
  configPath = path.join(rootDir, 'creevey.config');
52
46
  }
53
-
54
47
  return configPath;
55
48
  }
56
-
57
49
  export async function readConfig(options) {
58
50
  const configPath = resolveConfigPath(options.config);
59
- const userConfig = { ...defaultConfig
51
+ const userConfig = {
52
+ ...defaultConfig
60
53
  };
61
54
  if (isDefined(configPath)) Object.assign(userConfig, (await import(configPath)).default);
62
- storybookDirRef.current = userConfig.storybookDir;
63
- if (!userConfig.storiesProvider) userConfig.storiesProvider = (await isCSFv3Enabled()) ? browserStoriesProvider : nodejsStoriesProvider;
55
+ if (!userConfig.storiesProvider) userConfig.storiesProvider = browserStoriesProvider;
64
56
  if (options.failFast != undefined) userConfig.failFast = Boolean(options.failFast);
65
57
  if (options.reportDir) userConfig.reportDir = path.resolve(options.reportDir);
66
- if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir); // NOTE: Hack to pass typescript checking
58
+ if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir);
67
59
 
60
+ // NOTE: Hack to pass typescript checking
68
61
  const config = userConfig;
69
62
  Object.entries(config.browsers).forEach(([browser, browserConfig]) => config.browsers[browser] = normalizeBrowserConfig(browser, browserConfig));
70
63
  return config;
@@ -7,14 +7,11 @@ import { Writable } from 'stream';
7
7
  import ora from 'ora';
8
8
  import { logger } from './logger';
9
9
  const docker = new Dockerode();
10
-
11
10
  class DevNull extends Writable {
12
11
  _write(_chunk, _encoding, callback) {
13
12
  setImmediate(callback);
14
13
  }
15
-
16
14
  }
17
-
18
15
  export async function pullImages(images, {
19
16
  auth,
20
17
  platform
@@ -23,30 +20,27 @@ export async function pullImages(images, {
23
20
  if (auth) args.authconfig = auth;
24
21
  if (platform) args.platform = platform;
25
22
  logger.info('Pull docker images');
26
-
27
23
  for (const image of images) {
28
24
  await new Promise((resolve, reject) => {
29
- const spinner = ora(`${image}: Pull start`).start(); // eslint-disable-next-line @typescript-eslint/no-floating-promises
25
+ const spinner = ora(`${image}: Pull start`).start();
30
26
 
27
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
31
28
  docker.pull(image, args, function (pullError, stream) {
32
29
  if (pullError) {
33
30
  spinner.fail();
34
31
  return reject(pullError);
35
- } // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
36
-
32
+ }
37
33
 
34
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
38
35
  docker.modem.followProgress(stream, onFinished, onProgress);
39
-
40
36
  function onFinished(error) {
41
37
  if (error) {
42
38
  spinner.fail();
43
39
  return reject(error);
44
40
  }
45
-
46
41
  spinner.succeed(`${image}: Pull complete`);
47
42
  resolve();
48
43
  }
49
-
50
44
  function onProgress(event) {
51
45
  if (!/^[a-z0-9]{12}$/i.test(event.id)) return;
52
46
  spinner.text = `${image}: [${event.id}] ${event.status} ${event.progress ? `${event.progress}` : ''}`;
@@ -63,13 +57,11 @@ export async function runImage(image, args, options, debug) {
63
57
  }
64
58
  })).map(async info => {
65
59
  const container = docker.getContainer(info.Id);
66
-
67
60
  try {
68
61
  await container.stop();
69
62
  } catch (_) {
70
63
  /* noop */
71
64
  }
72
-
73
65
  await container.remove();
74
66
  }));
75
67
  const hub = docker.run(image, args, debug ? process.stdout : new DevNull(), options, error => {
@@ -1,7 +1,8 @@
1
1
  import cluster from 'cluster';
2
2
  import { readConfig, defaultBrowser } from './config';
3
- import { logger } from './logger'; // NOTE: Impure function, mutate config by adding gridUrl prop
3
+ import { logger } from './logger';
4
4
 
5
+ // NOTE: Impure function, mutate config by adding gridUrl prop
5
6
  async function startWebdriverServer(config, options) {
6
7
  if (config.useDocker) {
7
8
  return (await import('./docker')).default(config, options.browser, async () => (await import('./selenium/selenoid')).startSelenoidContainer(config, options.debug));
@@ -9,54 +10,39 @@ async function startWebdriverServer(config, options) {
9
10
  return (await import('./selenium/selenoid')).startSelenoidStandalone(config, options.debug);
10
11
  }
11
12
  }
12
-
13
13
  export default async function (options) {
14
14
  const config = await readConfig(options);
15
15
  const {
16
16
  browser = defaultBrowser,
17
- extract,
18
17
  tests,
19
18
  update,
20
- webpack,
21
19
  ui,
22
20
  port
23
21
  } = options;
24
- if (!config) return; // NOTE: We don't need docker nor selenoid for webpack or update options
22
+ if (!config) return;
25
23
 
24
+ // NOTE: We don't need docker nor selenoid for webpack or update options
26
25
  if (!(config.gridUrl || Object.values(config.browsers).every(({
27
26
  gridUrl
28
- }) => gridUrl)) && !extract && !webpack && !tests && !update) {
27
+ }) => gridUrl)) && !tests && !update) {
29
28
  await startWebdriverServer(config, options);
30
29
  }
31
-
32
30
  switch (true) {
33
- case Boolean(extract) || tests:
34
- {
35
- return (await import('./extract')).default(config, options);
36
- }
37
-
38
31
  case Boolean(update):
39
32
  {
40
33
  return (await import('./update')).default(config, typeof update == 'string' ? update : undefined);
41
34
  }
42
-
43
- case webpack:
44
- {
45
- logger.info('Starting Webpack Compiler');
46
- return (await import('./loaders/webpack/compile')).default(config, options);
47
- }
48
-
49
35
  case cluster.isPrimary:
50
36
  {
51
37
  logger.info('Starting Master Process');
52
38
  const resolveApi = (await import('./master/server')).default(config.reportDir, port, ui);
53
39
  return (await import('./master')).default(config, options, resolveApi);
54
40
  }
55
-
56
41
  default:
57
42
  {
58
43
  logger.info(`Starting Worker for ${browser}`);
59
- return (await import('./worker')).default(config, { ...options,
44
+ return (await import('./worker')).default(config, {
45
+ ...options,
60
46
  browser
61
47
  });
62
48
  }
@@ -15,6 +15,5 @@ prefix.apply(Logger, {
15
15
  const levelColor = colors[level.toUpperCase()];
16
16
  return `[${name}:${chalk.gray(process.pid)}] ${levelColor(level)} =>`;
17
17
  }
18
-
19
18
  });
20
19
  export const logger = Logger.getLogger('Creevey');
@@ -1,6 +1,5 @@
1
1
  import WebSocket from 'ws';
2
2
  import { logger } from '../logger';
3
-
4
3
  function broadcast(wss, message) {
5
4
  wss.clients.forEach(ws => {
6
5
  if (ws.readyState === WebSocket.OPEN) {
@@ -8,7 +7,6 @@ function broadcast(wss, message) {
8
7
  }
9
8
  });
10
9
  }
11
-
12
10
  export default function creeveyApi(runner) {
13
11
  return {
14
12
  subscribe(wss) {
@@ -17,15 +15,12 @@ export default function creeveyApi(runner) {
17
15
  payload
18
16
  }));
19
17
  },
20
-
21
18
  handleMessage(ws, message) {
22
19
  if (typeof message != 'string') {
23
20
  logger.info('unhandled message', message);
24
21
  return;
25
22
  }
26
-
27
23
  const command = JSON.parse(message);
28
-
29
24
  switch (command.type) {
30
25
  case 'status':
31
26
  {
@@ -35,19 +30,16 @@ export default function creeveyApi(runner) {
35
30
  }));
36
31
  return;
37
32
  }
38
-
39
33
  case 'start':
40
34
  {
41
35
  runner.start(command.payload);
42
36
  return;
43
37
  }
44
-
45
38
  case 'stop':
46
39
  {
47
40
  runner.stop();
48
41
  return;
49
42
  }
50
-
51
43
  case 'approve':
52
44
  {
53
45
  void runner.approve(command.payload);
@@ -55,6 +47,5 @@ export default function creeveyApi(runner) {
55
47
  }
56
48
  }
57
49
  }
58
-
59
50
  };
60
51
  }
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { writeFileSync, copyFile, readdir, mkdir, existsSync } from 'fs';
2
+ import { copyFile, readdir, mkdir, existsSync, writeFile } from 'fs';
3
3
  import { promisify } from 'util';
4
4
  import master from './master';
5
5
  import creeveyApi from './api';
@@ -7,10 +7,10 @@ import { isDefined } from '../../types';
7
7
  import { shutdown, shutdownWorkers, testsToImages, readDirRecursive } from '../utils';
8
8
  import { subscribeOn } from '../messages';
9
9
  import { logger } from '../logger';
10
+ const writeFileAsync = promisify(writeFile);
10
11
  const copyFileAsync = promisify(copyFile);
11
12
  const readdirAsync = promisify(readdir);
12
13
  const mkdirAsync = promisify(mkdir);
13
-
14
14
  async function copyStatics(reportDir) {
15
15
  const clientDir = path.join(__dirname, '../../client/web');
16
16
  const files = (await readdirAsync(clientDir, {
@@ -19,12 +19,10 @@ async function copyStatics(reportDir) {
19
19
  await mkdirAsync(reportDir, {
20
20
  recursive: true
21
21
  });
22
-
23
22
  for (const file of files) {
24
23
  await copyFileAsync(path.join(clientDir, file), path.join(reportDir, file));
25
24
  }
26
25
  }
27
-
28
26
  function reportDataModule(data) {
29
27
  return `
30
28
  (function (root, factory) {
@@ -36,44 +34,34 @@ function reportDataModule(data) {
36
34
  }(this, function () { return ${JSON.stringify(data)} }));
37
35
  `;
38
36
  }
39
-
40
37
  function outputUnnecessaryImages(imagesDir, images) {
41
38
  if (!existsSync(imagesDir)) return;
42
39
  const unnecessaryImages = readDirRecursive(imagesDir).map(imagePath => path.posix.relative(imagesDir, imagePath)).filter(imagePath => !images.has(imagePath));
43
-
44
40
  if (unnecessaryImages.length > 0) {
45
41
  logger.warn('We found unnecessary screenshot images, those can be safely removed:\n', unnecessaryImages.join('\n'));
46
42
  }
47
43
  }
48
-
49
44
  export default async function (config, options, resolveApi) {
50
45
  let runner = null;
51
-
52
46
  if (config.hooks.before) {
53
47
  await config.hooks.before();
54
48
  }
55
-
56
49
  subscribeOn('shutdown', () => {
57
50
  var _config$hooks$after, _config$hooks;
58
-
59
51
  return (_config$hooks$after = (_config$hooks = config.hooks).after) === null || _config$hooks$after === void 0 ? void 0 : _config$hooks$after.call(_config$hooks);
60
52
  });
61
53
  process.removeListener('SIGINT', shutdown);
62
54
  process.on('SIGINT', () => {
63
55
  var _runner, _runner2;
64
-
65
- (_runner = runner) === null || _runner === void 0 ? void 0 : _runner.removeAllListeners('stop');
66
-
56
+ (_runner = runner) === null || _runner === void 0 || _runner.removeAllListeners('stop');
67
57
  if ((_runner2 = runner) !== null && _runner2 !== void 0 && _runner2.isRunning) {
68
58
  var _runner4;
69
-
70
59
  // TODO Better handle stop
71
60
  void Promise.race([new Promise(resolve => setTimeout(resolve, 10000)), new Promise(resolve => {
72
61
  var _runner3;
73
-
74
62
  return (_runner3 = runner) === null || _runner3 === void 0 ? void 0 : _runner3.once('stop', resolve);
75
63
  })]).then(() => shutdownWorkers());
76
- (_runner4 = runner) === null || _runner4 === void 0 ? void 0 : _runner4.stop();
64
+ (_runner4 = runner) === null || _runner4 === void 0 || _runner4.stop();
77
65
  } else {
78
66
  void shutdownWorkers();
79
67
  }
@@ -83,43 +71,38 @@ export default async function (config, options, resolveApi) {
83
71
  debug: options.debug,
84
72
  port: options.port
85
73
  });
86
-
87
74
  if (options.saveReport) {
88
- await copyStatics(config.reportDir);
89
- runner.on('stop', () => {
75
+ runner.on('stop', async () => {
90
76
  var _runner5;
91
-
92
- return writeFileSync(path.join(config.reportDir, 'data.js'), reportDataModule((_runner5 = runner) === null || _runner5 === void 0 ? void 0 : _runner5.status.tests));
77
+ await copyStatics(config.reportDir);
78
+ await writeFileAsync(path.join(config.reportDir, 'data.js'), reportDataModule((_runner5 = runner) === null || _runner5 === void 0 ? void 0 : _runner5.status.tests));
93
79
  });
94
80
  }
95
-
96
81
  if (options.ui) {
97
82
  resolveApi(creeveyApi(runner));
98
83
  logger.info(`Started on http://localhost:${options.port}`);
99
84
  } else {
100
85
  if (Object.values(runner.status.tests).filter(test => test && !test.skip).length == 0) {
101
- logger.warn("Don't have any tests to run"); // eslint-disable-next-line no-process-exit
102
-
86
+ logger.warn("Don't have any tests to run");
87
+ // eslint-disable-next-line no-process-exit
103
88
  void shutdownWorkers().then(() => process.exit());
104
89
  return;
105
90
  }
106
-
107
91
  runner.once('stop', () => {
108
92
  var _runner6;
109
-
110
93
  const tests = Object.values(((_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) ?? {});
111
94
  const isSuccess = tests.filter(isDefined).filter(({
112
95
  skip
113
96
  }) => !skip).every(({
114
97
  status
115
- }) => status == 'success'); // TODO output summary
116
-
98
+ }) => status == 'success');
99
+ // TODO output summary
117
100
  process.exitCode = isSuccess ? 0 : -1;
118
- if (!config.failFast) outputUnnecessaryImages(config.screenDir, testsToImages(tests)); // eslint-disable-next-line no-process-exit
119
-
101
+ if (!config.failFast) outputUnnecessaryImages(config.screenDir, testsToImages(tests));
102
+ // eslint-disable-next-line no-process-exit
120
103
  void shutdownWorkers().then(() => process.exit());
121
- }); // TODO grep
122
-
104
+ });
105
+ // TODO grep
123
106
  runner.start(Object.keys(runner.status.tests));
124
107
  }
125
108
  }
@@ -2,8 +2,6 @@ import path from 'path';
2
2
  import { isDefined } from '../../types';
3
3
  import { loadTestsFromStories, saveTestsJson } from '../stories';
4
4
  import Runner from './runner';
5
- import { startWebpackCompiler } from '../loaders/webpack/start';
6
-
7
5
  function mergeTests(testsWithReports, testsFromStories) {
8
6
  Object.values(testsFromStories).filter(isDefined).forEach(test => {
9
7
  const testWithReport = testsWithReports[test.id];
@@ -15,18 +13,15 @@ function mergeTests(testsWithReports, testsFromStories) {
15
13
  });
16
14
  return testsFromStories;
17
15
  }
18
-
19
16
  export default async function master(config, options) {
20
- if (config.useWebpackToExtractTests) await startWebpackCompiler();
21
17
  const runner = new Runner(config);
22
18
  const reportDataPath = path.join(config.reportDir, 'data.js');
23
19
  let testsFromReport = {};
24
-
25
20
  try {
26
21
  testsFromReport = await import(reportDataPath);
27
- } catch (error) {// Ignore error
22
+ } catch (error) {
23
+ // Ignore error
28
24
  }
29
-
30
25
  await runner.init();
31
26
  const tests = await loadTestsFromStories(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
32
27
  runner.updateTests(testsDiff);
@@ -8,11 +8,9 @@ export default class Pool extends EventEmitter {
8
8
  workers = [];
9
9
  queue = [];
10
10
  forcedStop = false;
11
-
12
11
  get isRunning() {
13
12
  return this.workers.length !== this.freeWorkers.length;
14
13
  }
15
-
16
14
  constructor(config, browser) {
17
15
  super();
18
16
  this.browser = browser;
@@ -20,7 +18,6 @@ export default class Pool extends EventEmitter {
20
18
  this.maxRetries = config.maxRetries;
21
19
  this.config = config.browsers[browser];
22
20
  }
23
-
24
21
  async init() {
25
22
  const poolSize = this.config.limit || 1;
26
23
  this.workers = (await Promise.all(Array.from({
@@ -29,7 +26,6 @@ export default class Pool extends EventEmitter {
29
26
  if (this.workers.length != poolSize) throw new Error(`Can't instantiate workers for ${this.browser} due many errors`);
30
27
  this.workers.forEach(worker => this.exitHandler(worker));
31
28
  }
32
-
33
29
  start(tests) {
34
30
  if (this.isRunning) return false;
35
31
  this.queue = tests.map(({
@@ -43,27 +39,22 @@ export default class Pool extends EventEmitter {
43
39
  this.process();
44
40
  return true;
45
41
  }
46
-
47
42
  stop() {
48
43
  if (!this.isRunning) {
49
44
  this.emit('stop');
50
45
  return;
51
46
  }
52
-
53
47
  this.forcedStop = true;
54
48
  this.queue = [];
55
49
  }
56
-
57
50
  process() {
58
51
  const worker = this.getFreeWorker();
59
52
  const [test] = this.queue;
60
-
61
53
  if (this.queue.length == 0 && this.workers.length === this.freeWorkers.length) {
62
54
  this.forcedStop = false;
63
55
  this.emit('stop');
64
56
  return;
65
57
  }
66
-
67
58
  if (!worker || !test) return;
68
59
  worker.isRunning = true;
69
60
  const {
@@ -81,23 +72,18 @@ export default class Pool extends EventEmitter {
81
72
  });
82
73
  this.process();
83
74
  }
84
-
85
75
  sendStatus(message) {
86
76
  this.emit('test', message);
87
77
  }
88
-
89
78
  getFreeWorker() {
90
79
  return this.freeWorkers[Math.floor(Math.random() * this.freeWorkers.length)];
91
80
  }
92
-
93
81
  get aliveWorkers() {
94
82
  return this.workers.filter(worker => !worker.exitedAfterDisconnect);
95
83
  }
96
-
97
84
  get freeWorkers() {
98
85
  return this.aliveWorkers.filter(worker => !worker.isRunning);
99
86
  }
100
-
101
87
  async forkWorker(retry = 0) {
102
88
  cluster.setupMaster({
103
89
  args: ['--browser', this.browser, ...process.argv.slice(2)]
@@ -109,7 +95,6 @@ export default class Pool extends EventEmitter {
109
95
  worker.off('message', readyHandler);
110
96
  resolve(message);
111
97
  };
112
-
113
98
  worker.on('message', readyHandler);
114
99
  });
115
100
  if (message.type != 'error') return worker;
@@ -117,7 +102,6 @@ export default class Pool extends EventEmitter {
117
102
  if (retry == FORK_RETRIES) return message.payload;
118
103
  return this.forkWorker(retry + 1);
119
104
  }
120
-
121
105
  exitHandler(worker) {
122
106
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
123
107
  worker.once('exit', async () => {
@@ -129,25 +113,20 @@ export default class Pool extends EventEmitter {
129
113
  this.process();
130
114
  });
131
115
  }
132
-
133
116
  gracefullyKill(worker) {
134
117
  const timeout = setTimeout(() => worker.kill(), 10000);
135
118
  worker.on('exit', () => clearTimeout(timeout));
136
119
  sendShutdownMessage(worker);
137
120
  }
138
-
139
121
  shouldRetry(test) {
140
122
  return test.retries < this.maxRetries && !this.forcedStop;
141
123
  }
142
-
143
124
  handleTestResult(worker, test, result) {
144
125
  const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
145
-
146
126
  if (shouldRetry) {
147
127
  test.retries += 1;
148
128
  this.queue[this.failFast ? 'unshift' : 'push'](test);
149
129
  }
150
-
151
130
  this.sendStatus({
152
131
  id: test.id,
153
132
  status: shouldRetry ? 'retrying' : result.status,
@@ -156,7 +135,6 @@ export default class Pool extends EventEmitter {
156
135
  worker.isRunning = false;
157
136
  setImmediate(() => this.process());
158
137
  }
159
-
160
138
  subscribe(worker, test) {
161
139
  const subscriptions = [subscribeOnWorker(worker, 'worker', message => {
162
140
  if (message.type != 'error') return;
@@ -172,5 +150,4 @@ export default class Pool extends EventEmitter {
172
150
  this.handleTestResult(worker, test, message.payload);
173
151
  })];
174
152
  }
175
-
176
153
  }