@testomatio/reporter 2.3.9-beta-bin-fix → 2.4.0

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 (62) hide show
  1. package/README.md +3 -2
  2. package/lib/adapter/codecept.js +12 -9
  3. package/lib/bin/cli.js +40 -11
  4. package/lib/bin/reportXml.js +5 -2
  5. package/lib/client.d.ts +1 -11
  6. package/lib/client.js +57 -152
  7. package/lib/data-storage.d.ts +1 -1
  8. package/lib/helpers.d.ts +1 -0
  9. package/lib/helpers.js +4 -0
  10. package/lib/junit-adapter/csharp.d.ts +0 -1
  11. package/lib/junit-adapter/csharp.js +43 -7
  12. package/lib/junit-adapter/nunit-parser.d.ts +82 -0
  13. package/lib/junit-adapter/nunit-parser.js +433 -0
  14. package/lib/pipe/bitbucket.js +5 -5
  15. package/lib/pipe/coverage.d.ts +82 -0
  16. package/lib/pipe/coverage.js +373 -0
  17. package/lib/pipe/gitlab.js +4 -4
  18. package/lib/pipe/index.js +2 -0
  19. package/lib/pipe/testomatio.d.ts +3 -2
  20. package/lib/pipe/testomatio.js +44 -18
  21. package/lib/reporter-functions.js +14 -12
  22. package/lib/reporter.d.ts +31 -21
  23. package/lib/reporter.js +40 -5
  24. package/lib/services/artifacts.d.ts +1 -1
  25. package/lib/services/key-values.d.ts +1 -1
  26. package/lib/services/links.d.ts +1 -1
  27. package/lib/services/logger.d.ts +1 -1
  28. package/lib/uploader.js +4 -0
  29. package/lib/utils/log-formatter.d.ts +28 -0
  30. package/lib/utils/log-formatter.js +127 -0
  31. package/lib/utils/pipe_utils.d.ts +15 -0
  32. package/lib/utils/pipe_utils.js +44 -2
  33. package/lib/utils/utils.d.ts +6 -0
  34. package/lib/utils/utils.js +260 -25
  35. package/lib/xmlReader.d.ts +32 -26
  36. package/lib/xmlReader.js +121 -52
  37. package/package.json +12 -7
  38. package/src/adapter/codecept.js +19 -19
  39. package/src/adapter/mocha.js +1 -1
  40. package/src/adapter/playwright.js +2 -2
  41. package/src/bin/cli.js +51 -13
  42. package/src/bin/reportXml.js +5 -2
  43. package/src/client.js +69 -130
  44. package/src/helpers.js +1 -0
  45. package/src/junit-adapter/csharp.js +48 -6
  46. package/src/junit-adapter/nunit-parser.js +474 -0
  47. package/src/pipe/bitbucket.js +5 -5
  48. package/src/pipe/coverage.js +440 -0
  49. package/src/pipe/debug.js +1 -2
  50. package/src/pipe/gitlab.js +4 -4
  51. package/src/pipe/index.js +2 -0
  52. package/src/pipe/testomatio.js +109 -85
  53. package/src/reporter-functions.js +15 -12
  54. package/src/reporter.js +6 -4
  55. package/src/services/links.js +1 -1
  56. package/src/uploader.js +5 -0
  57. package/src/utils/log-formatter.js +113 -0
  58. package/src/utils/pipe_utils.js +52 -3
  59. package/src/utils/utils.js +277 -22
  60. package/src/xmlReader.js +144 -46
  61. package/types/types.d.ts +364 -0
  62. package/types/vitest.types.d.ts +93 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Enhanced NUnit XML Parser that properly handles test-suite hierarchy
