creevey 0.9.0-beta.2 → 0.9.0-non-webpack.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/AUTHORS +15 -15
  2. package/CHANGELOG.md +1275 -1275
  3. package/LICENSE +21 -21
  4. package/README.md +7 -0
  5. package/addon/README.md +3 -0
  6. package/addon/package.json +4 -0
  7. package/docs/config.md +212 -212
  8. package/docs/grid.md +10 -10
  9. package/docs/tests.md +63 -63
  10. package/jest.config.js +6 -0
  11. package/lib/cjs/client/addon/Manager.js +11 -5
  12. package/lib/cjs/client/addon/components/Addon.js +1 -1
  13. package/lib/cjs/client/addon/components/Icons.js +2 -2
  14. package/lib/cjs/client/addon/components/Tools.js +1 -1
  15. package/lib/cjs/client/addon/index.js +31 -0
  16. package/lib/cjs/client/addon/preset.js +3 -3
  17. package/lib/cjs/client/addon/register.js +7 -3
  18. package/lib/cjs/client/addon/withCreevey.js +57 -30
  19. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +1 -1
  20. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +1 -1
  21. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +1 -1
  22. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +1 -1
  23. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +1 -1
  24. package/lib/cjs/client/shared/components/ImagesView/index.js +4 -4
  25. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +1 -1
  26. package/lib/cjs/client/shared/components/ResultsPage.js +2 -2
  27. package/lib/cjs/client/shared/creeveyClientApi.js +6 -2
  28. package/lib/cjs/client/shared/helpers.js +22 -22
  29. package/lib/cjs/client/shared/viewMode.js +1 -1
  30. package/lib/cjs/client/web/142.js +2 -0
  31. package/lib/cjs/client/web/142.js.LICENSE.txt +12 -0
  32. package/lib/cjs/client/web/32.js +1 -0
  33. package/lib/cjs/client/web/551.js +1 -0
  34. package/lib/cjs/client/web/566.js +2 -0
  35. package/lib/cjs/client/web/566.js.LICENSE.txt +31 -0
  36. package/lib/cjs/client/web/691.js +2 -0
  37. package/lib/cjs/client/web/691.js.LICENSE.txt +8 -0
  38. package/lib/cjs/client/web/725.js +1 -0
  39. package/lib/cjs/client/web/index.html +19 -19
  40. package/lib/cjs/client/web/main.js +2 -38
  41. package/lib/cjs/client/web/main.js.LICENSE.txt +49 -0
  42. package/lib/cjs/creevey.js +3 -5
  43. package/lib/cjs/index.js +4 -4
  44. package/lib/cjs/server/config.js +1 -1
  45. package/lib/cjs/server/docker.js +3 -7
  46. package/lib/cjs/server/index.js +1 -1
  47. package/lib/cjs/server/loaders/babel/creevey-plugin.js +1 -3
  48. package/lib/cjs/server/loaders/babel/helpers.js +13 -23
  49. package/lib/cjs/server/loaders/babel/register.js +1 -3
  50. package/lib/cjs/server/loaders/webpack/compile.js +31 -24
  51. package/lib/cjs/server/loaders/webpack/creevey-loader.js +10 -5
  52. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +2 -7
  53. package/lib/cjs/server/loaders/webpack/mdx-loader.js +1 -1
  54. package/lib/cjs/server/loaders/webpack/start.js +1 -1
  55. package/lib/cjs/server/logger.js +2 -1
  56. package/lib/cjs/server/master/index.js +2 -2
  57. package/lib/cjs/server/master/pool.js +9 -18
  58. package/lib/cjs/server/master/runner.js +53 -66
  59. package/lib/cjs/server/master/server.js +2 -2
  60. package/lib/cjs/server/messages.js +8 -10
  61. package/lib/cjs/server/selenium/browser.js +23 -31
  62. package/lib/cjs/server/selenium/selenoid.js +5 -7
  63. package/lib/cjs/server/stories.js +9 -20
  64. package/lib/cjs/server/storybook/entry.js +5 -3
  65. package/lib/cjs/server/storybook/helpers.js +15 -21
  66. package/lib/cjs/server/storybook/providers/browser.js +5 -9
  67. package/lib/cjs/server/storybook/providers/nodejs.js +4 -4
  68. package/lib/cjs/server/update.js +1 -5
  69. package/lib/cjs/server/utils.js +13 -15
  70. package/lib/cjs/server/worker/reporter.js +8 -20
  71. package/lib/cjs/server/worker/worker.js +6 -16
  72. package/lib/cjs/shared/index.js +89 -0
  73. package/lib/cjs/shared/serializeRegExp.js +41 -0
  74. package/lib/cjs/types.js +6 -6
  75. package/lib/esm/client/addon/Manager.js +11 -5
  76. package/lib/esm/client/addon/components/Icons.js +1 -1
  77. package/lib/esm/client/addon/index.js +2 -0
  78. package/lib/esm/client/addon/preset.js +1 -1
  79. package/lib/esm/client/addon/register.js +6 -2
  80. package/lib/esm/client/addon/withCreevey.js +55 -30
  81. package/lib/esm/client/shared/creeveyClientApi.js +6 -2
  82. package/lib/esm/client/shared/helpers.js +6 -6
  83. package/lib/esm/creevey.js +3 -5
  84. package/lib/esm/index.js +1 -3
  85. package/lib/esm/server/docker.js +2 -2
  86. package/lib/esm/server/index.js +1 -1
  87. package/lib/esm/server/loaders/babel/creevey-plugin.js +1 -3
  88. package/lib/esm/server/loaders/babel/helpers.js +12 -22
  89. package/lib/esm/server/loaders/babel/register.js +1 -3
  90. package/lib/esm/server/loaders/webpack/compile.js +31 -24
  91. package/lib/esm/server/loaders/webpack/creevey-loader.js +9 -4
  92. package/lib/esm/server/loaders/webpack/dummy-hmr.js +2 -6
  93. package/lib/esm/server/loaders/webpack/start.js +1 -1
  94. package/lib/esm/server/master/index.js +2 -2
  95. package/lib/esm/server/master/pool.js +7 -18
  96. package/lib/esm/server/master/runner.js +53 -66
  97. package/lib/esm/server/master/server.js +2 -2
  98. package/lib/esm/server/messages.js +3 -5
  99. package/lib/esm/server/selenium/browser.js +20 -28
  100. package/lib/esm/server/selenium/selenoid.js +4 -6
  101. package/lib/esm/server/stories.js +9 -20
  102. package/lib/esm/server/storybook/entry.js +4 -2
  103. package/lib/esm/server/storybook/helpers.js +7 -15
  104. package/lib/esm/server/storybook/providers/browser.js +4 -5
  105. package/lib/esm/server/storybook/providers/nodejs.js +3 -3
  106. package/lib/esm/server/update.js +1 -5
  107. package/lib/esm/server/utils.js +5 -9
  108. package/lib/esm/server/worker/reporter.js +8 -20
  109. package/lib/esm/server/worker/worker.js +6 -16
  110. package/lib/esm/shared/index.js +66 -0
  111. package/lib/esm/shared/serializeRegExp.js +23 -0
  112. package/lib/types/cli.d.ts +1 -1
  113. package/lib/types/client/addon/Manager.d.ts +37 -37
  114. package/lib/types/client/addon/components/Addon.d.ts +8 -8
  115. package/lib/types/client/addon/components/Icons.d.ts +7 -7
  116. package/lib/types/client/addon/components/Panel.d.ts +9 -9
  117. package/lib/types/client/addon/components/TestSelect.d.ts +8 -9
  118. package/lib/types/client/addon/components/Tools.d.ts +6 -6
  119. package/lib/types/client/addon/decorator.d.ts +1 -1
  120. package/lib/types/client/addon/index.d.ts +2 -0
  121. package/lib/types/client/addon/preset.d.ts +23 -24
  122. package/lib/types/client/addon/readyForCapture.d.ts +6 -6
  123. package/lib/types/client/addon/register.d.ts +3 -3
  124. package/lib/types/client/addon/utils.d.ts +2 -2
  125. package/lib/types/client/addon/withCreevey.d.ts +24 -24
  126. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -3
  127. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +24 -25
  128. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -3
  129. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -3
  130. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -3
  131. package/lib/types/client/shared/components/ImagesView/index.d.ts +5 -5
  132. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +8 -9
  133. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +7 -8
  134. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +12 -12
  135. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +16 -17
  136. package/lib/types/client/shared/components/ResultsPage.d.ts +18 -18
  137. package/lib/types/client/shared/creeveyClientApi.d.ts +9 -9
  138. package/lib/types/client/shared/helpers.d.ts +46 -46
  139. package/lib/types/client/shared/viewMode.d.ts +4 -4
  140. package/lib/types/client/web/CreeveyApp.d.ts +11 -12
  141. package/lib/types/client/web/CreeveyContext.d.ts +11 -11
  142. package/lib/types/client/web/CreeveyLoader.d.ts +2 -3
  143. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +19 -19
  144. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  145. package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  146. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +12 -13
  147. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +33 -33
  148. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +7 -8
  149. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +10 -10
  150. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +9 -9
  151. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  152. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +1 -1
  153. package/lib/types/client/web/KeyboardEventsContext.d.ts +13 -13
  154. package/lib/types/client/web/index.d.ts +4 -4
  155. package/lib/types/creevey.d.ts +1 -1
  156. package/lib/types/index.d.ts +0 -1
  157. package/lib/types/server/config.d.ts +4 -4
  158. package/lib/types/server/docker.d.ts +7 -7
  159. package/lib/types/server/extract.d.ts +2 -2
  160. package/lib/types/server/index.d.ts +2 -2
  161. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +1 -1
  162. package/lib/types/server/loaders/babel/helpers.d.ts +19 -19
  163. package/lib/types/server/loaders/babel/register.d.ts +5 -5
  164. package/lib/types/server/loaders/hooks/mdx.d.ts +1 -1
  165. package/lib/types/server/loaders/hooks/svelte.d.ts +1 -1
  166. package/lib/types/server/loaders/webpack/compile.d.ts +2 -2
  167. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +4 -2
  168. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +10 -10
  169. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +6 -6
  170. package/lib/types/server/loaders/webpack/start.d.ts +1 -1
  171. package/lib/types/server/logger.d.ts +10 -6
  172. package/lib/types/server/master/api.d.ts +7 -7
  173. package/lib/types/server/master/index.d.ts +3 -3
  174. package/lib/types/server/master/master.d.ts +7 -7
  175. package/lib/types/server/master/pool.d.ts +31 -31
  176. package/lib/types/server/master/runner.d.ts +26 -26
  177. package/lib/types/server/master/server.d.ts +2 -2
  178. package/lib/types/server/messages.d.ts +27 -27
  179. package/lib/types/server/selenium/browser.d.ts +17 -17
  180. package/lib/types/server/selenium/index.d.ts +2 -2
  181. package/lib/types/server/selenium/selenoid.d.ts +3 -3
  182. package/lib/types/server/stories.d.ts +8 -8
  183. package/lib/types/server/storybook/entry.d.ts +18 -18
  184. package/lib/types/server/storybook/helpers.d.ts +24 -24
  185. package/lib/types/server/storybook/providers/browser.d.ts +4 -4
  186. package/lib/types/server/storybook/providers/hybrid.d.ts +4 -4
  187. package/lib/types/server/storybook/providers/nodejs.d.ts +9 -9
  188. package/lib/types/server/testsFiles/parser.d.ts +12 -12
  189. package/lib/types/server/testsFiles/register.d.ts +2 -2
  190. package/lib/types/server/update.d.ts +2 -2
  191. package/lib/types/server/utils.d.ts +20 -20
  192. package/lib/types/server/worker/chai-image.d.ts +6 -6
  193. package/lib/types/server/worker/helpers.d.ts +8 -8
  194. package/lib/types/server/worker/index.d.ts +1 -1
  195. package/lib/types/server/worker/reporter.d.ts +8 -8
  196. package/lib/types/server/worker/worker.d.ts +4 -4
  197. package/lib/types/{shared.d.ts → shared/index.d.ts} +7 -16
  198. package/lib/types/shared/serializeRegExp.d.ts +9 -0
  199. package/lib/types/types.d.ts +490 -489
  200. package/package.json +115 -102
  201. package/preset.js +9 -9
  202. package/types/babel__register.d.ts +1 -1
  203. package/types/chai.d.ts +12 -12
  204. package/types/event-source-polyfill.d.ts +6 -6
  205. package/types/mdx.d.ts +3 -2
  206. package/types/mocha.d.ts +20 -20
  207. package/types/png.d.ts +4 -4
  208. package/lib/cjs/client/web/1.js +0 -13
  209. package/lib/cjs/client/web/2.js +0 -1
  210. package/lib/cjs/shared.js +0 -124
  211. package/lib/esm/shared.js +0 -93
  212. package/storybook-static/stories.json +0 -21
