@testomatio/reporter 1.6.0-beta-2-artifacts → 2.0.0-beta-esm

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 (97) hide show
  1. package/lib/adapter/codecept.js +288 -330
  2. package/lib/adapter/cucumber/current.js +195 -203
  3. package/lib/adapter/cucumber/legacy.js +130 -155
  4. package/lib/adapter/cucumber.js +5 -16
  5. package/lib/adapter/cypress-plugin/index.js +91 -105
  6. package/lib/adapter/jasmine/jasmine.js +63 -0
  7. package/lib/adapter/jasmine.js +54 -53
  8. package/lib/adapter/jest.js +97 -99
  9. package/lib/adapter/mocha/mocha.js +125 -0
  10. package/lib/adapter/mocha.js +111 -140
  11. package/lib/adapter/playwright.js +168 -200
  12. package/lib/adapter/vitest.js +144 -143
  13. package/lib/adapter/webdriver.js +113 -97
  14. package/lib/bin/reportXml.js +49 -49
  15. package/lib/bin/startTest.js +80 -97
  16. package/lib/client.js +344 -385
  17. package/lib/config.js +16 -21
  18. package/lib/constants.js +49 -43
  19. package/lib/data-storage.js +206 -188
  20. package/lib/fileUploader.js +245 -0
  21. package/lib/junit-adapter/adapter.js +17 -20
  22. package/lib/junit-adapter/csharp.js +18 -14
  23. package/lib/junit-adapter/index.js +27 -25
  24. package/lib/junit-adapter/java.js +41 -53
  25. package/lib/junit-adapter/javascript.js +30 -27
  26. package/lib/junit-adapter/python.js +38 -37
  27. package/lib/junit-adapter/ruby.js +11 -8
  28. package/lib/output.js +44 -52
  29. package/lib/package.json +1 -0
  30. package/lib/pipe/bitbucket.js +208 -227
  31. package/lib/pipe/csv.js +111 -124
  32. package/lib/pipe/github.js +184 -211
  33. package/lib/pipe/gitlab.js +164 -205
  34. package/lib/pipe/html.js +253 -312
  35. package/lib/pipe/index.js +83 -63
  36. package/lib/pipe/testomatio.js +391 -454
  37. package/lib/reporter-functions.js +16 -20
  38. package/lib/reporter.js +47 -17
  39. package/lib/services/artifacts.js +55 -51
  40. package/lib/services/index.js +14 -12
  41. package/lib/services/key-values.js +56 -53
  42. package/lib/services/logger.js +227 -245
  43. package/lib/utils/chalk.js +10 -0
  44. package/lib/utils/pipe_utils.js +91 -84
  45. package/lib/utils/utils.js +289 -273
  46. package/lib/xmlReader.js +480 -519
  47. package/package.json +57 -19
  48. package/src/adapter/codecept.js +369 -0
  49. package/src/adapter/cucumber/current.js +228 -0
  50. package/src/adapter/cucumber/legacy.js +158 -0
  51. package/src/adapter/cucumber.js +4 -0
  52. package/src/adapter/cypress-plugin/index.js +110 -0
  53. package/src/adapter/jasmine.js +60 -0
  54. package/src/adapter/jest.js +107 -0
  55. package/src/adapter/mocha.cjs +2 -0
  56. package/src/adapter/mocha.js +156 -0
  57. package/src/adapter/playwright.js +222 -0
  58. package/src/adapter/vitest.js +183 -0
  59. package/src/adapter/webdriver.js +111 -0
  60. package/src/bin/reportXml.js +67 -0
  61. package/src/bin/startTest.js +119 -0
  62. package/src/client.js +423 -0
  63. package/src/config.js +30 -0
  64. package/src/constants.js +49 -0
  65. package/src/data-storage.js +204 -0
  66. package/src/fileUploader.js +307 -0
  67. package/src/junit-adapter/adapter.js +23 -0
  68. package/src/junit-adapter/csharp.js +16 -0
  69. package/src/junit-adapter/index.js +28 -0
  70. package/src/junit-adapter/java.js +58 -0
  71. package/src/junit-adapter/javascript.js +31 -0
  72. package/src/junit-adapter/python.js +42 -0
  73. package/src/junit-adapter/ruby.js +10 -0
  74. package/src/output.js +57 -0
  75. package/src/pipe/bitbucket.js +254 -0
  76. package/src/pipe/csv.js +140 -0
  77. package/src/pipe/github.js +234 -0
  78. package/src/pipe/gitlab.js +229 -0
  79. package/src/pipe/html.js +366 -0
  80. package/src/pipe/index.js +73 -0
  81. package/src/pipe/testomatio.js +498 -0
  82. package/src/reporter-functions.js +44 -0
  83. package/src/reporter.cjs +22 -0
  84. package/src/reporter.js +24 -0
  85. package/src/services/artifacts.js +59 -0
  86. package/src/services/index.js +13 -0
  87. package/src/services/key-values.js +59 -0
  88. package/src/services/logger.js +314 -0
  89. package/src/template/emptyData.svg +23 -0
  90. package/src/template/testomatio.hbs +1421 -0
  91. package/src/utils/chalk.js +13 -0
  92. package/src/utils/pipe_utils.js +127 -0
  93. package/src/utils/utils.js +341 -0
  94. package/src/xmlReader.js +551 -0
  95. package/lib/bin/cli.js +0 -216
  96. package/lib/bin/uploadArtifacts.js +0 -86
  97. package/lib/uploader.js +0 -312
