@testomatio/reporter 2.7.1 → 2.7.2-beta.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 (49) hide show
  1. package/README.md +2 -1
  2. package/lib/adapter/codecept.js +81 -26
  3. package/lib/adapter/playwright.d.ts +1 -1
  4. package/lib/adapter/playwright.js +54 -34
  5. package/lib/adapter/utils/step-formatter.d.ts +134 -0
  6. package/lib/adapter/utils/step-formatter.js +237 -0
  7. package/lib/bin/cli.js +28 -31
  8. package/lib/bin/reportXml.js +5 -6
  9. package/lib/bin/uploadArtifacts.js +6 -6
  10. package/lib/client.d.ts +8 -0
  11. package/lib/client.js +71 -10
  12. package/lib/constants.d.ts +1 -0
  13. package/lib/constants.js +7 -1
  14. package/lib/pipe/bitbucket.js +2 -1
  15. package/lib/pipe/coverage.js +16 -15
  16. package/lib/pipe/debug.js +3 -3
  17. package/lib/pipe/github.js +3 -2
  18. package/lib/pipe/gitlab.js +2 -1
  19. package/lib/pipe/index.js +5 -5
  20. package/lib/pipe/testomatio.js +21 -24
  21. package/lib/uploader.js +3 -2
  22. package/lib/utils/log.d.ts +45 -0
  23. package/lib/utils/log.js +98 -0
  24. package/lib/utils/pipe_utils.js +5 -5
  25. package/lib/utils/utils.d.ts +10 -0
  26. package/lib/utils/utils.js +16 -1
  27. package/lib/xmlReader.js +5 -4
  28. package/package.json +1 -1
  29. package/src/adapter/codecept.js +99 -29
  30. package/src/adapter/playwright.js +64 -39
  31. package/src/adapter/utils/step-formatter.js +232 -0
  32. package/src/bin/cli.js +34 -31
  33. package/src/bin/reportXml.js +5 -6
  34. package/src/bin/uploadArtifacts.js +6 -6
  35. package/src/client.js +76 -26
  36. package/src/constants.js +4 -0
  37. package/src/pipe/bitbucket.js +2 -1
  38. package/src/pipe/coverage.js +16 -15
  39. package/src/pipe/debug.js +3 -3
  40. package/src/pipe/github.js +4 -3
  41. package/src/pipe/gitlab.js +2 -1
  42. package/src/pipe/index.js +5 -7
  43. package/src/pipe/testomatio.js +32 -25
  44. package/src/uploader.js +3 -2
  45. package/src/utils/log.js +87 -0
  46. package/src/utils/pipe_utils.js +5 -5
  47. package/src/utils/utils.js +14 -0
  48. package/src/xmlReader.js +5 -4
  49. package/types/types.d.ts +3 -0
package/lib/client.js CHANGED
@@ -14,8 +14,10 @@ const path_1 = __importDefault(require("path"));
14
14
  const node_url_1 = require("node:url");
15
15
  const uploader_js_1 = require("./uploader.js");
16
16
  const utils_js_1 = require("./utils/utils.js");
17
+ const step_formatter_js_1 = require("./adapter/utils/step-formatter.js");
17
18
  const filesize_1 = require("filesize");
18
19
  const log_formatter_js_1 = require("./utils/log-formatter.js");
20
+ const log_js_1 = require("./utils/log.js");
19
21
  const debug = (0, debug_1.default)('@testomatio/reporter:client');
20
22
  // removed __dirname usage, because:
21
23
  // 1. replaced with ESM syntax (import.meta.url), but it throws an error on tsc compilation;
