@testomatio/reporter 2.7.1 → 2.7.2
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 +2 -1
- package/lib/adapter/codecept.js +81 -26
- package/lib/adapter/playwright.d.ts +1 -1
- package/lib/adapter/playwright.js +54 -34
- package/lib/adapter/utils/step-formatter.d.ts +134 -0
- package/lib/adapter/utils/step-formatter.js +237 -0
- package/lib/adapter/vitest.d.ts +9 -0
- package/lib/adapter/vitest.js +75 -29
- package/lib/bin/cli.js +28 -31
- package/lib/bin/reportXml.js +5 -6
- package/lib/bin/uploadArtifacts.js +6 -6
- package/lib/client.d.ts +8 -0
- package/lib/client.js +71 -10
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +7 -1
- package/lib/pipe/bitbucket.js +2 -1
- package/lib/pipe/coverage.js +16 -15
- package/lib/pipe/debug.js +3 -3
- package/lib/pipe/github.js +3 -2
- package/lib/pipe/gitlab.js +2 -1
- package/lib/pipe/index.js +5 -5
- package/lib/pipe/testomatio.js +21 -24
- package/lib/uploader.js +3 -2
- package/lib/utils/log.d.ts +45 -0
- package/lib/utils/log.js +98 -0
- package/lib/utils/pipe_utils.js +5 -5
- package/lib/utils/utils.d.ts +10 -0
- package/lib/utils/utils.js +16 -1
- package/lib/xmlReader.js +5 -4
- package/package.json +1 -1
- package/src/adapter/codecept.js +99 -29
- package/src/adapter/playwright.js +64 -39
- package/src/adapter/utils/step-formatter.js +232 -0
- package/src/adapter/vitest.js +70 -26
- package/src/bin/cli.js +34 -31
- package/src/bin/reportXml.js +5 -6
- package/src/bin/uploadArtifacts.js +6 -6
- package/src/client.js +76 -26
- package/src/constants.js +4 -0
- package/src/pipe/bitbucket.js +2 -1
- package/src/pipe/coverage.js +16 -15
- package/src/pipe/debug.js +3 -3
- package/src/pipe/github.js +4 -3
- package/src/pipe/gitlab.js +2 -1
- package/src/pipe/index.js +5 -7
- package/src/pipe/testomatio.js +32 -25
- package/src/uploader.js +3 -2
- package/src/utils/log.js +87 -0
- package/src/utils/pipe_utils.js +5 -5
- package/src/utils/utils.js +14 -0
- package/src/xmlReader.js +5 -4
- package/types/types.d.ts +3 -0
package/src/pipe/github.js
CHANGED
|
@@ -3,9 +3,10 @@ import path from 'path';
|
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import humanizeDuration from 'humanize-duration';
|
|
5
5
|
import merge from 'lodash.merge';
|
|
6
|
-
import {
|
|
6
|
+
import { testomatLogoURL } from '../constants.js';
|
|
7
7
|
import { ansiRegExp, isSameTest } from '../utils/utils.js';
|
|
8
8
|
import { statusEmoji, fullName } from '../utils/pipe_utils.js';
|
|
9
|
+
import { log } from '../utils/log.js';
|
|
9
10
|
|
|
10
11
|
const debug = createDebugMessages('@testomatio/reporter:pipe:github');
|
|
11
12
|
|
|
@@ -191,9 +192,9 @@ class GitHubPipe {
|
|
|
191
192
|
debug('Comment URL:', url);
|
|
192
193
|
this.store.githubUrl = url;
|
|
193
194
|
|
|
194
|
-
|
|
195
|
+
log.info(pc.yellow('GitHub'), `Report created: ${pc.magenta(url)}`);
|
|
195
196
|
} catch (err) {
|
|
196
|
-
|
|
197
|
+
log.info(pc.yellow('GitHub'), `Couldn't create GitHub report ${err}`);
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
|
package/src/pipe/gitlab.js
CHANGED
|
@@ -7,6 +7,7 @@ import path from 'path';
|
|
|
7
7
|
import { APP_PREFIX, testomatLogoURL } from '../constants.js';
|
|
8
8
|
import { ansiRegExp, isSameTest } from '../utils/utils.js';
|
|
9
9
|
import { statusEmoji, fullName } from '../utils/pipe_utils.js';
|
|
10
|
+
import { log } from '../utils/log.js';
|
|
10
11
|
|
|
11
12
|
const debug = createDebugMessages('@testomatio/reporter:pipe:gitlab');
|
|
12
13
|
|
|
@@ -183,7 +184,7 @@ class GitLabPipe {
|
|
|
183
184
|
// eslint-disable-next-line max-len
|
|
184
185
|
const commentURL = `${this.ENV.CI_PROJECT_URL}/-/merge_requests/${this.ENV.CI_MERGE_REQUEST_IID}#note_${commentID}`;
|
|
185
186
|
|
|
186
|
-
|
|
187
|
+
log.info(pc.yellow('GitLab'), `Report created: ${pc.magenta(commentURL)}`);
|
|
187
188
|
} catch (err) {
|
|
188
189
|
console.error(
|
|
189
190
|
APP_PREFIX,
|
package/src/pipe/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
|
-
import { APP_PREFIX } from '../constants.js';
|
|
5
4
|
import TestomatioPipe from './testomatio.js';
|
|
6
5
|
import GitHubPipe from './github.js';
|
|
7
6
|
import GitLabPipe from './gitlab.js';
|
|
@@ -10,6 +9,7 @@ import HtmlPipe from './html.js';
|
|
|
10
9
|
import CoveragePipe from './coverage.js';
|
|
11
10
|
import { BitbucketPipe } from './bitbucket.js';
|
|
12
11
|
import { DebugPipe } from './debug.js';
|
|
12
|
+
import { log } from '../utils/log.js';
|
|
13
13
|
|
|
14
14
|
export async function pipesFactory(params, opts) {
|
|
15
15
|
const extraPipes = [];
|
|
@@ -29,14 +29,14 @@ export async function pipesFactory(params, opts) {
|
|
|
29
29
|
try {
|
|
30
30
|
PipeClass = await import(pipeDef);
|
|
31
31
|
} catch (err) {
|
|
32
|
-
|
|
32
|
+
log.info(`Can't load module Testomatio pipe module from ${pipeDef}`);
|
|
33
33
|
continue;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
try {
|
|
37
37
|
extraPipes.push(new PipeClass(params, opts));
|
|
38
38
|
} catch (err) {
|
|
39
|
-
|
|
39
|
+
log.info(`Can't instantiate Testomatio for ${pipeDef}`, err);
|
|
40
40
|
continue;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -56,15 +56,13 @@ export async function pipesFactory(params, opts) {
|
|
|
56
56
|
|
|
57
57
|
const pipesEnabled = pipes.filter(p => p.isEnabled);
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
APP_PREFIX,
|
|
59
|
+
log.info(
|
|
61
60
|
pc.cyan('Pipes:'),
|
|
62
61
|
pc.cyan(pipesEnabled.map(p => p.toString()).join(', ') || 'No pipes enabled'),
|
|
63
62
|
);
|
|
64
63
|
|
|
65
64
|
if (!pipesEnabled.length) {
|
|
66
|
-
|
|
67
|
-
APP_PREFIX,
|
|
65
|
+
log.info(
|
|
68
66
|
pc.dim('If you want to use Testomatio reporter, pass your token as TESTOMATIO env variable'),
|
|
69
67
|
);
|
|
70
68
|
}
|
package/src/pipe/testomatio.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '../utils/utils.js';
|
|
13
13
|
import { parseFilterParams, generateFilterRequestParams, setS3Credentials } from '../utils/pipe_utils.js';
|
|
14
14
|
import { config } from '../config.js';
|
|
15
|
+
import { log } from '../utils/log.js';
|
|
15
16
|
|
|
16
17
|
const debug = createDebugMessages('@testomatio/reporter:pipe:testomatio');
|
|
17
18
|
|
|
@@ -65,10 +66,12 @@ class TestomatioPipe {
|
|
|
65
66
|
const sha = getGitCommitSha();
|
|
66
67
|
if (sha) {
|
|
67
68
|
this.title = `Shared Run - ${sha}`;
|
|
68
|
-
|
|
69
|
+
log.info(`🔄 Auto-generated title for shared run: ${this.title}`);
|
|
69
70
|
} else {
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
log.warn(
|
|
72
|
+
pc.red('Failed to resolve git commit SHA for shared run title.'),
|
|
73
|
+
'Please run the tests inside a Git repository or set TESTOMATIO_TITLE explicitly.',
|
|
74
|
+
);
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
|
|
@@ -106,7 +109,7 @@ class TestomatioPipe {
|
|
|
106
109
|
|
|
107
110
|
if (!isValidUrl(this.url.trim())) {
|
|
108
111
|
this.isEnabled = false;
|
|
109
|
-
|
|
112
|
+
log.error(pc.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -117,7 +120,7 @@ class TestomatioPipe {
|
|
|
117
120
|
*/
|
|
118
121
|
#formatData(data) {
|
|
119
122
|
data.api_key = this.apiKey;
|
|
120
|
-
data.create = this.createNewTests;
|
|
123
|
+
if (data.create === undefined) data.create = this.createNewTests;
|
|
121
124
|
|
|
122
125
|
// add test ID + run ID
|
|
123
126
|
if (data.rid) data.rid = `${this.runId}-${data.rid}`;
|
|
@@ -177,9 +180,9 @@ class TestomatioPipe {
|
|
|
177
180
|
return resp.data.tests;
|
|
178
181
|
}
|
|
179
182
|
|
|
180
|
-
|
|
183
|
+
log.warn(`⛔ No tests found for your --filter --> ${type}=${id}`);
|
|
181
184
|
} catch (err) {
|
|
182
|
-
|
|
185
|
+
log.error(`🚩 Error getting Testomat.io test grepList: ${err}`);
|
|
183
186
|
}
|
|
184
187
|
}
|
|
185
188
|
|
|
@@ -262,8 +265,8 @@ class TestomatioPipe {
|
|
|
262
265
|
this.runPublicUrl = resp.data.public_url;
|
|
263
266
|
this.store.runUrl = this.runUrl;
|
|
264
267
|
this.store.runPublicUrl = this.runPublicUrl;
|
|
265
|
-
|
|
266
|
-
|
|
268
|
+
log.info('📊 Using existing run. Report ID:', this.runId);
|
|
269
|
+
log.info('📊 Report URL:', pc.magenta(this.runUrl));
|
|
267
270
|
}
|
|
268
271
|
return;
|
|
269
272
|
}
|
|
@@ -287,7 +290,7 @@ class TestomatioPipe {
|
|
|
287
290
|
this.store.runUrl = this.runUrl;
|
|
288
291
|
this.store.runPublicUrl = this.runPublicUrl;
|
|
289
292
|
this.store.runId = this.runId;
|
|
290
|
-
|
|
293
|
+
log.info('📊 Report created. Report ID:', this.runId);
|
|
291
294
|
process.env.runId = this.runId;
|
|
292
295
|
debug('Run created', this.runId);
|
|
293
296
|
} catch (err) {
|
|
@@ -355,7 +358,7 @@ class TestomatioPipe {
|
|
|
355
358
|
this.#logFailedResponse(err);
|
|
356
359
|
printCreateIssue();
|
|
357
360
|
} else {
|
|
358
|
-
|
|
361
|
+
log.info(pc.blue(data?.title || ''), "Report couldn't be processed", err);
|
|
359
362
|
}
|
|
360
363
|
});
|
|
361
364
|
};
|
|
@@ -406,7 +409,7 @@ class TestomatioPipe {
|
|
|
406
409
|
this.#logFailedResponse(err);
|
|
407
410
|
printCreateIssue();
|
|
408
411
|
} else {
|
|
409
|
-
|
|
412
|
+
log.info("Report couldn't be processed", err);
|
|
410
413
|
}
|
|
411
414
|
});
|
|
412
415
|
};
|
|
@@ -420,7 +423,7 @@ class TestomatioPipe {
|
|
|
420
423
|
|
|
421
424
|
this.runId = this.runId || process.env.runId || this.store.runId || readLatestRunId();
|
|
422
425
|
if (!this.runId) {
|
|
423
|
-
|
|
426
|
+
log.warn(pc.red('Run ID is not set, skipping test reporting'));
|
|
424
427
|
return;
|
|
425
428
|
}
|
|
426
429
|
|
|
@@ -495,21 +498,21 @@ class TestomatioPipe {
|
|
|
495
498
|
});
|
|
496
499
|
|
|
497
500
|
if (this.runUrl) {
|
|
498
|
-
|
|
501
|
+
log.warn('📊 Report URL:', pc.magenta(this.runUrl));
|
|
499
502
|
}
|
|
500
503
|
if (this.runPublicUrl) {
|
|
501
|
-
|
|
504
|
+
log.info('🌟 Public URL:', pc.magenta(this.runPublicUrl));
|
|
502
505
|
}
|
|
503
506
|
}
|
|
504
507
|
if (this.runUrl && this.proceed) {
|
|
505
508
|
const notFinishedMessage = pc.yellow(pc.bold('Run was not finished because of $TESTOMATIO_PROCEED'));
|
|
506
|
-
|
|
507
|
-
|
|
509
|
+
log.warn(`📊 ${notFinishedMessage}. Report URL: ${pc.magenta(this.runUrl)}`);
|
|
510
|
+
log.warn(`🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx @testomatio/reporter finish`);
|
|
508
511
|
}
|
|
509
512
|
|
|
510
513
|
if (this.hasUnmatchedTests) {
|
|
511
514
|
console.log('');
|
|
512
|
-
|
|
515
|
+
log.warn(pc.yellow(pc.bold('⚠️ Some reported tests were not found in Testomat.io project')));
|
|
513
516
|
console.log(
|
|
514
517
|
APP_PREFIX,
|
|
515
518
|
`If you use Testomat.io as a reporter only, please re-run tests using ${pc.bold('TESTOMATIO_CREATE=1')}`,
|
|
@@ -518,14 +521,18 @@ class TestomatioPipe {
|
|
|
518
521
|
APP_PREFIX,
|
|
519
522
|
`But to keep your tests consistent it is recommended to ${pc.bold('import tests first')}`,
|
|
520
523
|
);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
524
|
+
log.info(
|
|
525
|
+
'If tests were imported but still not matched, assign test IDs to your tests.',
|
|
526
|
+
'You can do that automatically via command line tools:',
|
|
527
|
+
pc.bold('npx check-tests ... --update-ids'),
|
|
528
|
+
'See: https://bit.ly/js-update-ids',
|
|
529
|
+
'or for Cucumber:',
|
|
530
|
+
pc.bold('npx check-cucumber ... --update-ids'),
|
|
531
|
+
'See: https://bit.ly/bdd-update-ids',
|
|
532
|
+
);
|
|
526
533
|
}
|
|
527
534
|
} catch (err) {
|
|
528
|
-
|
|
535
|
+
log.info('Error updating status, skipping...', err);
|
|
529
536
|
if (process.env.DEBUG || process.env.TESTOMATIO_DEBUG) this.#logFailedResponse(err);
|
|
530
537
|
printCreateIssue();
|
|
531
538
|
}
|
|
@@ -541,7 +548,7 @@ class TestomatioPipe {
|
|
|
541
548
|
clearInterval(this.batch.intervalFunction);
|
|
542
549
|
this.batch.intervalFunction = null;
|
|
543
550
|
this.batch.isEnabled = false;
|
|
544
|
-
}
|
|
551
|
+
}
|
|
545
552
|
this.batch.tests = [];
|
|
546
553
|
}
|
|
547
554
|
|
package/src/uploader.js
CHANGED
|
@@ -8,6 +8,7 @@ import promiseRetry from 'promise-retry';
|
|
|
8
8
|
import pc from 'picocolors';
|
|
9
9
|
import { APP_PREFIX } from './constants.js';
|
|
10
10
|
import { filesize as prettyBytes } from 'filesize';
|
|
11
|
+
import { log } from './utils/log.js';
|
|
11
12
|
|
|
12
13
|
const debug = createDebugMessages('@testomatio/reporter:file-uploader');
|
|
13
14
|
|
|
@@ -133,7 +134,7 @@ export class S3Uploader {
|
|
|
133
134
|
} catch (e) {
|
|
134
135
|
this.failedUploads.push({ path: file.path, size: file.size });
|
|
135
136
|
debug('S3 uploading error:', e);
|
|
136
|
-
|
|
137
|
+
log.info('Upload failed:', e.message, '\nConfig:\n', this.getMaskedConfig());
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|
|
@@ -160,7 +161,7 @@ export class S3Uploader {
|
|
|
160
161
|
const diffHours = diff / 1000 / 60 / 60;
|
|
161
162
|
debug('Diff hours:', diffHours);
|
|
162
163
|
if (diffHours > 3) {
|
|
163
|
-
|
|
164
|
+
log.info("Artifacts file is too old, can't process artifacts. Please re-run the tests.");
|
|
164
165
|
return [];
|
|
165
166
|
}
|
|
166
167
|
|
package/src/utils/log.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { APP_PREFIX } from '../constants.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Log levels for the Testomat.io reporter.
|
|
5
|
+
* A message is logged if its level is <= the current log level.
|
|
6
|
+
* @example
|
|
7
|
+
* TESTOMATIO_LOG_LEVEL=ERROR npx codeceptjs run // Only errors
|
|
8
|
+
* TESTOMATIO_LOG_LEVEL=WARN npx codeceptjs run // Warnings and errors
|
|
9
|
+
* TESTOMATIO_LOG_LEVEL=INFO npx codeceptjs run // Info, warnings, errors (default)
|
|
10
|
+
*/
|
|
11
|
+
export const LOG_LEVELS = {
|
|
12
|
+
ERROR: 0,
|
|
13
|
+
WARN: 1,
|
|
14
|
+
INFO: 2,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the current log level from TESTOMATIO_LOG_LEVEL environment variable.
|
|
19
|
+
* Defaults to INFO (info, warn, and error messages).
|
|
20
|
+
* @returns {number} Numeric log level (0-2)
|
|
21
|
+
*/
|
|
22
|
+
export function getLogLevel() {
|
|
23
|
+
const envLevel = process.env.TESTOMATIO_LOG_LEVEL?.toUpperCase();
|
|
24
|
+
return LOG_LEVELS[envLevel] ?? LOG_LEVELS.INFO;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if a message should be logged based on its level.
|
|
29
|
+
* A message is logged if its level is <= the current log level,
|
|
30
|
+
* or if TESTOMATIO_DEBUG is set (for debugging with the debug package).
|
|
31
|
+
* @param {number} messageLevel - Message level (LOG_LEVELS value)
|
|
32
|
+
* @returns {boolean} True if the message should be logged
|
|
33
|
+
*/
|
|
34
|
+
export function shouldLog(messageLevel) {
|
|
35
|
+
return messageLevel <= getLogLevel() || !!process.env.TESTOMATIO_DEBUG;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Log an info message with [TESTOMATIO] prefix.
|
|
40
|
+
* Only logs when TESTOMATIO_LOG_LEVEL is INFO.
|
|
41
|
+
* @param {...any} args - Arguments to log
|
|
42
|
+
*/
|
|
43
|
+
export function info(...args) {
|
|
44
|
+
if (shouldLog(LOG_LEVELS.INFO)) {
|
|
45
|
+
console.log(APP_PREFIX, ...args);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Log a warning message with [TESTOMATIO] prefix.
|
|
51
|
+
* Only logs when TESTOMATIO_LOG_LEVEL is WARN or INFO.
|
|
52
|
+
* @param {...any} args - Arguments to log
|
|
53
|
+
*/
|
|
54
|
+
export function warn(...args) {
|
|
55
|
+
if (shouldLog(LOG_LEVELS.WARN)) {
|
|
56
|
+
console.warn(APP_PREFIX, ...args);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Log an error message with [TESTOMATIO] prefix.
|
|
62
|
+
* Logs for all TESTOMATIO_LOG_LEVEL values.
|
|
63
|
+
* @param {...any} args - Arguments to log
|
|
64
|
+
*/
|
|
65
|
+
export function error(...args) {
|
|
66
|
+
if (shouldLog(LOG_LEVELS.ERROR)) {
|
|
67
|
+
console.error(APP_PREFIX, ...args);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Logging utility for Testomat.io reporter.
|
|
73
|
+
* All messages are prefixed with [TESTOMATIO] and respect TESTOMATIO_LOG_LEVEL.
|
|
74
|
+
* @example
|
|
75
|
+
* import { log } from './utils/log.js';
|
|
76
|
+
* log.info('Test started');
|
|
77
|
+
* log.warn('This is a warning');
|
|
78
|
+
* log.error('Something went wrong');
|
|
79
|
+
*/
|
|
80
|
+
export const log = {
|
|
81
|
+
info,
|
|
82
|
+
warn,
|
|
83
|
+
error,
|
|
84
|
+
getLogLevel,
|
|
85
|
+
shouldLog,
|
|
86
|
+
LOG_LEVELS,
|
|
87
|
+
};
|
package/src/utils/pipe_utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { log } from './log.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Set S3 credentials from the provided artifacts object.
|
|
@@ -7,7 +7,7 @@ import { APP_PREFIX } from '../constants.js';
|
|
|
7
7
|
function setS3Credentials(artifacts) {
|
|
8
8
|
if (!Object.keys(artifacts).length) return;
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
log.info( 'S3 credentials obtained from Testomat.io...');
|
|
11
11
|
|
|
12
12
|
if (artifacts.ACCESS_KEY_ID) process.env.S3_ACCESS_KEY_ID = artifacts.ACCESS_KEY_ID;
|
|
13
13
|
if (artifacts.SECRET_ACCESS_KEY) process.env.S3_SECRET_ACCESS_KEY = artifacts.SECRET_ACCESS_KEY;
|
|
@@ -28,7 +28,7 @@ function setS3Credentials(artifacts) {
|
|
|
28
28
|
function generateFilterRequestParams(params) {
|
|
29
29
|
// Defensive check: ensure params is an object
|
|
30
30
|
if (!params || typeof params !== 'object') {
|
|
31
|
-
|
|
31
|
+
log.error( `Invalid parameters provided. Expected an object, got: ${typeof params}`);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -39,7 +39,7 @@ function generateFilterRequestParams(params) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (!id) {
|
|
42
|
-
|
|
42
|
+
log.error( `Please make sure your settings "${type.toUpperCase()}"= "${id}" is correct!`);
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -99,7 +99,7 @@ function updateFilterType(type) {
|
|
|
99
99
|
];
|
|
100
100
|
|
|
101
101
|
if (!filterTypes.includes(typeLowerCase)) {
|
|
102
|
-
|
|
102
|
+
log.error( `❗ Invalid filter: "${type}" start settings! Available option list: ${filterTypes}`);
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
|
package/src/utils/utils.js
CHANGED
|
@@ -92,6 +92,19 @@ const isValidUrl = s => {
|
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Checks whether a value is an HTTP(S) URL.
|
|
97
|
+
*
|
|
98
|
+
* Used for artifact handling: if a step artifact is already a remote URL,
|
|
99
|
+
* it should not be uploaded again as a local file path.
|
|
100
|
+
*
|
|
101
|
+
* @param {*} value - Artifact value to validate
|
|
102
|
+
* @returns {boolean} true when value starts with http:// or https://
|
|
103
|
+
*/
|
|
104
|
+
const isHttpUrl = value => {
|
|
105
|
+
return /^https?:\/\//i.test(String(value || ''));
|
|
106
|
+
};
|
|
107
|
+
|
|
95
108
|
const fileMatchRegex = /file:(\/*)([A-Za-z]:[\\/].*?|\/.*?)\.(png|avi|webm|jpg|html|txt)/gi;
|
|
96
109
|
|
|
97
110
|
const fetchFilesFromStackTrace = (stack = '', checkExists = true) => {
|
|
@@ -705,6 +718,7 @@ export {
|
|
|
705
718
|
getGitCommitSha,
|
|
706
719
|
getTestomatIdFromTestTitle,
|
|
707
720
|
humanize,
|
|
721
|
+
isHttpUrl,
|
|
708
722
|
isValidUrl,
|
|
709
723
|
parseSuite,
|
|
710
724
|
readLatestRunId,
|
package/src/xmlReader.js
CHANGED
|
@@ -21,6 +21,7 @@ import { pipesFactory } from './pipe/index.js';
|
|
|
21
21
|
import adapterFactory from './junit-adapter/index.js';
|
|
22
22
|
import { config } from './config.js';
|
|
23
23
|
import { S3Uploader } from './uploader.js';
|
|
24
|
+
import { log } from './utils/log.js';
|
|
24
25
|
|
|
25
26
|
// @ts-ignore this line will be removed in compiled code, because __dirname is defined in commonjs
|
|
26
27
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -86,7 +87,7 @@ class XmlReader {
|
|
|
86
87
|
// @ts-ignore
|
|
87
88
|
const packageJsonPath = path.resolve(__dirname, '..', 'package.json');
|
|
88
89
|
this.version = JSON.parse(fs.readFileSync(packageJsonPath).toString()).version;
|
|
89
|
-
|
|
90
|
+
log.info(`Testomatio Reporter v${this.version}`);
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
connectAdapter() {
|
|
@@ -508,7 +509,7 @@ class XmlReader {
|
|
|
508
509
|
|
|
509
510
|
const runId = this.runId || this.store.runId || Date.now().toString();
|
|
510
511
|
test.artifacts = await Promise.all(files.map(f => this.uploader.uploadFileByPath(f, [runId, path.basename(f)])));
|
|
511
|
-
|
|
512
|
+
log.info(`🗄️ Uploaded ${pc.bold(`${files.length} artifacts`)} for test ${test.title}`);
|
|
512
513
|
}
|
|
513
514
|
}
|
|
514
515
|
|
|
@@ -626,9 +627,9 @@ class XmlReader {
|
|
|
626
627
|
}
|
|
627
628
|
|
|
628
629
|
if (totalChunks > 1) {
|
|
629
|
-
|
|
630
|
+
log.info(`✅ Successfully uploaded ${uploadedTests} tests in ${totalChunks} chunks`);
|
|
630
631
|
} else {
|
|
631
|
-
|
|
632
|
+
log.info(`✅ Successfully uploaded ${uploadedTests} tests`);
|
|
632
633
|
}
|
|
633
634
|
|
|
634
635
|
const finishData = {
|