@testomatio/reporter 1.6.13 → 2.0.1-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 (142) hide show
  1. package/lib/adapter/codecept.d.ts +2 -0
  2. package/lib/adapter/codecept.js +295 -335
  3. package/lib/adapter/cucumber/current.d.ts +14 -0
  4. package/lib/adapter/cucumber/current.js +195 -203
  5. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  6. package/lib/adapter/cucumber/legacy.js +130 -155
  7. package/lib/adapter/cucumber.d.ts +2 -0
  8. package/lib/adapter/cucumber.js +5 -16
  9. package/lib/adapter/cypress-plugin/index.d.ts +2 -0
  10. package/lib/adapter/cypress-plugin/index.js +93 -105
  11. package/lib/adapter/jasmine.d.ts +11 -0
  12. package/lib/adapter/jasmine.js +54 -53
  13. package/lib/adapter/jest.d.ts +13 -0
  14. package/lib/adapter/jest.js +97 -99
  15. package/lib/adapter/mocha.d.ts +2 -0
  16. package/lib/adapter/mocha.js +112 -140
  17. package/lib/adapter/playwright.d.ts +14 -0
  18. package/lib/adapter/playwright.js +195 -231
  19. package/lib/adapter/vitest.d.ts +35 -0
  20. package/lib/adapter/vitest.js +150 -149
  21. package/lib/adapter/webdriver.d.ts +24 -0
  22. package/lib/adapter/webdriver.js +134 -119
  23. package/lib/bin/cli.d.ts +2 -0
  24. package/lib/bin/cli.js +164 -211
  25. package/lib/bin/reportXml.d.ts +2 -0
  26. package/lib/bin/reportXml.js +49 -52
  27. package/lib/bin/startTest.d.ts +2 -0
  28. package/lib/bin/startTest.js +82 -95
  29. package/lib/bin/uploadArtifacts.d.ts +2 -0
  30. package/lib/bin/uploadArtifacts.js +55 -61
  31. package/lib/client.d.ts +76 -0
  32. package/lib/client.js +411 -465
  33. package/lib/config.d.ts +1 -0
  34. package/lib/config.js +16 -21
  35. package/lib/constants.d.ts +25 -0
  36. package/lib/constants.js +50 -44
  37. package/lib/data-storage.d.ts +34 -0
  38. package/lib/data-storage.js +206 -188
  39. package/lib/junit-adapter/adapter.d.ts +9 -0
  40. package/lib/junit-adapter/adapter.js +17 -20
  41. package/lib/junit-adapter/csharp.d.ts +4 -0
  42. package/lib/junit-adapter/csharp.js +18 -14
  43. package/lib/junit-adapter/index.d.ts +3 -0
  44. package/lib/junit-adapter/index.js +27 -25
  45. package/lib/junit-adapter/java.d.ts +5 -0
  46. package/lib/junit-adapter/java.js +41 -53
  47. package/lib/junit-adapter/javascript.d.ts +4 -0
  48. package/lib/junit-adapter/javascript.js +30 -27
  49. package/lib/junit-adapter/python.d.ts +5 -0
  50. package/lib/junit-adapter/python.js +38 -37
  51. package/lib/junit-adapter/ruby.d.ts +4 -0
  52. package/lib/junit-adapter/ruby.js +11 -8
  53. package/lib/output.d.ts +11 -0
  54. package/lib/output.js +44 -52
  55. package/lib/package.json +3 -0
  56. package/lib/pipe/bitbucket.d.ts +23 -0
  57. package/lib/pipe/bitbucket.js +210 -229
  58. package/lib/pipe/csv.d.ts +47 -0
  59. package/lib/pipe/csv.js +113 -126
  60. package/lib/pipe/debug.d.ts +29 -0
  61. package/lib/pipe/debug.js +104 -99
  62. package/lib/pipe/github.d.ts +30 -0
  63. package/lib/pipe/github.js +186 -213
  64. package/lib/pipe/gitlab.d.ts +23 -0
  65. package/lib/pipe/gitlab.js +166 -207
  66. package/lib/pipe/html.d.ts +34 -0
  67. package/lib/pipe/html.js +260 -319
  68. package/lib/pipe/index.d.ts +1 -0
  69. package/lib/pipe/index.js +84 -66
  70. package/lib/pipe/testomatio.d.ts +70 -0
  71. package/lib/pipe/testomatio.js +413 -462
  72. package/lib/reporter-functions.d.ts +34 -0
  73. package/lib/reporter-functions.js +28 -26
  74. package/lib/reporter.d.ts +232 -0
  75. package/lib/reporter.js +34 -29
  76. package/lib/services/artifacts.d.ts +33 -0
  77. package/lib/services/artifacts.js +55 -51
  78. package/lib/services/index.d.ts +9 -0
  79. package/lib/services/index.js +14 -12
  80. package/lib/services/key-values.d.ts +27 -0
  81. package/lib/services/key-values.js +56 -53
  82. package/lib/services/logger.d.ts +64 -0
  83. package/lib/services/logger.js +227 -245
  84. package/lib/template/testomatio.hbs +651 -1366
  85. package/lib/uploader.d.ts +60 -0
  86. package/lib/uploader.js +291 -360
  87. package/lib/utils/pipe_utils.d.ts +41 -0
  88. package/lib/utils/pipe_utils.js +89 -85
  89. package/lib/utils/utils.d.ts +45 -0
  90. package/lib/utils/utils.js +347 -307
  91. package/lib/xmlReader.d.ts +92 -0
  92. package/lib/xmlReader.js +490 -529
  93. package/package.json +57 -15
  94. package/src/adapter/codecept.js +375 -0
  95. package/src/adapter/cucumber/current.js +228 -0
  96. package/src/adapter/cucumber/legacy.js +158 -0
  97. package/src/adapter/cucumber.js +4 -0
  98. package/src/adapter/cypress-plugin/index.js +112 -0
  99. package/src/adapter/jasmine.js +60 -0
  100. package/src/adapter/jest.js +107 -0
  101. package/src/adapter/mocha.cjs +2 -0
  102. package/src/adapter/mocha.js +157 -0
  103. package/src/adapter/playwright.js +250 -0
  104. package/src/adapter/vitest.js +183 -0
  105. package/src/adapter/webdriver.js +142 -0
  106. package/src/bin/cli.js +280 -0
  107. package/src/bin/reportXml.js +74 -0
  108. package/src/bin/startTest.js +123 -0
  109. package/src/bin/uploadArtifacts.js +90 -0
  110. package/src/client.js +504 -0
  111. package/src/config.js +30 -0
  112. package/src/constants.js +53 -0
  113. package/src/data-storage.js +204 -0
  114. package/src/junit-adapter/adapter.js +23 -0
  115. package/src/junit-adapter/csharp.js +16 -0
  116. package/src/junit-adapter/index.js +28 -0
  117. package/src/junit-adapter/java.js +58 -0
  118. package/src/junit-adapter/javascript.js +31 -0
  119. package/src/junit-adapter/python.js +42 -0
  120. package/src/junit-adapter/ruby.js +10 -0
  121. package/src/output.js +57 -0
  122. package/src/pipe/bitbucket.js +254 -0
  123. package/src/pipe/csv.js +140 -0
  124. package/src/pipe/debug.js +104 -0
  125. package/src/pipe/github.js +233 -0
  126. package/src/pipe/gitlab.js +229 -0
  127. package/src/pipe/html.js +374 -0
  128. package/src/pipe/index.js +71 -0
  129. package/src/pipe/testomatio.js +503 -0
  130. package/src/reporter-functions.js +55 -0
  131. package/src/reporter.cjs_decprecated +21 -0
  132. package/src/reporter.js +33 -0
  133. package/src/services/artifacts.js +59 -0
  134. package/src/services/index.js +13 -0
  135. package/src/services/key-values.js +59 -0
  136. package/src/services/logger.js +316 -0
  137. package/src/template/emptyData.svg +23 -0
  138. package/src/template/testomatio.hbs +706 -0
  139. package/src/uploader.js +371 -0
  140. package/src/utils/pipe_utils.js +119 -0
  141. package/src/utils/utils.js +383 -0
  142. package/src/xmlReader.js +562 -0