@@ -39,7 +41,7 @@ class Client {
39
41
  const pathToPackageJSON = path_1.default.join(__dirname, '../package.json');
40
42
  try {
41
43
  this.version = JSON.parse(fs_1.default.readFileSync(pathToPackageJSON).toString()).version;
42
- console.log(constants_js_1.APP_PREFIX, `Testomatio Reporter v${this.version}`);
44
+ log_js_1.log.info(`Testomatio Reporter v${this.version}`);
43
45
  }
44
46
  catch (e) {
45
47
  // do nothing
@@ -67,7 +69,7 @@ class Client {
67
69
  const { pipe, pipeOptions } = params;
68
70
  // ❗ Validation: pipe is required
69
71
  if (!pipe || !pipeOptions) {
70
- console.warn(`❗ No valid pipe found in filter cmd. Expected format: <pipe>:<options>
72
+ log_js_1.log.warn(`❗ No valid pipe found in filter cmd. Expected format: <pipe>:<options>
71
73
  Examples:
72
74
  --filter "testomatio:tag-name=frontend"
73
75
  --filter "coverage:file=coverage.yml"
@@ -84,7 +86,7 @@ class Client {
84
86
  const p = this.pipes.find(p => p.constructor.name.toLowerCase() === `${pipe.toLowerCase()}pipe`);
85
87
  // const p = this.pipes.find(p => p.id === `${pipe.toLowerCase()}`); TODO: as future updates
86
88
  if (!p?.isEnabled) {
87
- console.warn(constants_js_1.APP_PREFIX, "🚫 No active pipes were found in the system. Execution aborted!");
89
+ log_js_1.log.warn('🚫 No active pipes were found in the system. Execution aborted!');
88
90
  return;
89
91
  }
90
92
  // Run only the selected pipe
@@ -94,7 +96,7 @@ class Client {
94
96
  return result;
95
97
  }
96
98
  catch (err) {
97
- console.error(constants_js_1.APP_PREFIX, err);
99
+ log_js_1.log.error(err);
98
100
  }
99
101
  }
100
102
  /**
@@ -111,7 +113,7 @@ class Client {
111
113
  return Promise.resolve();
112
114
  this.queue = this.queue
113
115
  .then(() => Promise.all(this.pipes.map(p => p.createRun(params))))
114
- .catch(err => console.log(constants_js_1.APP_PREFIX, err))
116
+ .catch(err => log_js_1.log.info(err))
115
117
  .then(() => {
116
118
  const runId = this.pipeStore?.runId;
117
119
  if (runId)
@@ -123,6 +125,58 @@ class Client {
123
125
  // debug('Run', this.queue);
124
126
  return this.queue;
125
127
  }
128
+ /**
129
+ * Recursively uploads artifacts from steps
130
+ *
131
+ * @param {*} steps - Steps payload (validated inside function)
132
+ * @param {string} testRid - Test/result ID
133
+ * @returns {Promise<void>}
134
+ */
135
+ async uploadStepArtifacts(steps, testRid) {
136
+ if (!steps || !Array.isArray(steps))
137
+ return;
138
+ if (!this.uploader.isEnabled || !constants_js_1.SCREENSHOTS_ON_STEPS)
139
+ return;
140
+ try {
141
+ for (const step of steps) {
142
+ if (!(step.artifacts && Array.isArray(step.artifacts))) {
143
+ if (step.steps) {
144
+ await this.uploadStepArtifacts(step.steps, testRid);
145
+ }
146
+ continue;
147
+ }
148
+ const uploadedArtifacts = [];
149
+ for (const artifact of step.artifacts) {
150
+ if (typeof artifact === 'string' && !(0, utils_js_1.isHttpUrl)(artifact)) {
151
+ const filename = (0, step_formatter_js_1.generateShortFilename)(artifact);
152
+ try {
153
+ const uploadResult = await this.uploader.uploadFileByPath(artifact, [this.runId, testRid, 'steps', filename]);
154
+ if (uploadResult) {
155
+ uploadedArtifacts.push(uploadResult);
156
+ }
157
+ else {
158
+ uploadedArtifacts.push(artifact);
159
+ }
160
+ }
161
+ catch (uploadErr) {
162
+ uploadedArtifacts.push(artifact);
163
+ }
164
+ }
165
+ else {
166
+ uploadedArtifacts.push(artifact);
167
+ }
168
+ }
169
+ step.artifacts = uploadedArtifacts;
170
+ if (step.steps) {
171
+ await this.uploadStepArtifacts(step.steps, testRid);
172
+ }
173
+ }
174
+ }
175
+ catch (err) {
176
+ console.error(constants_js_1.APP_PREFIX, 'Error in uploadStepArtifacts for testRid', testRid, ':', err);
177
+ throw err;
178
+ }
179
+ }
126
180
  /**
127
181
  * Updates test status and its data
128
182
  *
@@ -145,6 +199,13 @@ class Client {
145
199
  */
146
200
  const { rid, error = null, steps: originalSteps, title, suite_title } = testData;
147
201
  let steps = originalSteps;
202
+ // Upload artifacts from steps
203
+ try {
204
+ await this.uploadStepArtifacts(steps, rid);
205
+ }
206
+ catch (err) {
207
+ console.log(constants_js_1.APP_PREFIX, 'Failed to upload step artifacts:', err);
208
+ }
148
209
  const uploadedFiles = [];
149
210
  const stackArtifactsEnabled = (0, utils_js_1.transformEnvVarToBoolean)(process.env.TESTOMATIO_STACK_ARTIFACTS);
150
211
  const { time = 0, example = null, files = [], filesBuffers = [], code = null, file, suite_id, test_id, timestamp, links, manuallyAttachedArtifacts, overwrite, tags, } = testData;
@@ -237,7 +298,7 @@ class Client {
237
298
  return { pipe: pipe.toString(), result };
238
299
  }
239
300
  catch (err) {
240
- console.log(constants_js_1.APP_PREFIX, pipe.toString(), err);
301
+ log_js_1.log.info(pipe.toString(), err);
241
302
  }
242
303
  })));
243
304
  // @ts-ignore
@@ -276,7 +337,7 @@ class Client {
276
337
  });
277
338
  }
