@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.
Files changed (57) hide show
  1. package/README.md +9 -11
  2. package/lib/adapter/playwright.d.ts +2 -0
  3. package/lib/adapter/playwright.js +29 -5
  4. package/lib/adapter/utils/playwright.d.ts +25 -0
  5. package/lib/adapter/utils/playwright.js +123 -0
  6. package/lib/adapter/vitest.js +2 -1
  7. package/lib/bin/cli.js +36 -36
  8. package/lib/data-storage.d.ts +1 -1
  9. package/lib/data-storage.js +1 -0
  10. package/lib/junit-adapter/index.js +0 -4
  11. package/lib/pipe/coverage.js +63 -5
  12. package/lib/pipe/debug.js +1 -2
  13. package/lib/pipe/github.js +15 -0
  14. package/lib/pipe/html.d.ts +2 -3
  15. package/lib/pipe/html.js +745 -37
  16. package/lib/pipe/testomatio.js +83 -36
  17. package/lib/reporter-functions.d.ts +36 -11
  18. package/lib/reporter-functions.js +72 -22
  19. package/lib/reporter.d.ts +90 -38
  20. package/lib/services/artifacts.d.ts +1 -1
  21. package/lib/services/key-values.d.ts +1 -1
  22. package/lib/services/links.d.ts +5 -3
  23. package/lib/services/links.js +1 -1
  24. package/lib/services/logger.d.ts +1 -1
  25. package/lib/template/testomatio-old.hbs +1421 -0
  26. package/lib/template/testomatio.hbs +3200 -1157
  27. package/lib/utils/log-formatter.d.ts +1 -2
  28. package/lib/utils/log-formatter.js +8 -4
  29. package/lib/utils/utils.js +0 -9
  30. package/package.json +2 -2
  31. package/src/adapter/playwright.js +32 -6
  32. package/src/adapter/utils/playwright.js +121 -0
  33. package/src/adapter/vitest.js +2 -1
  34. package/src/bin/cli.js +39 -47
  35. package/src/data-storage.js +1 -0
  36. package/src/junit-adapter/index.js +0 -4
  37. package/src/pipe/coverage.js +90 -32
  38. package/src/pipe/debug.js +1 -2
  39. package/src/pipe/github.js +14 -0
  40. package/src/pipe/html.js +844 -38
  41. package/src/pipe/testomatio.js +98 -53
  42. package/src/reporter-functions.js +73 -25
  43. package/src/services/links.js +1 -1
  44. package/src/template/testomatio-old.hbs +1421 -0
  45. package/src/template/testomatio.hbs +3200 -1157
  46. package/src/utils/log-formatter.js +9 -4
  47. package/src/utils/utils.js +0 -5
  48. package/types/types.d.ts +30 -6
  49. package/lib/allureReader.d.ts +0 -65
  50. package/lib/allureReader.js +0 -448
  51. package/lib/junit-adapter/kotlin.d.ts +0 -5
  52. package/lib/junit-adapter/kotlin.js +0 -46
  53. package/lib/services/labels.d.ts +0 -0
  54. package/lib/services/labels.js +0 -0
  55. package/src/allureReader.js +0 -523
  56. package/src/junit-adapter/kotlin.js +0 -48
  57. package/src/services/labels.js +0 -1
@@ -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.tests.add(id.slice(1));
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 ?? !transformEnvVarToBoolean(process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD),
18
+ isEnabled: this.params.isBatchEnabled ?? !process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD ?? true,
20
19
  intervalFunction: null,
21
20
  intervalTime: 5000,
22
21
  tests: [],
@@ -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`;