package/lib/output.js CHANGED
@@ -1,57 +1,49 @@
1
- const { format } = require('util');
2
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const util_1 = require("util");
3
4
  const consoleLog = console.log;
4
5
  const consoleError = console.error;
5
-
6
- const formatArgs = args => format.apply(format, Array.prototype.slice.call(args));
7
-
6
+ const formatArgs = args => util_1.format.apply(util_1.format, Array.prototype.slice.call(args));
8
7
  class Output {
9
- constructor(opts = {}) {
10
- this.filterFn = opts.filterFn || (() => true);
11
- this.reset();
12
- }
13
-
14
- reset() {
15
- this.log = [];
16
- this.stop(); // resotre console log if it was overridden
17
- }
18
-
19
- start() {
20
- const { filterFn } = this;
21
- const self = this;
22
- console.log = (...args) => {
23
- const obj = {};
24
- Error.captureStackTrace(obj);
25
- const logString = formatArgs(args);
26
- if (filterFn(obj.stack)) {
27
- self.log.push(logString);
28
- }
29
- consoleLog(logString);
30
- };
31
-
32
- console.error = (...args) => {
33
- const obj = {};
34
- Error.captureStackTrace(obj);
35
- const logString = formatArgs(args);
36
- if (filterFn(obj.stack)) {
37
- self.log.push(logString);
38
- }
39
- consoleError(logString);
40
- };
41
- }
42
-
43
- push(line) {
44
- this.log.push(line);
45
- }
46
-
47
- text() {
48
- return this.log.join('\n');
49
- }
50
-
51
- stop() {
52
- console.log = consoleLog;
53
- console.error = consoleError;
54
- }
8
+ constructor(opts = {}) {
9
+ this.filterFn = opts.filterFn || (() => true);
10
+ this.reset();
11
+ }
12
+ reset() {
13
+ this.log = [];
14
+ this.stop(); // resotre console log if it was overridden
15
+ }
16
+ start() {
17
+ const { filterFn } = this;
18
+ const self = this;
19
+ console.log = (...args) => {
20
+ const obj = {};
21
+ Error.captureStackTrace(obj);
22
+ const logString = formatArgs(args);
23
+ if (filterFn(obj.stack)) {
24
+ self.log.push(logString);
25
+ }
26
+ consoleLog(logString);
27
+ };
28
+ console.error = (...args) => {
29
+ const obj = {};
30
+ Error.captureStackTrace(obj);
31
+ const logString = formatArgs(args);
32
+ if (filterFn(obj.stack)) {
33
+ self.log.push(logString);
34
+ }
35
+ consoleError(logString);
36
+ };
37
+ }
38
+ push(line) {
39
+ this.log.push(line);
40
+ }
41
+ text() {
42
+ return this.log.join('\n');
43
+ }
44
+ stop() {
45
+ console.log = consoleLog;
46
+ console.error = consoleError;
47
+ }
55
48
  }
56
-
57
49
  module.exports = Output;
