creevey 0.9.0-beta.2 → 0.9.0-beta.20

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 (226) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/.yarnrc.yml +1 -0
  3. package/CHANGELOG.md +51 -0
  4. package/README.md +9 -1
  5. package/addon/README.md +3 -0
  6. package/addon/package.json +5 -0
  7. package/docs/config.md +29 -26
  8. package/jest.config.js +6 -0
  9. package/lib/cjs/cli.js +1 -0
  10. package/lib/cjs/client/addon/Manager.js +170 -390
  11. package/lib/cjs/client/addon/components/Addon.js +17 -45
  12. package/lib/cjs/client/addon/components/Icons.js +12 -14
  13. package/lib/cjs/client/addon/components/Panel.js +21 -30
  14. package/lib/cjs/client/addon/components/TestSelect.js +20 -31
  15. package/lib/cjs/client/addon/components/Tools.js +35 -65
  16. package/lib/cjs/client/addon/decorator.js +1 -4
  17. package/lib/cjs/client/addon/index.js +27 -0
  18. package/lib/cjs/client/addon/preset.js +3 -76
  19. package/lib/cjs/client/addon/preview.js +11 -0
  20. package/lib/cjs/client/addon/readyForCapture.js +1 -4
  21. package/lib/cjs/client/addon/register.js +43 -82
  22. package/lib/cjs/client/addon/utils.js +4 -8
  23. package/lib/cjs/client/addon/withCreevey.js +145 -404
  24. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +25 -35
  25. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +29 -41
  26. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +46 -83
  27. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +39 -67
  28. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +26 -57
  29. package/lib/cjs/client/shared/components/ImagesView/index.js +9 -14
  30. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +13 -16
  31. package/lib/cjs/client/shared/components/PageFooter/Paging.js +16 -37
  32. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +42 -34
  33. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +40 -84
  34. package/lib/cjs/client/shared/components/ResultsPage.js +42 -99
  35. package/lib/cjs/client/shared/creeveyClientApi.js +56 -93
  36. package/lib/cjs/client/shared/helpers.js +149 -274
  37. package/lib/cjs/client/shared/viewMode.js +5 -9
  38. package/lib/cjs/client/web/192.js +1 -0
  39. package/lib/cjs/client/web/632.js +43 -0
  40. package/lib/cjs/client/web/794.js +1 -0
  41. package/lib/cjs/client/web/main.js +79 -38
  42. package/lib/cjs/client/web/main.js.LICENSE.txt +34 -0
  43. package/lib/cjs/creevey.js +15 -30
  44. package/lib/cjs/index.js +0 -15
  45. package/lib/cjs/server/config.js +16 -36
  46. package/lib/cjs/server/docker.js +8 -34
  47. package/lib/cjs/server/index.js +9 -34
  48. package/lib/cjs/server/logger.js +7 -20
  49. package/lib/cjs/server/master/api.js +1 -14
  50. package/lib/cjs/server/master/index.js +25 -49
  51. package/lib/cjs/server/master/master.js +6 -21
  52. package/lib/cjs/server/master/pool.js +10 -53
  53. package/lib/cjs/server/master/runner.js +65 -105
  54. package/lib/cjs/server/master/server.js +10 -29
  55. package/lib/cjs/server/messages.js +14 -62
  56. package/lib/cjs/server/selenium/browser.js +149 -185
  57. package/lib/cjs/server/selenium/index.js +0 -4
  58. package/lib/cjs/server/selenium/selenoid.js +18 -44
  59. package/lib/cjs/server/stories.js +35 -57
  60. package/lib/cjs/server/storybook/providers/browser.js +15 -29
  61. package/lib/cjs/server/storybook/providers/hybrid.js +16 -37
  62. package/lib/cjs/server/telemetry.js +167 -0
  63. package/lib/cjs/server/testsFiles/parser.js +3 -19
  64. package/lib/cjs/server/testsFiles/register.js +8 -14
  65. package/lib/cjs/server/update.js +4 -25
  66. package/lib/cjs/server/utils.js +35 -76
  67. package/lib/cjs/server/worker/chai-image.js +1 -27
  68. package/lib/cjs/server/worker/helpers.js +2 -12
  69. package/lib/cjs/server/worker/index.js +1 -3
  70. package/lib/cjs/server/worker/reporter.js +16 -43
  71. package/lib/cjs/server/worker/worker.js +32 -72
  72. package/lib/cjs/shared/index.js +87 -0
  73. package/lib/cjs/shared/serializeRegExp.js +34 -0
  74. package/lib/cjs/types.js +11 -20
  75. package/lib/esm/cli.js +1 -1
  76. package/lib/esm/client/addon/Manager.js +170 -381
  77. package/lib/esm/client/addon/components/Addon.js +15 -34
  78. package/lib/esm/client/addon/components/Icons.js +10 -6
  79. package/lib/esm/client/addon/components/Panel.js +20 -18
  80. package/lib/esm/client/addon/components/TestSelect.js +19 -23
  81. package/lib/esm/client/addon/components/Tools.js +33 -49
  82. package/lib/esm/client/addon/decorator.js +1 -1
  83. package/lib/esm/client/addon/index.js +2 -0
  84. package/lib/esm/client/addon/preset.js +2 -56
  85. package/lib/esm/client/addon/preview.js +5 -0
  86. package/lib/esm/client/addon/readyForCapture.js +1 -3
  87. package/lib/esm/client/addon/register.js +41 -67
  88. package/lib/esm/client/addon/utils.js +3 -7
  89. package/lib/esm/client/addon/withCreevey.js +142 -388
  90. package/lib/esm/client/shared/components/ImagesView/BlendView.js +22 -18
  91. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +27 -25
  92. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +43 -63
  93. package/lib/esm/client/shared/components/ImagesView/SlideView.js +36 -47
  94. package/lib/esm/client/shared/components/ImagesView/SwapView.js +23 -40
  95. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +12 -8
  96. package/lib/esm/client/shared/components/PageFooter/Paging.js +15 -29
  97. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +40 -25
  98. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +38 -66
  99. package/lib/esm/client/shared/components/ResultsPage.js +39 -75
  100. package/lib/esm/client/shared/creeveyClientApi.js +56 -90
  101. package/lib/esm/client/shared/helpers.js +133 -230
  102. package/lib/esm/client/shared/viewMode.js +4 -4
  103. package/lib/esm/client/web/192.js +1 -0
  104. package/lib/esm/client/web/632.js +43 -0
  105. package/lib/esm/client/web/794.js +1 -0
  106. package/lib/esm/client/web/index.html +19 -0
  107. package/lib/esm/client/web/main.js +79 -0
  108. package/lib/esm/client/web/main.js.LICENSE.txt +34 -0
  109. package/lib/esm/creevey.js +13 -16
  110. package/lib/esm/index.js +1 -4
  111. package/lib/esm/server/config.js +9 -16
  112. package/lib/esm/server/docker.js +6 -14
  113. package/lib/esm/server/index.js +8 -22
  114. package/lib/esm/server/logger.js +0 -1
  115. package/lib/esm/server/master/api.js +0 -9
  116. package/lib/esm/server/master/index.js +25 -35
  117. package/lib/esm/server/master/master.js +2 -7
  118. package/lib/esm/server/master/pool.js +8 -41
  119. package/lib/esm/server/master/runner.js +64 -90
  120. package/lib/esm/server/master/server.js +9 -11
  121. package/lib/esm/server/messages.js +8 -42
  122. package/lib/esm/server/selenium/browser.js +147 -163
  123. package/lib/esm/server/selenium/selenoid.js +16 -27
  124. package/lib/esm/server/stories.js +34 -46
  125. package/lib/esm/server/storybook/providers/browser.js +12 -17
  126. package/lib/esm/server/storybook/providers/hybrid.js +11 -22
  127. package/lib/esm/server/telemetry.js +160 -0
  128. package/lib/esm/server/testsFiles/parser.js +0 -6
  129. package/lib/esm/server/testsFiles/register.js +6 -7
  130. package/lib/esm/server/update.js +1 -13
  131. package/lib/esm/server/utils.js +20 -41
  132. package/lib/esm/server/worker/chai-image.js +0 -21
  133. package/lib/esm/server/worker/helpers.js +2 -9
  134. package/lib/esm/server/worker/reporter.js +15 -29
  135. package/lib/esm/server/worker/worker.js +31 -48
  136. package/lib/esm/shared/index.js +77 -0
  137. package/lib/esm/shared/serializeRegExp.js +24 -0
  138. package/lib/esm/types.js +5 -1
  139. package/lib/types/client/addon/Manager.d.ts +3 -3
  140. package/lib/types/client/addon/components/Addon.d.ts +1 -0
  141. package/lib/types/client/addon/components/Icons.d.ts +1 -0
  142. package/lib/types/client/addon/components/Panel.d.ts +1 -0
  143. package/lib/types/client/addon/components/Tools.d.ts +1 -0
  144. package/lib/types/client/addon/decorator.d.ts +1 -1
  145. package/lib/types/client/addon/index.d.ts +2 -0
  146. package/lib/types/client/addon/preset.d.ts +2 -24
  147. package/lib/types/client/addon/preview.d.ts +4 -0
  148. package/lib/types/client/addon/utils.d.ts +1 -0
  149. package/lib/types/client/addon/withCreevey.d.ts +4 -3
  150. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -1
  151. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -1
  152. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -1
  153. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -1
  154. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +3 -1
  155. package/lib/types/client/shared/components/ResultsPage.d.ts +3 -1
  156. package/lib/types/client/web/CreeveyLoader.d.ts +1 -1
  157. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +6 -3
  158. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +1 -0
  159. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +19 -14
  160. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +3 -1
  161. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +3 -1
  162. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +1 -0
  163. package/lib/types/client/web/KeyboardEventsContext.d.ts +4 -2
  164. package/lib/types/index.d.ts +4 -1
  165. package/lib/types/server/logger.d.ts +6 -2
  166. package/lib/types/server/messages.d.ts +14 -12
  167. package/lib/types/server/selenium/browser.d.ts +5 -3
  168. package/lib/types/server/storybook/providers/browser.d.ts +2 -4
  169. package/lib/types/server/storybook/providers/hybrid.d.ts +2 -4
  170. package/lib/types/server/telemetry.d.ts +2 -0
  171. package/lib/types/server/utils.d.ts +5 -1
  172. package/lib/types/shared/index.d.ts +7 -0
  173. package/lib/types/shared/serializeRegExp.d.ts +9 -0
  174. package/lib/types/types.d.ts +29 -36
  175. package/package.json +132 -133
  176. package/types/global.d.ts +5 -0
  177. package/lib/cjs/client/web/1.js +0 -13
  178. package/lib/cjs/client/web/2.js +0 -1
  179. package/lib/cjs/server/extract.js +0 -50
  180. package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -88
  181. package/lib/cjs/server/loaders/babel/helpers.js +0 -479
  182. package/lib/cjs/server/loaders/babel/register.js +0 -126
  183. package/lib/cjs/server/loaders/hooks/mdx.js +0 -30
  184. package/lib/cjs/server/loaders/hooks/svelte.js +0 -65
  185. package/lib/cjs/server/loaders/webpack/compile.js +0 -286
  186. package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -174
  187. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -44
  188. package/lib/cjs/server/loaders/webpack/mdx-loader.js +0 -72
  189. package/lib/cjs/server/loaders/webpack/start.js +0 -41
  190. package/lib/cjs/server/storybook/entry.js +0 -68
  191. package/lib/cjs/server/storybook/helpers.js +0 -165
  192. package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
  193. package/lib/cjs/shared.js +0 -124
  194. package/lib/esm/server/extract.js +0 -34
  195. package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -74
  196. package/lib/esm/server/loaders/babel/helpers.js +0 -462
  197. package/lib/esm/server/loaders/babel/register.js +0 -105
  198. package/lib/esm/server/loaders/hooks/mdx.js +0 -15
  199. package/lib/esm/server/loaders/hooks/svelte.js +0 -49
  200. package/lib/esm/server/loaders/webpack/compile.js +0 -263
  201. package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -153
  202. package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -36
  203. package/lib/esm/server/loaders/webpack/mdx-loader.js +0 -58
  204. package/lib/esm/server/loaders/webpack/start.js +0 -27
  205. package/lib/esm/server/storybook/entry.js +0 -44
  206. package/lib/esm/server/storybook/helpers.js +0 -106
  207. package/lib/esm/server/storybook/providers/nodejs.js +0 -217
  208. package/lib/esm/shared.js +0 -93
  209. package/lib/types/server/extract.d.ts +0 -2
  210. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +0 -1
  211. package/lib/types/server/loaders/babel/helpers.d.ts +0 -19
  212. package/lib/types/server/loaders/babel/register.d.ts +0 -5
  213. package/lib/types/server/loaders/hooks/mdx.d.ts +0 -1
  214. package/lib/types/server/loaders/hooks/svelte.d.ts +0 -1
  215. package/lib/types/server/loaders/webpack/compile.d.ts +0 -2
  216. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +0 -2
  217. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +0 -10
  218. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +0 -6
  219. package/lib/types/server/loaders/webpack/start.d.ts +0 -1
  220. package/lib/types/server/storybook/entry.d.ts +0 -18
  221. package/lib/types/server/storybook/helpers.d.ts +0 -24
  222. package/lib/types/server/storybook/providers/nodejs.d.ts +0 -9
  223. package/lib/types/shared.d.ts +0 -16
  224. package/preset.js +0 -9
  225. package/storybook-static/stories.json +0 -21
  226. package/types/mdx.d.ts +0 -6
