creevey 0.9.0-beta.0 → 0.9.0-beta.1

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 (148) hide show
  1. package/lib/types/index.d.ts +4 -3
  2. package/lib/types/server/config.d.ts +1 -1
  3. package/lib/types/server/messages.d.ts +0 -1
  4. package/lib/types/server/{parser.d.ts → testsFiles/parser.d.ts} +1 -1
  5. package/lib/types/server/testsFiles/register.d.ts +2 -0
  6. package/lib/types/types.d.ts +3 -2
  7. package/package.json +5 -2
  8. package/lib/cjs/cli.js +0 -5
  9. package/lib/cjs/client/addon/Manager.js +0 -412
  10. package/lib/cjs/client/addon/components/Addon.js +0 -76
  11. package/lib/cjs/client/addon/components/Icons.js +0 -42
  12. package/lib/cjs/client/addon/components/Panel.js +0 -68
  13. package/lib/cjs/client/addon/components/TestSelect.js +0 -63
  14. package/lib/cjs/client/addon/components/Tools.js +0 -114
  15. package/lib/cjs/client/addon/decorator.js +0 -11
  16. package/lib/cjs/client/addon/preset.js +0 -81
  17. package/lib/cjs/client/addon/readyForCapture.js +0 -12
  18. package/lib/cjs/client/addon/register.js +0 -96
  19. package/lib/cjs/client/addon/utils.js +0 -38
  20. package/lib/cjs/client/addon/withCreevey.js +0 -556
  21. package/lib/cjs/client/shared/components/ImagesView/BlendView.js +0 -85
  22. package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +0 -88
  23. package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +0 -176
  24. package/lib/cjs/client/shared/components/ImagesView/SlideView.js +0 -179
  25. package/lib/cjs/client/shared/components/ImagesView/SwapView.js +0 -110
  26. package/lib/cjs/client/shared/components/ImagesView/index.js +0 -45
  27. package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +0 -46
  28. package/lib/cjs/client/shared/components/PageFooter/Paging.js +0 -98
  29. package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +0 -78
  30. package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +0 -144
  31. package/lib/cjs/client/shared/components/ResultsPage.js +0 -173
  32. package/lib/cjs/client/shared/creeveyClientApi.js +0 -103
  33. package/lib/cjs/client/shared/helpers.js +0 -482
  34. package/lib/cjs/client/shared/viewMode.js +0 -17
  35. package/lib/cjs/client/web/index.html +0 -19
  36. package/lib/cjs/creevey.js +0 -71
  37. package/lib/cjs/index.js +0 -62
  38. package/lib/cjs/server/config.js +0 -96
  39. package/lib/cjs/server/docker.js +0 -150
  40. package/lib/cjs/server/extract.js +0 -50
  41. package/lib/cjs/server/index.js +0 -83
  42. package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -88
  43. package/lib/cjs/server/loaders/babel/helpers.js +0 -479
  44. package/lib/cjs/server/loaders/babel/register.js +0 -126
  45. package/lib/cjs/server/loaders/hooks/mdx.js +0 -30
  46. package/lib/cjs/server/loaders/hooks/svelte.js +0 -65
  47. package/lib/cjs/server/loaders/webpack/compile.js +0 -286
  48. package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -174
  49. package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -44
  50. package/lib/cjs/server/loaders/webpack/mdx-loader.js +0 -72
  51. package/lib/cjs/server/loaders/webpack/start.js +0 -41
  52. package/lib/cjs/server/logger.js +0 -47
  53. package/lib/cjs/server/master/api.js +0 -71
  54. package/lib/cjs/server/master/index.js +0 -146
  55. package/lib/cjs/server/master/master.js +0 -57
  56. package/lib/cjs/server/master/pool.js +0 -206
  57. package/lib/cjs/server/master/runner.js +0 -294
  58. package/lib/cjs/server/master/server.js +0 -129
  59. package/lib/cjs/server/messages.js +0 -266
  60. package/lib/cjs/server/parser.js +0 -85
  61. package/lib/cjs/server/selenium/browser.js +0 -680
  62. package/lib/cjs/server/selenium/index.js +0 -31
  63. package/lib/cjs/server/selenium/selenoid.js +0 -174
  64. package/lib/cjs/server/stories.js +0 -170
  65. package/lib/cjs/server/storybook/entry.js +0 -68
  66. package/lib/cjs/server/storybook/helpers.js +0 -165
  67. package/lib/cjs/server/storybook/providers/browser.js +0 -78
  68. package/lib/cjs/server/storybook/providers/hybrid.js +0 -79
  69. package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
  70. package/lib/cjs/server/update.js +0 -83
  71. package/lib/cjs/server/utils.js +0 -185
  72. package/lib/cjs/server/worker/chai-image.js +0 -142
  73. package/lib/cjs/server/worker/helpers.js +0 -69
  74. package/lib/cjs/server/worker/index.js +0 -15
  75. package/lib/cjs/server/worker/reporter.js +0 -120
  76. package/lib/cjs/server/worker/worker.js +0 -278
  77. package/lib/cjs/shared.js +0 -107
  78. package/lib/cjs/types.js +0 -74
  79. package/lib/esm/cli.js +0 -4
  80. package/lib/esm/client/addon/Manager.js +0 -396
  81. package/lib/esm/client/addon/components/Addon.js +0 -58
  82. package/lib/esm/client/addon/components/Icons.js +0 -27
  83. package/lib/esm/client/addon/components/Panel.js +0 -49
  84. package/lib/esm/client/addon/components/TestSelect.js +0 -49
  85. package/lib/esm/client/addon/components/Tools.js +0 -91
  86. package/lib/esm/client/addon/decorator.js +0 -2
  87. package/lib/esm/client/addon/preset.js +0 -56
  88. package/lib/esm/client/addon/readyForCapture.js +0 -5
  89. package/lib/esm/client/addon/register.js +0 -75
  90. package/lib/esm/client/addon/utils.js +0 -31
  91. package/lib/esm/client/addon/withCreevey.js +0 -532
  92. package/lib/esm/client/shared/components/ImagesView/BlendView.js +0 -63
  93. package/lib/esm/client/shared/components/ImagesView/ImagesView.js +0 -65
  94. package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +0 -151
  95. package/lib/esm/client/shared/components/ImagesView/SlideView.js +0 -154
  96. package/lib/esm/client/shared/components/ImagesView/SwapView.js +0 -88
  97. package/lib/esm/client/shared/components/ImagesView/index.js +0 -5
  98. package/lib/esm/client/shared/components/PageFooter/PageFooter.js +0 -32
  99. package/lib/esm/client/shared/components/PageFooter/Paging.js +0 -84
  100. package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +0 -64
  101. package/lib/esm/client/shared/components/PageHeader/PageHeader.js +0 -120
  102. package/lib/esm/client/shared/components/ResultsPage.js +0 -143
  103. package/lib/esm/client/shared/creeveyClientApi.js +0 -94
  104. package/lib/esm/client/shared/helpers.js +0 -424
  105. package/lib/esm/client/shared/viewMode.js +0 -6
  106. package/lib/esm/creevey.js +0 -56
  107. package/lib/esm/index.js +0 -7
  108. package/lib/esm/server/config.js +0 -73
  109. package/lib/esm/server/docker.js +0 -123
  110. package/lib/esm/server/extract.js +0 -34
  111. package/lib/esm/server/index.js +0 -64
  112. package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -74
  113. package/lib/esm/server/loaders/babel/helpers.js +0 -462
  114. package/lib/esm/server/loaders/babel/register.js +0 -105
  115. package/lib/esm/server/loaders/hooks/mdx.js +0 -15
  116. package/lib/esm/server/loaders/hooks/svelte.js +0 -49
  117. package/lib/esm/server/loaders/webpack/compile.js +0 -263
  118. package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -153
  119. package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -36
  120. package/lib/esm/server/loaders/webpack/mdx-loader.js +0 -58
  121. package/lib/esm/server/loaders/webpack/start.js +0 -27
  122. package/lib/esm/server/logger.js +0 -20
  123. package/lib/esm/server/master/api.js +0 -60
  124. package/lib/esm/server/master/index.js +0 -125
  125. package/lib/esm/server/master/master.js +0 -38
  126. package/lib/esm/server/master/pool.js +0 -187
  127. package/lib/esm/server/master/runner.js +0 -272
  128. package/lib/esm/server/master/server.js +0 -105
  129. package/lib/esm/server/messages.js +0 -234
  130. package/lib/esm/server/parser.js +0 -63
  131. package/lib/esm/server/selenium/browser.js +0 -647
  132. package/lib/esm/server/selenium/index.js +0 -2
  133. package/lib/esm/server/selenium/selenoid.js +0 -151
  134. package/lib/esm/server/stories.js +0 -151
  135. package/lib/esm/server/storybook/entry.js +0 -44
  136. package/lib/esm/server/storybook/helpers.js +0 -106
  137. package/lib/esm/server/storybook/providers/browser.js +0 -61
  138. package/lib/esm/server/storybook/providers/hybrid.js +0 -63
  139. package/lib/esm/server/storybook/providers/nodejs.js +0 -217
  140. package/lib/esm/server/update.js +0 -65
  141. package/lib/esm/server/utils.js +0 -146
  142. package/lib/esm/server/worker/chai-image.js +0 -130
  143. package/lib/esm/server/worker/helpers.js +0 -60
  144. package/lib/esm/server/worker/index.js +0 -1
  145. package/lib/esm/server/worker/reporter.js +0 -98
  146. package/lib/esm/server/worker/worker.js +0 -248
  147. package/lib/esm/shared.js +0 -76
  148. package/lib/esm/types.js +0 -43
