@testomatio/reporter 2.6.0-beta.1.allure → 2.6.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.
- package/README.md +9 -11
- package/lib/adapter/playwright.d.ts +2 -0
- package/lib/adapter/playwright.js +29 -5
- package/lib/adapter/utils/playwright.d.ts +25 -0
- package/lib/adapter/utils/playwright.js +123 -0
- package/lib/adapter/vitest.js +2 -1
- package/lib/bin/cli.js +36 -36
- package/lib/data-storage.d.ts +1 -1
- package/lib/data-storage.js +1 -0
- package/lib/junit-adapter/index.js +0 -4
- package/lib/pipe/coverage.js +63 -5
- package/lib/pipe/debug.js +1 -2
- package/lib/pipe/github.js +15 -0
- package/lib/pipe/html.d.ts +2 -3
- package/lib/pipe/html.js +745 -37
- package/lib/pipe/testomatio.js +83 -36
- package/lib/reporter-functions.d.ts +36 -11
- package/lib/reporter-functions.js +72 -22
- package/lib/reporter.d.ts +90 -38
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/links.d.ts +5 -3
- package/lib/services/links.js +1 -1
- package/lib/services/logger.d.ts +1 -1
- package/lib/template/testomatio-old.hbs +1421 -0
- package/lib/template/testomatio.hbs +3200 -1157
- package/lib/utils/log-formatter.d.ts +1 -2
- package/lib/utils/log-formatter.js +8 -4
- package/lib/utils/utils.js +0 -9
- package/package.json +2 -2
- package/src/adapter/playwright.js +32 -6
- package/src/adapter/utils/playwright.js +121 -0
- package/src/adapter/vitest.js +2 -1
- package/src/bin/cli.js +39 -47
- package/src/data-storage.js +1 -0
- package/src/junit-adapter/index.js +0 -4
- package/src/pipe/coverage.js +90 -32
- package/src/pipe/debug.js +1 -2
- package/src/pipe/github.js +14 -0
- package/src/pipe/html.js +844 -38
- package/src/pipe/testomatio.js +98 -53
- package/src/reporter-functions.js +73 -25
- package/src/services/links.js +1 -1
- package/src/template/testomatio-old.hbs +1421 -0
- package/src/template/testomatio.hbs +3200 -1157
- package/src/utils/log-formatter.js +9 -4
- package/src/utils/utils.js +0 -5
- package/types/types.d.ts +30 -6
- package/lib/allureReader.d.ts +0 -65
- package/lib/allureReader.js +0 -448
- package/lib/junit-adapter/kotlin.d.ts +0 -5
- package/lib/junit-adapter/kotlin.js +0 -46
- package/lib/services/labels.d.ts +0 -0
- package/lib/services/labels.js +0 -0
- package/src/allureReader.js +0 -523
- package/src/junit-adapter/kotlin.js +0 -48
- package/src/services/labels.js +0 -1
package/src/pipe/coverage.js
CHANGED
|
@@ -54,7 +54,7 @@ class CoveragePipe { // or Changes for the future???
|
|
|
54
54
|
|
|
55
55
|
this.branch = options?.diff || process.env.COVERAGE_BRANCH || this.#GIT.default_branch;
|
|
56
56
|
this.isBranchDefault = !options.diff && !process.env.COVERAGE_BRANCH;
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
if (this.isBranchDefault) {
|
|
59
59
|
console.log(
|
|
60
60
|
APP_PREFIX,
|
|
@@ -98,7 +98,7 @@ class CoveragePipe { // or Changes for the future???
|
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
// In case if we have all needed data
|
|
101
|
+
// In case if we have all needed data
|
|
102
102
|
this.isEnabled = true;
|
|
103
103
|
|
|
104
104
|
debug('Coverage Pipe initialized', {
|
|
@@ -108,7 +108,7 @@ class CoveragePipe { // or Changes for the future???
|
|
|
108
108
|
|
|
109
109
|
this.parsedCoverage = {};
|
|
110
110
|
this.changedFiles = [];
|
|
111
|
-
this.matchedLines = new Set();
|
|
111
|
+
this.matchedLines = new Set();
|
|
112
112
|
this.tests = new Set();
|
|
113
113
|
this.suiteIds = new Set();
|
|
114
114
|
this.tagLabels = new Set();
|
|
@@ -118,12 +118,15 @@ class CoveragePipe { // or Changes for the future???
|
|
|
118
118
|
debug(`Coverage Pipe: is Enabled = ${this.isEnabled}`);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
async prepareRun(opts) {
|
|
121
|
+
async prepareRun(opts) {
|
|
122
122
|
// Reset internal mutable state for isolation
|
|
123
123
|
this.tests.clear();
|
|
124
124
|
this.suiteIds.clear();
|
|
125
125
|
this.tagLabels.clear();
|
|
126
126
|
this.results = [];
|
|
127
|
+
if (this.store) {
|
|
128
|
+
this.store.coverageConfiguration = undefined;
|
|
129
|
+
}
|
|
127
130
|
|
|
128
131
|
if (!this.isEnabled) return [];
|
|
129
132
|
|
|
@@ -132,6 +135,9 @@ class CoveragePipe { // or Changes for the future???
|
|
|
132
135
|
|
|
133
136
|
// Step 2: Extract all available tests and compare with coverage file
|
|
134
137
|
const lines = await this.extractRelevantTestsFromChanges();
|
|
138
|
+
if (this.store?.filterList && lines.size > 0) {
|
|
139
|
+
console.log(APP_PREFIX, `Matched files: ${[...lines].join(', ')}`);
|
|
140
|
+
}
|
|
135
141
|
|
|
136
142
|
if (lines.size === 0) {
|
|
137
143
|
console.log(APP_PREFIX, 'ℹ️ No matching entries in coverage file for provided Git changes.');
|
|
@@ -148,22 +154,33 @@ class CoveragePipe { // or Changes for the future???
|
|
|
148
154
|
if (!tests) return [];
|
|
149
155
|
|
|
150
156
|
console.log(
|
|
151
|
-
APP_PREFIX,
|
|
157
|
+
APP_PREFIX,
|
|
152
158
|
`✅ We found ${tests.length === 1 ? 'one entry' : `${tests.length} (test/suite) entries`}` +
|
|
153
159
|
' in Testomat.io service side.'
|
|
154
160
|
);
|
|
155
|
-
|
|
161
|
+
|
|
156
162
|
tests.forEach(testId => this.tests.add(testId));
|
|
157
|
-
}
|
|
163
|
+
}
|
|
158
164
|
}
|
|
159
165
|
|
|
160
|
-
if (this.tests.size === 0) {
|
|
161
|
-
console.log(APP_PREFIX, 'ℹ️ No tests found for execution based on Git changes.');
|
|
166
|
+
if (this.tests.size === 0 && this.suiteIds.size === 0) {
|
|
167
|
+
console.log(APP_PREFIX, 'ℹ️ No tests found for execution based on Git changes.');
|
|
162
168
|
return [];
|
|
163
169
|
}
|
|
164
170
|
|
|
165
|
-
this.results = [...this.tests];
|
|
166
|
-
|
|
171
|
+
this.results = [...this.tests, ...this.suiteIds];
|
|
172
|
+
if (this.store) {
|
|
173
|
+
this.store.coverageConfiguration = {
|
|
174
|
+
tests: [...this.tests],
|
|
175
|
+
suites: [...this.suiteIds],
|
|
176
|
+
};
|
|
177
|
+
this.store.coverageDescription = this.#buildRunDescription({
|
|
178
|
+
matchedLines: lines,
|
|
179
|
+
testsCount: this.tests.size,
|
|
180
|
+
suitesCount: this.suiteIds.size,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
167
184
|
return this.results;
|
|
168
185
|
}
|
|
169
186
|
|
|
@@ -214,18 +231,18 @@ class CoveragePipe { // or Changes for the future???
|
|
|
214
231
|
|
|
215
232
|
if (!Array.isArray(resp.data?.tests) && resp.data?.tests?.length === 0) {
|
|
216
233
|
console.log(APP_PREFIX, `🔍 No test by ${type}=${id} were found on the Testomat.io server side!`);
|
|
217
|
-
|
|
234
|
+
|
|
218
235
|
return undefined;
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
return resp.data.tests;
|
|
222
|
-
}
|
|
239
|
+
}
|
|
223
240
|
catch (err) {
|
|
224
241
|
console.error(
|
|
225
242
|
APP_PREFIX,
|
|
226
243
|
`🚩 Error getting available tests from the Testomat.io by "test_grep" option: ${err}`
|
|
227
244
|
);
|
|
228
|
-
|
|
245
|
+
|
|
229
246
|
return undefined;
|
|
230
247
|
}
|
|
231
248
|
}
|
|
@@ -243,48 +260,48 @@ class CoveragePipe { // or Changes for the future???
|
|
|
243
260
|
encoding: 'utf-8',
|
|
244
261
|
stdio: ['pipe', 'pipe', 'ignore']
|
|
245
262
|
});
|
|
246
|
-
|
|
263
|
+
|
|
247
264
|
return result
|
|
248
265
|
.split('\n')
|
|
249
266
|
.map(f => f.trim())
|
|
250
267
|
.filter(Boolean);
|
|
251
|
-
}
|
|
268
|
+
}
|
|
252
269
|
catch (err) {
|
|
253
270
|
const errorMessage = err.message || '';
|
|
254
271
|
// Git edge: Not a git repository or other error
|
|
255
272
|
if (errorMessage.includes('Not a git repository')) {
|
|
256
273
|
console.error(APP_PREFIX, '❌ Error: This folder is not a Git repository.');
|
|
257
|
-
}
|
|
274
|
+
}
|
|
258
275
|
else {
|
|
259
276
|
throw new Error(`❌ Git command failed ("${cmd}"):\n`, errorMessage);
|
|
260
277
|
}
|
|
261
|
-
|
|
278
|
+
|
|
262
279
|
return [];
|
|
263
280
|
}
|
|
264
281
|
}
|
|
265
282
|
|
|
266
283
|
/**
|
|
267
|
-
* Builds a Git command string to list file changes between the current state
|
|
284
|
+
* Builds a Git command string to list file changes between the current state
|
|
268
285
|
* and a specified Git branch using `git diff --name-only`.
|
|
269
|
-
*
|
|
286
|
+
*
|
|
270
287
|
* Private pipe function
|
|
271
288
|
* @throws {Error} Throws an error if `this.branch` is not defined.
|
|
272
289
|
* @returns {string} A Git command string, e.g., 'git diff <branch> --name-only'.
|
|
273
290
|
*/
|
|
274
291
|
#buildGitCommand() {
|
|
275
292
|
if (!this.branch) throw new Error(`❌ Invalid changes option for setted branch!`);
|
|
276
|
-
|
|
277
|
-
return `git diff ${this.branch} --name-only`; // Example: 'git diff <master> --name-only'
|
|
293
|
+
|
|
294
|
+
return `git diff ${this.branch} --name-only`; // Example: 'git diff <master> --name-only'
|
|
278
295
|
}
|
|
279
296
|
|
|
280
297
|
/**
|
|
281
|
-
* Retrieves the list of files changed in the current Git working directory
|
|
298
|
+
* Retrieves the list of files changed in the current Git working directory
|
|
282
299
|
* compared to a specified branch.
|
|
283
300
|
*
|
|
284
|
-
* This method builds a Git diff command and attempts to retrieve the changed
|
|
301
|
+
* This method builds a Git diff command and attempts to retrieve the changed
|
|
285
302
|
* files using that command. It logs helpful information and errors during the process.
|
|
286
303
|
*
|
|
287
|
-
* If no changed files are found, or an error occurs at any stage, the method logs
|
|
304
|
+
* If no changed files are found, or an error occurs at any stage, the method logs
|
|
288
305
|
* the issue and returns `undefined`.
|
|
289
306
|
*
|
|
290
307
|
* @returns {this | undefined} Returns the current instance (`this`) if changed files are found;
|
|
@@ -295,12 +312,12 @@ class CoveragePipe { // or Changes for the future???
|
|
|
295
312
|
|
|
296
313
|
try {
|
|
297
314
|
cmd = this.#buildGitCommand();
|
|
298
|
-
}
|
|
315
|
+
}
|
|
299
316
|
catch (err) {
|
|
300
317
|
console.error(APP_PREFIX, err.message);
|
|
301
318
|
return undefined;
|
|
302
319
|
}
|
|
303
|
-
|
|
320
|
+
|
|
304
321
|
console.error(APP_PREFIX, `ℹ️ We will use '${cmd}' Git command.`);
|
|
305
322
|
|
|
306
323
|
try {
|
|
@@ -325,9 +342,9 @@ class CoveragePipe { // or Changes for the future???
|
|
|
325
342
|
console.error(APP_PREFIX, err.message);
|
|
326
343
|
console.error(APP_PREFIX, "🔍 Pls, check this Git command manually to understand the original problem.");
|
|
327
344
|
return undefined;
|
|
328
|
-
}
|
|
345
|
+
}
|
|
329
346
|
|
|
330
|
-
console.log(APP_PREFIX, `📑 GIT changed files:\n - ${this.changedFiles.join('\n - ')}`);
|
|
347
|
+
console.log(APP_PREFIX, `📑 GIT changed files:\n - ${this.changedFiles.join('\n - ')}`);
|
|
331
348
|
return this;
|
|
332
349
|
}
|
|
333
350
|
|
|
@@ -412,7 +429,7 @@ class CoveragePipe { // or Changes for the future???
|
|
|
412
429
|
for (const [pattern, ids] of Object.entries(this.parsedCoverage)) {
|
|
413
430
|
if (minimatch(changedFile, pattern)) {
|
|
414
431
|
this.matchedLines.add(changedFile);
|
|
415
|
-
|
|
432
|
+
|
|
416
433
|
ids.forEach(id => {
|
|
417
434
|
// Example: "@Tt74099t1"
|
|
418
435
|
if (id.startsWith('@T')) {
|
|
@@ -420,7 +437,7 @@ class CoveragePipe { // or Changes for the future???
|
|
|
420
437
|
}
|
|
421
438
|
// Example: "@Sd74099c1"
|
|
422
439
|
else if (id.startsWith('@S')) {
|
|
423
|
-
this.
|
|
440
|
+
this.suiteIds.add(id.slice(1));
|
|
424
441
|
}
|
|
425
442
|
// Example: "tag:@TestSmoke"
|
|
426
443
|
else if (id.startsWith('tag')) {
|
|
@@ -435,6 +452,47 @@ class CoveragePipe { // or Changes for the future???
|
|
|
435
452
|
|
|
436
453
|
return this.matchedLines;
|
|
437
454
|
}
|
|
455
|
+
|
|
456
|
+
#buildRunDescription({ matchedLines, testsCount, suitesCount }) {
|
|
457
|
+
const sourceBranch =
|
|
458
|
+
process.env.GITHUB_HEAD_REF ||
|
|
459
|
+
process.env.GITHUB_REF_NAME ||
|
|
460
|
+
process.env.CI_COMMIT_REF_NAME ||
|
|
461
|
+
this.#getCurrentGitBranch() ||
|
|
462
|
+
'current branch';
|
|
463
|
+
const targetBranch = this.branch || 'target branch';
|
|
464
|
+
const coverageFile = this.coverageFilePath ? path.basename(this.coverageFilePath) : 'coverage.yml';
|
|
465
|
+
const updatedFiles = matchedLines && matchedLines.size > 0 ? [...matchedLines] : this.changedFiles;
|
|
466
|
+
|
|
467
|
+
let description = `Changes to **${updatedFiles.length}** files in ${sourceBranch} to ${targetBranch}.\n\n`;
|
|
468
|
+
if (suitesCount > 0 || testsCount > 0) {
|
|
469
|
+
const affectedItems = [];
|
|
470
|
+
if (suitesCount > 0) affectedItems.push(`**${suitesCount} suites**`);
|
|
471
|
+
if (testsCount > 0) affectedItems.push(`**${testsCount} individual tests**`);
|
|
472
|
+
description += `May affect ${affectedItems.join(' and ')} which are recommended to be tested for regression.\n\n`; // eslint-disable-line
|
|
473
|
+
}
|
|
474
|
+
description += 'Updated source files:\n';
|
|
475
|
+
if (updatedFiles.length) {
|
|
476
|
+
description += updatedFiles.map(file => `* \`${file}\``).join('\n');
|
|
477
|
+
description += '\n\n';
|
|
478
|
+
} else {
|
|
479
|
+
description += '* No matched files found\n\n';
|
|
480
|
+
}
|
|
481
|
+
description += `Mapping source files to tests set via \`${coverageFile}\` file.`;
|
|
482
|
+
return description;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
#getCurrentGitBranch() {
|
|
486
|
+
try {
|
|
487
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
488
|
+
encoding: 'utf-8',
|
|
489
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
490
|
+
}).trim();
|
|
491
|
+
return branch || undefined;
|
|
492
|
+
} catch (err) {
|
|
493
|
+
return undefined;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
438
496
|
}
|
|
439
497
|
|
|
440
|
-
export default CoveragePipe;
|
|
498
|
+
export default CoveragePipe;
|
package/src/pipe/debug.js
CHANGED
|
@@ -4,7 +4,6 @@ import os from 'os';
|
|
|
4
4
|
import createDebugMessages from 'debug';
|
|
5
5
|
import { APP_PREFIX } from '../constants.js';
|
|
6
6
|
import prettyMs from 'pretty-ms';
|
|
7
|
-
import { transformEnvVarToBoolean } from '../utils/utils.js';
|
|
8
7
|
|
|
9
8
|
const debug = createDebugMessages('@testomatio/reporter:pipe:debug');
|
|
10
9
|
|
|
@@ -16,7 +15,7 @@ export class DebugPipe {
|
|
|
16
15
|
this.isEnabled = !!process.env.TESTOMATIO_DEBUG || !!process.env.DEBUG;
|
|
17
16
|
if (this.isEnabled) {
|
|
18
17
|
this.batch = {
|
|
19
|
-
isEnabled: this.params.isBatchEnabled ?? !
|
|
18
|
+
isEnabled: this.params.isBatchEnabled ?? !process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD ?? true,
|
|
20
19
|
intervalFunction: null,
|
|
21
20
|
intervalTime: 5000,
|
|
22
21
|
tests: [],
|
package/src/pipe/github.js
CHANGED
|
@@ -142,6 +142,20 @@ class GitHubPipe {
|
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
let body = summary;
|
|
145
|
+
const coverageConfiguration = this.store?.coverageConfiguration;
|
|
146
|
+
const isManualRun = this.store?.runKind === 'manual';
|
|
147
|
+
if (isManualRun && coverageConfiguration) {
|
|
148
|
+
const testsCount = coverageConfiguration.tests?.length || 0;
|
|
149
|
+
const suitesCount = coverageConfiguration.suites?.length || 0;
|
|
150
|
+
body += '\n\n<details>\n<summary><h3>🧭 Coverage Scope</h3></summary>\n\n';
|
|
151
|
+
if (!testsCount && !suitesCount) {
|
|
152
|
+
body += '- No tests were affected, run disabled\n';
|
|
153
|
+
} else {
|
|
154
|
+
body += `- Suites: ${suitesCount}\n`;
|
|
155
|
+
body += `- Tests: ${testsCount}\n`;
|
|
156
|
+
}
|
|
157
|
+
body += '\n</details>';
|
|
158
|
+
}
|
|
145
159
|
|
|
146
160
|
if (failures.length) {
|
|
147
161
|
body += `\n<details>\n<summary><h3>🟥 Failures (${failures.length})</h4></summary>\n\n${failures.join('\n')}\n`;
|