@@ -1,15 +1,14 @@
1
- import cluster, { isMaster } from 'cluster';
1
+ import cluster from 'cluster';
2
2
  import { loadStoriesFromBrowser } from '../../selenium';
3
3
  import { emitStoriesMessage, sendStoriesMessage, subscribeOn, subscribeOnWorker } from '../../messages';
4
- import { deserializeRawStories } from '../../../shared';
5
4
  import { isDefined } from '../../../types';
6
5
  import { logger } from '../../logger';
7
6
  export async function loadStories(_config, {
8
7
  port
9
8
  }, storiesListener) {
10
- if (isMaster) {
9
+ if (cluster.isPrimary) {
11
10
  return new Promise(resolve => {
12
- const worker = Object.values(cluster.workers).filter(isDefined).find(worker => worker.isConnected());
11
+ const worker = Object.values(cluster.workers ?? {}).filter(isDefined).find(worker => worker.isConnected());
13
12
 
14
13
  if (worker) {
15
14
  const unsubscribe = subscribeOnWorker(worker, 'stories', message => {
@@ -44,7 +43,7 @@ export async function loadStories(_config, {
44
43
  });
45
44
  if (message.type == 'update') storiesListener(new Map(message.payload));
46
45
  });
47
- const stories = deserializeRawStories(await loadStoriesFromBrowser(port));
46
+ const stories = await loadStoriesFromBrowser(port);
48
47
  const storiesWithOldTests = [];
49
48
  Object.values(stories).forEach(story => {
50
49
  var _parameters, _parameters$creevey;
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/ban-ts-comment */
2
2
  import path from 'path';
3
- import { isWorker, isMaster } from 'cluster';
3
+ import cluster from 'cluster';
4
4
  import chokidar from 'chokidar';
5
5
  import { noop } from '../../../types';
6
6
  import { getCreeveyCache } from '../../utils';
@@ -25,7 +25,7 @@ async function initStorybookEnvironment() {
25
25
  logger
26
26
  } = await importStorybookClientLogger(); // NOTE: Disable duplication warnings for >=6.2 storybook
27
27
 
28
- if (isWorker) logger.warn = noop; // NOTE: disable logger for 5.x storybook
28
+ if (cluster.isWorker) logger.warn = noop; // NOTE: disable logger for 5.x storybook
29
29
 
30
30
  logger.debug = noop;
31
31
  return import('../entry');
@@ -154,7 +154,7 @@ async function loadStoriesDirectly(config, {
154
154
  try {
155
155
  configure(contexts.map(ctx => ctx()), module, false);
156
156
  } catch (error) {
157
- if (isMaster) logger.error(error);
157
+ if (cluster.isPrimary) logger.error(error);
158
158
  }
159
159
  }
160
160
 
@@ -15,11 +15,7 @@ function tryToLoadTestsData(filename) {
15
15
  const actualRegex = /^(.*)-actual-(\d+)\.png$/i;
16
16
 
17
17
  function approve(dirents, srcPath, dstPath, testPaths, isMatch) {
18
- dirents.filter(dirent => dirent.isFile()).map(dirent => actualRegex.exec(dirent.name)).filter(isDefined).filter(([fileName, imageName]) => !testPaths || testPaths.find(([token]) => token == imageName) && isMatch(path.join(srcPath, fileName))).reduce((images, [, imageName, retry]) => {
19
- var _images$get;
20
-
21
- return Number(retry) > ((_images$get = images.get(imageName)) !== null && _images$get !== void 0 ? _images$get : -1) ? images.set(imageName, Number(retry)) : images;
22
- }, new Map()).forEach((retry, imageName) => {
18
+ dirents.filter(dirent => dirent.isFile()).map(dirent => actualRegex.exec(dirent.name)).filter(isDefined).filter(([fileName, imageName]) => !testPaths || testPaths.find(([token]) => token == imageName) && isMatch(path.join(srcPath, fileName))).reduce((images, [, imageName, retry]) => Number(retry) > (images.get(imageName) ?? -1) ? images.set(imageName, Number(retry)) : images, new Map()).forEach((retry, imageName) => {
23
19
  mkdirSync(dstPath, {
24
20
  recursive: true
25
21
  });
@@ -64,7 +64,7 @@ export function shouldSkip(browser, meta, skipOptions, test) {
64
64
  }
65
65
  export async function shutdownWorkers() {
66
66
  isShuttingDown.current = true;
67
- await Promise.all(Object.values(cluster.workers).filter(isDefined).filter(worker => worker.isConnected()).map(worker => new Promise(resolve => {
67
+ await Promise.all(Object.values(cluster.workers ?? {}).filter(isDefined).filter(worker => worker.isConnected()).map(worker => new Promise(resolve => {
68
68
  const timeout = setTimeout(() => worker.kill(), 10000);
69
69
  worker.on('exit', () => {
70
70
  clearTimeout(timeout);
@@ -96,27 +96,23 @@ export function testsToImages(tests) {
96
96
  storyPath,
97
97
  results
98
98
  }) => {
99
- var _results$slice$0$imag, _results$slice$;
99
+ var _results$slice$;
100
100
 
101
- return Object.keys((_results$slice$0$imag = results === null || results === void 0 ? void 0 : (_results$slice$ = results.slice(-1)[0]) === null || _results$slice$ === void 0 ? void 0 : _results$slice$.images) !== null && _results$slice$0$imag !== void 0 ? _results$slice$0$imag : {}).map(image => `${[...storyPath, testName, browser, browser == image ? undefined : image].filter(isDefined).join('/')}.png`);
101
+ return Object.keys((results === null || results === void 0 ? void 0 : (_results$slice$ = results.slice(-1)[0]) === null || _results$slice$ === void 0 ? void 0 : _results$slice$.images) ?? {}).map(image => `${[...storyPath, testName, browser, browser == image ? undefined : image].filter(isDefined).join('/')}.png`);
102
102
  })));
103
103
  } // https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
104
104
 
105
105
  export const isInsideDocker = existsSync('/proc/1/cgroup') && /docker/.test(readFileSync('/proc/1/cgroup', 'utf8'));
106
106
  export const downloadBinary = (downloadUrl, destination) => new Promise((resolve, reject) => get(downloadUrl, response => {
107
- var _response$statusCode2;
108
-
109
107
  if (response.statusCode == 302) {
110
- var _response$statusCode;
111
-
112
108
  const {
113
109
  location
114
110
  } = response.headers;
115
- if (!location) return reject(new Error(`Couldn't download selenoid. Status code: ${(_response$statusCode = response.statusCode) !== null && _response$statusCode !== void 0 ? _response$statusCode : 'UNKNOWN'}`));
111
+ if (!location) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
116
112
  return resolve(downloadBinary(location, destination));
117
113
  }
118
114
 
119
- if (response.statusCode != 200) return reject(new Error(`Couldn't download selenoid. Status code: ${(_response$statusCode2 = response.statusCode) !== null && _response$statusCode2 !== void 0 ? _response$statusCode2 : 'UNKNOWN'}`));
115
+ if (response.statusCode != 200) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
120
116
  const fileStream = createWriteStream(destination);
121
117
  response.pipe(fileStream);
122
118
  fileStream.on('finish', () => {
@@ -1,5 +1,3 @@
1
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
-
3
1
  import chalk from 'chalk';
4
2
  import { reporters } from 'mocha';
5
3
  import prefix from 'loglevel-plugin-prefix';
@@ -26,31 +24,18 @@ export class CreeveyReporter extends reporters.Base {
26
24
  });
27
25
  runner.on('test', test => testLogger.warn(chalk.cyan(test.titlePath().join('/'))));
28
26
  runner.on('pass', test => testLogger.info(chalk.cyan(test.titlePath().join('/'))));
29
- runner.on('fail', (test, error) => testLogger.error(chalk.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${chalk.bold(imageName !== null && imageName !== void 0 ? imageName : topLevelSuite)}:${error}`, error => {
30
- var _error$stack;
31
-
32
- return `${(_error$stack = error.stack) !== null && _error$stack !== void 0 ? _error$stack : error.message}`;
33
- }).join('\n ')));
27
+ runner.on('fail', (test, error) => testLogger.error(chalk.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${chalk.bold(imageName ?? topLevelSuite)}:${error}`, error => `${error.stack ?? error.message}`).join('\n ')));
34
28
  }
35
29
 
36
30
  }
37
31
  export class TeamcityReporter extends reporters.Base {
38
32
  constructor(runner, options) {
39
33
  super(runner);
40
-
41
- _defineProperty(this, "escape", str => {
42
- if (!str) return '';
43
- return str.toString() // eslint-disable-next-line no-control-regex
44
- .replace(/\x1B.*?m/g, '').replace(/\|/g, '||').replace(/\n/g, '|n').replace(/\r/g, '|r').replace(/\[/g, '|[').replace(/\]/g, '|]').replace(/\u0085/g, '|x').replace(/\u2028/g, '|l').replace(/\u2029/g, '|p').replace(/'/g, "|'");
45
- });
46
-
47
34
  const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
48
35
  const reporterOptions = options.reporterOptions;
49
36
  runner.on('suite', suite => suite.root ? console.log(`##teamcity[testSuiteStarted name='${topLevelSuite}' flowId='${process.pid}']`) : console.log(`##teamcity[testSuiteStarted name='${this.escape(suite.title)}' flowId='${process.pid}']`));
50
37
  runner.on('test', test => console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`));
51
38
  runner.on('fail', (test, error) => {
52
- var _error$stack2;
53
-
54
39
  Object.entries(reporterOptions.images).forEach(([name, image]) => {
55
40
  if (!image) return;
56
41
  const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/'); // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -66,7 +51,7 @@ export class TeamcityReporter extends reporters.Base {
66
51
  }); // Output failed test as passed due TC don't support retry mechanic
67
52
  // https://teamcity-support.jetbrains.com/hc/en-us/community/posts/207216829-Count-test-as-successful-if-at-least-one-try-is-successful?page=1#community_comment_207394125
68
53
 
69
- reporterOptions.willRetry ? console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`) : console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape((_error$stack2 = error.stack) !== null && _error$stack2 !== void 0 ? _error$stack2 : '')}' flowId='${process.pid}']`);
54
+ reporterOptions.willRetry ? console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`) : console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`);
70
55
  });
71
56
  runner.on('pending', test => console.log(`##teamcity[testIgnored name='${this.escape(test.title)}' message='${this.escape(typeof test.skipReason == 'boolean' ? test.title : test.skipReason)}' flowId='${process.pid}']`));
72
57
  runner.on('test end', test => console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`));
@@ -74,6 +59,11 @@ export class TeamcityReporter extends reporters.Base {
74
59
  runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
75
60
  }
76
61
 
62
+ escape = str => {
63
+ if (!str) return '';
64
+ return str.toString() // eslint-disable-next-line no-control-regex
65
+ .replace(/\x1B.*?m/g, '').replace(/\|/g, '||').replace(/\n/g, '|n').replace(/\r/g, '|r').replace(/\[/g, '|[').replace(/\]/g, '|]').replace(/\u0085/g, '|x').replace(/\u2028/g, '|l').replace(/\u2029/g, '|p').replace(/'/g, "|'");
66
+ };
77
67
  }
78
68
 
79
69
  function getErrors(error, imageErrorToString, errorToString) {
@@ -88,9 +78,7 @@ function getErrors(error, imageErrorToString, errorToString) {
88
78
  } else {
89
79
  const imageErrors = error.images;
90
80
  Object.keys(imageErrors).forEach(imageName => {
91
- var _imageErrors$imageNam;
92
-
93
- errors.push(imageErrorToString((_imageErrors$imageNam = imageErrors[imageName]) !== null && _imageErrors$imageNam !== void 0 ? _imageErrors$imageNam : '', imageName));
81
+ errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
94
82
  });
95
83
  }
96
84
 
@@ -34,9 +34,7 @@ async function getLastImageNumber(imageDir, imageName) {
34
34
  const actualImagesRegexp = new RegExp(`${imageName}-actual-(\\d+)\\.png`);
35
35
 
36
36
  try {
37
- var _await$readdirAsync$m;
38
-
39
- return (_await$readdirAsync$m = (await readdirAsync(imageDir)).map(filename => filename.replace(actualImagesRegexp, '$1')).map(Number).filter(x => !isNaN(x)).sort((a, b) => b - a)[0]) !== null && _await$readdirAsync$m !== void 0 ? _await$readdirAsync$m : 0;
37
+ return (await readdirAsync(imageDir)).map(filename => filename.replace(actualImagesRegexp, '$1')).map(Number).filter(x => !isNaN(x)).sort((a, b) => b - a)[0] ?? 0;
40
38
  } catch (_error) {
41
39
  return 0;
42
40
  }
@@ -54,8 +52,6 @@ export default async function worker(config, options) {
54
52
 
55
53
  function runHandler(failures) {
56
54
  if (failures > 0 && (error || Object.values(images).some(image => (image === null || image === void 0 ? void 0 : image.error) != null))) {
57
- var _error2;
58
-
59
55
  const isTimeout = hasTimeout(error) || Object.values(images).some(image => hasTimeout(image === null || image === void 0 ? void 0 : image.error));
60
56
  const payload = {
61
57
  status: 'failed',
@@ -65,7 +61,7 @@ export default async function worker(config, options) {
65
61
  isTimeout ? emitWorkerMessage({
66
62
  type: 'error',
67
63
  payload: {
68
- error: (_error2 = error) !== null && _error2 !== void 0 ? _error2 : 'Unknown error'
64
+ error: error ?? 'Unknown error'
69
65
  }
70
66
  }) : emitTestMessage({
71
67
  type: 'end',
@@ -96,18 +92,16 @@ export default async function worker(config, options) {
96
92
  }
97
93
 
98
94
  async function getExpected(assertImageName) {
99
- var _images$imageName;
100
-
101
95
  // context => [kind, story, test, browser]
102
96
  // rootSuite -> kindSuite -> storyTest -> [browsers.png]
103
97
  // rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
104
98
  const testPath = [...testScope];
105
- const imageName = assertImageName !== null && assertImageName !== void 0 ? assertImageName : testPath.pop();
99
+ const imageName = assertImageName ?? testPath.pop();
106
100
  const imagesMeta = [];
107
101
  const reportImageDir = path.join(config.reportDir, ...testPath);
108
102
  const imageNumber = (await getLastImageNumber(reportImageDir, imageName)) + 1;
109
103
  const actualImageName = `${imageName}-actual-${imageNumber}.png`;
110
- const image = images[imageName] = (_images$imageName = images[imageName]) !== null && _images$imageName !== void 0 ? _images$imageName : {
104
+ const image = images[imageName] = images[imageName] ?? {
111
105
  actual: actualImageName
112
106
  };
113
107
 
@@ -169,9 +163,7 @@ export default async function worker(config, options) {
169
163
 
170
164
  }
171
165
  };
172
- const mocha = new Mocha(mochaOptions); // @ts-expect-error: @types/mocha has out-dated types
173
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
174
-
166
+ const mocha = new Mocha(mochaOptions);
175
167
  mocha.cleanReferencesAfterRun(false);
176
168
  chai.use(chaiImage(getExpected, config.diffOptions));
177
169
  if ((await getBrowser(config, options.browser)) == null) return;
@@ -222,9 +214,7 @@ export default async function worker(config, options) {
222
214
  if (!(reason instanceof Error)) {
223
215
  error = reason;
224
216
  } else if (!isImageError(reason)) {
225
- var _reason$stack;
226
-
227
- error = (_reason$stack = reason.stack) !== null && _reason$stack !== void 0 ? _reason$stack : reason.message;
217
+ error = reason.stack ?? reason.message;
228
218
  } else if (typeof reason.images == 'string') {
229
219
  const image = images[testScope.slice(-1)[0]];
230
220
  if (image) image.error = reason.images;
@@ -0,0 +1,66 @@
1
+ import { mapValues, mergeWith, cloneDeepWith } from 'lodash';
2
+ import { deserializeRegExp, isSerializedRegExp, isRegExp, serializeRegExp } from './serializeRegExp'; // NOTE: Copy-paste from storybook/api
3
+
4
+ export const combineParameters = (...parameterSets) => // eslint-disable-next-line @typescript-eslint/no-unsafe-return
5
+ mergeWith({}, ...parameterSets, (_, srcValue) => {
6
+ // Treat arrays as scalars:
7
+ if (Array.isArray(srcValue)) return srcValue;
8
+ return undefined;
9
+ }); // NOTE: Copy-paste from storybook/api
10
+
11
+ export const denormalizeStoryParameters = ({
12
+ globalParameters,
13
+ kindParameters,
14
+ stories
15
+ }) => {
16
+ return mapValues(stories, storyData => ({ ...storyData,
17
+ parameters: combineParameters(globalParameters, kindParameters[storyData.kind] ?? {}, storyData.parameters)
18
+ }));
19
+ };
20
+ export const serializeRawStories = stories => {
21
+ return mapValues(stories, storyData => {
22
+ const creevey = storyData.parameters.creevey;
23
+
24
+ if (creevey !== null && creevey !== void 0 && creevey.skip) {
25
+ return { ...storyData,
26
+ parameters: { ...storyData.parameters,
27
+ creevey: { ...creevey,
28
+ skip: cloneDeepWith(creevey.skip, value => {
29
+ if (isRegExp(value)) {
30
+ return serializeRegExp(value);
31
+ }
32
+
33
+ return undefined;
34
+ })
35
+ }
36
+ }
37
+ };
38
+ }
39
+
40
+ return storyData;
41
+ });
42
+ };
43
+ export const deserializeRawStories = stories => {
44
+ return mapValues(stories, deserializeStory);
45
+ };
46
+ export const deserializeStory = story => {
47
+ const creevey = story.parameters.creevey;
48
+
49
+ if (creevey !== null && creevey !== void 0 && creevey.skip) {
50
+ return { ...story,
51
+ parameters: { ...story.parameters,
52
+ creevey: { ...creevey,
53
+ skip: cloneDeepWith(creevey.skip, value => {
54
+ if (isSerializedRegExp(value)) {
55
+ return deserializeRegExp(value);
56
+ }
57
+
58
+ return undefined;
59
+ })
60
+ }
61
+ }
62
+ };
63
+ }
64
+
65
+ return story;
66
+ };
@@ -0,0 +1,23 @@
1
+ export const isRegExp = exp => {
2
+ return exp instanceof RegExp;
3
+ };
4
+ export const isSerializedRegExp = exp => {
5
+ return typeof exp === 'object' && exp !== null && Reflect.get(exp, '__regexp') === true;
6
+ };
7
+ export const serializeRegExp = exp => {
8
+ const {
9
+ source,
10
+ flags
11
+ } = exp;
12
+ return {
13
+ __regexp: true,
14
+ source,
15
+ flags
16
+ };
17
+ };
18
+ export const deserializeRegExp = ({
19
+ source,
20
+ flags
21
+ }) => {
22
+ return new RegExp(source, flags);
23
+ };
@@ -1 +1 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
@@ -1,37 +1,37 @@
1
- import { API } from '@storybook/api';
2
- import { SetStoriesPayload } from '@storybook/api/dist/ts3.9/lib/stories';
3
- import { CreeveyStatus, CreeveyUpdate, TestData, TestStatus, StoriesRaw } from '../../types';
4
- import { CreeveyClientApi } from '../shared/creeveyClientApi';
5
- export declare class CreeveyManager {
6
- storybookApi: API;
7
- storyId: string;
8
- activeBrowser: string;
9
- selectedTestId: string;
10
- status: CreeveyStatus;
11
- creeveyApi: CreeveyClientApi | null;
12
- stories: StoriesRaw;
13
- updateStatusListeners: Array<(update: CreeveyUpdate) => void>;
14
- changeTestListeners: Array<(testId: string) => void>;
15
- constructor(storybookApi: API);
16
- initAll: () => Promise<void>;
17
- onUpdateStatus(listener: (update: CreeveyUpdate) => void): () => void;
18
- onChangeTest(listener: (testId: string) => void): () => void;
19
- handleCreeveyUpdate: (update: CreeveyUpdate) => void;
20
- getCurrentTest: () => TestData | undefined;
21
- onStoryRendered: (storyId: string) => void;
22
- onStart: () => void;
23
- onStop: () => void;
24
- onImageApprove: (id: string, retry: number, image: string) => void;
25
- onStartAllStoryTests: () => void;
26
- onStartAllTests: () => void;
27
- onSetStories: (data: SetStoriesPayload) => void;
28
- setActiveBrowser: (browser: string) => void;
29
- setSelectedTestId: (testId: string) => void;
30
- getStoryTests: (storyId: string) => TestData[];
31
- getBrowsers: () => string[];
32
- getTestsByStoryIdAndBrowser: (browser: string) => TestData[];
33
- getTabTitle: (browser: string) => string;
34
- setPanelsTitle: () => void;
35
- addStatusesToSideBar(): Promise<void>;
36
- addStatusToStoryName(name: string, status: TestStatus | undefined, skip: string | boolean): string;
37
- }
1
+ import { API } from '@storybook/api';
2
+ import { denormalizeStoryParameters } from '../../shared';
3
+ import { CreeveyStatus, CreeveyUpdate, TestData, TestStatus, StoriesRaw } from '../../types';
4
+ import { CreeveyClientApi } from '../shared/creeveyClientApi';
5
+ export declare class CreeveyManager {
6
+ storyId: string;
7
+ activeBrowser: string;
8
+ selectedTestId: string;
9
+ status: CreeveyStatus;
10
+ creeveyApi: CreeveyClientApi | null;
11
+ storybookApi: API;
12
+ stories: StoriesRaw;
13
+ updateStatusListeners: Array<(update: CreeveyUpdate) => void>;
14
+ changeTestListeners: Array<(testId: string) => void>;
15
+ constructor(storybookApi: API);
16
+ initAll: () => Promise<void>;
17
+ onUpdateStatus(listener: (update: CreeveyUpdate) => void): () => void;
18
+ onChangeTest(listener: (testId: string) => void): () => void;
19
+ handleCreeveyUpdate: (update: CreeveyUpdate) => void;
20
+ getCurrentTest: () => TestData | undefined;
21
+ onStoryRendered: (storyId: string) => void;
22
+ onStart: () => void;
23
+ onStop: () => void;
24
+ onImageApprove: (id: string, retry: number, image: string) => void;
25
+ onStartAllStoryTests: () => void;
26
+ onStartAllTests: () => void;
27
+ onSetStories: (data: Parameters<typeof denormalizeStoryParameters>['0']) => void;
28
+ setActiveBrowser: (browser: string) => void;
29
+ setSelectedTestId: (testId: string) => void;
30
+ getStoryTests: (storyId: string) => TestData[];
31
+ getBrowsers: () => string[];
32
+ getTestsByStoryIdAndBrowser: (browser: string) => TestData[];
33
+ getTabTitle: (browser: string) => string;
34
+ setPanelsTitle: () => void;
35
+ addStatusesToSideBar(): Promise<void>;
36
+ addStatusToStoryName(name: string, status: TestStatus | undefined, skip: string | boolean): string;
37
+ }
@@ -1,8 +1,8 @@
1
- import { CreeveyManager } from '../Manager';
2
- interface AddonProps {
3
- active?: boolean;
4
- browser: string;
5
- manager: CreeveyManager;
6
- }
7
- export declare const Addon: ({ active, browser, manager }: AddonProps) => JSX.Element | null;
8
- export {};
1
+ import { CreeveyManager } from '../Manager';
2
+ interface AddonProps {
3
+ active?: boolean;
4
+ browser: string;
5
+ manager: CreeveyManager;
6
+ }
7
+ export declare const Addon: ({ active, browser, manager }: AddonProps) => JSX.Element | null;
8
+ export {};
@@ -1,7 +1,7 @@
1
- interface IconProps {
2
- width?: number;
3
- height?: number;
4
- }
5
- export declare const NextIcon: ({ width, height }: IconProps) => JSX.Element;
6
- export declare const ForwardIcon: ({ width, height }: IconProps) => JSX.Element;
7
- export {};
1
+ interface IconProps {
2
+ width?: number;
3
+ height?: number;
4
+ }
5
+ export declare const NextIcon: ({ width, height }: IconProps) => JSX.Element;
6
+ export declare const ForwardIcon: ({ width, height }: IconProps) => JSX.Element;
7
+ export {};
@@ -1,9 +1,9 @@
1
- import { TestData } from '../../../types';
2
- interface PanelProps {
3
- tests: TestData[];
4
- selectedTestId: string;
5
- onChangeTest: (testId: string) => void;
6
- onImageApprove: (id: string, retry: number, image: string) => void;
7
- }
8
- export declare const Panel: ({ tests, selectedTestId, onChangeTest, onImageApprove }: PanelProps) => JSX.Element;
9
- export {};
1
+ import { TestData } from '../../../types';
2
+ interface PanelProps {
3
+ tests: TestData[];
4
+ selectedTestId: string;
5
+ onChangeTest: (testId: string) => void;
6
+ onImageApprove: (id: string, retry: number, image: string) => void;
7
+ }
8
+ export declare const Panel: ({ tests, selectedTestId, onChangeTest, onImageApprove }: PanelProps) => JSX.Element;
9
+ export {};
@@ -1,9 +1,8 @@
1
- /// <reference types="react" />
2
- import { TestData } from '../../../types';
3
- interface TestSelectProps {
4
- tests: TestData[];
5
- selectedTestId: string;
6
- onChangeTest: (testId: string) => void;
7
- }
8
- export default function TestSelect(props: TestSelectProps): JSX.Element;
9
- export {};
1
+ import { TestData } from '../../../types';
2
+ interface TestSelectProps {
3
+ tests: TestData[];
4
+ selectedTestId: string;
5
+ onChangeTest: (testId: string) => void;
6
+ }
7
+ export default function TestSelect(props: TestSelectProps): JSX.Element;
8
+ export {};
@@ -1,6 +1,6 @@
1
- import { CreeveyManager } from '../Manager';
2
- interface ToolsProps {
3
- manager: CreeveyManager;
4
- }
5
- export declare const Tools: ({ manager }: ToolsProps) => JSX.Element | null;
6
- export {};
1
+ import { CreeveyManager } from '../Manager';
2
+ interface ToolsProps {
3
+ manager: CreeveyManager;
4
+ }
5
+ export declare const Tools: ({ manager }: ToolsProps) => JSX.Element | null;
6
+ export {};
@@ -1 +1 @@
1
- export declare const decorators: import("@storybook/addons").MakeDecoratorResult[];
1
+ export declare const decorators: import("@storybook/addons").MakeDecoratorResult[];
@@ -0,0 +1,2 @@
1
+ export * from './withCreevey';
2
+ export * from './readyForCapture';
@@ -1,24 +1,23 @@
1
- /// <reference types="webpack-dev-server" />
2
- import { Configuration } from 'webpack';
3
- export declare function config(entry?: string[]): string[];
4
- export declare function managerEntries(entry?: string[]): string[];
5
- declare global {
6
- const __CREEVEY_SERVER_HOST__: string;
7
- const __CREEVEY_SERVER_PORT__: number;
8
- const __CREEVEY_CLIENT_PORT__: number | null;
9
- }
10
- export interface CreeveyAddonOptions {
11
- creeveyConfigPath?: string;
12
- creeveyPreExtract?: string;
13
- creeveyHost?: string;
14
- creeveyPort?: number;
15
- clientPort?: number;
16
- configType: string;
17
- configDir: string;
18
- outputDir: string;
19
- skipExtract?: boolean;
20
- presets?: {
21
- apply: <T>(preset: string) => Promise<T | undefined>;
22
- };
23
- }
24
- export declare function managerWebpack(config: Configuration, options: CreeveyAddonOptions): Promise<Configuration>;
1
+ import { Configuration } from 'webpack';
2
+ export declare function config(entry?: string[]): string[];
3
+ export declare function managerEntries(entry?: string[]): string[];
4
+ declare global {
5
+ const __CREEVEY_SERVER_HOST__: string;
6
+ const __CREEVEY_SERVER_PORT__: number;
7
+ const __CREEVEY_CLIENT_PORT__: number | null;
8
+ }
9
+ export interface CreeveyAddonOptions {
10
+ creeveyConfigPath?: string;
11
+ creeveyPreExtract?: string;
12
+ creeveyHost?: string;
13
+ creeveyPort?: number;
14
+ clientPort?: number;
15
+ configType: string;
16
+ configDir: string;
17
+ outputDir: string;
18
+ skipExtract?: boolean;
19
+ presets?: {
20
+ apply: <T>(preset: string) => Promise<T | undefined>;
21
+ };
22
+ }
23
+ export declare function _managerWebpack(config: Configuration, options: CreeveyAddonOptions): Promise<Configuration>;
@@ -1,6 +1,6 @@
1
- declare global {
2
- interface Window {
3
- __CREEVEY_SET_READY_FOR_CAPTURE__?: () => void;
4
- }
5
- }
6
- export declare function readyForCapture(): void;
1
+ declare global {
2
+ interface Window {
3
+ __CREEVEY_SET_READY_FOR_CAPTURE__?: () => void;
4
+ }
5
+ }
6
+ export declare function readyForCapture(): void;
@@ -1,3 +1,3 @@
1
- import { API } from '@storybook/api';
2
- export declare const ADDON_ID = "creevey";
3
- export declare function registerCreeveyPanels(storybookApi: API): Promise<void>;
1
+ import { API } from '@storybook/api';
2
+ export declare const ADDON_ID = "creevey";
3
+ export declare function registerCreeveyPanels(storybookApi: API): Promise<void>;
@@ -1,2 +1,2 @@
1
- import { TestStatus } from '../../types';
2
- export declare function getEmojiByTestStatus(status: TestStatus | undefined, skip?: string | boolean): string;
1
+ import { TestStatus } from '../../types';
2
+ export declare function getEmojiByTestStatus(status: TestStatus | undefined, skip?: string | boolean): string;