278
339
  if (this.uploader.failedUploads.length) {
279
- console.log(constants_js_1.APP_PREFIX, `🗄️ ${this.uploader.failedUploads.length} artifacts 🔴${picocolors_1.default.bold('failed')} to upload`);
340
+ log_js_1.log.info(`🗄️ ${this.uploader.failedUploads.length} artifacts 🔴${picocolors_1.default.bold('failed')} to upload`);
280
341
  const failedUploads = this.uploader.failedUploads.map(file => ({
281
342
  relativePath: file.path.replace(process.cwd(), ''),
282
343
  sizePretty: file.size == null ? 'unknown' : (0, filesize_1.filesize)(file.size, { round: 0 }).toString(),
@@ -287,7 +348,7 @@ class Client {
287
348
  });
288
349
  }
289
350
  if (this.uploader.skippedUploads.length) {
290
- console.log('\n', constants_js_1.APP_PREFIX, `🗄️ ${picocolors_1.default.bold(this.uploader.skippedUploads.length)} artifacts uploading 🟡${picocolors_1.default.bold('skipped')}`);
351
+ log_js_1.log.info(`🗄️ ${picocolors_1.default.bold(this.uploader.skippedUploads.length)} artifacts uploading 🟡${picocolors_1.default.bold('skipped')}`);
291
352
  const skippedUploads = this.uploader.skippedUploads.map(file => ({
292
353
  relativePath: file.path.replace(process.cwd(), ''),
293
354
  sizePretty: file.size === null ? 'unknown' : (0, filesize_1.filesize)(file.size, { round: 0 }).toString(),
@@ -300,11 +361,11 @@ class Client {
300
361
  if (this.uploader.skippedUploads.length || this.uploader.failedUploads.length) {
301
362
  const command = `TESTOMATIO=<your_api_key> TESTOMATIO_RUN=${this.runId} npx @testomatio/reporter upload-artifacts`;
302
363
  const numberOfNotUploadedArtifacts = this.uploader.skippedUploads.length + this.uploader.failedUploads.length;
303
- console.log(constants_js_1.APP_PREFIX, `${numberOfNotUploadedArtifacts} artifacts were not uploaded.
364
+ log_js_1.log.info(`${numberOfNotUploadedArtifacts} artifacts were not uploaded.
304
365
  Run "${picocolors_1.default.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`);
305
366
  }
306
367
  })
307
- .catch(err => console.log(constants_js_1.APP_PREFIX, err));
368
+ .catch(err => log_js_1.log.info(err));
308
369
  return this.queue;
309
370
  }
310
371
  }
@@ -23,3 +23,4 @@ export namespace REPORTER_REQUEST_RETRIES {
23
23
  let maxTotalRetries: number;
24
24
  let withinTimeSeconds: number;
25
25
  }
26
+ export const SCREENSHOTS_ON_STEPS: boolean;
package/lib/constants.js CHANGED
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.REPORTER_REQUEST_RETRIES = exports.testomatLogoURL = exports.AXIOS_TIMEOUT = exports.HTML_REPORT = exports.STATUS = exports.CSV_HEADERS = exports.TESTOMAT_TMP_STORAGE_DIR = exports.APP_PREFIX = void 0;
6
+ exports.SCREENSHOTS_ON_STEPS = exports.REPORTER_REQUEST_RETRIES = exports.testomatLogoURL = exports.AXIOS_TIMEOUT = exports.HTML_REPORT = exports.STATUS = exports.CSV_HEADERS = exports.TESTOMAT_TMP_STORAGE_DIR = exports.APP_PREFIX = void 0;
7
7
  const picocolors_1 = __importDefault(require("picocolors"));
8
8
  const os_1 = __importDefault(require("os"));
9
9
  const path_1 = __importDefault(require("path"));
10
+ const utils_js_1 = require("./utils/utils.js");
10
11
  const APP_PREFIX = picocolors_1.default.gray('[TESTOMATIO]');
11
12
  exports.APP_PREFIX = APP_PREFIX;
12
13
  const TESTOMATIO_REQUEST_TIMEOUT = parseInt(process.env.TESTOMATIO_REQUEST_TIMEOUT, 10);
@@ -15,6 +16,9 @@ if (TESTOMATIO_REQUEST_TIMEOUT) {
15
16
  }
16
17
  const AXIOS_TIMEOUT = TESTOMATIO_REQUEST_TIMEOUT || 20 * 1000;
17
18
  exports.AXIOS_TIMEOUT = AXIOS_TIMEOUT;
19
+ const SCREENSHOTS_ON_STEPS = process.env.TESTOMATIO_SCREENSHOTS_ON_STEPS == null
20
+ || (0, utils_js_1.transformEnvVarToBoolean)(process.env.TESTOMATIO_SCREENSHOTS_ON_STEPS);
21
+ exports.SCREENSHOTS_ON_STEPS = SCREENSHOTS_ON_STEPS;
18
22
  const TESTOMAT_TMP_STORAGE_DIR = path_1.default.join(os_1.default.tmpdir(), 'testomatio_tmp');
19
23
  exports.TESTOMAT_TMP_STORAGE_DIR = TESTOMAT_TMP_STORAGE_DIR;
20
24
  const CSV_HEADERS = [
@@ -53,6 +57,8 @@ module.exports.APP_PREFIX = APP_PREFIX;
53
57
 
54
58
  module.exports.AXIOS_TIMEOUT = AXIOS_TIMEOUT;
55
59
 
60
+ module.exports.SCREENSHOTS_ON_STEPS = SCREENSHOTS_ON_STEPS;
61
+
56
62
  module.exports.TESTOMAT_TMP_STORAGE_DIR = TESTOMAT_TMP_STORAGE_DIR;
57
63
 
58
64
  module.exports.CSV_HEADERS = CSV_HEADERS;
@@ -46,6 +46,7 @@ const humanize_duration_1 = __importDefault(require("humanize-duration"));
46
46
  const lodash_merge_1 = __importDefault(require("lodash.merge"));
47
47
  const path_1 = __importDefault(require("path"));
48
48
  const debug_1 = __importDefault(require("debug"));
49
+ const log_js_1 = require("../utils/log.js");
49
50
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:bitbucket');
50
51
  //! BITBUCKET_ACCESS_TOKEN environment variable is required for this functionality to work
51
52
  //! and your pipeline trigger should be a pull request
@@ -190,7 +191,7 @@ class BitbucketPipe {
190
191
  const commentID = addCommentResponse.data.id;
191
192
  // eslint-disable-next-line max-len
192
193
  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
+ log_js_1.log.info(picocolors_1.default.yellow('Bitbucket'), `Report created: ${picocolors_1.default.magenta(commentURL)}`);
194
195
  }
195
196
  catch (err) {
196
197
  console.error(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('Bitbucket'), `Couldn't create Bitbucket report\n${err}.
@@ -14,6 +14,7 @@ const pipe_utils_js_1 = require("../utils/pipe_utils.js");
14
14
  const pipe_utils_js_2 = require("../utils/pipe_utils.js");
15
15
  const config_js_1 = require("../config.js");
16
16
  const debug_1 = __importDefault(require("debug"));
17
+ const log_js_1 = require("../utils/log.js");
17
18
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:csv');
18
19
  // Example of use 'coverage:file=coverage/coverage.yml,diff=master' cmd:
19
20
  // | Option | Git command | Notes |
@@ -121,10 +122,10 @@ class CoveragePipe {
121
122
  // Step 2: Extract all available tests and compare with coverage file
122
123
  const lines = await this.extractRelevantTestsFromChanges();
123
124
  if (this.store?.filterList && lines.size > 0) {
124
- console.log(constants_js_1.APP_PREFIX, `Matched files: ${[...lines].join(', ')}`);
125
+ log_js_1.log.info(`Matched files: ${[...lines].join(', ')}`);
125
126
  }
126
127
  if (lines.size === 0) {
127
- console.log(constants_js_1.APP_PREFIX, 'ℹ️ No matching entries in coverage file for provided Git changes.');
128
+ log_js_1.log.info('ℹ️ No matching entries in coverage file for provided Git changes.');
128
129
  return [];
129
130
  }
130
131
  // Step 3: Handle tag labels tests from the server
@@ -141,7 +142,7 @@ class CoveragePipe {
141
142
  }
142
143
  }
143
144
  if (this.tests.size === 0 && this.suiteIds.size === 0) {
144
- console.log(constants_js_1.APP_PREFIX, 'ℹ️ No tests found for execution based on Git changes.');
145
+ log_js_1.log.info('ℹ️ No tests found for execution based on Git changes.');
145
146
  return [];
146
147
  }
147
148
  this.results = [...this.tests, ...this.suiteIds];
@@ -200,7 +201,7 @@ class CoveragePipe {
200
201
  ...q,
201
202
  });
202
203
  if (!Array.isArray(resp.data?.tests) && resp.data?.tests?.length === 0) {
203
- console.log(constants_js_1.APP_PREFIX, `🔍 No test by ${type}=${id} were found on the Testomat.io server side!`);
204
+ log_js_1.log.info(`🔍 No test by ${type}=${id} were found on the Testomat.io server side!`);
204
205
  return undefined;
205
206
  }
206
207
  return resp.data.tests;
@@ -232,7 +233,7 @@ class CoveragePipe {
232
233
  const errorMessage = err.message || '';
233
234
  // Git edge: Not a git repository or other error
234
235
  if (errorMessage.includes('Not a git repository')) {
235
- console.error(constants_js_1.APP_PREFIX, '❌ Error: This folder is not a Git repository.');
236
+ log_js_1.log.error('❌ Error: This folder is not a Git repository.');
236
237
  }
237
238
  else {
238
239
  throw new Error(`❌ Git command failed ("${cmd}"):\n`, errorMessage);
@@ -272,10 +273,10 @@ class CoveragePipe {
272
273
  cmd = this.#buildGitCommand();
273
274
  }
274
275
  catch (err) {
275
- console.error(constants_js_1.APP_PREFIX, err.message);
276
+ log_js_1.log.error(err.message);
276
277
  return undefined;
277
278
  }
278
- console.error(constants_js_1.APP_PREFIX, `ℹ️ We will use '${cmd}' Git command.`);
279
+ log_js_1.log.error(`ℹ️ We will use '${cmd}' Git command.`);
279
280
  try {
280
281
  // For clear unit testing process -> Like test_defaultGitChangedFile = todomvc-tests/edit-todos_test.js
281
282
  if (this.isDefaultGitChanges) {
@@ -290,11 +291,11 @@ class CoveragePipe {
290
291
  }
291
292
  }
292
293
  catch (err) {
293
- console.error(constants_js_1.APP_PREFIX, err.message);
294
- console.error(constants_js_1.APP_PREFIX, "🔍 Pls, check this Git command manually to understand the original problem.");
294
+ log_js_1.log.error(err.message);
295
+ log_js_1.log.error("🔍 Pls, check this Git command manually to understand the original problem.");
295
296
  return undefined;
296
297
  }
297
- console.log(constants_js_1.APP_PREFIX, `📑 GIT changed files:\n - ${this.changedFiles.join('\n - ')}`);
298
+ log_js_1.log.info(`📑 GIT changed files:\n - ${this.changedFiles.join('\n - ')}`);
298
299
  return this;
299
300
  }
300
301
  /**
@@ -313,18 +314,18 @@ class CoveragePipe {
313
314
  validateCoverageFile() {
314
315
  // Validate the presence of the coverage filepath
315
316
  if (!fs_1.default.existsSync(this.coverageFilePath)) {
316
- console.log(constants_js_1.APP_PREFIX, '❌ Coverage file not found:', this.coverageFilePath);
317
+ log_js_1.log.info('❌ Coverage file not found:', this.coverageFilePath);
317
318
  return undefined;
318
319
  }
319
320
  // Ensure the given path is a file (not a directory or other type)
320
321
  const stat = fs_1.default.statSync(this.coverageFilePath);
321
322
  if (!stat.isFile()) {
322
- console.log(constants_js_1.APP_PREFIX, '❌ Provided coverage path is not a file:', this.coverageFilePath);
323
+ log_js_1.log.info('❌ Provided coverage path is not a file:', this.coverageFilePath);
323
324
  return undefined;
324
325
  }
325
326
  // Validate the file extension to be ".yml" to ensure it's a YAML file
326
327
  if (path_1.default.extname(this.coverageFilePath) !== ".yml") {
327
- console.log(constants_js_1.APP_PREFIX, '❌ Coverage file must have a .yml extension:', this.coverageFilePath);
328
+ log_js_1.log.info('❌ Coverage file must have a .yml extension:', this.coverageFilePath);
328
329
  return undefined;
329
330
  }
330
331
  debug('Coverage file validation is OK!');
@@ -346,11 +347,11 @@ class CoveragePipe {
346
347
  const rawYml = fs_1.default.readFileSync(this.coverageFilePath, 'utf8');
347
348
  this.parsedCoverage = js_yaml_1.default.load(rawYml) || {};
348
349
  debug(`Coverage filepath = ${this.coverageFilePath})`);
349
- console.log(constants_js_1.APP_PREFIX, `✅ Coverage file parsed successfully: ${this.coverageFilePath}`);
350
+ log_js_1.log.info(`✅ Coverage file parsed successfully: ${this.coverageFilePath}`);
350
351
  return this;
351
352
  }
352
353
  catch (err) {
353
- console.error(constants_js_1.APP_PREFIX, '❌ Failed to parse YAML:', err.message);
354
+ log_js_1.log.error('❌ Failed to parse YAML:', err.message);
354
355
  return undefined;
355
356
  }
356
357
  }
package/lib/pipe/debug.js CHANGED
@@ -8,8 +8,8 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const debug_1 = __importDefault(require("debug"));
11
- const constants_js_1 = require("../constants.js");
12
11
  const pretty_ms_1 = __importDefault(require("pretty-ms"));
12
+ const log_js_1 = require("../utils/log.js");
13
13
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:debug');
14
14
  class DebugPipe {
15
15
  constructor(params, store) {
@@ -41,7 +41,7 @@ class DebugPipe {
41
41
  catch (err) {
42
42
  debug('Failed to create symlink:', err.message);
43
43
  }
44
- console.log(constants_js_1.APP_PREFIX, '🪲 Debug file created');
44
+ log_js_1.log.info('🪲 Debug file created');
45
45
  this.testomatioEnvVars = Object.keys(process.env)
46
46
  .filter(key => key.startsWith('TESTOMATIO_'))
47
47
  .reduce((acc, key) => {
@@ -118,7 +118,7 @@ class DebugPipe {
118
118
  if (this.batch.intervalFunction)
119
119
  clearInterval(this.batch.intervalFunction);
120
120
  this.logToFile({ action: 'finishRun', params });
121
- console.log(constants_js_1.APP_PREFIX, '🪲 Debug Saved to', this.logFilePath);
121
+ log_js_1.log.info('🪲 Debug Saved to', this.logFilePath);
122
122
  }
123
123
  async sync() {
124
124
  if (!this.isEnabled)
@@ -44,6 +44,7 @@ const lodash_merge_1 = __importDefault(require("lodash.merge"));
44
44
  const constants_js_1 = require("../constants.js");
45
45
  const utils_js_1 = require("../utils/utils.js");
46
46
  const pipe_utils_js_1 = require("../utils/pipe_utils.js");
47
+ const log_js_1 = require("../utils/log.js");
47
48
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:github');
48
49
  /**
49
50
  * @typedef {import('../../types/types.js').Pipe} Pipe
@@ -197,10 +198,10 @@ class GitHubPipe {
197
198
  const url = resp.data?.html_url;
198
199
  debug('Comment URL:', url);
199
200
  this.store.githubUrl = url;
200
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('GitHub'), `Report created: ${picocolors_1.default.magenta(url)}`);
201
+ log_js_1.log.info(picocolors_1.default.yellow('GitHub'), `Report created: ${picocolors_1.default.magenta(url)}`);
201
202
  }
202
203
  catch (err) {
203
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('GitHub'), `Couldn't create GitHub report ${err}`);
204
+ log_js_1.log.info(picocolors_1.default.yellow('GitHub'), `Couldn't create GitHub report ${err}`);
204
205
  }
205
206
  }
206
207
  async sync() {
@@ -12,6 +12,7 @@ const path_1 = __importDefault(require("path"));
12
12
  const constants_js_1 = require("../constants.js");
13
13
  const utils_js_1 = require("../utils/utils.js");
14
14
  const pipe_utils_js_1 = require("../utils/pipe_utils.js");
15
+ const log_js_1 = require("../utils/log.js");
15
16
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:gitlab');
16
17
  //! GITLAB_PAT environment variable is required for this functionality to work
17
18
  //! and your pipeline trigger should be merge_request
@@ -147,7 +148,7 @@ class GitLabPipe {
147
148
  const commentID = addCommentResponse.data.id;
148
149
  // eslint-disable-next-line max-len
149
150
  const commentURL = `${this.ENV.CI_PROJECT_URL}/-/merge_requests/${this.ENV.CI_MERGE_REQUEST_IID}#note_${commentID}`;
150
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('GitLab'), `Report created: ${picocolors_1.default.magenta(commentURL)}`);
151
+ log_js_1.log.info(picocolors_1.default.yellow('GitLab'), `Report created: ${picocolors_1.default.magenta(commentURL)}`);
151
152
  }
152
153
  catch (err) {
153
154
  console.error(constants_js_1.APP_PREFIX, picocolors_1.default.yellow('GitLab'), `Couldn't create GitLab report\n${err}.
package/lib/pipe/index.js CHANGED
@@ -40,7 +40,6 @@ exports.pipesFactory = pipesFactory;
40
40
  const fs_1 = __importDefault(require("fs"));
41
41
  const path_1 = __importDefault(require("path"));
42
42
  const picocolors_1 = __importDefault(require("picocolors"));
43
- const constants_js_1 = require("../constants.js");
44
43
  const testomatio_js_1 = __importDefault(require("./testomatio.js"));
45
44
  const github_js_1 = __importDefault(require("./github.js"));
46
45
  const gitlab_js_1 = __importDefault(require("./gitlab.js"));
@@ -49,6 +48,7 @@ const html_js_1 = __importDefault(require("./html.js"));
49
48
  const coverage_js_1 = __importDefault(require("./coverage.js"));
50
49
  const bitbucket_js_1 = require("./bitbucket.js");
51
50
  const debug_js_1 = require("./debug.js");
51
+ const log_js_1 = require("../utils/log.js");
52
52
  async function pipesFactory(params, opts) {
53
53
  const extraPipes = [];
54
54
  // Add extra pipes into package.json file:
@@ -65,14 +65,14 @@ async function pipesFactory(params, opts) {
65
65
  PipeClass = await Promise.resolve(`${pipeDef}`).then(s => __importStar(require(s)));
66
66
  }
67
67
  catch (err) {
68
- console.log(constants_js_1.APP_PREFIX, `Can't load module Testomatio pipe module from ${pipeDef}`);
68
+ log_js_1.log.info(`Can't load module Testomatio pipe module from ${pipeDef}`);
69
69
  continue;
70
70
  }
71
71
  try {
72
72
  extraPipes.push(new PipeClass(params, opts));
73
73
  }
74
74
  catch (err) {
75
- console.log(constants_js_1.APP_PREFIX, `Can't instantiate Testomatio for ${pipeDef}`, err);
75
+ log_js_1.log.info(`Can't instantiate Testomatio for ${pipeDef}`, err);
76
76
  continue;
77
77
  }
78
78
  }
@@ -89,9 +89,9 @@ async function pipesFactory(params, opts) {
89
89
  ...extraPipes,
90
90
  ];
91
91
  const pipesEnabled = pipes.filter(p => p.isEnabled);
92
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.cyan('Pipes:'), picocolors_1.default.cyan(pipesEnabled.map(p => p.toString()).join(', ') || 'No pipes enabled'));
92
+ log_js_1.log.info(picocolors_1.default.cyan('Pipes:'), picocolors_1.default.cyan(pipesEnabled.map(p => p.toString()).join(', ') || 'No pipes enabled'));
93
93
  if (!pipesEnabled.length) {
94
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.dim('If you want to use Testomatio reporter, pass your token as TESTOMATIO env variable'));
94
+ log_js_1.log.info(picocolors_1.default.dim('If you want to use Testomatio reporter, pass your token as TESTOMATIO env variable'));
95
95
  }
96
96
  return pipes;
97
97
  }
@@ -11,6 +11,7 @@ const constants_js_1 = require("../constants.js");
11
11
  const utils_js_1 = require("../utils/utils.js");
12
12
  const pipe_utils_js_1 = require("../utils/pipe_utils.js");
13
13
  const config_js_1 = require("../config.js");
14
+ const log_js_1 = require("../utils/log.js");
14
15
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:testomatio');
15
16
  if (process.env.TESTOMATIO_RUN)
16
17
  process.env.runId = process.env.TESTOMATIO_RUN;
@@ -57,11 +58,10 @@ class TestomatioPipe {
57
58
  const sha = (0, utils_js_1.getGitCommitSha)();
58
59
  if (sha) {
59
60
  this.title = `Shared Run - ${sha}`;
60
- console.log(constants_js_1.APP_PREFIX, `🔄 Auto-generated title for shared run: ${this.title}`);
61
+ log_js_1.log.info(`🔄 Auto-generated title for shared run: ${this.title}`);
61
62
  }
62
63
  else {
63
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.red('Failed to resolve git commit SHA for shared run title.'));
64
- console.log(constants_js_1.APP_PREFIX, 'Please run the tests inside a Git repository or set TESTOMATIO_TITLE explicitly.');
64
+ log_js_1.log.warn(picocolors_1.default.red('Failed to resolve git commit SHA for shared run title.'), 'Please run the tests inside a Git repository or set TESTOMATIO_TITLE explicitly.');
65
65
  }
66
66
  }