@@ -0,0 +1 @@
1
+ {}
@@ -1,254 +1,235 @@
1
- const debug = require('debug')('@testomatio/reporter:pipe:bitbucket');
2
- const { default: axios } = require('axios');
3
- const chalk = require('chalk');
4
- const humanizeDuration = require('humanize-duration');
5
- const merge = require('lodash.merge');
6
- const path = require('path');
7
- const { APP_PREFIX, testomatLogoURL } = require('../constants');
8
- const { ansiRegExp, isSameTest } = require('../utils/utils');
9
- const { statusEmoji, fullName } = require('../utils/pipe_utils');
10
-
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.BitbucketPipe = void 0;
30
+ const constants_js_1 = require("../constants.js");
31
+ const utils_js_1 = require("../utils/utils.js");
32
+ const pipe_utils_js_1 = require("../utils/pipe_utils.js");
33
+ const axios_1 = __importDefault(require("axios"));
34
+ const picocolors_1 = __importDefault(require("picocolors"));
35
+ const humanize_duration_1 = __importDefault(require("humanize-duration"));
36
+ const lodash_merge_1 = __importDefault(require("lodash.merge"));
37
+ const path_1 = __importDefault(require("path"));
38
+ const debug_1 = __importDefault(require("debug"));
39
+ const debug = (0, debug_1.default)('@testomatio/reporter:pipe:bitbucket');
11
40
  //! BITBUCKET_ACCESS_TOKEN environment variable is required for this functionality to work
12
41
  //! and your pipeline trigger should be a pull request
13
-
14
42
  /**
15
43
  * @class BitbucketPipe
16
44
  * @typedef {import('../../types').Pipe} Pipe
17
45
  * @typedef {import('../../types').TestData} TestData
18
46
  */