@@ -0,0 +1,374 @@
1
+ import createDebugMessages from 'debug';
2
+ import merge from 'lodash.merge';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import pc from 'picocolors';
6
+ import handlebars from 'handlebars';
7
+ import fileUrl from 'file-url';
8
+ import { fileSystem, isSameTest, ansiRegExp, formatStep } from '../utils/utils.js';
9
+ import { HTML_REPORT } from '../constants.js';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ const debug = createDebugMessages('@testomatio/reporter:pipe:html');
13
+
14
+ // @ts-ignore – this line will be removed in compiled code (already defined in the global scope of commonjs)
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+
17
+ class HtmlPipe {
18
+ constructor(params, store = {}) {
19
+ this.store = store || {};
20
+ this.title = params.title || process.env.TESTOMATIO_TITLE;
21
+ this.apiKey = params.apiKey || process.env.TESTOMATIO;
22
+ this.isHtml = process.env.TESTOMATIO_HTML_REPORT_SAVE;
23
+
24
+ debug('HTML Pipe: ', this.apiKey ? 'API KEY' : '*no api key provided*');
25
+
26
+ this.isEnabled = false;
27
+ this.htmlOutputPath = '';
28
+ this.fullHtmlOutputPath = '';
29
+ this.filenameMsg = '';
30
+ this.tests = [];
31
+
32
+ if (this.isHtml) {
33
+ this.isEnabled = true;
34
+ this.htmlReportDir = process.env.TESTOMATIO_HTML_REPORT_FOLDER || HTML_REPORT.FOLDER;
35
+
36
+ if (process.env.TESTOMATIO_HTML_FILENAME && process.env.TESTOMATIO_HTML_FILENAME.endsWith('.html')) {
37
+ this.htmlReportName = process.env.TESTOMATIO_HTML_FILENAME;
38
+ }
39
+
40
+ if (process.env.TESTOMATIO_HTML_FILENAME && !process.env.TESTOMATIO_HTML_FILENAME.endsWith('.html')) {
41
+ this.htmlReportName = HTML_REPORT.REPORT_DEFAULT_NAME;
42
+ this.filenameMsg =
43
+ 'HTML filename must include the extension ".html".' +
44
+ ` The default report name "${this.htmlReportDir}/${HTML_REPORT.REPORT_DEFAULT_NAME}" is used!`;
45
+ }
46
+
47
+ if (!process.env.TESTOMATIO_HTML_FILENAME) {
48
+ this.htmlReportName = HTML_REPORT.REPORT_DEFAULT_NAME;
49
+ }
50
+
51
+ this.templateFolderPath = path.resolve(__dirname, '..', 'template');
52
+ this.templateHtmlPath = path.resolve(this.templateFolderPath, HTML_REPORT.TEMPLATE_NAME);
53
+ this.htmlOutputPath = path.join(this.htmlReportDir, this.htmlReportName);
54
+ // create a new folder for the HTML reports
55
+ fileSystem.createDir(this.htmlReportDir);
56
+
57
+ debug(
58
+ pc.yellow('HTML Pipe:'),
59
+ `Save HTML report: ${this.isEnabled}`,
60
+ `HTML report folder: ${this.htmlReportDir}, report name: ${this.htmlReportName}`,
61
+ );
62
+ }
63
+ }
64
+
65
+ async createRun() {
66
+ // empty
67
+ }
68
+
69
+ updateRun() {
70
+ // empty
71
+ }
72
+
73
+ /**
74
+ * Add test data to the result array for saving. As a result of this function, we get a result object to save.
75
+ * @param {import('../../types/types.js').RunData} test - object which includes each test entry.
76
+ */
77
+ addTest(test) {
78
+ if (!this.isEnabled) return;
79
+
80
+ if (!test.status) return;
81
+
82
+ const index = this.tests.findIndex(t => isSameTest(t, test));
83
+ // update if they were already added
84
+ if (index >= 0) {
85
+ this.tests[index] = merge(this.tests[index], test);
86
+ return;
87
+ }
88
+
89
+ this.tests.push(test);
90
+ }
91
+
92
+ async finishRun(runParams) {
93
+ if (!this.isEnabled) return;
94
+
95
+ if (this.isHtml) {
96
+ // GENERATE HTML reports based on the results data
97
+ this.buildReport({
98
+ runParams,
99
+ // TODO: this.tests=[] in case of Mocha, need retest by Vitalii
100
+ tests: this.tests,
101
+ outputPath: this.htmlOutputPath,
102
+ templatePath: this.templateHtmlPath,
103
+ warningMsg: this.filenameMsg,
104
+ });
105
+ }
106
+ }
107
+ /**
108
+ * Generates an HTML report based on provided test data and a template.
109
+ * @param {object} opts - Test options used to generate the HTML report:
110
+ * runParams, tests, outputPath, templatePath
111
+ * @returns {void} - This function does not return anything.
112
+ */
113
+
114
+ buildReport(opts) {
115
+ const { runParams, tests, outputPath, templatePath, warningMsg: msg } = opts;
116
+
117
+ debug('HTML tests data:', tests);
118
+
119
+ if (!outputPath) {
120
+ console.log(pc.yellow(`🚨 HTML export path is not set, ignoring...`));
121
+ return;
122
+ }
123
+
124
+ console.log(pc.yellow(`⏳ The test results will be added to the HTML report. It will take some time...`));
125
+
126
+ if (msg) {
127
+ console.log(pc.blue(msg));
128
+ }
129
+
130
+ tests.forEach(test => {
131
+ // steps could be an array or a string
132
+ test.steps = Array.isArray(test.steps)
133
+ ? (test.steps = test.steps
134
+ .map(step => formatStep(step))
135
+ .flat()
136
+ .join('\n'))
137
+ : test.steps;
138
+
139
+ if (!test.message?.trim()) {
140
+ test.message = "This test has no 'message' code";
141
+ }
142
+
143
+ if (!test.suite_title?.trim()) {
144
+ test.suite_title = 'Unknown suite';
145
+ }
146
+
147
+ if (!test.title?.trim()) {
148
+ test.title = 'Unknown test title';
149
+ }
150
+
151
+ if (!test.files?.length) {
152
+ test.files = 'This test has no files';
153
+ }
154
+
155
+ if (!test.steps?.trim()) {
156
+ test.steps = "This test has no 'steps' code";
157
+ } else {
158
+ test.steps = removeAnsiColorCodes(test.steps);
159
+ }
160
+
161
+ // TODO: future-proof: currently there is no need to display Artifacts and Metadata in HTML
162
+ test.artifacts = test.artifacts || [];
163
+ test.meta = test.meta || {};
164
+ // TODO: u can added an additional test values to this checks in the future
165
+ });
166
+
167
+ const data = {
168
+ runId: this.store.runId || '',
169
+ status: runParams.status || 'No status info',
170
+ parallel: runParams.isParallel || 'No parallel info',
171
+ runUrl: this.store.runUrl || '',
172
+ executionTime: testExecutionSumTime(tests),
173
+ executionDate: getCurrentDateTimeFormatted(),
174
+ tests,
175
+ };
176
+ // generate output HTML based on the template
177
+ const html = this.#generateHTMLReport(data, templatePath);
178
+
179
+ if (!html) return;
180
+
181
+ fs.writeFileSync(outputPath, html, 'utf-8');
182
+ // Check if the file exists
183
+ if (fs.existsSync(outputPath)) {
184
+ // Get the absolute path of the file
185
+ const absolutePath = path.resolve(outputPath);
186
+ // Convert the file path to a file URL
187
+ const fileUrlPath = fileUrl(absolutePath, { resolve: true });
188
+
189
+ debug('HTML tests data:', fileUrlPath);
190
+
191
+ console.log(pc.green(`📊 The HTML report was successfully generated. Full filepath: ${fileUrlPath}`));
192
+ } else {
193
+ console.log(pc.red(`🚨 Failed to generate the HTML report.`));
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Generates an HTML report based on provided test data and a template path.
199
+ * @param {any} data - Test data used to generate the HTML report.
200
+ * @param {string} [templatePath=""] - The path to the HTML template used for generating the report.
201
+ * @returns {string | void} - The generated HTML report as a string or void if templatePath is not provided.
202
+ */
203
+ #generateHTMLReport(data, templatePath = '') {
204
+ if (!templatePath) {
205
+ console.log(pc.red(`🚨 HTML template not found. Report generation is impossible!`));
206
+ return;
207
+ }
208
+
209
+ const templateSource = fs.readFileSync(templatePath, 'utf8');
210
+ this.#loadReportHelpers();
211
+ try {
212
+ const template = handlebars.compile(templateSource);
213
+
214
+ return template(data);
215
+ } catch (e) {
216
+ console.log(pc.red('❌ Oops! An unknown error occurred when generating an HTML report'));
217
+ console.log(pc.red(e));
218
+ }
219
+ }
220
+
221
+ #loadReportHelpers() {
222
+ handlebars.registerHelper(
223
+ 'getTestsByStatus',
224
+ (tests, status) => tests.filter(test => test.status.toLowerCase() === status.toLowerCase()).length,
225
+ );
226
+
227
+ handlebars.registerHelper(
228
+ 'selectComponent',
229
+ () =>
230
+ new handlebars.SafeString(
231
+ `<select style="width: 70px;height: 38px;" class="form-select" aria-label="Tests counter on page">
232
+ <option value="0">10</option>
233
+ <option value="1">25</option>
234
+ <option value="2">50</option>
235
+ </select>`,
236
+ ),
237
+ );
238
+ /* eslint-disable */
239
+ handlebars.registerHelper('emptyDataComponent', () => {
240
+ const svgFilePath = path.join(__dirname, '..', 'template', 'emptyData.svg');
241
+ const svgContent = fs.readFileSync(svgFilePath, 'utf8');
242
+
243
+ return new handlebars.SafeString(
244
+ `
245
+ <div class="noData">
246
+ <div class="noDataSvg">
247
+ ${svgContent}
248
+ </div>
249
+ <div class="noDataText">
250
+ NO MATCHING TESTS
251
+ </div>
252
+ <div>`,
253
+ );
254
+ });
255
+ /* eslint-enable */
256
+ handlebars.registerHelper('pageDispleyElements', tests => {
257
+ // We wrapp the lines to the HTML format we need
258
+ const totalTests = JSON.parse(
259
+ JSON.stringify(tests)
260
+ .replace(/<script>/g, '&lt;script&gt;')
261
+ .replace(/<\/script>/g, '&lt;/script&gt;'), // eslint-disable-line
262
+ );
263
+
264
+ const paginationOptions = {
265
+ 0: 10,
266
+ 1: 25,
267
+ 2: 50,
268
+ };
269
+ const statuses = ['all', 'passed', 'failed', 'skipped'];
270
+ const pageItemGroups = {
271
+ all: {},
272
+ passed: {},
273
+ failed: {},
274
+ skipped: {},
275
+ totalTests,
276
+ };
277
+
278
+ function paginateItems(items, pageSize) {
279
+ const paginatedItems = [];
280
+ for (let i = 0; i < items.length; i += pageSize) {
281
+ paginatedItems.push(items.slice(i, i + pageSize));
282
+ }
283
+ return paginatedItems;
284
+ }
285
+
286
+ statuses.forEach(status => {
287
+ for (const option in paginationOptions) {
288
+ // eslint-disable-next-line no-prototype-builtins
289
+ if (paginationOptions.hasOwnProperty(option)) {
290
+ const pageSize = paginationOptions[option];
291
+ let filteredItems = totalTests;
292
+
293
+ if (status !== 'all') {
294
+ filteredItems = totalTests.filter(item => item.status === status);
295
+ }
296
+
297
+ pageItemGroups[status][option] = paginateItems(filteredItems, pageSize);
298
+ }
299
+ }
300
+ });
301
+
302
+ pageItemGroups.totalTests = totalTests;
303
+
304
+ return JSON.stringify(pageItemGroups);
305
+ });
306
+ }
307
+
308
+ toString() {
309
+ return 'HTML Reporter';
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Calculates the total execution time for an array of tests.
315
+ * @param {Object[]} tests - An array of test objects.
316
+ * @param {number} tests[].run_time - The execution time of each test in milliseconds.
317
+ * @returns {string} - The total execution time in a formatted duration string.
318
+ */
319
+ function testExecutionSumTime(tests) {
320
+ const totalMilliseconds = tests.reduce((sum, test) => {
321
+ if (typeof test.run_time === 'number' && !Number.isNaN(test.run_time)) {
322
+ return sum + test.run_time;
323
+ }
324
+ return sum;
325
+ }, 0);
326
+
327
+ return formatDuration(totalMilliseconds);
328
+ }
329
+
330
+ /**
331
+ * Removes ANSI color codes and converts newline characters to HTML line breaks in a given string.
332
+ * @param {string} str - The input string containing ANSI color codes.
333
+ * @returns {string} - The updated string with removed ANSI color codes and replaced newline characters.
334
+ */
335
+ function removeAnsiColorCodes(str) {
336
+ let updatedStr = str.replace(ansiRegExp(), '');
337
+ updatedStr = updatedStr.replace(/\n/g, '<br>');
338
+
339
+ return updatedStr;
340
+ }
341
+
342
+ /**
343
+ * Formats duration in milliseconds into a human-readable string representation.
344
+ * @param {number} duration - The duration in milliseconds.
345
+ * @returns {string} - The formatted duration string (e.g., "2h 30m 15s 500ms").
346
+ */
347
+ function formatDuration(duration) {
348
+ const milliseconds = duration % 1000;
349
+ duration = (duration - milliseconds) / 1000;
350
+ const seconds = duration % 60;
351
+ duration = (duration - seconds) / 60;
352
+ const minutes = duration % 60;
353
+ const hours = (duration - minutes) / 60;
354
+
355
+ return `${hours}h ${minutes}m ${seconds}s ${milliseconds}ms`;
356
+ }
357
+
358
+ /**
359
+ * Retrieves the current date and time in a formatted string.
360
+ * @returns {string} - The formatted date and time string (e.g., "(01/01/2023 12:00:00)").
361
+ */
362
+ function getCurrentDateTimeFormatted() {
363
+ const currentDate = new Date();
364
+ const day = currentDate.getDate().toString().padStart(2, '0');
365
+ const month = (currentDate.getMonth() + 1).toString().padStart(2, '0');
366
+ const year = currentDate.getFullYear();
367
+ const hours = currentDate.getHours().toString().padStart(2, '0');
368
+ const minutes = currentDate.getMinutes().toString().padStart(2, '0');
369
+ const seconds = currentDate.getSeconds().toString().padStart(2, '0');
370
+
371
+ return `(${day}/${month}/${year} ${hours}:${minutes}:${seconds})`;
372
+ }
373
+
374
+ export default HtmlPipe;
@@ -0,0 +1,71 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import pc from 'picocolors';
4
+ import { APP_PREFIX } from '../constants.js';
5
+ import TestomatioPipe from './testomatio.js';
6
+ import GitHubPipe from './github.js';
7
+ import GitLabPipe from './gitlab.js';
8
+ import CsvPipe from './csv.js';
9
+ import HtmlPipe from './html.js';
10
+ import { BitbucketPipe } from './bitbucket.js';
11
+ import { DebugPipe } from './debug.js';
12
+
13
+ export async function pipesFactory(params, opts) {
14
+ const extraPipes = [];
15
+
16
+ // Add extra pipes into package.json file:
17
+ // "testomatio": {
18
+ // "pipes": ["my-module-pipe", "./local/js/file/pipe"]
19
+ // }
20
+
21
+ const packageJsonFile = path.join(process.cwd(), 'package.json');
22
+ if (fs.existsSync(packageJsonFile)) {
23
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonFile).toString());
24
+ const pipeDefs = packageJson?.testomatio?.pipes || [];
25
+
26
+ for (const pipeDef of pipeDefs) {
27
+ let PipeClass;
28
+ try {
29
+ PipeClass = await import(pipeDef);
30
+ } catch (err) {
31
+ console.log(APP_PREFIX, `Can't load module Testomatio pipe module from ${pipeDef}`);
32
+ continue;
33
+ }
34
+
35
+ try {
36
+ extraPipes.push(new PipeClass(params, opts));
37
+ } catch (err) {
38
+ console.log(APP_PREFIX, `Can't instantiate Testomatio for ${pipeDef}`, err);
39
+ continue;
40
+ }
41
+ }
42
+ }
43
+
44
+ const pipes = [
45
+ new TestomatioPipe(params, opts),
46
+ new GitHubPipe(params, opts),
47
+ new GitLabPipe(params, opts),
48
+ new CsvPipe(params, opts),
49
+ new HtmlPipe(params, opts),
50
+ new BitbucketPipe(params, opts),
51
+ new DebugPipe(params, opts),
52
+ ...extraPipes,
53
+ ];
54
+
55
+ const pipesEnabled = pipes.filter(p => p.isEnabled);
56
+
57
+ console.log(
58
+ APP_PREFIX,
59
+ pc.cyan('Pipes:'),
60
+ pc.cyan(pipesEnabled.map(p => p.toString()).join(', ') || 'No pipes enabled'),
61
+ );
62
+
63
+ if (!pipesEnabled.length) {
64
+ console.log(
65
+ APP_PREFIX,
66
+ pc.dim('If you want to use Testomatio reporter, pass your token as TESTOMATIO env variable'),
67
+ );
68
+ }
69
+
70
+ return pipes;
71
+ }