@testomatio/reporter 2.0.1-beta.4 → 2.0.1-beta.5-timestamp

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