19
47
  class BitbucketPipe {
20
- constructor(params, store = {}) {
21
- this.isEnabled = false;
22
- this.ENV = process.env;
23
- this.store = store;
24
- this.tests = [];
25
- // Bitbucket PAT looks like bbpat-*****
26
- this.token = params.BITBUCKET_ACCESS_TOKEN || process.env.BITBUCKET_ACCESS_TOKEN || this.ENV.BITBUCKET_ACCESS_TOKEN;
27
- this.hiddenCommentData = `Testomat.io report: ${process.env.BITBUCKET_BRANCH || ''}`;
28
-
29
- debug(
30
- chalk.yellow('Bitbucket Pipe:'),
31
- this.token ? 'TOKEN passed' : '*no token*',
32
- `Project key: ${this.ENV.BITBUCKET_PROJECT_KEY}, Pull request ID: ${this.ENV.BITBUCKET_PR_ID}`,
33
- );
34
-
35
- if (!this.token) {
36
- debug(`Hint: Bitbucket CI variables are unavailable for unprotected branches by default.`);
37
- return;
48
+ constructor(params, store = {}) {
49
+ this.isEnabled = false;
50
+ this.ENV = process.env;
51
+ this.store = store;
52
+ this.tests = [];
53
+ // Bitbucket PAT looks like bbpat-*****
54
+ this.token = params.BITBUCKET_ACCESS_TOKEN || process.env.BITBUCKET_ACCESS_TOKEN || this.ENV.BITBUCKET_ACCESS_TOKEN;
55
+ this.hiddenCommentData = `Testomat.io report: ${process.env.BITBUCKET_BRANCH || ''}`;
56
+ debug(picocolors_1.default.yellow('Bitbucket Pipe:'), this.token ? 'TOKEN passed' : '*no token*', `Project key: ${this.ENV.BITBUCKET_PROJECT_KEY}, Pull request ID: ${this.ENV.BITBUCKET_PR_ID}`);
57
+ if (!this.token) {
58
+ debug(`Hint: Bitbucket CI variables are unavailable for unprotected branches by default.`);
59
+ return;
60
+ }
61
+ this.isEnabled = true;
62
+ debug('Bitbucket Pipe: Enabled');
38
63
  }
39
-
40
- this.isEnabled = true;
41
-
42
- debug('Bitbucket Pipe: Enabled');
43
- }
44
-
45
- async cleanLog(log) {
46
- const stripAnsi = (await import('strip-ansi')).default;
47
- return stripAnsi(log);
48
- }
49
-
50
- // Prepare the run (if needed)
51
- async prepareRun() {}
52
-
53
- // Create a new run (if needed)
54
- async createRun() {}
55
-
56
- addTest(test) {
57
- if (!this.isEnabled) return;
58
-
59
- const index = this.tests.findIndex(t => isSameTest(t, test));
60
- // Update if they were already added
61
- if (index >= 0) {
62
- this.tests[index] = merge(this.tests[index], test);
63
- return;
64
+ async cleanLog(log) {
65
+ const stripAnsi = (await Promise.resolve().then(() => __importStar(require('strip-ansi')))).default;
66
+ return stripAnsi(log);
64
67
  }
65
-
66
- this.tests.push(test);
67
- }
68
-
69
- async finishRun(runParams) {
70
- if (!this.isEnabled) return;
71
-
72
- if (runParams.tests) runParams.tests.forEach(t => this.addTest(t));
73
-
74
- // Clean up the logs from ANSI codes
75
- for (let i = 0; i < this.tests.length; i++) {
76
- this.tests[i].message = await this.cleanLog(this.tests[i].message || '');
77
- this.tests[i].stack = await this.cleanLog(this.tests[i].stack || '');
68
+ // Prepare the run (if needed)
69
+ async prepareRun() { }
70
+ // Create a new run (if needed)
71
+ async createRun() { }
72
+ addTest(test) {
73
+ if (!this.isEnabled)
74
+ return;
75
+ const index = this.tests.findIndex(t => (0, utils_js_1.isSameTest)(t, test));
76
+ // Update if they were already added
77
+ if (index >= 0) {
78
+ this.tests[index] = (0, lodash_merge_1.default)(this.tests[index], test);
79
+ return;
80
+ }
81
+ this.tests.push(test);
78
82
  }
79
-
80
- // Create a comment on Bitbucket
81
- const passedCount = this.tests.filter(t => t.status === 'passed').length;
82
- const failedCount = this.tests.filter(t => t.status === 'failed').length;
83
- const skippedCount = this.tests.filter(t => t.status === 'skipped').length;
84
-
85
- // Constructing the table
86
- let summary = `${this.hiddenCommentData}
83
+ async finishRun(runParams) {
84
+ if (!this.isEnabled)
85
+ return;
86
+ if (runParams.tests)
87
+ runParams.tests.forEach(t => this.addTest(t));
88
+ // Clean up the logs from ANSI codes
89
+ for (let i = 0; i < this.tests.length; i++) {
90
+ this.tests[i].message = await this.cleanLog(this.tests[i].message || '');
91
+ this.tests[i].stack = await this.cleanLog(this.tests[i].stack || '');
92
+ }
93
+ // Create a comment on Bitbucket
94
+ const passedCount = this.tests.filter(t => t.status === 'passed').length;
95
+ const failedCount = this.tests.filter(t => t.status === 'failed').length;
96
+ const skippedCount = this.tests.filter(t => t.status === 'skipped').length;
97
+ // Constructing the table
98
+ let summary = `${this.hiddenCommentData}
87
99
 
88
- | ![Testomat.io Report](${testomatLogoURL}) | ${statusEmoji(
89
- runParams.status,
90
- )} ${runParams.status.toUpperCase()} ${statusEmoji(runParams.status)} |
100
+ | ![Testomat.io Report](${constants_js_1.testomatLogoURL}) | ${(0, pipe_utils_js_1.statusEmoji)(runParams.status)} ${runParams.status.toUpperCase()} ${(0, pipe_utils_js_1.statusEmoji)(runParams.status)} |
91
101
  | --- | --- |
92
102
  | **Tests** | ✔️ **${this.tests.length}** tests run |
93
- | **Summary** | ${statusEmoji('failed')} **${failedCount}** failed; ${statusEmoji(
94
- 'passed',
95
- )} **${passedCount}** passed; **${statusEmoji('skipped')}** ${skippedCount} skipped |
96
- | **Duration** | 🕐 **${humanizeDuration(
97
- parseInt(
98
- this.tests.reduce((a, t) => a + (t.run_time || 0), 0),
99
- 10,
100
- ),
101
- {
102
- maxDecimalPoints: 0,
103
- },
104
- )}** |
103
+ | **Summary** | ${(0, pipe_utils_js_1.statusEmoji)('failed')} **${failedCount}** failed; ${(0, pipe_utils_js_1.statusEmoji)('passed')} **${passedCount}** passed; **${(0, pipe_utils_js_1.statusEmoji)('skipped')}** ${skippedCount} skipped |
104
+ | **Duration** | 🕐 **${(0, humanize_duration_1.default)(parseInt(this.tests.reduce((a, t) => a + (t.run_time || 0), 0), 10), {
105
+ maxDecimalPoints: 0,
106
+ })}** |
105
107
  `;
106
-
107
- if (this.ENV.BITBUCKET_BRANCH && this.ENV.BITBUCKET_COMMIT) {
108
- // eslint-disable-next-line max-len
109
- summary += `| **Job** | 👷 [#${this.ENV.BITBUCKET_BUILD_NUMBER}](https://bitbucket.org/${this.ENV.BITBUCKET_REPO_FULL_NAME}/pipelines/results/${this.ENV.BITBUCKET_BUILD_NUMBER}") by commit: **${this.ENV.BITBUCKET_COMMIT}** |`;
110
- }
111
-
112
- const failures = this.tests
113
- .filter(t => t.status === 'failed')
114
- .slice(0, 20)
115
- .map(t => {
116
- let text = `${statusEmoji('failed')} ${fullName(t)}\n`;
117
- if (t.message) {
118
- text += `> ${t.message
119
- .replace(/[^\x20-\x7E]/g, '')
120
- .replace(ansiRegExp(), '')
121
- .trim()}\n`;
108
+ if (this.ENV.BITBUCKET_BRANCH && this.ENV.BITBUCKET_COMMIT) {
109
+ // eslint-disable-next-line max-len
110
+ summary += `| **Job** | 👷 [#${this.ENV.BITBUCKET_BUILD_NUMBER}](https://bitbucket.org/${this.ENV.BITBUCKET_REPO_FULL_NAME}/pipelines/results/${this.ENV.BITBUCKET_BUILD_NUMBER}") by commit: **${this.ENV.BITBUCKET_COMMIT}** |`;
111
+ }
112
+ const failures = this.tests
113
+ .filter(t => t.status === 'failed')
114
+ .slice(0, 20)
115
+ .map(t => {
116
+ let text = `${(0, pipe_utils_js_1.statusEmoji)('failed')} ${(0, pipe_utils_js_1.fullName)(t)}\n`;
117
+ if (t.message) {
118
+ text += `> ${t.message
119
+ .replace(/[^\x20-\x7E]/g, '')
120
+ .replace((0, utils_js_1.ansiRegExp)(), '')
121
+ .trim()}\n`;
122
+ }
123
+ if (t.stack) {
124
+ text += `\n\`\`\`diff\n${t.stack
125
+ .replace((0, utils_js_1.ansiRegExp)(), '')
126
+ .replace(/^[\s\S]*################\[ Failure \]################/g, '################[ Failure ]################')
127
+ .trim()}\n\`\`\`\n`;
128
+ }
129
+ if (t.artifacts && t.artifacts.length && !this.ENV.TESTOMATIO_PRIVATE_ARTIFACTS) {
130
+ t.artifacts
131
+ .filter(f => !!f)
132
+ .forEach(f => {
133
+ if (f.endsWith('.png')) {
134
+ text += `![Image](${f})\n`;
135
+ }
136
+ else {
137
+ text += `[📄 ${path_1.default.basename(f)}](${f})\n`;
138
+ }
139
+ });
140
+ }
141
+ text += `\n---\n`;
142
+ return text;
143
+ });
144
+ let body = summary;
145
+ if (failures.length) {
146
+ body += `\n🟥 **Failures (${failures.length})**\n\n* ${failures.join('\n* ')}\n`;
147
+ if (failures.length > 10) {
148
+ body += `\n> Notice: Only the first 10 failures are shown.`;
149
+ }
122
150
  }
123
- if (t.stack) {
124
- text += `\n\`\`\`diff\n${t.stack
125
- .replace(ansiRegExp(), '')
126
- .replace(
127
- /^[\s\S]*################\[ Failure \]################/g,
128
- '################[ Failure ]################',
129
- )
130
- .trim()}\n\`\`\`\n`;
151
+ if (this.tests.length > 0) {
152
+ body += `\n\n**🐢 Slowest Tests**\n\n`;
153
+ body += this.tests
154
+ .sort((a, b) => b.run_time - a.run_time)
155
+ .slice(0, 5)
156
+ .map(t => `* **${(0, pipe_utils_js_1.fullName)(t)}** (${(0, humanize_duration_1.default)(parseFloat(t.run_time))})`)
157
+ .join('\n');
131
158
  }
132
- if (t.artifacts && t.artifacts.length && !this.ENV.TESTOMATIO_PRIVATE_ARTIFACTS) {
133
- t.artifacts
134
- .filter(f => !!f)
135
- .forEach(f => {
136
- if (f.endsWith('.png')) {
137
- text += `![Image](${f})\n`;
138
- } else {
139
- text += `[📄 ${path.basename(f)}](${f})\n`;
140
- }
159
+ // Construct Bitbucket API URL for comments
160
+ // eslint-disable-next-line max-len
161
+ const commentsRequestURL = `https://api.bitbucket.org/2.0/repositories/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pullrequests/${this.ENV.BITBUCKET_PR_ID}/comments`;
162
+ // Delete previous report
163
+ await deletePreviousReport(axios_1.default, commentsRequestURL, this.hiddenCommentData, this.token);
164
+ // Add current report
165
+ debug(`Adding comment via URL: ${commentsRequestURL}`);
166
+ debug(`Final Bitbucket API call body: ${body}`);
167
+ try {
168
+ const addCommentResponse = await axios_1.default.post(commentsRequestURL, { content: { raw: body } }, {
169
+ headers: {
170
+ Authorization: `Bearer ${this.token}`,
171
+ 'Content-Type': 'application/json',
172
+ },
141
173
  });
174
+ const commentID = addCommentResponse.data.id;
175
+ // eslint-disable-next-line max-len
176
+ const commentURL = `https://bitbucket.org/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pull-requests/${this.ENV.BITBUCKET_PR_ID}#comment-${commentID}`;
177
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('Bitbucket'), `Report created: ${picocolors_1.default.magenta(commentURL)}`);
142
178
  }
143
- text += `\n---\n`;
144
- return text;
145
- });
146
-
147
- let body = summary;
148
-
149
- if (failures.length) {
150
- body += `\n🟥 **Failures (${failures.length})**\n\n* ${failures.join('\n* ')}\n`;
151
- if (failures.length > 10) {
152
- body += `\n> Notice: Only the first 10 failures are shown.`;
153
- }
154
- }
155
-
156
- if (this.tests.length > 0) {
157
- body += `\n\n**🐢 Slowest Tests**\n\n`;
158
- body += this.tests
159
- .sort((a, b) => b.run_time - a.run_time)
160
- .slice(0, 5)
161
- .map(t => `* **${fullName(t)}** (${humanizeDuration(parseFloat(t.run_time))})`)
162
- .join('\n');
163
- }
164
-
165
- // Construct Bitbucket API URL for comments
166
- // eslint-disable-next-line max-len
167
- const commentsRequestURL = `https://api.bitbucket.org/2.0/repositories/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pullrequests/${this.ENV.BITBUCKET_PR_ID}/comments`;
168
-
169
- // Delete previous report
170
- await deletePreviousReport(axios, commentsRequestURL, this.hiddenCommentData, this.token);
171
-
172
- // Add current report
173
- debug(`Adding comment via URL: ${commentsRequestURL}`);
174
- debug(`Final Bitbucket API call body: ${body}`);
175
-
176
- try {
177
- const addCommentResponse = await axios.post(
178
- commentsRequestURL,
179
- { content: { raw: body } },
180
- {
181
- headers: {
182
- Authorization: `Bearer ${this.token}`,
183
- 'Content-Type': 'application/json',
184
- },
185
- },
186
- );
187
-
188
- const commentID = addCommentResponse.data.id;
189
- // eslint-disable-next-line max-len
190
- const commentURL = `https://bitbucket.org/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pull-requests/${this.ENV.BITBUCKET_PR_ID}#comment-${commentID}`;
191
-
192
- console.log(APP_PREFIX, chalk.yellow('Bitbucket'), `Report created: ${chalk.magenta(commentURL)}`);
193
- } catch (err) {
194
- console.error(
195
- APP_PREFIX,
196
- chalk.yellow('Bitbucket'),
197
- `Couldn't create Bitbucket report\n${err}.
179
+ catch (err) {
180
+ console.error(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('Bitbucket'), `Couldn't create Bitbucket report\n${err}.
198
181
  Request URL: ${commentsRequestURL}
199
- Request data: ${body}`,
200
- );
182
+ Request data: ${body}`);
183
+ }
201
184
  }
202
- }
203
-
204
- toString() {
205
- return 'Bitbucket Reporter';
206
- }
207
-
208
- updateRun() {}
185
+ toString() {
186
+ return 'Bitbucket Reporter';
187
+ }
188
+ updateRun() { }
209
189
  }
210
-
190
+ exports.BitbucketPipe = BitbucketPipe;
211
191
  async function deletePreviousReport(axiosInstance, commentsRequestURL, hiddenCommentData, token) {
212
- if (process.env.BITBUCKET_KEEP_OUTDATED_REPORTS) return;
213
-
214
- // Get comments
215
- let comments = [];
216
-
217
- try {
218
- const response = await axiosInstance.get(commentsRequestURL, {
219
- headers: {
220
- Authorization: `Bearer ${token}`,
221
- 'Content-Type': 'application/json',
222
- },
223
- });
224
- comments = response.data.values;
225
- } catch (e) {
226
- console.error('Error while attempting to retrieve comments on Bitbucket Pull Request:\n', e);
227
- }
228
-
229
- if (!comments.length) return;
230
-
231
- for (const comment of comments) {
232
- // If comment was left by the same workflow
233
- if (comment.content.raw.includes(hiddenCommentData)) {
234
- try {
235
- // Delete previous comment
236
- const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
237
- await axiosInstance.delete(deleteCommentURL, {
238
- headers: {
239
- Authorization: `Bearer ${token}`,
240
- 'Content-Type': 'application/json',
241
- },
192
+ if (process.env.BITBUCKET_KEEP_OUTDATED_REPORTS)
193
+ return;
194
+ // Get comments
195
+ let comments = [];
196
+ try {
197
+ const response = await axiosInstance.get(commentsRequestURL, {
198
+ headers: {
199
+ Authorization: `Bearer ${token}`,
200
+ 'Content-Type': 'application/json',
201
+ },
242
202
  });
243
- } catch (e) {
244
- console.warn(`Can't delete previously added comment with testomat.io report. Ignored.`);
245
- }
246
- // Pass next env var if need to clear all previous reports;
247
- // only the last one is removed by default
248
- if (!process.env.BITBUCKET_REMOVE_ALL_OUTDATED_REPORTS) break;
249
- // TODO: in case of many reports should implement pagination
203
+ comments = response.data.values;
204
+ }
205
+ catch (e) {
206
+ console.error('Error while attempting to retrieve comments on Bitbucket Pull Request:\n', e);
207
+ }
208
+ if (!comments.length)
209
+ return;
210
+ for (const comment of comments) {
211
+ // If comment was left by the same workflow
212
+ if (comment.content.raw.includes(hiddenCommentData)) {
213
+ try {
214
+ // Delete previous comment
215
+ const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
216
+ await axiosInstance.delete(deleteCommentURL, {
217
+ headers: {
218
+ Authorization: `Bearer ${token}`,
219
+ 'Content-Type': 'application/json',
220
+ },
221
+ });
222
+ }
223
+ catch (e) {
224
+ console.warn(`Can't delete previously added comment with testomat.io report. Ignored.`);
225
+ }
226
+ // Pass next env var if need to clear all previous reports;
227
+ // only the last one is removed by default
228
+ if (!process.env.BITBUCKET_REMOVE_ALL_OUTDATED_REPORTS)
229
+ break;
230
+ // TODO: in case of many reports should implement pagination
231
+ }
250
232
  }
251
- }
252
233
  }
253
234
 
254
- module.exports = BitbucketPipe;
235
+ module.exports.BitbucketPipe = BitbucketPipe;