@testomatio/reporter 2.0.0-beta.1-gaxios → 2.0.0-beta.1-xml
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/lib/adapter/nightwatch.js +5 -5
- package/lib/adapter/webdriver.d.ts +1 -1
- package/lib/bin/cli.js +7 -6
- package/lib/bin/reportXml.js +4 -2
- package/lib/bin/startTest.js +3 -2
- package/lib/bin/uploadArtifacts.js +5 -4
- package/lib/data-storage.d.ts +1 -1
- package/lib/junit-adapter/csharp.d.ts +1 -0
- package/lib/junit-adapter/csharp.js +11 -1
- package/lib/pipe/bitbucket.d.ts +0 -2
- package/lib/pipe/bitbucket.js +19 -21
- package/lib/pipe/gitlab.d.ts +0 -2
- package/lib/pipe/gitlab.js +8 -27
- package/lib/pipe/testomatio.d.ts +1 -2
- package/lib/pipe/testomatio.js +63 -73
- package/lib/reporter.d.ts +12 -12
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/logger.d.ts +1 -1
- package/lib/utils/utils.d.ts +2 -0
- package/lib/utils/utils.js +20 -4
- package/lib/xmlReader.js +38 -11
- package/package.json +6 -5
- package/src/adapter/nightwatch.js +1 -1
- package/src/adapter/webdriver.js +1 -1
- package/src/bin/cli.js +2 -1
- package/src/bin/reportXml.js +4 -1
- package/src/bin/startTest.js +2 -1
- package/src/bin/uploadArtifacts.js +2 -1
- package/src/junit-adapter/csharp.js +13 -1
- package/src/pipe/bitbucket.js +24 -22
- package/src/pipe/gitlab.js +8 -27
- package/src/pipe/testomatio.js +93 -92
- package/src/utils/utils.js +14 -1
- package/src/xmlReader.js +47 -11
package/lib/reporter.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type log = typeof import("./reporter-functions.js");
|
|
|
8
8
|
export const log: (...args: any[]) => void;
|
|
9
9
|
export type logger = typeof import("./services/index.js");
|
|
10
10
|
export const logger: {
|
|
11
|
-
"__#
|
|
11
|
+
"__#12@#originalUserLogger": {
|
|
12
12
|
assert(condition?: boolean, ...data: any[]): void;
|
|
13
13
|
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
|
14
14
|
clear(): void;
|
|
@@ -53,13 +53,13 @@ export const logger: {
|
|
|
53
53
|
profile(label?: string): void;
|
|
54
54
|
profileEnd(label?: string): void;
|
|
55
55
|
};
|
|
56
|
-
"__#
|
|
56
|
+
"__#12@#userLoggerWithOverridenMethods": any;
|
|
57
57
|
logLevel: string;
|
|
58
58
|
step(strings: any, ...values: any[]): void;
|
|
59
59
|
getLogs(context: string): string[];
|
|
60
|
-
"__#
|
|
60
|
+
"__#12@#stringifyLogs"(...args: any[]): string;
|
|
61
61
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
62
|
-
"__#
|
|
62
|
+
"__#12@#logWrapper"(argsArray: any, level: any): void;
|
|
63
63
|
assert(...args: any[]): void;
|
|
64
64
|
debug(...args: any[]): void;
|
|
65
65
|
error(...args: any[]): void;
|
|
@@ -83,7 +83,7 @@ export type step = typeof import("./reporter-functions.js");
|
|
|
83
83
|
export const step: (message: string) => void;
|
|
84
84
|
declare namespace _default {
|
|
85
85
|
let testomatioLogger: {
|
|
86
|
-
"__#
|
|
86
|
+
"__#12@#originalUserLogger": {
|
|
87
87
|
assert(condition?: boolean, ...data: any[]): void;
|
|
88
88
|
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
|
89
89
|
clear(): void;
|
|
@@ -128,13 +128,13 @@ declare namespace _default {
|
|
|
128
128
|
profile(label?: string): void;
|
|
129
129
|
profileEnd(label?: string): void;
|
|
130
130
|
};
|
|
131
|
-
"__#
|
|
131
|
+
"__#12@#userLoggerWithOverridenMethods": any;
|
|
132
132
|
logLevel: string;
|
|
133
133
|
step(strings: any, ...values: any[]): void;
|
|
134
134
|
getLogs(context: string): string[];
|
|
135
|
-
"__#
|
|
135
|
+
"__#12@#stringifyLogs"(...args: any[]): string;
|
|
136
136
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
137
|
-
"__#
|
|
137
|
+
"__#12@#logWrapper"(argsArray: any, level: any): void;
|
|
138
138
|
assert(...args: any[]): void;
|
|
139
139
|
debug(...args: any[]): void;
|
|
140
140
|
error(...args: any[]): void;
|
|
@@ -157,7 +157,7 @@ declare namespace _default {
|
|
|
157
157
|
}, context?: any) => void;
|
|
158
158
|
let log: (...args: any[]) => void;
|
|
159
159
|
let logger: {
|
|
160
|
-
"__#
|
|
160
|
+
"__#12@#originalUserLogger": {
|
|
161
161
|
assert(condition?: boolean, ...data: any[]): void;
|
|
162
162
|
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
|
163
163
|
clear(): void;
|
|
@@ -202,13 +202,13 @@ declare namespace _default {
|
|
|
202
202
|
profile(label?: string): void;
|
|
203
203
|
profileEnd(label?: string): void;
|
|
204
204
|
};
|
|
205
|
-
"__#
|
|
205
|
+
"__#12@#userLoggerWithOverridenMethods": any;
|
|
206
206
|
logLevel: string;
|
|
207
207
|
step(strings: any, ...values: any[]): void;
|
|
208
208
|
getLogs(context: string): string[];
|
|
209
|
-
"__#
|
|
209
|
+
"__#12@#stringifyLogs"(...args: any[]): string;
|
|
210
210
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
211
|
-
"__#
|
|
211
|
+
"__#12@#logWrapper"(argsArray: any, level: any): void;
|
|
212
212
|
assert(...args: any[]): void;
|
|
213
213
|
debug(...args: any[]): void;
|
|
214
214
|
error(...args: any[]): void;
|
package/lib/services/logger.d.ts
CHANGED
package/lib/utils/utils.d.ts
CHANGED
package/lib/utils/utils.js
CHANGED
|
@@ -36,7 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.testRunnerHelper = exports.specificTestInfo = exports.parseSuite = exports.isValidUrl = exports.humanize = exports.getTestomatIdFromTestTitle = exports.getCurrentDateTime = exports.foundedTestLog = exports.fileSystem = exports.fetchFilesFromStackTrace = exports.fetchIdFromOutput = exports.fetchIdFromCode = exports.fetchSourceCodeFromStackTrace = exports.fetchSourceCode = exports.isSameTest = exports.ansiRegExp = void 0;
|
|
39
|
+
exports.testRunnerHelper = exports.specificTestInfo = exports.parseSuite = exports.isValidUrl = exports.humanize = exports.getTestomatIdFromTestTitle = exports.getCurrentDateTime = exports.foundedTestLog = exports.fileSystem = exports.fetchFilesFromStackTrace = exports.fetchIdFromOutput = exports.fetchIdFromCode = exports.fetchSourceCodeFromStackTrace = exports.fetchSourceCode = exports.isSameTest = exports.ansiRegExp = exports.TEST_ID_REGEX = void 0;
|
|
40
|
+
exports.getPackageVersion = getPackageVersion;
|
|
40
41
|
exports.formatStep = formatStep;
|
|
41
42
|
exports.readLatestRunId = readLatestRunId;
|
|
42
43
|
exports.removeColorCodes = removeColorCodes;
|
|
@@ -48,7 +49,9 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
48
49
|
const is_valid_path_1 = __importDefault(require("is-valid-path"));
|
|
49
50
|
const debug_1 = __importDefault(require("debug"));
|
|
50
51
|
const os_1 = __importDefault(require("os"));
|
|
52
|
+
const url_2 = require("url");
|
|
51
53
|
const debug = (0, debug_1.default)('@testomatio/reporter:util');
|
|
54
|
+
// Use __dirname directly since we're compiling to CommonJS
|
|
52
55
|
/**
|
|
53
56
|
* @param {String} testTitle - Test title
|
|
54
57
|
*
|
|
@@ -140,7 +143,7 @@ const fetchSourceCodeFromStackTrace = (stack = '') => {
|
|
|
140
143
|
.join('\n');
|
|
141
144
|
};
|
|
142
145
|
exports.fetchSourceCodeFromStackTrace = fetchSourceCodeFromStackTrace;
|
|
143
|
-
|
|
146
|
+
exports.TEST_ID_REGEX = /@T([\w\d]{8})/;
|
|
144
147
|
const fetchIdFromCode = (code, opts = {}) => {
|
|
145
148
|
const comments = code
|
|
146
149
|
.split('\n')
|
|
@@ -154,11 +157,11 @@ const fetchIdFromCode = (code, opts = {}) => {
|
|
|
154
157
|
return l.startsWith('// ');
|
|
155
158
|
}
|
|
156
159
|
});
|
|
157
|
-
return comments.find(c => c.match(TEST_ID_REGEX))?.match(TEST_ID_REGEX)?.[1];
|
|
160
|
+
return comments.find(c => c.match(exports.TEST_ID_REGEX))?.match(exports.TEST_ID_REGEX)?.[1];
|
|
158
161
|
};
|
|
159
162
|
exports.fetchIdFromCode = fetchIdFromCode;
|
|
160
163
|
const fetchIdFromOutput = output => {
|
|
161
|
-
const TID_FULL_PATTERN = new RegExp(`tid:\\/\\/.*?(${TEST_ID_REGEX.source})`);
|
|
164
|
+
const TID_FULL_PATTERN = new RegExp(`tid:\\/\\/.*?(${exports.TEST_ID_REGEX.source})`);
|
|
162
165
|
return output.match(TID_FULL_PATTERN)?.[2];
|
|
163
166
|
};
|
|
164
167
|
exports.fetchIdFromOutput = fetchIdFromOutput;
|
|
@@ -183,6 +186,12 @@ const fetchSourceCode = (contents, opts = {}) => {
|
|
|
183
186
|
if (lineIndex === -1)
|
|
184
187
|
lineIndex = lines.findIndex(l => l.includes(`${title}(`));
|
|
185
188
|
}
|
|
189
|
+
else if (opts.lang === 'csharp') {
|
|
190
|
+
if (lineIndex === -1)
|
|
191
|
+
lineIndex = lines.findIndex(l => l.includes(`public void ${title}`));
|
|
192
|
+
if (lineIndex === -1)
|
|
193
|
+
lineIndex = lines.findIndex(l => l.includes(`${title}(`));
|
|
194
|
+
}
|
|
186
195
|
else {
|
|
187
196
|
lineIndex = lines.findIndex(l => l.includes(title));
|
|
188
197
|
}
|
|
@@ -384,6 +393,13 @@ function formatStep(step, shift = 0) {
|
|
|
384
393
|
}
|
|
385
394
|
return lines;
|
|
386
395
|
}
|
|
396
|
+
function getPackageVersion() {
|
|
397
|
+
const packageJsonPath = path_1.default.resolve(__dirname, '../../package.json');
|
|
398
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
|
|
399
|
+
return packageJson.version;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
module.exports.getPackageVersion = getPackageVersion;
|
|
387
403
|
|
|
388
404
|
module.exports.formatStep = formatStep;
|
|
389
405
|
|
package/lib/xmlReader.js
CHANGED
|
@@ -20,7 +20,7 @@ const uploader_js_1 = require("./uploader.js");
|
|
|
20
20
|
const debug = (0, debug_1.default)('@testomatio/reporter:xml');
|
|
21
21
|
const ridRunId = (0, crypto_1.randomUUID)();
|
|
22
22
|
const TESTOMATIO_URL = process.env.TESTOMATIO_URL || 'https://app.testomat.io';
|
|
23
|
-
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN, TESTOMATIO_MARK_DETACHED } = process.env;
|
|
23
|
+
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_SUITE, TESTOMATIO_MAX_STACK_TRACE, TESTOMATIO_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN, TESTOMATIO_MARK_DETACHED } = process.env;
|
|
24
24
|
const options = {
|
|
25
25
|
ignoreDeclaration: true,
|
|
26
26
|
ignoreAttributes: false,
|
|
@@ -28,6 +28,7 @@ const options = {
|
|
|
28
28
|
attributeNamePrefix: '',
|
|
29
29
|
parseTagValue: true,
|
|
30
30
|
};
|
|
31
|
+
const MAX_OUTPUT_LENGTH = parseInt(TESTOMATIO_MAX_STACK_TRACE, 10) || 10000;
|
|
31
32
|
const reduceOptions = {};
|
|
32
33
|
class XmlReader {
|
|
33
34
|
constructor(opts = {}) {
|
|
@@ -75,7 +76,7 @@ class XmlReader {
|
|
|
75
76
|
/(<system-out><!\[CDATA\[)([\s\S]*?)(\]\]><\/system-out>)/g,
|
|
76
77
|
];
|
|
77
78
|
for (const regex of cutRegexes) {
|
|
78
|
-
xmlData = xmlData.replace(regex, (_, p1, p2, p3) => `${p1}${p2.substring(0,
|
|
79
|
+
xmlData = xmlData.replace(regex, (_, p1, p2, p3) => `${p1}${p2.substring(0, MAX_OUTPUT_LENGTH)}${p3}`);
|
|
79
80
|
}
|
|
80
81
|
const jsonResult = this.parser.parse(xmlData);
|
|
81
82
|
let jsonSuite;
|
|
@@ -313,6 +314,8 @@ class XmlReader {
|
|
|
313
314
|
this.stats.language = 'js';
|
|
314
315
|
if (file.endsWith('.ts'))
|
|
315
316
|
this.stats.language = 'ts';
|
|
317
|
+
if (file.endsWith('.cs'))
|
|
318
|
+
this.stats.language = 'csharp';
|
|
316
319
|
}
|
|
317
320
|
if (!fs_1.default.existsSync(file)) {
|
|
318
321
|
debug('Failed to open file with the source code', file);
|
|
@@ -359,13 +362,13 @@ class XmlReader {
|
|
|
359
362
|
async uploadArtifacts() {
|
|
360
363
|
for (const test of this.tests.filter(t => !!t.stack)) {
|
|
361
364
|
let files = [];
|
|
362
|
-
if (test.files?.length)
|
|
363
|
-
|
|
364
|
-
files =
|
|
365
|
+
if (!test.files?.length)
|
|
366
|
+
continue;
|
|
367
|
+
files = test.files.map(f => path_1.default.isAbsolute(f) ? f : path_1.default.join(process.cwd(), f));
|
|
365
368
|
if (!files.length)
|
|
366
369
|
continue;
|
|
367
370
|
const runId = this.runId || this.store.runId || Date.now().toString();
|
|
368
|
-
test.artifacts = await Promise.all(files.map(f => this.uploader.uploadFileByPath(f, [runId])));
|
|
371
|
+
test.artifacts = await Promise.all(files.map(f => this.uploader.uploadFileByPath(f, [runId, path_1.default.basename(f)])));
|
|
369
372
|
console.log(constants_js_1.APP_PREFIX, `🗄️ Uploaded ${picocolors_1.default.bold(`${files.length} artifacts`)} for test ${test.title}`);
|
|
370
373
|
}
|
|
371
374
|
}
|
|
@@ -425,7 +428,7 @@ function reduceTestCases(prev, item) {
|
|
|
425
428
|
testCases
|
|
426
429
|
.filter(t => !!t)
|
|
427
430
|
.forEach(testCaseItem => {
|
|
428
|
-
const file = testCaseItem.file || item.filepath || '';
|
|
431
|
+
const file = testCaseItem.file || item.filepath || item.fullname || '';
|
|
429
432
|
let stack = '';
|
|
430
433
|
let message = '';
|
|
431
434
|
if (testCaseItem.error)
|
|
@@ -458,15 +461,34 @@ function reduceTestCases(prev, item) {
|
|
|
458
461
|
title = title.replace(/\(.*?\)/, '').trim();
|
|
459
462
|
}
|
|
460
463
|
stack = `${testCaseItem['system-out'] || testCaseItem.output || testCaseItem.log || ''}\n\n${stack}\n\n${suiteOutput}\n\n${suiteErr}`.trim();
|
|
461
|
-
|
|
464
|
+
let testId = (0, utils_js_1.fetchIdFromOutput)(stack);
|
|
465
|
+
if (tags?.length && !testId) {
|
|
466
|
+
testId = tags.filter(t => t.startsWith('T')).map(t => `@${t}`).find(t => t.match(utils_js_1.TEST_ID_REGEX))?.slice(2);
|
|
467
|
+
}
|
|
462
468
|
let status = constants_js_1.STATUS.PASSED.toString();
|
|
463
469
|
if ('failure' in testCaseItem || 'error' in testCaseItem)
|
|
464
470
|
status = constants_js_1.STATUS.FAILED;
|
|
465
471
|
if ('skipped' in testCaseItem)
|
|
466
472
|
status = constants_js_1.STATUS.SKIPPED;
|
|
473
|
+
if (testCaseItem.result && Object.values(constants_js_1.STATUS).includes(testCaseItem.result.toLowerCase())) {
|
|
474
|
+
status = testCaseItem.result.toLowerCase();
|
|
475
|
+
}
|
|
467
476
|
let rid = null;
|
|
468
477
|
if (testCaseItem.id)
|
|
469
478
|
rid = `${ridRunId}-${testCaseItem.id}`;
|
|
479
|
+
// Extract attachments
|
|
480
|
+
let files = [];
|
|
481
|
+
if (testCaseItem.attachments) {
|
|
482
|
+
const attachments = Array.isArray(testCaseItem.attachments.attachment)
|
|
483
|
+
? testCaseItem.attachments.attachment
|
|
484
|
+
: [testCaseItem.attachments.attachment];
|
|
485
|
+
files = attachments
|
|
486
|
+
.filter(a => a && a.filePath)
|
|
487
|
+
.map(a => a.filePath);
|
|
488
|
+
}
|
|
489
|
+
// Extract files from stack trace using existing utility
|
|
490
|
+
const stackFiles = (0, utils_js_1.fetchFilesFromStackTrace)(stack);
|
|
491
|
+
files = [...new Set([...files, ...stackFiles])]; // Remove duplicates
|
|
470
492
|
prev.push({
|
|
471
493
|
rid,
|
|
472
494
|
file,
|
|
@@ -481,7 +503,9 @@ function reduceTestCases(prev, item) {
|
|
|
481
503
|
run_time: parseFloat(testCaseItem.time || testCaseItem.duration) * 1000,
|
|
482
504
|
status,
|
|
483
505
|
title,
|
|
506
|
+
root_suite_id: TESTOMATIO_SUITE,
|
|
484
507
|
suite_title: suiteTitle,
|
|
508
|
+
files,
|
|
485
509
|
});
|
|
486
510
|
});
|
|
487
511
|
return prev;
|
|
@@ -505,11 +529,14 @@ function fetchProperties(item) {
|
|
|
505
529
|
let title = '';
|
|
506
530
|
if (!item.properties)
|
|
507
531
|
return {};
|
|
508
|
-
|
|
532
|
+
// Handle both single property and array of properties
|
|
533
|
+
const properties = Array.isArray(item.properties.property)
|
|
534
|
+
? item.properties.property
|
|
535
|
+
: [item.properties.property].filter(Boolean);
|
|
536
|
+
const prop = properties.find(p => p.name === 'Description');
|
|
509
537
|
if (prop)
|
|
510
538
|
title = prop.value;
|
|
511
|
-
|
|
512
|
-
.flat()
|
|
539
|
+
properties
|
|
513
540
|
.filter(p => p.name === 'Category')
|
|
514
541
|
.forEach(p => tags.push(p.value));
|
|
515
542
|
return { title, tags };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/reporter",
|
|
3
|
-
"version": "2.0.0-beta.1-
|
|
3
|
+
"version": "2.0.0-beta.1-xml",
|
|
4
4
|
"description": "Testomatio Reporter Client",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"@cucumber/cucumber": "^10.9.0",
|
|
17
17
|
"@octokit/rest": "^21.1.1",
|
|
18
18
|
"aws-sdk": "^2.1072.0",
|
|
19
|
-
"
|
|
19
|
+
"axios": "^1.6.2",
|
|
20
|
+
"axios-retry": "^3.9.1",
|
|
20
21
|
"callsite-record": "^4.1.4",
|
|
21
22
|
"commander": "^12",
|
|
22
23
|
"cross-spawn": "^7.0.3",
|
|
@@ -48,7 +49,6 @@
|
|
|
48
49
|
"testcafe"
|
|
49
50
|
],
|
|
50
51
|
"scripts": {
|
|
51
|
-
"@cucumber/cucumber": "^10.9.0",
|
|
52
52
|
"clear-exportdir": "rm -rf export/",
|
|
53
53
|
"pretty": "npx prettier --check .",
|
|
54
54
|
"pretty:fix": "prettier --write .",
|
|
@@ -67,8 +67,9 @@
|
|
|
67
67
|
"test:adapter:playwright:example": "npx playwright test --config='./tests/adapter/examples/playwright/playwright.config.ts'",
|
|
68
68
|
"test:adapter:vitest:example": "npx vitest --config='./tests/adapter/examples/vitest/vitest.config.ts'",
|
|
69
69
|
"test:storage": "npx mocha tests-storage/artifact-storage.test.js && npx mocha tests-storage/data-storage.test.js && TESTOMATIO_INTERCEPT_CONSOLE_LOGS=true npx mocha tests-storage/logger.test.js && npx mocha tests-storage/logger-2.test.js && npx mocha tests-storage/reporter-functions.test.js",
|
|
70
|
-
"
|
|
71
|
-
"build": "rm -rf ./cjs &&
|
|
70
|
+
"build": "rm -rf ./cjs && tsc --module commonjs && npx tsx build/scripts/edit-js-files.js && npx tsx build/scripts/edit-package-json.js && chmod +x ./build/scripts/copy-tesmplate.sh && ./build/scripts/copy-tesmplate.sh",
|
|
71
|
+
"build:bun": "rm -rf ./cjs && bun build ./src/reporter.js ./src/bin/reportXml.js ./src/bin/startTest.js ./src/bin/uploadArtifacts.js --outdir ./cjs --target node",
|
|
72
|
+
"build:watch:bun": "rm -rf ./cjs && bun build ./src/bin/reportXml.js ./src/bin/startTest.js ./src/bin/uploadArtifacts.js --outdir ./cjs --target node --watch --onSuccess \"build/scripts/post-build.js\""
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
75
|
"@playwright/test": "^1.49.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import TestomatClient from '../client.js';
|
|
2
2
|
import { config } from '../config.js';
|
|
3
|
-
import { STATUS } from '../constants';
|
|
3
|
+
import { STATUS } from '../constants.js';
|
|
4
4
|
import { getTestomatIdFromTestTitle } from '../utils/utils.js';
|
|
5
5
|
|
|
6
6
|
const apiKey = config.TESTOMATIO;
|
package/src/adapter/webdriver.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import WDIOReporter,
|
|
1
|
+
import { default as WDIOReporter, RunnerStats } from '@wdio/reporter';
|
|
2
2
|
import TestomatClient from '../client.js';
|
|
3
3
|
import { getTestomatIdFromTestTitle, fileSystem } from '../utils/utils.js';
|
|
4
4
|
import { services } from '../services/index.js';
|
package/src/bin/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import createDebugMessages from 'debug';
|
|
|
7
7
|
import TestomatClient from '../client.js';
|
|
8
8
|
import XmlReader from '../xmlReader.js';
|
|
9
9
|
import { APP_PREFIX, STATUS } from '../constants.js';
|
|
10
|
-
import {
|
|
10
|
+
import { getPackageVersion } from '../utils/utils.js';
|
|
11
11
|
import { config } from '../config.js';
|
|
12
12
|
import { readLatestRunId } from '../utils/utils.js';
|
|
13
13
|
import pc from 'picocolors';
|
|
@@ -15,6 +15,7 @@ import { filesize as prettyBytes } from 'filesize';
|
|
|
15
15
|
import dotenv from 'dotenv';
|
|
16
16
|
|
|
17
17
|
const debug = createDebugMessages('@testomatio/reporter:xml-cli');
|
|
18
|
+
const version = getPackageVersion();
|
|
18
19
|
console.log(pc.cyan(pc.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
19
20
|
const program = new Command();
|
|
20
21
|
|
package/src/bin/reportXml.js
CHANGED
|
@@ -5,8 +5,11 @@ import { glob } from 'glob';
|
|
|
5
5
|
import createDebugMessages from 'debug';
|
|
6
6
|
import { APP_PREFIX } from '../constants.js';
|
|
7
7
|
import XmlReader from '../xmlReader.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getPackageVersion } from '../utils/utils.js';
|
|
9
9
|
import dotenv from 'dotenv';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
|
|
12
|
+
const version = getPackageVersion();
|
|
10
13
|
|
|
11
14
|
const debug = createDebugMessages('@testomatio/reporter:xml-cli');
|
|
12
15
|
console.log(pc.cyan(pc.bold(` 🤩 Testomat.io XML Reporter v${version}`)));
|
package/src/bin/startTest.js
CHANGED
|
@@ -4,10 +4,11 @@ import { Command } from 'commander';
|
|
|
4
4
|
import pc from 'picocolors';
|
|
5
5
|
import TestomatClient from '../client.js';
|
|
6
6
|
import { APP_PREFIX, STATUS } from '../constants.js';
|
|
7
|
-
import {
|
|
7
|
+
import { getPackageVersion } from '../utils/utils.js';
|
|
8
8
|
import { config } from '../config.js';
|
|
9
9
|
import dotenv from 'dotenv';
|
|
10
10
|
|
|
11
|
+
const version = getPackageVersion();
|
|
11
12
|
console.log(pc.cyan(pc.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
12
13
|
const program = new Command();
|
|
13
14
|
|
|
@@ -5,12 +5,13 @@ import pc from 'picocolors';
|
|
|
5
5
|
import createDebugMessages from 'debug';
|
|
6
6
|
import TestomatClient from '../client.js';
|
|
7
7
|
import { APP_PREFIX } from '../constants.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getPackageVersion } from '../utils/utils.js';
|
|
9
9
|
import { config } from '../config.js';
|
|
10
10
|
import { readLatestRunId } from '../utils/utils.js';
|
|
11
11
|
import dotenv from 'dotenv';
|
|
12
12
|
|
|
13
13
|
const debug = createDebugMessages('@testomatio/reporter:upload-cli');
|
|
14
|
+
const version = getPackageVersion();
|
|
14
15
|
console.log(pc.cyan(pc.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
15
16
|
const program = new Command();
|
|
16
17
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'path';
|
|
1
2
|
import Adapter from './adapter.js';
|
|
2
3
|
|
|
3
4
|
class CSharpAdapter extends Adapter {
|
|
@@ -7,10 +8,21 @@ class CSharpAdapter extends Adapter {
|
|
|
7
8
|
if (example) t.example = { ...example[1].split(',') };
|
|
8
9
|
const suite = t.suite_title.split('.');
|
|
9
10
|
t.suite_title = suite.pop();
|
|
10
|
-
t.file =
|
|
11
|
+
t.file = namespaceToFileName(t.file);
|
|
11
12
|
t.title = title.trim();
|
|
12
13
|
return t;
|
|
13
14
|
}
|
|
15
|
+
|
|
16
|
+
getFilePath(t) {
|
|
17
|
+
const fileName = namespaceToFileName(t.file);
|
|
18
|
+
return fileName;
|
|
19
|
+
}
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export default CSharpAdapter;
|
|
23
|
+
|
|
24
|
+
function namespaceToFileName(fileName) {
|
|
25
|
+
const fileParts = fileName.split('.');
|
|
26
|
+
fileParts[fileParts.length - 1] = fileParts[fileParts.length - 1]?.replace(/\$.*/, '');
|
|
27
|
+
return `${fileParts.join(path.sep)}.cs`;
|
|
28
|
+
}
|
package/src/pipe/bitbucket.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { APP_PREFIX, testomatLogoURL } from '../constants.js';
|
|
2
2
|
import { ansiRegExp, isSameTest } from '../utils/utils.js';
|
|
3
3
|
import { statusEmoji, fullName } from '../utils/pipe_utils.js';
|
|
4
|
-
import
|
|
4
|
+
import axios from 'axios';
|
|
5
5
|
import pc from 'picocolors';
|
|
6
6
|
import humanizeDuration from 'humanize-duration';
|
|
7
7
|
import merge from 'lodash.merge';
|
|
@@ -40,13 +40,6 @@ export class BitbucketPipe {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
this.isEnabled = true;
|
|
43
|
-
this.client = new Gaxios({
|
|
44
|
-
baseURL: 'https://api.bitbucket.org/2.0',
|
|
45
|
-
headers: {
|
|
46
|
-
'Content-Type': 'application/json',
|
|
47
|
-
'Authorization': `Bearer ${this.token}`
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
43
|
|
|
51
44
|
debug('Bitbucket Pipe: Enabled');
|
|
52
45
|
}
|
|
@@ -173,21 +166,26 @@ export class BitbucketPipe {
|
|
|
173
166
|
|
|
174
167
|
// Construct Bitbucket API URL for comments
|
|
175
168
|
// eslint-disable-next-line max-len
|
|
176
|
-
const commentsRequestURL =
|
|
169
|
+
const commentsRequestURL = `https://api.bitbucket.org/2.0/repositories/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pullrequests/${this.ENV.BITBUCKET_PR_ID}/comments`;
|
|
177
170
|
|
|
178
171
|
// Delete previous report
|
|
179
|
-
await deletePreviousReport(
|
|
172
|
+
await deletePreviousReport(axios, commentsRequestURL, this.hiddenCommentData, this.token);
|
|
180
173
|
|
|
181
174
|
// Add current report
|
|
182
175
|
debug(`Adding comment via URL: ${commentsRequestURL}`);
|
|
183
176
|
debug(`Final Bitbucket API call body: ${body}`);
|
|
184
177
|
|
|
185
178
|
try {
|
|
186
|
-
const addCommentResponse = await
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
179
|
+
const addCommentResponse = await axios.post(
|
|
180
|
+
commentsRequestURL,
|
|
181
|
+
{ content: { raw: body } },
|
|
182
|
+
{
|
|
183
|
+
headers: {
|
|
184
|
+
Authorization: `Bearer ${this.token}`,
|
|
185
|
+
'Content-Type': 'application/json',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
);
|
|
191
189
|
|
|
192
190
|
const commentID = addCommentResponse.data.id;
|
|
193
191
|
// eslint-disable-next-line max-len
|
|
@@ -212,16 +210,18 @@ export class BitbucketPipe {
|
|
|
212
210
|
updateRun() {}
|
|
213
211
|
}
|
|
214
212
|
|
|
215
|
-
async function deletePreviousReport(
|
|
213
|
+
async function deletePreviousReport(axiosInstance, commentsRequestURL, hiddenCommentData, token) {
|
|
216
214
|
if (process.env.BITBUCKET_KEEP_OUTDATED_REPORTS) return;
|
|
217
215
|
|
|
218
216
|
// Get comments
|
|
219
217
|
let comments = [];
|
|
220
218
|
|
|
221
219
|
try {
|
|
222
|
-
const response = await
|
|
223
|
-
|
|
224
|
-
|
|
220
|
+
const response = await axiosInstance.get(commentsRequestURL, {
|
|
221
|
+
headers: {
|
|
222
|
+
Authorization: `Bearer ${token}`,
|
|
223
|
+
'Content-Type': 'application/json',
|
|
224
|
+
},
|
|
225
225
|
});
|
|
226
226
|
comments = response.data.values;
|
|
227
227
|
} catch (e) {
|
|
@@ -236,9 +236,11 @@ async function deletePreviousReport(client, commentsRequestURL, hiddenCommentDat
|
|
|
236
236
|
try {
|
|
237
237
|
// Delete previous comment
|
|
238
238
|
const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
|
|
239
|
-
await
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
await axiosInstance.delete(deleteCommentURL, {
|
|
240
|
+
headers: {
|
|
241
|
+
Authorization: `Bearer ${token}`,
|
|
242
|
+
'Content-Type': 'application/json',
|
|
243
|
+
},
|
|
242
244
|
});
|
|
243
245
|
} catch (e) {
|
|
244
246
|
console.warn(`Can't delete previously added comment with testomat.io report. Ignored.`);
|
package/src/pipe/gitlab.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import createDebugMessages from 'debug';
|
|
2
|
-
import
|
|
2
|
+
import axios from 'axios';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import humanizeDuration from 'humanize-duration';
|
|
5
5
|
import merge from 'lodash.merge';
|
|
@@ -45,12 +45,6 @@ class GitLabPipe {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
this.isEnabled = true;
|
|
48
|
-
this.client = new Gaxios({
|
|
49
|
-
baseURL: 'https://gitlab.com/api/v4',
|
|
50
|
-
headers: {
|
|
51
|
-
'Content-Type': 'application/json',
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
48
|
|
|
55
49
|
debug('GitLab Pipe: Enabled');
|
|
56
50
|
}
|
|
@@ -163,21 +157,16 @@ class GitLabPipe {
|
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
// eslint-disable-next-line max-len
|
|
166
|
-
const commentsRequestURL =
|
|
160
|
+
const commentsRequestURL = `https://gitlab.com/api/v4/projects/${this.ENV.CI_PROJECT_ID}/merge_requests/${this.ENV.CI_MERGE_REQUEST_IID}/notes`;
|
|
167
161
|
|
|
168
162
|
// delete previous report
|
|
169
|
-
await deletePreviousReport(
|
|
163
|
+
await deletePreviousReport(axios, commentsRequestURL, this.hiddenCommentData, this.token);
|
|
170
164
|
|
|
171
165
|
// add current report
|
|
172
166
|
debug(`Adding comment via url: ${commentsRequestURL}`);
|
|
173
167
|
|
|
174
168
|
try {
|
|
175
|
-
const addCommentResponse = await
|
|
176
|
-
method: 'POST',
|
|
177
|
-
url: commentsRequestURL,
|
|
178
|
-
params: { access_token: this.token },
|
|
179
|
-
data: { body }
|
|
180
|
-
});
|
|
169
|
+
const addCommentResponse = await axios.post(`${commentsRequestURL}?access_token=${this.token}`, { body });
|
|
181
170
|
|
|
182
171
|
const commentID = addCommentResponse.data.id;
|
|
183
172
|
// eslint-disable-next-line max-len
|
|
@@ -202,18 +191,14 @@ class GitLabPipe {
|
|
|
202
191
|
updateRun() {}
|
|
203
192
|
}
|
|
204
193
|
|
|
205
|
-
async function deletePreviousReport(
|
|
194
|
+
async function deletePreviousReport(axiosInstance, commentsRequestURL, hiddenCommentData, token) {
|
|
206
195
|
if (process.env.GITLAB_KEEP_OUTDATED_REPORTS) return;
|
|
207
196
|
|
|
208
197
|
// get comments
|
|
209
198
|
let comments = [];
|
|
210
199
|
|
|
211
200
|
try {
|
|
212
|
-
const response = await
|
|
213
|
-
method: 'GET',
|
|
214
|
-
url: commentsRequestURL,
|
|
215
|
-
params: { access_token: token }
|
|
216
|
-
});
|
|
201
|
+
const response = await axiosInstance.get(`${commentsRequestURL}?access_token=${token}`);
|
|
217
202
|
comments = response.data;
|
|
218
203
|
} catch (e) {
|
|
219
204
|
console.error('Error while attempt to retrieve comments on GitLab Merge Request:\n', e);
|
|
@@ -226,12 +211,8 @@ async function deletePreviousReport(client, commentsRequestURL, hiddenCommentDat
|
|
|
226
211
|
if (comment.body.includes(hiddenCommentData)) {
|
|
227
212
|
try {
|
|
228
213
|
// delete previous comment
|
|
229
|
-
const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
|
|
230
|
-
await
|
|
231
|
-
method: 'DELETE',
|
|
232
|
-
url: deleteCommentURL,
|
|
233
|
-
params: { access_token: token }
|
|
234
|
-
});
|
|
214
|
+
const deleteCommentURL = `${commentsRequestURL}/${comment.id}?access_token=${token}`;
|
|
215
|
+
await axiosInstance.delete(deleteCommentURL);
|
|
235
216
|
} catch (e) {
|
|
236
217
|
console.warn(`Can't delete previously added comment with testomat.io report. Ignore.`);
|
|
237
218
|
}
|