67
67
  this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
@@ -97,7 +97,7 @@ class TestomatioPipe {
97
97
  this.requestFailures = 0;
98
98
  if (!(0, utils_js_1.isValidUrl)(this.url.trim())) {
99
99
  this.isEnabled = false;
100
- console.error(constants_js_1.APP_PREFIX, picocolors_1.default.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
100
+ log_js_1.log.error(picocolors_1.default.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
101
101
  }
102
102
  }
103
103
  /**
@@ -107,7 +107,8 @@ class TestomatioPipe {
107
107
  */
108
108
  #formatData(data) {
109
109
  data.api_key = this.apiKey;
110
- data.create = this.createNewTests;
110
+ if (data.create === undefined)
111
+ data.create = this.createNewTests;
111
112
  // add test ID + run ID
112
113
  if (data.rid)
113
114
  data.rid = `${this.runId}-${data.rid}`;
@@ -155,10 +156,10 @@ class TestomatioPipe {
155
156
  (0, utils_js_1.foundedTestLog)(constants_js_1.APP_PREFIX, resp.data.tests);
156
157
  return resp.data.tests;
157
158
  }
158
- console.log(constants_js_1.APP_PREFIX, `⛔ No tests found for your --filter --> ${type}=${id}`);
159
+ log_js_1.log.warn(`⛔ No tests found for your --filter --> ${type}=${id}`);
159
160
  }
160
161
  catch (err) {
161
- console.error(constants_js_1.APP_PREFIX, `🚩 Error getting Testomat.io test grepList: ${err}`);
162
+ log_js_1.log.error(`🚩 Error getting Testomat.io test grepList: ${err}`);
162
163
  }
163
164
  }