@@ -4,20 +4,14 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = _default;
7
-
8
7
  var _pngjs = require("pngjs");
9
-
10
8
  var _pixelmatch = _interopRequireDefault(require("pixelmatch"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
10
  function normalizeImageSize(image, width, height) {
15
11
  const normalizedImage = Buffer.alloc(4 * width * height);
16
-
17
12
  for (let y = 0; y < height; y++) {
18
13
  for (let x = 0; x < width; x++) {
19
14
  const i = (y * width + x) * 4;
20
-
21
15
  if (x < image.width && y < image.height) {
22
16
  const j = (y * image.width + x) * 4;
23
17
  normalizedImage[i + 0] = image.data[j + 0];
@@ -32,23 +26,17 @@ function normalizeImageSize(image, width, height) {
32
26
  }
33
27
  }
34
28
  }
35
-
36
29
  return normalizedImage;
37
30
  }
38
-
39
31
  function hasDiffPixels(diff) {
40
32
  for (let i = 0; i < diff.length; i += 4) {
41
33
  if (diff[i + 0] == 255 && diff[i + 1] == 0 && diff[i + 2] == 0 && diff[i + 3] == 255) return true;
42
34
  }
43
-
44
35
  return false;
45
36
  }
46
-
47
37
  function compareImages(expect, actual, diffOptions) {
48
38
  const expectImage = _pngjs.PNG.sync.read(expect);
49
-
50
39
  const actualImage = _pngjs.PNG.sync.read(actual);
51
-
52
40
  const width = Math.max(actualImage.width, expectImage.width);
53
41
  const height = Math.max(actualImage.height, expectImage.height);
54
42
  const diffImage = new _pngjs.PNG({
@@ -56,42 +44,34 @@ function compareImages(expect, actual, diffOptions) {
56
44
  height
57
45
  });
58
46
  let actualImageData = actualImage.data;
59
-
60
47
  if (actualImage.width < width || actualImage.height < height) {
61
48
  actualImageData = normalizeImageSize(actualImage, width, height);
62
49
  }
63
-
64
50
  let expectImageData = expectImage.data;
65
-
66
51
  if (expectImage.width < width || expectImage.height < height) {
67
52
  expectImageData = normalizeImageSize(expectImage, width, height);
68
53
  }
69
-
70
54
  (0, _pixelmatch.default)(expectImageData, actualImageData, diffImage.data, width, height, diffOptions);
71
55
  return {
72
56
  isEqual: !hasDiffPixels(diffImage.data),
73
57
  diff: _pngjs.PNG.sync.write(diffImage)
74
58
  };
75
59
  }
76
-
77
60
  function _default(getExpected, diffOptions) {
78
61
  return function chaiImage({
79
62
  Assertion
80
63
  }, utils) {
81
64
  async function assertImage(actual, imageName) {
82
65
  let onCompare = () => Promise.resolve();
83
-
84
66
  let expected = await getExpected(imageName);
85
67
  if (!(expected instanceof Buffer) && expected != null) ({
86
68
  expected,
87
69
  onCompare
88
70
  } = expected);
89
-
90
71
  if (expected == null) {
91
72
  await onCompare(actual);
92
73
  return imageName ? `Expected image '${imageName}' does not exists` : 'Expected image does not exists';
93
74
  }
94
-
95
75
  if (actual.equals(expected)) return await onCompare(actual);
96
76
  const {
97
77
  isEqual,
@@ -101,11 +81,9 @@ function _default(getExpected, diffOptions) {
101
81
  await onCompare(actual, expected, diff);
102
82
  return imageName ? `Expected image '${imageName}' to match` : 'Expected image to match';
103
83
  }
104
-
105
84
  utils.addMethod(Assertion.prototype, 'matchImage', async function matchImage(imageName) {
106
85
  const actual = utils.flag(this, 'object');
107
86
  const errorMessage = await assertImage(typeof actual == 'string' ? Buffer.from(actual, 'base64') : actual, imageName);
108
-
109
87
  if (errorMessage) {
110
88
  throw createImageError(imageName ? {
111
89
  [imageName]: errorMessage
@@ -116,25 +94,21 @@ function _default(getExpected, diffOptions) {
116
94
  const errors = {};
117
95
  await Promise.all(Object.entries(utils.flag(this, 'object')).map(async ([imageName, imageOrBase64]) => {
118
96
  let errorMessage;
119
-
120
97
  try {
121
98
  errorMessage = await assertImage(typeof imageOrBase64 == 'string' ? Buffer.from(imageOrBase64, 'base64') : imageOrBase64, imageName);
122
99
  } catch (error) {
123
100
  errorMessage = error.stack;
124
101
  }
125
-
126
102
  if (errorMessage) {
127
103
  errors[imageName] = errorMessage;
128
104
  }
129
105
  }));
130
-
131
106
  if (Object.keys(errors).length > 0) {
132
107
  throw createImageError(errors);
133
108
  }
134
109
  });
135
110
  };
136
111
  }
137
-
138
112
  function createImageError(imageErrors) {
139
113
  const error = new Error('Expected image to match');
140
114
  error.images = imageErrors;
@@ -4,34 +4,26 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.addTestsFromStories = addTestsFromStories;
7
-
8
7
  var _mocha = require("mocha");
9
-
10
8
  var _types = require("../../types");
11
-
12
9
  var _stories = require("../stories");
13
-
14
10
  function findOrCreateSuite(name, parent) {
15
11
  const suite = parent.suites.find(({
16
12
  title
17
13
  }) => title == name) || new _mocha.Suite(name, parent.ctx);
18
-
19
14
  if (!suite.parent) {
20
15
  suite.parent = parent;
21
16
  parent.addSuite(suite);
22
17
  }
23
-
24
18
  return suite;
25
19
  }
26
-
27
20
  function createTest(name, fn, skip = false) {
28
21
  const test = new _mocha.Test(name, skip ? undefined : fn);
29
- test.pending = Boolean(skip); // NOTE Can't define skip reason in mocha https://github.com/mochajs/mocha/issues/2026
30
-
22
+ test.pending = Boolean(skip);
23
+ // NOTE Can't define skip reason in mocha https://github.com/mochajs/mocha/issues/2026
31
24
  test.skipReason = skip;
32
25
  return test;
33
26
  }
34
-
35
27
  function addTest(rootSuite, test) {
36
28
  const [testName, ...suitePath] = [...test.storyPath, test.testName].reverse().filter(_types.isDefined);
37
29
  const suite = suitePath.reduceRight((subSuite, suiteName) => findOrCreateSuite(suiteName, subSuite), rootSuite);
@@ -43,7 +35,6 @@ function addTest(rootSuite, test) {
43
35
  }, suite.ctx);
44
36
  return mochaTest;
45
37
  }
46
-
47
38
  function removeTestOrSuite(testOrSuite) {
48
39
  const {
49
40
  parent
@@ -53,7 +44,6 @@ function removeTestOrSuite(testOrSuite) {
53
44
  if (testOrSuite instanceof _mocha.Suite) parent.suites = parent.suites.filter(suite => suite != testOrSuite);
54
45
  if (parent.tests.length == 0 && parent.suites.length == 0) removeTestOrSuite(parent);
55
46
  }
56
-
57
47
  async function addTestsFromStories(rootSuite, config, {
58
48
  browser,
59
49
  ...options
@@ -9,7 +9,5 @@ Object.defineProperty(exports, "default", {
9
9
  return _worker.default;
10
10
  }
11
11
  });
12
-
13
12
  var _worker = _interopRequireDefault(require("./worker"));
14
-
15
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -4,28 +4,19 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.TeamcityReporter = exports.CreeveyReporter = void 0;
7
-
8
7
  var _chalk = _interopRequireDefault(require("chalk"));
9
-
10
8
  var _mocha = require("mocha");
11
-
12
9
  var _loglevelPluginPrefix = _interopRequireDefault(require("loglevel-plugin-prefix"));
13
-
14
10
  var _types = require("../../types");
15
-
16
11
  var _logger = require("../logger");
17
-
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
-
20
- 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; }
21
-
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
13
  const testLevels = {
23
14
  INFO: _chalk.default.green('PASS'),
24
15
  WARN: _chalk.default.yellow('START'),
25
16
  ERROR: _chalk.default.red('FAIL')
26
17
  };
27
-
28
18
  class CreeveyReporter extends _mocha.reporters.Base {
19
+ // TODO Output in better way, like vitest, maybe
29
20
  constructor(runner, options) {
30
21
  super(runner);
31
22
  const {
@@ -33,48 +24,29 @@ class CreeveyReporter extends _mocha.reporters.Base {
33
24
  topLevelSuite
34
25
  } = options.reporterOptions;
35
26
  const testLogger = (0, _logger.getLogger)(topLevelSuite);
36
-
37
27
  _loglevelPluginPrefix.default.apply(testLogger, {
38
28
  format(level) {
39
29
  return `${testLevels[level]} => (${topLevelSuite}:${_chalk.default.gray(sessionId)})`;
40
30
  }
41
-
42
31
  });
43
-
44
32
  runner.on('test', test => testLogger.warn(_chalk.default.cyan(test.titlePath().join('/'))));
45
33
  runner.on('pass', test => testLogger.info(_chalk.default.cyan(test.titlePath().join('/'))));
46
- runner.on('fail', (test, error) => testLogger.error(_chalk.default.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${_chalk.default.bold(imageName !== null && imageName !== void 0 ? imageName : topLevelSuite)}:${error}`, error => {
47
- var _error$stack;
48
-
49
- return `${(_error$stack = error.stack) !== null && _error$stack !== void 0 ? _error$stack : error.message}`;
50
- }).join('\n ')));
34
+ runner.on('fail', (test, error) => testLogger.error(_chalk.default.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${_chalk.default.bold(imageName ?? topLevelSuite)}:${error}`, error => `${error.stack ?? error.message}`).join('\n ')));
51
35
  }
52
-
53
36
  }
54
-
55
37
  exports.CreeveyReporter = CreeveyReporter;
56
-
57
38
  class TeamcityReporter extends _mocha.reporters.Base {
58
39
  constructor(runner, options) {
59
40
  super(runner);
60
-
61
- _defineProperty(this, "escape", str => {
62
- if (!str) return '';
63
- return str.toString() // eslint-disable-next-line no-control-regex
64
- .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, "|'");
65
- });
66
-
67
41
  const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
68
42
  const reporterOptions = options.reporterOptions;
69
43
  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}']`));
70
44
  runner.on('test', test => console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`));
71
45
  runner.on('fail', (test, error) => {
72
- var _error$stack2;
73
-
74
46
  Object.entries(reporterOptions.images).forEach(([name, image]) => {
75
47
  if (!image) return;
76
- const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/'); // eslint-disable-next-line @typescript-eslint/no-unused-vars
77
-
48
+ const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/');
49
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
78
50
  const {
79
51
  error,
80
52
  ...rest
@@ -83,24 +55,28 @@ class TeamcityReporter extends _mocha.reporters.Base {
83
55
  console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
84
56
  console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
85
57
  });
86
- }); // Output failed test as passed due TC don't support retry mechanic
58
+ });
59
+
60
+ // Output failed test as passed due TC don't support retry mechanic
87
61
  // 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
88
62
 
89
- 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}']`);
63
+ 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}']`);
90
64
  });
91
65
  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}']`));
92
66
  runner.on('test end', test => console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`));
93
67
  runner.on('suite end', suite => suite.root || console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`));
94
68
  runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
95
69
  }
96
-
70
+ escape = str => {
71
+ if (!str) return '';
72
+ return str.toString()
73
+ // eslint-disable-next-line no-control-regex
74
+ .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, "|'");
75
+ };
97
76
  }
98
-
99
77
  exports.TeamcityReporter = TeamcityReporter;
100
-
101
78
  function getErrors(error, imageErrorToString, errorToString) {
102
79
  const errors = [];
103
-
104
80
  if (!(error instanceof Error)) {
105
81
  errors.push(error);
106
82
  } else if (!(0, _types.isImageError)(error)) {
@@ -110,11 +86,8 @@ function getErrors(error, imageErrorToString, errorToString) {
110
86
  } else {
111
87
  const imageErrors = error.images;
112
88
  Object.keys(imageErrors).forEach(imageName => {
113
- var _imageErrors$imageNam;
114
-
115
- errors.push(imageErrorToString((_imageErrors$imageNam = imageErrors[imageName]) !== null && _imageErrors$imageNam !== void 0 ? _imageErrors$imageNam : '', imageName));
89
+ errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
116
90
  });
117
91
  }
118
-
119
92
  return errors;
120
93
  }
@@ -4,43 +4,26 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = worker;
7
-
8
7
  var _util = require("util");
9
-
10
8
  var _fs = _interopRequireDefault(require("fs"));
11
-
12
9
  var _path = _interopRequireDefault(require("path"));
13
-
14
10
  var _chai = _interopRequireDefault(require("chai"));
15
-
16
11
  var _chalk = _interopRequireDefault(require("chalk"));
17
-
18
12
  var _mocha = _interopRequireDefault(require("mocha"));
19
-
20
13
  var _seleniumWebdriver = require("selenium-webdriver");
21
-
22
14
  var _types = require("../../types");
23
-
24
15
  var _messages = require("../messages");
25
-
26
16
  var _chaiImage = _interopRequireDefault(require("./chai-image"));
27
-
28
17
  var _selenium = require("../selenium");
29
-
30
18
  var _reporter = require("./reporter");
31
-
32
19
  var _helpers = require("./helpers");
33
-
34
20
  var _logger = require("../logger");
35
-
36
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
-
21
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
38
22
  const statAsync = (0, _util.promisify)(_fs.default.stat);
39
23
  const readdirAsync = (0, _util.promisify)(_fs.default.readdir);
40
24
  const readFileAsync = (0, _util.promisify)(_fs.default.readFile);
41
25
  const writeFileAsync = (0, _util.promisify)(_fs.default.writeFile);
42
26
  const mkdirAsync = (0, _util.promisify)(_fs.default.mkdir);
43
-
44
27
  async function getStat(filePath) {
45
28
  try {
46
29
  return await statAsync(filePath);
@@ -48,37 +31,28 @@ async function getStat(filePath) {
48
31
  if (typeof error == 'object' && error && error.code === 'ENOENT') {
49
32
  return null;
50
33
  }
51
-
52
34
  throw error;
53
35
  }
54
36
  }
55
-
56
37
  async function getLastImageNumber(imageDir, imageName) {
57
38
  const actualImagesRegexp = new RegExp(`${imageName}-actual-(\\d+)\\.png`);
58
-
59
39
  try {
60
- var _await$readdirAsync$m;
61
-
62
- 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;
40
+ return (await readdirAsync(imageDir)).map(filename => filename.replace(actualImagesRegexp, '$1')).map(Number).filter(x => !isNaN(x)).sort((a, b) => b - a)[0] ?? 0;
63
41
  } catch (_error) {
64
42
  return 0;
65
43
  }
66
- } // FIXME browser options hotfix
67
-
44
+ }
68
45
 
46
+ // FIXME browser options hotfix
69
47
  async function worker(config, options) {
70
48
  var _await$browser$getSes;
71
-
72
49
  let retries = 0;
73
50
  let images = {};
74
51
  let error = undefined;
75
52
  const screenshots = [];
76
53
  const testScope = [];
77
-
78
54
  function runHandler(failures) {
79
55
  if (failures > 0 && (error || Object.values(images).some(image => (image === null || image === void 0 ? void 0 : image.error) != null))) {
80
- var _error2;
81
-
82
56
  const isTimeout = hasTimeout(error) || Object.values(images).some(image => hasTimeout(image === null || image === void 0 ? void 0 : image.error));
83
57
  const payload = {
84
58
  status: 'failed',
@@ -88,7 +62,7 @@ async function worker(config, options) {
88
62
  isTimeout ? (0, _messages.emitWorkerMessage)({
89
63
  type: 'error',
90
64
  payload: {
91
- error: (_error2 = error) !== null && _error2 !== void 0 ? _error2 : 'Unknown error'
65
+ error: error ?? 'Unknown error'
92
66
  }
93
67
  }) : (0, _messages.emitTestMessage)({
94
68
  type: 'end',
@@ -104,12 +78,10 @@ async function worker(config, options) {
104
78
  });
105
79
  }
106
80
  }
107
-
108
81
  async function saveImages(imageDir, images) {
109
82
  await mkdirAsync(imageDir, {
110
83
  recursive: true
111
84
  });
112
-
113
85
  for (const {
114
86
  name,
115
87
  data
@@ -117,31 +89,24 @@ async function worker(config, options) {
117
89
  await writeFileAsync(_path.default.join(imageDir, name), data);
118
90
  }
119
91
  }
120
-
121
92
  async function getExpected(assertImageName) {
122
- var _images$imageName;
123
-
124
93
  // context => [kind, story, test, browser]
125
94
  // rootSuite -> kindSuite -> storyTest -> [browsers.png]
126
95
  // rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
127
96
  const testPath = [...testScope];
128
- const imageName = assertImageName !== null && assertImageName !== void 0 ? assertImageName : testPath.pop();
97
+ const imageName = assertImageName ?? testPath.pop();
129
98
  const imagesMeta = [];
130
-
131
99
  const reportImageDir = _path.default.join(config.reportDir, ...testPath);
132
-
133
100
  const imageNumber = (await getLastImageNumber(reportImageDir, imageName)) + 1;
134
101
  const actualImageName = `${imageName}-actual-${imageNumber}.png`;
135
- const image = images[imageName] = (_images$imageName = images[imageName]) !== null && _images$imageName !== void 0 ? _images$imageName : {
102
+ const image = images[imageName] = images[imageName] ?? {
136
103
  actual: actualImageName
137
104
  };
138
-
139
105
  const onCompare = async (actual, expect, diff) => {
140
106
  imagesMeta.push({
141
107
  name: image.actual,
142
108
  data: actual
143
109
  });
144
-
145
110
  if (diff && expect) {
146
111
  image.expect = `${imageName}-expect-${imageNumber}.png`;
147
112
  image.diff = `${imageName}-diff-${imageNumber}.png`;
@@ -154,14 +119,11 @@ async function worker(config, options) {
154
119
  data: diff
155
120
  });
156
121
  }
157
-
158
122
  if (options.saveReport) {
159
123
  await saveImages(reportImageDir, imagesMeta);
160
124
  }
161
125
  };
162
-
163
126
  const expectImageDir = _path.default.join(config.screenDir, ...testPath);
164
-
165
127
  const expectImageStat = await getStat(_path.default.join(expectImageDir, `${imageName}.png`));
166
128
  if (!expectImageStat) return {
167
129
  expected: null,
@@ -173,58 +135,48 @@ async function worker(config, options) {
173
135
  onCompare
174
136
  };
175
137
  }
176
-
177
138
  const mochaOptions = {
178
139
  timeout: 30000,
179
140
  reporter: process.env.TEAMCITY_VERSION ? _reporter.TeamcityReporter : options.reporter || _reporter.CreeveyReporter,
180
141
  reporterOptions: {
181
142
  reportDir: config.reportDir,
182
143
  topLevelSuite: options.browser,
183
-
184
144
  get willRetry() {
185
145
  return retries < config.maxRetries;
186
146
  },
187
-
188
147
  get images() {
189
148
  return images;
190
149
  },
191
-
192
150
  get sessionId() {
193
151
  return sessionId;
194
152
  }
195
-
196
153
  }
197
154
  };
198
- const mocha = new _mocha.default(mochaOptions); // @ts-expect-error: @types/mocha has out-dated types
199
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
200
-
155
+ const mocha = new _mocha.default(mochaOptions);
201
156
  mocha.cleanReferencesAfterRun(false);
202
-
203
157
  _chai.default.use((0, _chaiImage.default)(getExpected, config.diffOptions));
204
-
205
- if ((await (0, _selenium.getBrowser)(config, options.browser)) == null) return;
158
+ if ((await (0, _selenium.getBrowser)(config, options)) == null) return;
206
159
  await (0, _helpers.addTestsFromStories)(mocha.suite, config, {
207
160
  browser: options.browser,
208
161
  watch: options.ui,
209
162
  debug: options.debug,
210
163
  port: options.port
211
164
  });
212
-
213
165
  try {
214
166
  var _await$getBrowser;
215
-
216
- await ((_await$getBrowser = await (0, _selenium.getBrowser)(config, options.browser)) === null || _await$getBrowser === void 0 ? void 0 : _await$getBrowser.getCurrentUrl());
167
+ await ((_await$getBrowser = await (0, _selenium.getBrowser)(config, options)) === null || _await$getBrowser === void 0 ? void 0 : _await$getBrowser.getCurrentUrl());
217
168
  } catch (_) {
218
169
  await (0, _selenium.closeBrowser)();
219
170
  }
220
-
221
- const browser = await (0, _selenium.getBrowser)(config, options.browser);
171
+ const browser = await (0, _selenium.getBrowser)(config, options);
222
172
  const sessionId = (_await$browser$getSes = await (browser === null || browser === void 0 ? void 0 : browser.getSession())) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
223
173
  if (browser == null) return;
224
- const interval = setInterval(() => void browser.getCurrentUrl().then(url => {
225
- if (options.debug) _logger.logger.debug(`${options.browser}:${_chalk.default.gray(sessionId)}`, 'current url', _chalk.default.magenta(url));
226
- }), 10 * 1000);
227
- (0, _messages.subscribeOn)('shutdown', () => clearInterval(interval));
174
+ if (options.debug) {
175
+ const interval = setInterval(() => void browser.getCurrentUrl().then(url => {
176
+ _logger.logger.debug(`${options.browser}:${_chalk.default.gray(sessionId)}`, 'current url', _chalk.default.magenta(url));
177
+ }), 10 * 1000);
178
+ (0, _messages.subscribeOn)('shutdown', () => clearInterval(interval));
179
+ }
228
180
  mocha.suite.beforeAll(function () {
229
181
  this.config = config;
230
182
  this.browser = browser;
@@ -236,6 +188,18 @@ async function worker(config, options) {
236
188
  this.screenshots = screenshots;
237
189
  });
238
190
  mocha.suite.beforeEach(_selenium.switchStory);
191
+ if (options.trace) {
192
+ mocha.suite.afterEach(async function () {
193
+ const types = await (browser === null || browser === void 0 ? void 0 : browser.manage().logs().getAvailableLogTypes());
194
+ for (const type of types ?? []) {
195
+ const logs = await (browser === null || browser === void 0 ? void 0 : browser.manage().logs().get(type));
196
+ logs.forEach(log => {
197
+ var _this$currentTest;
198
+ return _logger.logger.trace(sessionId, (_this$currentTest = this.currentTest) === null || _this$currentTest === void 0 ? void 0 : _this$currentTest.titlePath().join('/'), log.toJSON());
199
+ });
200
+ }
201
+ });
202
+ }
239
203
  (0, _messages.subscribeOn)('test', message => {
240
204
  if (message.type != 'start') return;
241
205
  const test = message.payload;
@@ -244,15 +208,14 @@ async function worker(config, options) {
244
208
  error = undefined;
245
209
  retries = test.retries;
246
210
  mocha.grep(new RegExp(`^${testPath}$`));
247
- const runner = mocha.run(runHandler); // TODO How handle browser corruption?
211
+ const runner = mocha.run(runHandler);
248
212
 
213
+ // TODO How handle browser corruption?
249
214
  runner.on('fail', (_test, reason) => {
250
215
  if (!(reason instanceof Error)) {
251
216
  error = reason;
252
217
  } else if (!(0, _types.isImageError)(reason)) {
253
- var _reason$stack;
254
-
255
- error = (_reason$stack = reason.stack) !== null && _reason$stack !== void 0 ? _reason$stack : reason.message;
218
+ error = reason.stack ?? reason.message;
256
219
  } else if (typeof reason.images == 'string') {
257
220
  const image = images[testScope.slice(-1)[0]];
258
221
  if (image) image.error = reason.images;
@@ -265,14 +228,11 @@ async function worker(config, options) {
265
228
  }
266
229
  });
267
230
  });
268
-
269
231
  _logger.logger.info(`${options.browser}:${_chalk.default.gray(sessionId)} is ready`);
270
-
271
232
  (0, _messages.emitWorkerMessage)({
272
233
  type: 'ready'
273
234
  });
274
235
  }
275
-
276
236
  function hasTimeout(str) {
277
237
  return str != null && str.toLowerCase().includes('timeout');
278
238
  }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.serializeRawStories = exports.deserializeStory = exports.deserializeRawStories = exports.denormalizeStoryParameters = exports.combineParameters = void 0;
7
+ var _lodash = require("lodash");
8
+ var _serializeRegExp = require("./serializeRegExp");
9
+ // NOTE: Copy-paste from storybook/api
10
+ const combineParameters = function () {
11
+ for (var _len = arguments.length, parameterSets = new Array(_len), _key = 0; _key < _len; _key++) {
12
+ parameterSets[_key] = arguments[_key];
13
+ }
14
+ return (
15
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
16
+ (0, _lodash.mergeWith)({}, ...parameterSets, (_, srcValue) => {
17
+ // Treat arrays as scalars:
18
+ if (Array.isArray(srcValue)) return srcValue;
19
+ return undefined;
20
+ })
21
+ );
22
+ };
23
+
24
+ // NOTE: Copy-paste from storybook/api
25
+ exports.combineParameters = combineParameters;
26
+ const denormalizeStoryParameters = _ref => {
27
+ let {
28
+ globalParameters,
29
+ kindParameters,
30
+ stories
31
+ } = _ref;
32
+ return (0, _lodash.mapValues)(stories, storyData => ({
33
+ ...storyData,
34
+ parameters: combineParameters(globalParameters, kindParameters[storyData.kind] ?? {}, storyData.parameters)
35
+ }));
36
+ };
37
+ exports.denormalizeStoryParameters = denormalizeStoryParameters;
38
+ const serializeRawStories = stories => {
39
+ return (0, _lodash.mapValues)(stories, storyData => {
40
+ const creevey = storyData.parameters.creevey;
41
+ if (creevey?.skip) {
42
+ return {
43
+ ...storyData,
44
+ parameters: {
45
+ ...storyData.parameters,
46
+ creevey: {
47
+ ...creevey,
48
+ skip: (0, _lodash.cloneDeepWith)(creevey.skip, value => {
49
+ if ((0, _serializeRegExp.isRegExp)(value)) {
50
+ return (0, _serializeRegExp.serializeRegExp)(value);
51
+ }
52
+ return undefined;
53
+ })
54
+ }
55
+ }
56
+ };
57
+ }
58
+ return storyData;
59
+ });
60
+ };
61
+ exports.serializeRawStories = serializeRawStories;
62
+ const deserializeRawStories = stories => {
63
+ return (0, _lodash.mapValues)(stories, deserializeStory);
64
+ };
65
+ exports.deserializeRawStories = deserializeRawStories;
66
+ const deserializeStory = story => {
67
+ const creevey = story.parameters.creevey;
68
+ if (creevey?.skip) {
69
+ return {
70
+ ...story,
71
+ parameters: {
72
+ ...story.parameters,
73
+ creevey: {
74
+ ...creevey,
75
+ skip: (0, _lodash.cloneDeepWith)(creevey.skip, value => {
76
+ if ((0, _serializeRegExp.isSerializedRegExp)(value)) {
77
+ return (0, _serializeRegExp.deserializeRegExp)(value);
78
+ }
79
+ return undefined;
80
+ })
81
+ }
82
+ }
83
+ };
84
+ }
85
+ return story;
86
+ };
87
+ exports.deserializeStory = deserializeStory;