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
@@ -4,19 +4,18 @@ import { createHash } from 'crypto';
4
4
  import { mapValues, pick } from 'lodash';
5
5
  import { isDefined, isFunction, isObject } from '../types';
6
6
  import { shouldSkip, removeProps } from './utils';
7
-
8
7
  function storyTestFabric(delay, testFn) {
9
8
  return async function storyTest() {
10
9
  delay ? await new Promise(resolve => setTimeout(resolve, delay)) : void 0;
11
10
  await (testFn ? testFn.call(this) : this.screenshots.length > 0 ? this.expect(this.screenshots.reduce((screenshots, {
12
11
  imageName,
13
12
  screenshot
14
- }, index) => ({ ...screenshots,
13
+ }, index) => ({
14
+ ...screenshots,
15
15
  [imageName ?? `screenshot_${index}`]: screenshot
16
16
  }), {})).to.matchImages() : this.expect(await this.takeScreenshot()).to.matchImage());
17
17
  };
18
18
  }
19
-
20
19
  function createCreeveyTest(browser, storyMeta, skipOptions, testName) {
21
20
  const {
22
21
  kind,
@@ -38,7 +37,6 @@ function createCreeveyTest(browser, storyMeta, skipOptions, testName) {
38
37
  storyId
39
38
  };
40
39
  }
41
-
42
40
  function convertStories(browserName, stories) {
43
41
  const tests = {};
44
42
  (Array.isArray(stories) ? stories : Object.values(stories)).forEach(storyMeta => {
@@ -49,24 +47,27 @@ function convertStories(browserName, stories) {
49
47
  tests: storyTests,
50
48
  skip
51
49
  } = storyMeta.parameters.creevey ?? {};
52
- const delay = typeof delayParam == 'number' ? delayParam : delayParam !== null && delayParam !== void 0 && delayParam.for.includes(browserName) ? delayParam.ms : 0; // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png]
50
+ const delay = typeof delayParam == 'number' ? delayParam : delayParam !== null && delayParam !== void 0 && delayParam.for.includes(browserName) ? delayParam.ms : 0;
51
+
52
+ // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png]
53
53
  // typeof tests === "function" => rootSuite -> kindSuite -> storyTest -> browser -> [images.png]
54
54
  // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
55
55
  // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> browser -> [images.png]
56
56
 
57
57
  if (!storyTests) {
58
58
  const test = createCreeveyTest(browserName, storyMeta, skip);
59
- tests[test.id] = { ...test,
59
+ tests[test.id] = {
60
+ ...test,
60
61
  storyId: storyMeta.id,
61
62
  story: storyMeta,
62
63
  fn: storyTestFabric(delay)
63
64
  };
64
65
  return;
65
66
  }
66
-
67
67
  Object.entries(storyTests).forEach(([testName, testFn]) => {
68
68
  const test = createCreeveyTest(browserName, storyMeta, skip, testName);
69
- tests[test.id] = { ...test,
69
+ tests[test.id] = {
70
+ ...test,
70
71
  storyId: storyMeta.id,
71
72
  story: storyMeta,
72
73
  fn: storyTestFabric(delay, testFn)
@@ -75,7 +76,6 @@ function convertStories(browserName, stories) {
75
76
  });
76
77
  return tests;
77
78
  }
78
-
79
79
  export async function loadTestsFromStories(browsers, provider, update) {
80
80
  const testIdsByFiles = new Map();
81
81
  const stories = await provider(storiesByFiles => {
@@ -84,7 +84,6 @@ export async function loadTestsFromStories(browsers, provider, update) {
84
84
  browsers.forEach(browser => {
85
85
  Array.from(storiesByFiles.entries()).forEach(([filename, stories]) => {
86
86
  var _testIdsByFiles$get;
87
-
88
87
  Object.assign(tests, convertStories(browser, stories));
89
88
  const changed = Object.keys(tests);
90
89
  const removed = ((_testIdsByFiles$get = testIdsByFiles.get(filename)) === null || _testIdsByFiles$get === void 0 ? void 0 : _testIdsByFiles$get.filter(testId => !tests[testId])) ?? [];
@@ -93,7 +92,7 @@ export async function loadTestsFromStories(browsers, provider, update) {
93
92
  removed.forEach(testId => testsDiff[testId] = undefined);
94
93
  });
95
94
  });
96
- update === null || update === void 0 ? void 0 : update(testsDiff);
95
+ update === null || update === void 0 || update(testsDiff);
97
96
  });
98
97
  const tests = browsers.reduce((tests, browser) => Object.assign(tests, convertStories(browser, stories)), {});
99
98
  Object.values(tests).filter(isDefined).forEach(({
@@ -103,22 +102,26 @@ export async function loadTestsFromStories(browsers, provider, update) {
103
102
  fileName
104
103
  }
105
104
  }
106
- }) => // TODO Don't use filename as a key, due possible collisions if two require.context with same structure of modules are defined
105
+ }) =>
106
+ // TODO Don't use filename as a key, due possible collisions if two require.context with same structure of modules are defined
107
107
  testIdsByFiles.set(fileName, [...(testIdsByFiles.get(fileName) ?? []), id]));
108
108
  return tests;
109
109
  }
110
110
  export function saveStoriesJson(storiesData, extract) {
111
- const outputDir = typeof extract == 'boolean' ? 'storybook-static' : extract; // NOTE Copy-pasted from Storybook's `getStoriesJsonData` method
111
+ const outputDir = typeof extract == 'boolean' ? 'storybook-static' : extract;
112
112
 
113
+ // NOTE Copy-pasted from Storybook's `getStoriesJsonData` method
113
114
  const allowed = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory'];
114
- storiesData.globalParameters = pick(storiesData.globalParameters, allowed); // @ts-expect-error ignore error
115
-
116
- storiesData.kindParameters = mapValues(storiesData.kindParameters, v => pick(v, allowed)); // @ts-expect-error ignore error
117
-
118
- storiesData.stories = mapValues(storiesData.stories, v => ({ ...pick(v, ['id', 'name', 'kind', 'story']),
115
+ storiesData.globalParameters = pick(storiesData.globalParameters, allowed);
116
+ // @ts-expect-error ignore error
117
+ storiesData.kindParameters = mapValues(storiesData.kindParameters, v => pick(v, allowed));
118
+ // @ts-expect-error ignore error
119
+ storiesData.stories = mapValues(storiesData.stories, v => ({
120
+ ...pick(v, ['id', 'name', 'kind', 'story']),
119
121
  parameters: pick(v.parameters, allowed)
120
- })); // TODO Fix args stories
122
+ }));
121
123
 
124
+ // TODO Fix args stories
122
125
  removeProps(storiesData ?? {}, ['stories', () => true, 'parameters', '__isArgsStory']);
123
126
  Object.values((storiesData === null || storiesData === void 0 ? void 0 : storiesData.stories) ?? {}).forEach(story => isObject(story) && 'parameters' in story && isObject(story.parameters) && delete story.parameters.__isArgsStory);
124
127
  mkdirSync(outputDir, {
@@ -130,6 +133,7 @@ export function saveTestsJson(tests, dstPath = process.cwd()) {
130
133
  mkdirSync(dstPath, {
131
134
  recursive: true
132
135
  });
133
- writeFileSync(path.join(dstPath, 'tests.json'), // eslint-disable-next-line @typescript-eslint/no-unsafe-return
136
+ writeFileSync(path.join(dstPath, 'tests.json'),
137
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
134
138
  JSON.stringify(tests, (_, value) => isFunction(value) ? value.toString() : value, 2));
135
139
  }
@@ -8,7 +8,6 @@ export const loadStories = async (_config, _options, storiesListener) => {
8
8
  if (cluster.isPrimary) {
9
9
  return new Promise(resolve => {
10
10
  const worker = Object.values(cluster.workers ?? {}).filter(isDefined).find(worker => worker.isConnected());
11
-
12
11
  if (worker) {
13
12
  const unsubscribe = subscribeOnWorker(worker, 'stories', message => {
14
13
  if (message.type == 'set') {
@@ -25,7 +24,6 @@ export const loadStories = async (_config, _options, storiesListener) => {
25
24
  type: 'get'
26
25
  });
27
26
  }
28
-
29
27
  subscribeOn('stories', message => {
30
28
  // TODO updates only one browser :(
31
29
  if (message.type == 'update') storiesListener(new Map(message.payload));
@@ -45,12 +43,10 @@ export const loadStories = async (_config, _options, storiesListener) => {
45
43
  const stories = deserializeRawStories(await loadStoriesFromBrowser());
46
44
  const storiesWithOldTests = [];
47
45
  Object.values(stories).forEach(story => {
48
- var _parameters, _parameters$creevey;
49
-
50
- if ((_parameters = story.parameters) !== null && _parameters !== void 0 && (_parameters$creevey = _parameters.creevey) !== null && _parameters$creevey !== void 0 && _parameters$creevey.tests) {
51
- var _parameters2, _parameters2$creevey;
52
-
53
- (_parameters2 = story.parameters) === null || _parameters2 === void 0 ? true : (_parameters2$creevey = _parameters2.creevey) === null || _parameters2$creevey === void 0 ? true : delete _parameters2$creevey.tests;
46
+ var _parameters;
47
+ if ((_parameters = story.parameters) !== null && _parameters !== void 0 && (_parameters = _parameters.creevey) !== null && _parameters !== void 0 && _parameters.tests) {
48
+ var _parameters2;
49
+ (_parameters2 = story.parameters) === null || _parameters2 === void 0 || (_parameters2 = _parameters2.creevey) === null || _parameters2 === void 0 || delete _parameters2.tests;
54
50
  storiesWithOldTests.push(`${story.kind}/${story.name}`);
55
51
  }
56
52
  });
@@ -6,55 +6,47 @@ import { readDirRecursive } from '../../../server/utils';
6
6
  import { combineParameters } from '../../../shared';
7
7
  export const loadStories = async (_config, _options, storiesListener) => {
8
8
  let creeveyParamsByStoryId = {};
9
-
10
9
  const mergeParamsFromTestsToStory = (story, creeveyParams) => {
11
10
  if (story.parameters) {
12
11
  story.parameters.creevey = combineParameters(story.parameters.creevey || {}, creeveyParams);
13
12
  }
14
13
  };
15
-
16
14
  const stories = await browserProvider(_config, {}, updatedStoriesByFiles => {
17
15
  Array.from(updatedStoriesByFiles.entries()).forEach(([, storiesArray]) => {
18
16
  storiesArray.forEach(story => {
19
17
  const creeveyParams = creeveyParamsByStoryId[story.id];
20
-
21
18
  if (creeveyParams) {
22
19
  mergeParamsFromTestsToStory(story, creeveyParams);
23
20
  }
24
21
  });
25
22
  });
26
23
  storiesListener(updatedStoriesByFiles);
27
- }); // TODO fix test files hot reloading
24
+ });
28
25
 
29
- creeveyParamsByStoryId = await parseParams(_config
30
- /*, (data) => console.log(data) */
31
- );
26
+ // TODO fix test files hot reloading
27
+ creeveyParamsByStoryId = await parseParams(_config /*, (data) => console.log(data) */);
32
28
  Object.entries(stories).forEach(([storyId, story]) => {
33
29
  mergeParamsFromTestsToStory(story, creeveyParamsByStoryId[storyId]);
34
30
  });
35
31
  return stories;
36
32
  };
37
-
38
33
  async function parseParams(config, listener) {
39
34
  if (!config.testsDir) {
40
35
  return Promise.resolve({});
41
36
  }
42
-
43
37
  const testFiles = readDirRecursive(config.testsDir).filter(file => {
44
38
  var _config$testsRegex;
45
-
46
39
  return (_config$testsRegex = config.testsRegex) === null || _config$testsRegex === void 0 ? void 0 : _config$testsRegex.test(file);
47
40
  });
48
41
  await (await import('../../testsFiles/register')).default(config);
49
-
50
42
  if (listener) {
51
43
  chokidar.watch(testFiles).on('change', filePath => {
52
- logger.debug(`changed: ${filePath}`); // doesn't work, always returns {} due modules caching
53
- // see https://github.com/nodejs/modules/issues/307
44
+ logger.debug(`changed: ${filePath}`);
54
45
 
46
+ // doesn't work, always returns {} due modules caching
47
+ // see https://github.com/nodejs/modules/issues/307
55
48
  void parse(testFiles).then(data => listener(data));
56
49
  });
57
50
  }
58
-
59
51
  return parse(testFiles);
60
52
  }
@@ -8,15 +8,12 @@ let result = {};
8
8
  let kindTitle = '';
9
9
  let storyTitle = '';
10
10
  let storyParams = null;
11
-
12
11
  const setStoryParameters = params => {
13
12
  storyParams = params;
14
13
  };
15
-
16
14
  const getStoryId = (kindTitle, storyTitle) => {
17
15
  return toId(kindTitle, storyNameFromExport(storyTitle));
18
16
  };
19
-
20
17
  export const kind = (title, kindFn) => {
21
18
  kindTitle = title;
22
19
  kindFn();
@@ -24,7 +21,6 @@ export const kind = (title, kindFn) => {
24
21
  };
25
22
  export const story = (title, storyFn) => {
26
23
  var _result$storyId;
27
-
28
24
  storyTitle = title;
29
25
  storyParams = null;
30
26
  storyFn({
@@ -39,11 +35,9 @@ export const story = (title, storyFn) => {
39
35
  };
40
36
  export const test = (title, testFn) => {
41
37
  const storyId = getStoryId(kindTitle, storyTitle);
42
-
43
38
  if (!result[storyId]) {
44
39
  result[storyId] = {};
45
40
  }
46
-
47
41
  result[storyId].tests = Object.assign({}, result[storyId].tests, {
48
42
  [title]: testFn
49
43
  });
@@ -7,8 +7,9 @@ export default async function register(config) {
7
7
  });
8
8
  const {
9
9
  path: tsConfigPath
10
- } = getTsconfig(config.tsConfig) || {}; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
10
+ } = getTsconfig(config.tsConfig) || {};
11
11
 
12
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
12
13
  (await import('@babel/register')).default(config.babelOptions({
13
14
  babelrc: false,
14
15
  rootMode: 'upward-optional',
@@ -27,5 +28,7 @@ export default async function register(config) {
27
28
  plugins: [['@babel/plugin-transform-runtime'], ...(tsConfigPath ? [['babel-plugin-tsconfig-paths', {
28
29
  tsconfig: tsConfigPath
29
30
  }]] : [])]
30
- })); // (await import('ts-node')).register({ project: tsConfigPath, transpileOnly: true });
31
+ }));
32
+
33
+ // (await import('ts-node')).register({ project: tsConfigPath, transpileOnly: true });
31
34
  }
@@ -2,7 +2,6 @@ import path from 'path';
2
2
  import fs, { mkdirSync } from 'fs';
3
3
  import micromatch from 'micromatch';
4
4
  import { isDefined } from '../types';
5
-
6
5
  function tryToLoadTestsData(filename) {
7
6
  try {
8
7
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -11,9 +10,7 @@ function tryToLoadTestsData(filename) {
11
10
  /* noop */
12
11
  }
13
12
  }
14
-
15
13
  const actualRegex = /^(.*)-actual-(\d+)\.png$/i;
16
-
17
14
  function approve(dirents, srcPath, dstPath, testPaths, isMatch) {
18
15
  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) => {
19
16
  mkdirSync(dstPath, {
@@ -22,7 +19,6 @@ function approve(dirents, srcPath, dstPath, testPaths, isMatch) {
22
19
  fs.copyFileSync(path.join(srcPath, `${imageName}-actual-${retry}.png`), path.join(dstPath, `${imageName}.png`));
23
20
  });
24
21
  }
25
-
26
22
  function traverse(srcPath, dstPath, testPaths, isMatch) {
27
23
  const dirents = fs.readdirSync(srcPath, {
28
24
  withFileTypes: true
@@ -30,7 +26,6 @@ function traverse(srcPath, dstPath, testPaths, isMatch) {
30
26
  approve(dirents, srcPath, dstPath, testPaths, isMatch);
31
27
  dirents.filter(dirent => dirent.isDirectory()).map(dirent => [dirent.name, testPaths === null || testPaths === void 0 ? void 0 : testPaths.map(([token, ...restPath]) => token == dirent.name ? restPath : null).filter(isDefined)]).filter(([, paths]) => !paths || paths.length > 0).forEach(([dirname, paths]) => traverse(path.join(srcPath, dirname), path.join(dstPath, dirname), paths, isMatch));
32
28
  }
33
-
34
29
  export default function update(config, grepPattern) {
35
30
  const {
36
31
  reportDir,
@@ -42,13 +37,11 @@ export default function update(config, grepPattern) {
42
37
  const testsMeta = tryToLoadTestsData(`${reportDir}/tests.json`);
43
38
  const testsReport = tryToLoadTestsData(`${reportDir}/data`);
44
39
  let testPaths = null;
45
-
46
40
  if (testsMeta && testsReport) {
47
41
  testPaths = Object.values(testsMeta).filter(isDefined).filter(({
48
42
  id
49
43
  }) => {
50
44
  var _testsReport$id;
51
-
52
45
  return ((_testsReport$id = testsReport[id]) === null || _testsReport$id === void 0 ? void 0 : _testsReport$id.status) == 'failed';
53
46
  }).map(({
54
47
  storyPath,
@@ -56,6 +49,5 @@ export default function update(config, grepPattern) {
56
49
  browser
57
50
  }) => [...storyPath, ...(testName ? [testName] : []), browser]);
58
51
  }
59
-
60
52
  traverse(reportDir, screenDir, testPaths, value => isMatch(path.relative(reportDir, value)));
61
53
  }
@@ -10,21 +10,17 @@ export const isShuttingDown = {
10
10
  export const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
11
11
  export const extensions = ['.js', '.jsx', '.ts', '.tsx'];
12
12
  export const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
13
-
14
13
  function matchBy(pattern, value) {
15
14
  return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !isDefined(pattern);
16
15
  }
17
-
18
16
  export function shouldSkip(browser, meta, skipOptions, test) {
19
17
  if (typeof skipOptions != 'object') {
20
18
  return skipOptions;
21
19
  }
22
-
23
20
  for (const skipKey in skipOptions) {
24
21
  const reason = shouldSkipByOption(browser, meta, skipOptions[skipKey], skipKey, test);
25
22
  if (reason) return reason;
26
23
  }
27
-
28
24
  return false;
29
25
  }
30
26
  export function shouldSkipByOption(browser, meta, skipOption, reason, test) {
@@ -33,10 +29,8 @@ export function shouldSkipByOption(browser, meta, skipOption, reason, test) {
33
29
  const result = shouldSkipByOption(browser, meta, skip, reason, test);
34
30
  if (result) return result;
35
31
  }
36
-
37
32
  return false;
38
33
  }
39
-
40
34
  const {
41
35
  in: browsers,
42
36
  kinds,
@@ -88,11 +82,11 @@ export function testsToImages(tests) {
88
82
  results
89
83
  }) => {
90
84
  var _results$slice$;
91
-
92
- 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`);
85
+ return Object.keys((results === null || results === 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`);
93
86
  })));
94
- } // https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
87
+ }
95
88
 
89
+ // https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
96
90
  export const isInsideDocker = existsSync('/proc/1/cgroup') && /docker/.test(readFileSync('/proc/1/cgroup', 'utf8'));
97
91
  export const downloadBinary = (downloadUrl, destination) => new Promise((resolve, reject) => get(downloadUrl, response => {
98
92
  if (response.statusCode == 302) {
@@ -102,7 +96,6 @@ export const downloadBinary = (downloadUrl, destination) => new Promise((resolve
102
96
  if (!location) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
103
97
  return resolve(downloadBinary(location, destination));
104
98
  }
105
-
106
99
  if (response.statusCode != 200) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
107
100
  const fileStream = createWriteStream(destination);
108
101
  response.pipe(fileStream);
@@ -117,7 +110,6 @@ export const downloadBinary = (downloadUrl, destination) => new Promise((resolve
117
110
  }));
118
111
  export function removeProps(obj, propPath) {
119
112
  const [prop, ...restPath] = propPath;
120
-
121
113
  if (restPath.length > 0) {
122
114
  if (typeof prop == 'string') obj[prop] && removeProps(obj[prop], restPath);
123
115
  if (isFunction(prop)) Object.keys(obj).filter(prop).forEach(key => obj[key] && removeProps(obj[key], restPath));
@@ -1,13 +1,10 @@
1
1
  import { PNG } from 'pngjs';
2
2
  import pixelmatch from 'pixelmatch';
3
-
4
3
  function normalizeImageSize(image, width, height) {
5
4
  const normalizedImage = Buffer.alloc(4 * width * height);
6
-
7
5
  for (let y = 0; y < height; y++) {
8
6
  for (let x = 0; x < width; x++) {
9
7
  const i = (y * width + x) * 4;
10
-
11
8
  if (x < image.width && y < image.height) {
12
9
  const j = (y * image.width + x) * 4;
13
10
  normalizedImage[i + 0] = image.data[j + 0];
@@ -22,18 +19,14 @@ function normalizeImageSize(image, width, height) {
22
19
  }
23
20
  }
24
21
  }
25
-
26
22
  return normalizedImage;
27
23
  }
28
-
29
24
  function hasDiffPixels(diff) {
30
25
  for (let i = 0; i < diff.length; i += 4) {
31
26
  if (diff[i + 0] == 255 && diff[i + 1] == 0 && diff[i + 2] == 0 && diff[i + 3] == 255) return true;
32
27
  }
33
-
34
28
  return false;
35
29
  }
36
-
37
30
  function compareImages(expect, actual, diffOptions) {
38
31
  const expectImage = PNG.sync.read(expect);
39
32
  const actualImage = PNG.sync.read(actual);
@@ -44,42 +37,34 @@ function compareImages(expect, actual, diffOptions) {
44
37
  height
45
38
  });
46
39
  let actualImageData = actualImage.data;
47
-
48
40
  if (actualImage.width < width || actualImage.height < height) {
49
41
  actualImageData = normalizeImageSize(actualImage, width, height);
50
42
  }
51
-
52
43
  let expectImageData = expectImage.data;
53
-
54
44
  if (expectImage.width < width || expectImage.height < height) {
55
45
  expectImageData = normalizeImageSize(expectImage, width, height);
56
46
  }
57
-
58
47
  pixelmatch(expectImageData, actualImageData, diffImage.data, width, height, diffOptions);
59
48
  return {
60
49
  isEqual: !hasDiffPixels(diffImage.data),
61
50
  diff: PNG.sync.write(diffImage)
62
51
  };
63
52
  }
64
-
65
53
  export default function (getExpected, diffOptions) {
66
54
  return function chaiImage({
67
55
  Assertion
68
56
  }, utils) {
69
57
  async function assertImage(actual, imageName) {
70
58
  let onCompare = () => Promise.resolve();
71
-
72
59
  let expected = await getExpected(imageName);
73
60
  if (!(expected instanceof Buffer) && expected != null) ({
74
61
  expected,
75
62
  onCompare
76
63
  } = expected);
77
-
78
64
  if (expected == null) {
79
65
  await onCompare(actual);
80
66
  return imageName ? `Expected image '${imageName}' does not exists` : 'Expected image does not exists';
81
67
  }
82
-
83
68
  if (actual.equals(expected)) return await onCompare(actual);
84
69
  const {
85
70
  isEqual,
@@ -89,11 +74,9 @@ export default function (getExpected, diffOptions) {
89
74
  await onCompare(actual, expected, diff);
90
75
  return imageName ? `Expected image '${imageName}' to match` : 'Expected image to match';
91
76
  }
92
-
93
77
  utils.addMethod(Assertion.prototype, 'matchImage', async function matchImage(imageName) {
94
78
  const actual = utils.flag(this, 'object');
95
79
  const errorMessage = await assertImage(typeof actual == 'string' ? Buffer.from(actual, 'base64') : actual, imageName);
96
-
97
80
  if (errorMessage) {
98
81
  throw createImageError(imageName ? {
99
82
  [imageName]: errorMessage
@@ -104,25 +87,21 @@ export default function (getExpected, diffOptions) {
104
87
  const errors = {};
105
88
  await Promise.all(Object.entries(utils.flag(this, 'object')).map(async ([imageName, imageOrBase64]) => {
106
89
  let errorMessage;
107
-
108
90
  try {
109
91
  errorMessage = await assertImage(typeof imageOrBase64 == 'string' ? Buffer.from(imageOrBase64, 'base64') : imageOrBase64, imageName);
110
92
  } catch (error) {
111
93
  errorMessage = error.stack;
112
94
  }
113
-
114
95
  if (errorMessage) {
115
96
  errors[imageName] = errorMessage;
116
97
  }
117
98
  }));
118
-
119
99
  if (Object.keys(errors).length > 0) {
120
100
  throw createImageError(errors);
121
101
  }
122
102
  });
123
103
  };
124
104
  }
125
-
126
105
  function createImageError(imageErrors) {
127
106
  const error = new Error('Expected image to match');
128
107
  error.images = imageErrors;
@@ -1,28 +1,23 @@
1
1
  import { Suite, Test } from 'mocha';
2
2
  import { isDefined } from '../../types';
3
3
  import { loadTestsFromStories } from '../stories';
4
-
5
4
  function findOrCreateSuite(name, parent) {
6
5
  const suite = parent.suites.find(({
7
6
  title
8
7
  }) => title == name) || new Suite(name, parent.ctx);
9
-
10
8
  if (!suite.parent) {
11
9
  suite.parent = parent;
12
10
  parent.addSuite(suite);
13
11
  }
14
-
15
12
  return suite;
16
13
  }
17
-
18
14
  function createTest(name, fn, skip = false) {
19
15
  const test = new Test(name, skip ? undefined : fn);
20
- test.pending = Boolean(skip); // NOTE Can't define skip reason in mocha https://github.com/mochajs/mocha/issues/2026
21
-
16
+ test.pending = Boolean(skip);
17
+ // NOTE Can't define skip reason in mocha https://github.com/mochajs/mocha/issues/2026
22
18
  test.skipReason = skip;
23
19
  return test;
24
20
  }
25
-
26
21
  function addTest(rootSuite, test) {
27
22
  const [testName, ...suitePath] = [...test.storyPath, test.testName].reverse().filter(isDefined);
28
23
  const suite = suitePath.reduceRight((subSuite, suiteName) => findOrCreateSuite(suiteName, subSuite), rootSuite);
@@ -34,7 +29,6 @@ function addTest(rootSuite, test) {
34
29
  }, suite.ctx);
35
30
  return mochaTest;
36
31
  }
37
-
38
32
  function removeTestOrSuite(testOrSuite) {
39
33
  const {
40
34
  parent
@@ -44,7 +38,6 @@ function removeTestOrSuite(testOrSuite) {
44
38
  if (testOrSuite instanceof Suite) parent.suites = parent.suites.filter(suite => suite != testOrSuite);
45
39
  if (parent.tests.length == 0 && parent.suites.length == 0) removeTestOrSuite(parent);
46
40
  }
47
-
48
41
  export async function addTestsFromStories(rootSuite, config, {
49
42
  browser,
50
43
  ...options
@@ -20,13 +20,11 @@ export class CreeveyReporter extends reporters.Base {
20
20
  format(level) {
21
21
  return `${testLevels[level]} => (${topLevelSuite}:${chalk.gray(sessionId)})`;
22
22
  }
23
-
24
23
  });
25
24
  runner.on('test', test => testLogger.warn(chalk.cyan(test.titlePath().join('/'))));
26
25
  runner.on('pass', test => testLogger.info(chalk.cyan(test.titlePath().join('/'))));
27
26
  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 ')));
28
27
  }
29
-
30
28
  }
31
29
  export class TeamcityReporter extends reporters.Base {
32
30
  constructor(runner, options) {
@@ -38,8 +36,8 @@ export class TeamcityReporter extends reporters.Base {
38
36
  runner.on('fail', (test, error) => {
39
37
  Object.entries(reporterOptions.images).forEach(([name, image]) => {
40
38
  if (!image) return;
41
- const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/'); // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
-
39
+ const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/');
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
43
41
  const {
44
42
  error,
45
43
  ...rest
@@ -48,7 +46,9 @@ export class TeamcityReporter extends reporters.Base {
48
46
  console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
49
47
  console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
50
48
  });
51
- }); // Output failed test as passed due TC don't support retry mechanic
49
+ });
50
+
51
+ // Output failed test as passed due TC don't support retry mechanic
52
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
53
53
 
54
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}']`);
@@ -58,17 +58,15 @@ export class TeamcityReporter extends reporters.Base {
58
58
  runner.on('suite end', suite => suite.root || console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`));
59
59
  runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
60
60
  }
61
-
62
61
  escape = str => {
63
62
  if (!str) return '';
64
- return str.toString() // eslint-disable-next-line no-control-regex
63
+ return str.toString()
64
+ // eslint-disable-next-line no-control-regex
65
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
66
  };
67
67
  }
68
-
69
68
  function getErrors(error, imageErrorToString, errorToString) {
70
69
  const errors = [];
71
-
72
70
  if (!(error instanceof Error)) {
73
71
  errors.push(error);
74
72
  } else if (!isImageError(error)) {
@@ -81,6 +79,5 @@ function getErrors(error, imageErrorToString, errorToString) {
81
79
  errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
82
80
  });
83
81
  }
84
-
85
82
  return errors;
86
83
  }