3
+ * and parameterized tests
4
+ */
5
+ export class NUnitXmlParser {
6
+ constructor(options?: {});
7
+ options: {};
8
+ tests: any[];
9
+ stats: {
10
+ total: number;
11
+ passed: number;
12
+ failed: number;
13
+ skipped: number;
14
+ inconclusive: number;
15
+ };
16
+ /**
17
+ * Parse NUnit XML test-run structure
18
+ * @param {Object} testRun - Parsed XML test-run object
19
+ * @returns {Object} - Parsed test results
20
+ */
21
+ parseTestRun(testRun: any): any;
22
+ /**
23
+ * Recursively parse test-suite elements based on their type
24
+ * @param {Object|Array} testSuite - Test suite object or array
25
+ * @param {Array} parentPath - Current path in the hierarchy
26
+ */
27
+ parseTestSuite(testSuite: any | any[], parentPath?: any[]): void;
28
+ /**
29
+ * Process child elements of a test suite
30
+ * @param {Object} testSuite - Test suite object
31
+ * @param {Array} currentPath - Current path in hierarchy
32
+ */
33
+ processChildren(testSuite: any, currentPath: any[]): void;
34
+ /**
35
+ * Parse test-case elements (actual tests)
36
+ * @param {Object|Array} testCases - Test case object or array
37
+ * @param {Array} suitePath - Path to the test suite
38
+ * @param {Object} parentSuite - Parent test suite for context
39
+ */
40
+ parseTestCases(testCases: any | any[], suitePath: any[], parentSuite: any): void;
41
+ /**
42
+ * Parse individual test case
43
+ * @param {Object} testCase - Test case object
44
+ * @param {Array} suitePath - Path to the test suite
45
+ * @param {Object} parentSuite - Parent test suite for context
46
+ * @returns {Object|null} - Parsed test object
47
+ */
48
+ parseTestCase(testCase: any, suitePath: any[], parentSuite: any): any | null;
49
+ /**
50
+ * Extract method name and parameters from test name
51
+ * @param {string} testName - Full test name
52
+ * @returns {Object} - Extracted information
53
+ */
54
+ extractParameters(testName: string): any;
55
+ /**
56
+ * Parse parameter string into array of parameters
57
+ * @param {string} paramString - Parameter string
58
+ * @returns {Array} - Array of parameters
59
+ */
60
+ parseParameterString(paramString: string): any[];
61
+ /**
62
+ * Extract method name from test name (fallback)
63
+ * @param {string} testName - Test name
64
+ * @returns {string} - Method name
65
+ */
66
+ extractMethodName(testName: string): string;
67
+ /**
68
+ * Build file path from suite path and class name
69
+ * @param {Array} suitePath - Suite path array
70
+ * @param {string} className - Class name
71
+ * @param {Object} parentSuite - Parent suite for context
72
+ * @returns {string} - File path
73
+ */
74
+ buildFilePath(suitePath: any[], className: string, parentSuite: any): string;
75
+ /**
76
+ * Group parameterized tests by base method name
77
+ * @param {Array} tests - Array of parsed tests
78
+ * @returns {Object} - Grouped tests
79
+ */
80
+ groupParameterizedTests(tests: any[]): any;
81
+ }
82
+ export default NUnitXmlParser;
@@ -0,0 +1,433 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NUnitXmlParser = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const constants_js_1 = require("../constants.js");
9
+ const utils_js_1 = require("../utils/utils.js");
10
+ const debug = (0, debug_1.default)('@testomatio/reporter:nunit-parser');
11
+ /**
12
+ * Enhanced NUnit XML Parser that properly handles test-suite hierarchy
13
+ * and parameterized tests
14
+ */
15
+ class NUnitXmlParser {
16
+ constructor(options = {}) {
17
+ this.options = options;
18
+ this.tests = [];
19
+ this.stats = {
20
+ total: 0,
21
+ passed: 0,
22
+ failed: 0,
23
+ skipped: 0,
24
+ inconclusive: 0,
25
+ };
26
+ }
27
+ /**
28
+ * Parse NUnit XML test-run structure
29
+ * @param {Object} testRun - Parsed XML test-run object
30
+ * @returns {Object} - Parsed test results
31
+ */
32
+ parseTestRun(testRun) {
33
+ debug('Parsing NUnit test-run');
34
+ // Extract run-level statistics
35
+ this.stats = {
36
+ total: parseInt(testRun.total || 0, 10),
37
+ passed: parseInt(testRun.passed || 0, 10),
38
+ failed: parseInt(testRun.failed || 0, 10),
39
+ skipped: parseInt(testRun.skipped || 0, 10),
40
+ inconclusive: parseInt(testRun.inconclusive || 0, 10),
41
+ };
42
+ // Process the root test-suite
43
+ if (testRun['test-suite']) {
44
+ this.parseTestSuite(testRun['test-suite'], []);
45
+ }
46
+ debug(`Parsed ${this.tests.length} tests from NUnit XML`);
47
+ return {
48
+ status: testRun.result?.toLowerCase() || 'unknown',
49
+ create_tests: true,
50
+ tests_count: this.tests.length,
51
+ passed_count: this.tests.filter(t => t.status === constants_js_1.STATUS.PASSED).length,
52
+ failed_count: this.tests.filter(t => t.status === constants_js_1.STATUS.FAILED).length,
53
+ skipped_count: this.tests.filter(t => t.status === constants_js_1.STATUS.SKIPPED).length,
54
+ tests: this.tests,
55
+ };
56
+ }
57
+ /**
58
+ * Recursively parse test-suite elements based on their type
59
+ * @param {Object|Array} testSuite - Test suite object or array
60
+ * @param {Array} parentPath - Current path in the hierarchy
61
+ */
62
+ parseTestSuite(testSuite, parentPath = []) {
63
+ if (!testSuite)
64
+ return;
65
+ // Handle arrays of test suites
66
+ if (Array.isArray(testSuite)) {
67
+ testSuite.forEach(suite => this.parseTestSuite(suite, parentPath));
68
+ return;
69
+ }
70
+ const suiteType = testSuite.type;
71
+ const suiteName = testSuite.name;
72
+ const fullName = testSuite.fullname;
73
+ debug(`Processing test-suite: type=${suiteType}, name=${suiteName}`);
74
+ switch (suiteType) {
75
+ case 'Assembly':
76
+ // Assembly level - ignore the name, just process children
77
+ debug('Processing Assembly level - ignoring name, processing children');
78
+ this.processChildren(testSuite, parentPath);
79
+ break;
80
+ case 'TestSuite':
81
+ // Namespace/grouping level - add to path but don't create test
82
+ debug(`Processing TestSuite level - adding '${suiteName}' to path`);
83
+ // Avoid adding duplicate suite names to the path
84
+ const newPath = parentPath[parentPath.length - 1] === suiteName ? [...parentPath] : [...parentPath, suiteName];
85
+ this.processChildren(testSuite, newPath);
86
+ break;
87
+ case 'TestFixture':
88
+ // Test class level - add to path and process test cases
89
+ debug(`Processing TestFixture level - test class '${suiteName}'`);
90
+ const testFixturePath = [...parentPath, suiteName];
91
+ this.processChildren(testSuite, testFixturePath);
92
+ break;
93
+ case 'ParameterizedMethod':
94
+ // Parameterized method level - process test cases directly
95
+ debug(`Processing ParameterizedMethod level - method '${suiteName}'`);
96
+ // Don't add to path, just process children directly
97
+ this.processChildren(testSuite, parentPath);
98
+ break;
99
+ default:
100
+ debug(`Unknown test-suite type: ${suiteType}, treating as TestSuite`);
101
+ const unknownPath = [...parentPath, suiteName];
102
+ this.processChildren(testSuite, unknownPath);
103
+ break;
104
+ }
105
+ }
106
+ /**
107
+ * Process child elements of a test suite
108
+ * @param {Object} testSuite - Test suite object
109
+ * @param {Array} currentPath - Current path in hierarchy
110
+ */
111
+ processChildren(testSuite, currentPath) {
112
+ // Process test-cases first (to maintain order)
113
+ if (testSuite['test-case']) {
114
+ this.parseTestCases(testSuite['test-case'], currentPath, testSuite);
115
+ }
116
+ // Process nested test-suites
117
+ if (testSuite['test-suite']) {
118
+ this.parseTestSuite(testSuite['test-suite'], currentPath);
119
+ }
120
+ }
121
+ /**
122
+ * Parse test-case elements (actual tests)
123
+ * @param {Object|Array} testCases - Test case object or array
124
+ * @param {Array} suitePath - Path to the test suite
125
+ * @param {Object} parentSuite - Parent test suite for context
126
+ */
127
+ parseTestCases(testCases, suitePath, parentSuite) {
128
+ if (!testCases)
129
+ return;
130
+ // Handle arrays of test cases
131
+ if (!Array.isArray(testCases)) {
132
+ testCases = [testCases];
133
+ }
134
+ testCases.forEach(testCase => {
135
+ const parsedTest = this.parseTestCase(testCase, suitePath, parentSuite);
136
+ if (parsedTest) {
137
+ this.tests.push(parsedTest);
138
+ }
139
+ });
140
+ }
141
+ /**
142
+ * Parse individual test case
143
+ * @param {Object} testCase - Test case object
144
+ * @param {Array} suitePath - Path to the test suite
145
+ * @param {Object} parentSuite - Parent test suite for context
146
+ * @returns {Object|null} - Parsed test object
147
+ */
148
+ parseTestCase(testCase, suitePath, parentSuite) {
149
+ if (!testCase || !testCase.name) {
150
+ debug('Skipping test case without name');
151
+ return null;
152
+ }
153
+ // Use Description from properties if available (for SpecFlow tests), otherwise use name
154
+ let testName = testCase.name;
155
+ if (testCase.properties && testCase.properties.property) {
156
+ const properties = Array.isArray(testCase.properties.property)
157
+ ? testCase.properties.property
158
+ : [testCase.properties.property];
159
+ const descriptionProperty = properties.find(p => p.name === 'Description');
160
+ if (descriptionProperty && descriptionProperty.value) {
161
+ // Clean up SpecFlow description format: [C211256] Allow mobile print behavior -> Allow mobile print behavior
162
+ testName = descriptionProperty.value.replace(/^\[[^\]]+\]\s*/, '');
163
+ }
164
+ }
165
+ const fullName = testCase.fullname;
166
+ const methodName = testCase.methodname || this.extractMethodName(testName);
167
+ const className = testCase.classname || parentSuite?.name;
168
+ debug(`Parsing test case: ${testName}`);
169
+ debug(`Test case structure:`, JSON.stringify(testCase, null, 2));
170
+ // Extract parameters if this is a parameterized test
171
+ const { baseMethodName, parameters, isParameterized } = this.extractParameters(testName);
172
+ // Determine test status
173
+ let status = constants_js_1.STATUS.PASSED;
174
+ if (testCase.result) {
175
+ switch (testCase.result.toLowerCase()) {
176
+ case 'passed':
177
+ status = constants_js_1.STATUS.PASSED;
178
+ break;
179
+ case 'failed':
180
+ status = constants_js_1.STATUS.FAILED;
181
+ break;
182
+ case 'skipped':
183
+ case 'ignored':
184
+ status = constants_js_1.STATUS.SKIPPED;
185
+ break;
186
+ case 'inconclusive':
187
+ status = constants_js_1.STATUS.SKIPPED; // Treat inconclusive as skipped
188
+ break;
189
+ default:
190
+ status = constants_js_1.STATUS.PASSED;
191
+ }
192
+ }
193
+ // Extract error information
194
+ let message = '';
195
+ let stack = '';
196
+ const files = [];
197
+ // Extract attachments (NUnit format)
198
+ if (testCase.attachments) {
199
+ const attachments = Array.isArray(testCase.attachments.attachment)
200
+ ? testCase.attachments.attachment
201
+ : [testCase.attachments.attachment];
202
+ const attachmentFiles = attachments.filter(a => a && a.filePath).map(a => a.filePath);
203
+ files.push(...attachmentFiles);
204
+ }
205
+ if (testCase.failure) {
206
+ message = testCase.failure.message || '';
207
+ stack = testCase.failure['stack-trace'] || testCase.failure['#text'] || '';
208
+ }
209
+ if (testCase.output) {
210
+ const outputText = typeof testCase.output === 'string' ? testCase.output : testCase.output['#text'];
211
+ const stackFiles = (0, utils_js_1.fetchFilesFromStackTrace)(outputText);
212
+ files.push(...stackFiles);
213
+ if (outputText) {
214
+ debug(`Found output in test case: ${outputText.substring(0, 100)}...`);
215
+ stack = `${stack}\n\n${outputText}`.trim();
216
+ }
217
+ else {
218
+ debug('No output text found in test case');
219
+ }
220
+ }
221
+ else {
222
+ debug('No output found in test case');
223
+ }
224
+ // Extract test ID and tags from properties
225
+ let testId = null;
226
+ let tags = [];
227
+ if (testCase.properties && testCase.properties.property) {
228
+ const properties = Array.isArray(testCase.properties.property)
229
+ ? testCase.properties.property
230
+ : [testCase.properties.property];
231
+ const idProperty = properties.find(p => p.name === 'ID');
232
+ if (idProperty) {
233
+ testId = idProperty.value;
234
+ // Remove @ and T prefixes if present
235
+ if (testId.startsWith('@'))
236
+ testId = testId.slice(1);
237
+ if (testId.startsWith('T'))
238
+ testId = testId.slice(1);
239
+ }
240
+ // Extract Category properties as tags
241
+ const categoryProperties = properties.filter(p => p.name === 'Category');
242
+ tags = categoryProperties.map(p => p.value);
243
+ }
244
+ // If no test ID found in properties, try to extract from output
245
+ if (!testId && testCase.output) {
246
+ const outputText = typeof testCase.output === 'string' ? testCase.output : testCase.output['#text'];
247
+ if (outputText) {
248
+ debug(`Looking for test ID in output: ${outputText.substring(0, 200)}...`);
249
+ const idMatch = outputText.match(/\[ID\]\s+tid:\/\/@T([a-f0-9]{8})/i);
250
+ if (idMatch) {
251
+ testId = idMatch[1];
252
+ debug(`Found test ID in output: ${testId}`);
253
+ }
254
+ else {
255
+ debug('No test ID found in output');
256
+ }
257
+ }
258
+ }
259
+ // Build file path from suite path and class name
260
+ const filePath = this.buildFilePath(suitePath, className, parentSuite);
261
+ // For parameterized tests, format example as expected by Testomatio API
262
+ // Convert array of parameters to object with numeric keys
263
+ let example = null;
264
+ if (isParameterized && parameters.length > 0) {
265
+ example = {};
266
+ parameters.forEach((param, index) => {
267
+ example[index] = param;
268
+ });
269
+ }
270
+ return {
271
+ // For runs: use full test name with parameters (TestBooleanValue(true))
272
+ // For import: API will group by base name using the example field
273
+ title: testName, // Full name with parameters for run display
274
+ methodName: baseMethodName || methodName || testName,
275
+ fullName: fullName,
276
+ suitePath: suitePath,
277
+ suite_title: className || suitePath[suitePath.length - 1] || 'Unknown',
278
+ file: filePath,
279
+ files: files, // Array of files that will be attached
280
+ status: status,
281
+ message: message,
282
+ stack: stack,
283
+ run_time: parseFloat(testCase.duration || testCase.time || 0) * 1000,
284
+ test_id: testId,
285
+ tags: tags, // Array of category tags from properties
286
+ create: true,
287
+ retry: false,
288
+ // Parameterized test metadata
289
+ example: example, // Parameters as object for API grouping
290
+ isParameterized: isParameterized,
291
+ parameters: parameters, // Keep original array for reference
292
+ baseMethodName: baseMethodName,
293
+ };
294
+ }
295
+ /**
296
+ * Extract method name and parameters from test name
297
+ * @param {string} testName - Full test name
298
+ * @returns {Object} - Extracted information
299
+ */
300
+ extractParameters(testName) {
301
+ const paramMatch = testName.match(/^(.+?)\((.+)\)$/);
302
+ if (paramMatch) {
303
+ const baseMethodName = paramMatch[1].trim();
304
+ const paramString = paramMatch[2];
305
+ // Parse parameters - handle quoted strings and nested structures
306
+ const parameters = this.parseParameterString(paramString);
307
+ return {
308
+ baseMethodName: baseMethodName,
309
+ parameters: parameters,
310
+ isParameterized: true,
311
+ };
312
+ }
313
+ return {
314
+ baseMethodName: testName,
315
+ parameters: [],
316
+ isParameterized: false,
317
+ };
318
+ }
319
+ /**
320
+ * Parse parameter string into array of parameters
321
+ * @param {string} paramString - Parameter string
322
+ * @returns {Array} - Array of parameters
323
+ */
324
+ parseParameterString(paramString) {
325
+ const parameters = [];
326
+ let current = '';
327
+ let inQuotes = false;
328
+ let quoteChar = null;
329
+ let depth = 0;
330
+ for (let i = 0; i < paramString.length; i++) {
331
+ const char = paramString[i];
332
+ if (!inQuotes && (char === '"' || char === "'")) {
333
+ inQuotes = true;
334
+ quoteChar = char;
335
+ current += char;
336
+ }
337
+ else if (inQuotes && char === quoteChar) {
338
+ inQuotes = false;
339
+ quoteChar = null;
340
+ current += char;
341
+ }
342
+ else if (!inQuotes && char === '(') {
343
+ depth++;
344
+ current += char;
345
+ }
346
+ else if (!inQuotes && char === ')') {
347
+ depth--;
348
+ current += char;
349
+ }
350
+ else if (!inQuotes && char === ',' && depth === 0) {
351
+ parameters.push(current.trim());
352
+ current = '';
353
+ }
354
+ else {
355
+ current += char;
356
+ }
357
+ }
358
+ if (current.trim()) {
359
+ parameters.push(current.trim());
360
+ }
361
+ // Clean up parameters - remove quotes if they wrap the entire parameter and filter empty ones
362
+ return parameters
363
+ .map(param => {
364
+ param = param.trim();
365
+ if ((param.startsWith('"') && param.endsWith('"')) || (param.startsWith("'") && param.endsWith("'"))) {
366
+ return param.slice(1, -1);
367
+ }
368
+ return param;
369
+ })
370
+ .filter(p => !!p);
371
+ }
372
+ /**
373
+ * Extract method name from test name (fallback)
374
+ * @param {string} testName - Test name
375
+ * @returns {string} - Method name
376
+ */
377
+ extractMethodName(testName) {
378
+ // Remove parameters if present
379
+ const paramMatch = testName.match(/^(.+?)\(/);
380
+ return paramMatch ? paramMatch[1].trim() : testName;
381
+ }
382
+ /**
383
+ * Build file path from suite path and class name
384
+ * @param {Array} suitePath - Suite path array
385
+ * @param {string} className - Class name
386
+ * @param {Object} parentSuite - Parent suite for context
387
+ * @returns {string} - File path
388
+ */
389
+ buildFilePath(suitePath, className, parentSuite) {
390
+ // Try to get file path from parent suite
391
+ if (parentSuite && parentSuite.filepath) {
392
+ return parentSuite.filepath;
393
+ }
394
+ // Build path from suite hierarchy
395
+ const pathParts = [...suitePath];
396
+ if (className && !pathParts.includes(className)) {
397
+ pathParts.push(className);
398
+ }
399
+ // Convert to file path format
400
+ return pathParts.join('/') + '.cs'; // Assume C# for NUnit
401
+ }
402
+ /**
403
+ * Group parameterized tests by base method name
404
+ * @param {Array} tests - Array of parsed tests
405
+ * @returns {Object} - Grouped tests
406
+ */
407
+ groupParameterizedTests(tests) {
408
+ const grouped = {};
409
+ tests.forEach(test => {
410
+ const key = test.isParameterized
411
+ ? `${test.suitePath.join('.')}.${test.baseMethodName}`
412
+ : `${test.suitePath.join('.')}.${test.title}`;
413
+ if (!grouped[key]) {
414
+ grouped[key] = {
415
+ baseTest: {
416
+ name: test.baseMethodName || test.title,
417
+ suitePath: test.suitePath,
418
+ suite_title: test.suite_title,
419
+ file: test.file,
420
+ isParameterized: test.isParameterized,
421
+ },
422
+ variations: [],
423
+ };
424
+ }
425
+ grouped[key].variations.push(test);
426
+ });
427
+ return grouped;
428
+ }
429
+ }
430
+ exports.NUnitXmlParser = NUnitXmlParser;
431
+ module.exports = NUnitXmlParser;
432
+
433
+ module.exports.NUnitXmlParser = NUnitXmlParser;
@@ -73,8 +73,8 @@ class BitbucketPipe {
73
73
  baseURL: 'https://api.bitbucket.org/2.0',
74
74
  headers: {
75
75
  'Content-Type': 'application/json',
76
- 'Authorization': `Bearer ${this.token}`
77
- }
76
+ Authorization: `Bearer ${this.token}`,
77
+ },
78
78
  });