164
165
  /**
@@ -234,8 +235,8 @@ class TestomatioPipe {
234
235
  this.runPublicUrl = resp.data.public_url;
235
236
  this.store.runUrl = this.runUrl;
236
237
  this.store.runPublicUrl = this.runPublicUrl;
237
- console.log(constants_js_1.APP_PREFIX, '📊 Using existing run. Report ID:', this.runId);
238
- console.log(constants_js_1.APP_PREFIX, '📊 Report URL:', picocolors_1.default.magenta(this.runUrl));
238
+ log_js_1.log.info('📊 Using existing run. Report ID:', this.runId);
239
+ log_js_1.log.info('📊 Report URL:', picocolors_1.default.magenta(this.runUrl));
239
240
  }
240
241
  return;
241
242
  }
@@ -256,7 +257,7 @@ class TestomatioPipe {
256
257
  this.store.runUrl = this.runUrl;
257
258
  this.store.runPublicUrl = this.runPublicUrl;
258
259
  this.store.runId = this.runId;
259
- console.log(constants_js_1.APP_PREFIX, '📊 Report created. Report ID:', this.runId);
260
+ log_js_1.log.info('📊 Report created. Report ID:', this.runId);
260
261
  process.env.runId = this.runId;
261
262
  debug('Run created', this.runId);
262
263
  }
@@ -323,7 +324,7 @@ class TestomatioPipe {
323
324
  printCreateIssue();
324
325
  }
325
326
  else {
326
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.blue(data?.title || ''), "Report couldn't be processed", err);
327
+ log_js_1.log.info(picocolors_1.default.blue(data?.title || ''), "Report couldn't be processed", err);
327
328
  }
328
329
  });
329
330
  };
@@ -376,7 +377,7 @@ class TestomatioPipe {
376
377
  printCreateIssue();
377
378
  }
378
379
  else {
379
- console.log(constants_js_1.APP_PREFIX, "Report couldn't be processed", err);
380
+ log_js_1.log.info("Report couldn't be processed", err);
380
381
  }
381
382
  });
382
383
  };
@@ -389,7 +390,7 @@ class TestomatioPipe {
389
390
  return;
390
391
  this.runId = this.runId || process.env.runId || this.store.runId || (0, utils_js_1.readLatestRunId)();
391
392
  if (!this.runId) {
392
- console.warn(constants_js_1.APP_PREFIX, picocolors_1.default.red('Run ID is not set, skipping test reporting'));
393
+ log_js_1.log.warn(picocolors_1.default.red('Run ID is not set, skipping test reporting'));
393
394
  return;
394
395
  }
395
396
  this.#formatData(data);
@@ -456,31 +457,27 @@ class TestomatioPipe {
456
457
  },
457
458
  });
458
459
  if (this.runUrl) {
459
- console.log(constants_js_1.APP_PREFIX, '📊 Report Saved. Report URL:', picocolors_1.default.magenta(this.runUrl));
460
+ log_js_1.log.warn('📊 Report URL:', picocolors_1.default.magenta(this.runUrl));
460
461
  }
461
462
  if (this.runPublicUrl) {
462
- console.log(constants_js_1.APP_PREFIX, '🌟 Public URL:', picocolors_1.default.magenta(this.runPublicUrl));
463
+ log_js_1.log.info('🌟 Public URL:', picocolors_1.default.magenta(this.runPublicUrl));
463
464
  }
464
465
  }
465
466
  if (this.runUrl && this.proceed) {
466
467
  const notFinishedMessage = picocolors_1.default.yellow(picocolors_1.default.bold('Run was not finished because of $TESTOMATIO_PROCEED'));
467
- console.log(constants_js_1.APP_PREFIX, `📊 ${notFinishedMessage}. Report URL: ${picocolors_1.default.magenta(this.runUrl)}`);
468
- console.log(constants_js_1.APP_PREFIX, `🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx @testomatio/reporter finish`);
468
+ log_js_1.log.warn(`📊 ${notFinishedMessage}. Report URL: ${picocolors_1.default.magenta(this.runUrl)}`);
469
+ log_js_1.log.warn(`🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx @testomatio/reporter finish`);
469
470
  }
470
471
  if (this.hasUnmatchedTests) {
471
472
  console.log('');
472
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow(picocolors_1.default.bold('⚠️ Some reported tests were not found in Testomat.io project')));
473
+ log_js_1.log.warn(picocolors_1.default.yellow(picocolors_1.default.bold('⚠️ Some reported tests were not found in Testomat.io project')));
473
474
  console.log(constants_js_1.APP_PREFIX, `If you use Testomat.io as a reporter only, please re-run tests using ${picocolors_1.default.bold('TESTOMATIO_CREATE=1')}`);
474
475
  console.log(constants_js_1.APP_PREFIX, `But to keep your tests consistent it is recommended to ${picocolors_1.default.bold('import tests first')}`);
475
- console.log(constants_js_1.APP_PREFIX, 'If tests were imported but still not matched, assign test IDs to your tests.');
476
- console.log(constants_js_1.APP_PREFIX, 'You can do that automatically via command line tools:');
477
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids');
478
- console.log(constants_js_1.APP_PREFIX, 'or for Cucumber:');
479
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-cucumber ... --update-ids'), 'See: https://bit.ly/bdd-update-ids');
476
+ log_js_1.log.info('If tests were imported but still not matched, assign test IDs to your tests.', 'You can do that automatically via command line tools:', picocolors_1.default.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids', 'or for Cucumber:', picocolors_1.default.bold('npx check-cucumber ... --update-ids'), 'See: https://bit.ly/bdd-update-ids');
480
477
  }
481
478
  }
482
479
  catch (err) {
483
- console.log(constants_js_1.APP_PREFIX, 'Error updating status, skipping...', err);
480
+ log_js_1.log.info('Error updating status, skipping...', err);
484
481
  if (process.env.DEBUG || process.env.TESTOMATIO_DEBUG)
485
482
  this.#logFailedResponse(err);
486
483
  printCreateIssue();
package/lib/uploader.js CHANGED
@@ -14,6 +14,7 @@ const promise_retry_1 = __importDefault(require("promise-retry"));
14
14
  const picocolors_1 = __importDefault(require("picocolors"));
15
15
  const constants_js_1 = require("./constants.js");
16
16
  const filesize_1 = require("filesize");
17
+ const log_js_1 = require("./utils/log.js");
17
18
  const debug = (0, debug_1.default)('@testomatio/reporter:file-uploader');
18
19
  class S3Uploader {
19
20
  constructor() {
@@ -119,7 +120,7 @@ class S3Uploader {
119
120
  catch (e) {
120
121
  this.failedUploads.push({ path: file.path, size: file.size });
121
122
  debug('S3 uploading error:', e);
122
- console.log(constants_js_1.APP_PREFIX, 'Upload failed:', e.message, '\nConfig:\n', this.getMaskedConfig());
123
+ log_js_1.log.info('Upload failed:', e.message, '\nConfig:\n', this.getMaskedConfig());
123
124
  }
124
125
  }
125
126
  /**
@@ -142,7 +143,7 @@ class S3Uploader {
142
143
  const diffHours = diff / 1000 / 60 / 60;
143
144
  debug('Diff hours:', diffHours);
144
145
  if (diffHours > 3) {
145
- console.log(constants_js_1.APP_PREFIX, "Artifacts file is too old, can't process artifacts. Please re-run the tests.");
146
+ log_js_1.log.info("Artifacts file is too old, can't process artifacts. Please re-run the tests.");
146
147
  return [];
147
148
  }
148
149
  const data = fs_1.default.readFileSync(tempFilePath, 'utf8');