@@ -1,142 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
-
8
- var _pngjs = require("pngjs");
9
-
10
- var _pixelmatch = _interopRequireDefault(require("pixelmatch"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- function normalizeImageSize(image, width, height) {
15
- const normalizedImage = Buffer.alloc(4 * width * height);
16
-
17
- for (let y = 0; y < height; y++) {
18
- for (let x = 0; x < width; x++) {
19
- const i = (y * width + x) * 4;
20
-
21
- if (x < image.width && y < image.height) {
22
- const j = (y * image.width + x) * 4;
23
- normalizedImage[i + 0] = image.data[j + 0];
24
- normalizedImage[i + 1] = image.data[j + 1];
25
- normalizedImage[i + 2] = image.data[j + 2];
26
- normalizedImage[i + 3] = image.data[j + 3];
27
- } else {
28
- normalizedImage[i + 0] = 0;
29
- normalizedImage[i + 1] = 0;
30
- normalizedImage[i + 2] = 0;
31
- normalizedImage[i + 3] = 0;
32
- }
33
- }
34
- }
35
-
36
- return normalizedImage;
37
- }
38
-
39
- function hasDiffPixels(diff) {
40
- for (let i = 0; i < diff.length; i += 4) {
41
- if (diff[i + 0] == 255 && diff[i + 1] == 0 && diff[i + 2] == 0 && diff[i + 3] == 255) return true;
42
- }
43
-
44
- return false;
45
- }
46
-
47
- function compareImages(expect, actual, diffOptions) {
48
- const expectImage = _pngjs.PNG.sync.read(expect);
49
-
50
- const actualImage = _pngjs.PNG.sync.read(actual);
51
-
52
- const width = Math.max(actualImage.width, expectImage.width);
53
- const height = Math.max(actualImage.height, expectImage.height);
54
- const diffImage = new _pngjs.PNG({
55
- width,
56
- height
57
- });
58
- let actualImageData = actualImage.data;
59
-
60
- if (actualImage.width < width || actualImage.height < height) {
61
- actualImageData = normalizeImageSize(actualImage, width, height);
62
- }
63
-
64
- let expectImageData = expectImage.data;
65
-
66
- if (expectImage.width < width || expectImage.height < height) {
67
- expectImageData = normalizeImageSize(expectImage, width, height);
68
- }
69
-
70
- (0, _pixelmatch.default)(expectImageData, actualImageData, diffImage.data, width, height, diffOptions);
71
- return {
72
- isEqual: !hasDiffPixels(diffImage.data),
73
- diff: _pngjs.PNG.sync.write(diffImage)
74
- };
75
- }
76
-
77
- function _default(getExpected, diffOptions) {
78
- return function chaiImage({
79
- Assertion
80
- }, utils) {
81
- async function assertImage(actual, imageName) {
82
- let onCompare = () => Promise.resolve();
83
-
84
- let expected = await getExpected(imageName);
85
- if (!(expected instanceof Buffer) && expected != null) ({
86
- expected,
87
- onCompare
88
- } = expected);
89
-
90
- if (expected == null) {
91
- await onCompare(actual);
92
- return imageName ? `Expected image '${imageName}' does not exists` : 'Expected image does not exists';
93
- }
94
-
95
- if (actual.equals(expected)) return await onCompare(actual);
96
- const {
97
- isEqual,
98
- diff
99
- } = compareImages(expected, actual, diffOptions);
100
- if (isEqual) return await onCompare(actual);
101
- await onCompare(actual, expected, diff);
102
- return imageName ? `Expected image '${imageName}' to match` : 'Expected image to match';
103
- }
104
-
105
- utils.addMethod(Assertion.prototype, 'matchImage', async function matchImage(imageName) {
106
- const actual = utils.flag(this, 'object');
107
- const errorMessage = await assertImage(typeof actual == 'string' ? Buffer.from(actual, 'base64') : actual, imageName);
108
-
109
- if (errorMessage) {
110
- throw createImageError(imageName ? {
111
- [imageName]: errorMessage
112
- } : errorMessage);
113
- }
114
- });
115
- utils.addMethod(Assertion.prototype, 'matchImages', async function matchImages() {
116
- const errors = {};
117
- await Promise.all(Object.entries(utils.flag(this, 'object')).map(async ([imageName, imageOrBase64]) => {
118
- let errorMessage;
119
-
120
- try {
121
- errorMessage = await assertImage(typeof imageOrBase64 == 'string' ? Buffer.from(imageOrBase64, 'base64') : imageOrBase64, imageName);
122
- } catch (error) {
123
- errorMessage = error.stack;
124
- }
125
-
126
- if (errorMessage) {
127
- errors[imageName] = errorMessage;
128
- }
129
- }));
130
-
131
- if (Object.keys(errors).length > 0) {
132
- throw createImageError(errors);
133
- }
134
- });
135
- };
136
- }
137
-
138
- function createImageError(imageErrors) {
139
- const error = new Error('Expected image to match');
140
- error.images = imageErrors;
141
- return error;
142
- }
@@ -1,69 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.addTestsFromStories = addTestsFromStories;
7
-
8
- var _mocha = require("mocha");
9
-
10
- var _types = require("../../types");
11
-
12
- var _stories = require("../stories");
13
-
14
- function findOrCreateSuite(name, parent) {
15
- const suite = parent.suites.find(({
16
- title
17
- }) => title == name) || new _mocha.Suite(name, parent.ctx);
18
-
19
- if (!suite.parent) {
20
- suite.parent = parent;
21
- parent.addSuite(suite);
22
- }
23
-
24
- return suite;
25
- }
26
-
27
- function createTest(name, fn, skip = false) {
28
- 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
-
31
- test.skipReason = skip;
32
- return test;
33
- }
34
-
35
- function addTest(rootSuite, test) {
36
- const [testName, ...suitePath] = [...test.storyPath, test.testName].reverse().filter(_types.isDefined);
37
- const suite = suitePath.reduceRight((subSuite, suiteName) => findOrCreateSuite(suiteName, subSuite), rootSuite);
38
- const mochaTest = createTest(testName, test.fn, test.skip);
39
- suite.addTest(mochaTest);
40
- mochaTest.ctx = Object.setPrototypeOf({
41
- id: test.id,
42
- story: test.story
43
- }, suite.ctx);
44
- return mochaTest;
45
- }
46
-
47
- function removeTestOrSuite(testOrSuite) {
48
- const {
49
- parent
50
- } = testOrSuite;
51
- if (!parent) return;
52
- if (testOrSuite instanceof _mocha.Test) parent.tests = parent.tests.filter(test => test != testOrSuite);
53
- if (testOrSuite instanceof _mocha.Suite) parent.suites = parent.suites.filter(suite => suite != testOrSuite);
54
- if (parent.tests.length == 0 && parent.suites.length == 0) removeTestOrSuite(parent);
55
- }
56
-
57
- async function addTestsFromStories(rootSuite, config, {
58
- browser,
59
- ...options
60
- }) {
61
- const mochaTestsById = new Map();
62
- const tests = await (0, _stories.loadTestsFromStories)([browser], listener => config.storiesProvider(config, options, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
63
- const oldTest = mochaTestsById.get(id);
64
- mochaTestsById.delete(id);
65
- if (oldTest) removeTestOrSuite(oldTest);
66
- if (newTest) mochaTestsById.set(id, addTest(rootSuite, newTest));
67
- }));
68
- Object.values(tests).filter(_types.isDefined).forEach(test => mochaTestsById.set(test.id, addTest(rootSuite, test)));
69
- }
@@ -1,15 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "default", {
7
- enumerable: true,
8
- get: function () {
9
- return _worker.default;
10
- }
11
- });
12
-
13
- var _worker = _interopRequireDefault(require("./worker"));
14
-
15
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -1,120 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TeamcityReporter = exports.CreeveyReporter = void 0;
7
-
8
- var _chalk = _interopRequireDefault(require("chalk"));
9
-
10
- var _mocha = require("mocha");
11
-
12
- var _loglevelPluginPrefix = _interopRequireDefault(require("loglevel-plugin-prefix"));
13
-
14
- var _types = require("../../types");
15
-
16
- 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
-
22
- const testLevels = {
23
- INFO: _chalk.default.green('PASS'),
24
- WARN: _chalk.default.yellow('START'),
25
- ERROR: _chalk.default.red('FAIL')
26
- };
27
-
28
- class CreeveyReporter extends _mocha.reporters.Base {
29
- constructor(runner, options) {
30
- super(runner);
31
- const {
32
- sessionId,
33
- topLevelSuite
34
- } = options.reporterOptions;
35
- const testLogger = (0, _logger.getLogger)(topLevelSuite);
36
-
37
- _loglevelPluginPrefix.default.apply(testLogger, {
38
- format(level) {
39
- return `${testLevels[level]} => (${topLevelSuite}:${_chalk.default.gray(sessionId)})`;
40
- }
41
-
42
- });
43
-
44
- runner.on('test', test => testLogger.warn(_chalk.default.cyan(test.titlePath().join('/'))));
45
- 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 ')));
51
- }
52
-
53
- }
54
-
55
- exports.CreeveyReporter = CreeveyReporter;
56
-
57
- class TeamcityReporter extends _mocha.reporters.Base {
58
- constructor(runner, options) {
59
- 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
- const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
68
- const reporterOptions = options.reporterOptions;
69
- 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
- runner.on('test', test => console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`));
71
- runner.on('fail', (test, error) => {
72
- var _error$stack2;
73
-
74
- Object.entries(reporterOptions.images).forEach(([name, image]) => {
75
- 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
-
78
- const {
79
- error,
80
- ...rest
81
- } = image;
82
- Object.values(rest).filter(_types.isDefined).forEach(fileName => {
83
- console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
84
- console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
85
- });
86
- }); // Output failed test as passed due TC don't support retry mechanic
87
- // 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
-
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}']`);
90
- });
91
- 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
- runner.on('test end', test => console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`));
93
- runner.on('suite end', suite => suite.root || console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`));
94
- runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
95
- }
96
-
97
- }
98
-
99
- exports.TeamcityReporter = TeamcityReporter;
100
-
101
- function getErrors(error, imageErrorToString, errorToString) {
102
- const errors = [];
103
-
104
- if (!(error instanceof Error)) {
105
- errors.push(error);
106
- } else if (!(0, _types.isImageError)(error)) {
107
- errors.push(errorToString(error));
108
- } else if (typeof error.images == 'string') {
109
- errors.push(imageErrorToString(error.images));
110
- } else {
111
- const imageErrors = error.images;
112
- 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));
116
- });
117
- }
118
-
119
- return errors;
120
- }
@@ -1,278 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = worker;
7
-
8
- var _util = require("util");
9
-
10
- var _fs = _interopRequireDefault(require("fs"));
11
-
12
- var _path = _interopRequireDefault(require("path"));
13
-
14
- var _chai = _interopRequireDefault(require("chai"));
15
-
16
- var _chalk = _interopRequireDefault(require("chalk"));
17
-
18
- var _mocha = _interopRequireDefault(require("mocha"));
19
-
20
- var _seleniumWebdriver = require("selenium-webdriver");
21
-
22
- var _types = require("../../types");
23
-
24
- var _messages = require("../messages");
25
-
26
- var _chaiImage = _interopRequireDefault(require("./chai-image"));
27
-
28
- var _selenium = require("../selenium");
29
-
30
- var _reporter = require("./reporter");
31
-
32
- var _helpers = require("./helpers");
33
-
34
- var _logger = require("../logger");
35
-
36
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
-
38
- const statAsync = (0, _util.promisify)(_fs.default.stat);
39
- const readdirAsync = (0, _util.promisify)(_fs.default.readdir);
40
- const readFileAsync = (0, _util.promisify)(_fs.default.readFile);
41
- const writeFileAsync = (0, _util.promisify)(_fs.default.writeFile);
42
- const mkdirAsync = (0, _util.promisify)(_fs.default.mkdir);
43
-
44
- async function getStat(filePath) {
45
- try {
46
- return await statAsync(filePath);
47
- } catch (error) {
48
- if (typeof error == 'object' && error && error.code === 'ENOENT') {
49
- return null;
50
- }
51
-
52
- throw error;
53
- }
54
- }
55
-
56
- async function getLastImageNumber(imageDir, imageName) {
57
- const actualImagesRegexp = new RegExp(`${imageName}-actual-(\\d+)\\.png`);
58
-
59
- 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;
63
- } catch (_error) {
64
- return 0;
65
- }
66
- } // FIXME browser options hotfix
67
-
68
-
69
- async function worker(config, options) {
70
- var _await$browser$getSes;
71
-
72
- let retries = 0;
73
- let images = {};
74
- let error = undefined;
75
- const screenshots = [];
76
- const testScope = [];
77
-
78
- function runHandler(failures) {
79
- if (failures > 0 && (error || Object.values(images).some(image => (image === null || image === void 0 ? void 0 : image.error) != null))) {
80
- var _error2;
81
-
82
- const isTimeout = hasTimeout(error) || Object.values(images).some(image => hasTimeout(image === null || image === void 0 ? void 0 : image.error));
83
- const payload = {
84
- status: 'failed',
85
- images,
86
- error
87
- };
88
- isTimeout ? (0, _messages.emitWorkerMessage)({
89
- type: 'error',
90
- payload: {
91
- error: (_error2 = error) !== null && _error2 !== void 0 ? _error2 : 'Unknown error'
92
- }
93
- }) : (0, _messages.emitTestMessage)({
94
- type: 'end',
95
- payload
96
- });
97
- } else {
98
- (0, _messages.emitTestMessage)({
99
- type: 'end',
100
- payload: {
101
- status: 'success',
102
- images
103
- }
104
- });
105
- }
106
- }
107
-
108
- async function saveImages(imageDir, images) {
109
- await mkdirAsync(imageDir, {
110
- recursive: true
111
- });
112
-
113
- for (const {
114
- name,
115
- data
116
- } of images) {
117
- await writeFileAsync(_path.default.join(imageDir, name), data);
118
- }
119
- }
120
-
121
- async function getExpected(assertImageName) {
122
- var _images$imageName;
123
-
124
- // context => [kind, story, test, browser]
125
- // rootSuite -> kindSuite -> storyTest -> [browsers.png]
126
- // rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
127
- const testPath = [...testScope];
128
- const imageName = assertImageName !== null && assertImageName !== void 0 ? assertImageName : testPath.pop();
129
- const imagesMeta = [];
130
-
131
- const reportImageDir = _path.default.join(config.reportDir, ...testPath);
132
-
133
- const imageNumber = (await getLastImageNumber(reportImageDir, imageName)) + 1;
134
- const actualImageName = `${imageName}-actual-${imageNumber}.png`;
135
- const image = images[imageName] = (_images$imageName = images[imageName]) !== null && _images$imageName !== void 0 ? _images$imageName : {
136
- actual: actualImageName
137
- };
138
-
139
- const onCompare = async (actual, expect, diff) => {
140
- imagesMeta.push({
141
- name: image.actual,
142
- data: actual
143
- });
144
-
145
- if (diff && expect) {
146
- image.expect = `${imageName}-expect-${imageNumber}.png`;
147
- image.diff = `${imageName}-diff-${imageNumber}.png`;
148
- imagesMeta.push({
149
- name: image.expect,
150
- data: expect
151
- });
152
- imagesMeta.push({
153
- name: image.diff,
154
- data: diff
155
- });
156
- }
157
-
158
- if (options.saveReport) {
159
- await saveImages(reportImageDir, imagesMeta);
160
- }
161
- };
162
-
163
- const expectImageDir = _path.default.join(config.screenDir, ...testPath);
164
-
165
- const expectImageStat = await getStat(_path.default.join(expectImageDir, `${imageName}.png`));
166
- if (!expectImageStat) return {
167
- expected: null,
168
- onCompare
169
- };
170
- const expected = await readFileAsync(_path.default.join(expectImageDir, `${imageName}.png`));
171
- return {
172
- expected,
173
- onCompare
174
- };
175
- }
176
-
177
- const mochaOptions = {
178
- timeout: 30000,
179
- reporter: process.env.TEAMCITY_VERSION ? _reporter.TeamcityReporter : options.reporter || _reporter.CreeveyReporter,
180
- reporterOptions: {
181
- reportDir: config.reportDir,
182
- topLevelSuite: options.browser,
183
-
184
- get willRetry() {
185
- return retries < config.maxRetries;
186
- },
187
-
188
- get images() {
189
- return images;
190
- },
191
-
192
- get sessionId() {
193
- return sessionId;
194
- }
195
-
196
- }
197
- };
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
-
201
- mocha.cleanReferencesAfterRun(false);
202
-
203
- _chai.default.use((0, _chaiImage.default)(getExpected, config.diffOptions));
204
-
205
- if ((await (0, _selenium.getBrowser)(config, options.browser)) == null) return;
206
- await (0, _helpers.addTestsFromStories)(mocha.suite, config, {
207
- browser: options.browser,
208
- watch: options.ui,
209
- debug: options.debug,
210
- port: options.port
211
- });
212
-
213
- try {
214
- 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());
217
- } catch (_) {
218
- await (0, _selenium.closeBrowser)();
219
- }
220
-
221
- const browser = await (0, _selenium.getBrowser)(config, options.browser);
222
- 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
- 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));
228
- mocha.suite.beforeAll(function () {
229
- this.config = config;
230
- this.browser = browser;
231
- this.until = _seleniumWebdriver.until;
232
- this.keys = _seleniumWebdriver.Key;
233
- this.expect = _chai.default.expect;
234
- this.browserName = options.browser;
235
- this.testScope = testScope;
236
- this.screenshots = screenshots;
237
- });
238
- mocha.suite.beforeEach(_selenium.switchStory);
239
- (0, _messages.subscribeOn)('test', message => {
240
- if (message.type != 'start') return;
241
- const test = message.payload;
242
- const testPath = test.path.join(' ').replace(/[|\\{}()[\]^$+*?.-]/g, '\\$&');
243
- images = {};
244
- error = undefined;
245
- retries = test.retries;
246
- mocha.grep(new RegExp(`^${testPath}$`));
247
- const runner = mocha.run(runHandler); // TODO How handle browser corruption?
248
-
249
- runner.on('fail', (_test, reason) => {
250
- if (!(reason instanceof Error)) {
251
- error = reason;
252
- } 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;
256
- } else if (typeof reason.images == 'string') {
257
- const image = images[testScope.slice(-1)[0]];
258
- if (image) image.error = reason.images;
259
- } else {
260
- const imageErrors = reason.images;
261
- Object.keys(imageErrors).forEach(imageName => {
262
- const image = images[imageName];
263
- if (image) image.error = imageErrors[imageName];
264
- });
265
- }
266
- });
267
- });
268
-
269
- _logger.logger.info(`${options.browser}:${_chalk.default.gray(sessionId)} is ready`);
270
-
271
- (0, _messages.emitWorkerMessage)({
272
- type: 'ready'
273
- });
274
- }
275
-
276
- function hasTimeout(str) {
277
- return str != null && str.toLowerCase().includes('timeout');
278
- }