79
79
  debug('Bitbucket Pipe: Enabled');
80
80
  }
@@ -185,7 +185,7 @@ class BitbucketPipe {
185
185
  const addCommentResponse = await this.client.request({
186
186
  method: 'POST',
187
187
  url: commentsRequestURL,
188
- data: { content: { raw: body } }
188
+ data: { content: { raw: body } },
189
189
  });
190
190
  const commentID = addCommentResponse.data.id;
191
191
  // eslint-disable-next-line max-len
@@ -212,7 +212,7 @@ async function deletePreviousReport(client, commentsRequestURL, hiddenCommentDat
212
212
  try {
213
213
  const response = await client.request({
214
214
  method: 'GET',
215
- url: commentsRequestURL
215
+ url: commentsRequestURL,
216
216
  });
217
217
  comments = response.data.values;
218
218
  }
@@ -229,7 +229,7 @@ async function deletePreviousReport(client, commentsRequestURL, hiddenCommentDat
229
229
  const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
230
230
  await client.request({
231
231
  method: 'DELETE',
232
- url: deleteCommentURL
232
+ url: deleteCommentURL,
233
233
  });
234
234
  }
235
235
  catch (e) {
@@ -0,0 +1,82 @@
1
+ export default CoveragePipe;
2
+ declare class CoveragePipe {
3
+ constructor(params: any, store: any);
4
+ id: string;
5
+ store: any;
6
+ branch: any;
7
+ isDefaultGitChanges: boolean;
8
+ isEnabled: boolean;
9
+ coverageFilePath: any;
10
+ isBranchDefault: boolean;
11
+ formattedDate: string;
12
+ title: string;
13
+ apiKey: string;
14
+ url: any;
15
+ client: Gaxios;
16
+ parsedCoverage: {};
17
+ changedFiles: any[];
18
+ matchedLines: Set<any>;
19
+ tests: Set<any>;
20
+ suiteIds: Set<any>;
21
+ tagLabels: Set<any>;
22
+ results: any[];
23
+ prepareRun(opts: any): Promise<any[]>;
24
+ addTest(data: any): void;
25
+ createRun(): Promise<void>;
26
+ updateRun(): void;
27
+ finishRun(runParams: any): Promise<void>;
28
+ toString(): string;
29
+ /**
30
+ * Retrieves the list of files changed in the current Git working directory
31
+ * compared to a specified branch.
32
+ *
33
+ * This method builds a Git diff command and attempts to retrieve the changed
34
+ * files using that command. It logs helpful information and errors during the process.
35
+ *
36
+ * If no changed files are found, or an error occurs at any stage, the method logs
37
+ * the issue and returns `undefined`.
38
+ *
39
+ * @returns {this | undefined} Returns the current instance (`this`) if changed files are found;
40
+ * otherwise, returns `undefined`.
41
+ */
42
+ getGitChangedFiles(): this | undefined;
43
+ /**
44
+ * Validates the coverage file path (stored in `this.coverageFilePath`).
45
+ *
46
+ * This method checks:
47
+ * - That the file exists on disk.
48
+ * - That it is a regular file (not a directory or special file).
49
+ * - That it has a `.yml` extension to ensure it's a YAML file.
50
+ *
51
+ * Logs descriptive error messages for any failures.
52
+ *
53
+ * @returns {this | undefined} "true" in case if coverage file is valid and we can keep going;
54
+ * otherwise, `undefined`.
55
+ */
56
+ validateCoverageFile(): this | undefined;
57
+ /**
58
+ * Parses the YAML coverage file (located at `this.coverageFilePath`) into a JavaScript object.
59
+ *
60
+ * - Reads the file content using UTF-8 encoding.
61
+ * - Parses it as YAML using the `yaml` library.
62
+ * - Stores the result in `this.parsedCoverage`.
63
+ * - If parsing fails, logs an error and returns `undefined`.
64
+ *
65
+ * @returns {this | undefined} The current parsed coverage yml file change lines, or "undefined" if parsing fails.
66
+ */
67
+ parseCoverageFile(): this | undefined;
68
+ /**
69
+ * Extracts relevant test identifiers from changed files based on coverage mapping.
70
+ *
71
+ * Iterates over changed files and matches them against patterns in the parsed coverage data.
72
+ * For each match, it extracts test IDs or tags and stores them in corresponding sets:
73
+ * - Test IDs (starting with '@T' or '@S') are stored in `this.tests`
74
+ * - Tag labels (starting with 'tag:') are stored in `this.tagLabels`
75
+ * - Matched file paths are stored in `this.matchedLines`
76
+ *
77
+ * @returns {Promise <Set<string>>} A set of file paths that matched coverage patterns (`this.matchedLines`).
78
+ */
79
+ extractRelevantTestsFromChanges(): Promise<Set<string>>;
80
+ #private;
81
+ }
82
+ import { Gaxios } from 'gaxios';