@testomatio/reporter 0.8.0-beta.9 → 0.8.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.
- package/README.md +77 -7
- package/lib/ArtifactStorage.js +131 -0
- package/lib/adapter/codecept.js +25 -24
- package/lib/adapter/cucumber/current.js +16 -12
- package/lib/adapter/cucumber/legacy.js +14 -10
- package/lib/adapter/cypress-plugin/index.js +7 -7
- package/lib/adapter/jasmine.js +5 -4
- package/lib/adapter/jest.js +7 -11
- package/lib/adapter/mocha.js +69 -18
- package/lib/adapter/playwright.js +8 -5
- package/lib/adapter/webdriver.js +2 -1
- package/lib/bin/reportXml.js +5 -2
- package/lib/bin/startTest.js +2 -2
- package/lib/client.js +73 -49
- package/lib/constants.js +17 -2
- package/lib/fileUploader.js +86 -49
- package/lib/junit-adapter/csharp.js +0 -1
- package/lib/junit-adapter/index.js +3 -2
- package/lib/pipe/csv.js +133 -0
- package/lib/pipe/github.js +137 -73
- package/lib/pipe/gitlab.js +229 -0
- package/lib/pipe/index.js +27 -12
- package/lib/pipe/testomatio.js +71 -44
- package/lib/reporter.js +2 -0
- package/lib/util.js +46 -13
- package/lib/xmlReader.js +47 -31
- package/package.json +12 -3
- package/testcafe/index.js +0 -61
- package/testcafe/package.json +0 -14
package/lib/xmlReader.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
const debug = require('debug')('@testomatio/reporter:xml');
|
|
1
2
|
const path = require("path");
|
|
2
3
|
const chalk = require('chalk');
|
|
3
4
|
const fs = require("fs");
|
|
4
|
-
|
|
5
|
-
// const util = require("util"); // you can see a result
|
|
6
5
|
const { XMLParser } = require("fast-xml-parser");
|
|
7
|
-
const { APP_PREFIX,
|
|
6
|
+
const { APP_PREFIX, STATUS } = require('./constants');
|
|
8
7
|
const { fetchFilesFromStackTrace, fetchSourceCode, fetchSourceCodeFromStackTrace } = require('./util');
|
|
9
8
|
const upload = require('./fileUploader');
|
|
10
9
|
const pipesFactory = require('./pipe');
|
|
11
10
|
const adapterFactory = require('./junit-adapter');
|
|
12
11
|
|
|
12
|
+
|
|
13
13
|
const TESTOMATIO_URL = process.env.TESTOMATIO_URL || "https://app.testomat.io";
|
|
14
14
|
const TESTOMATIO = process.env.TESTOMATIO; // key?
|
|
15
15
|
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN } = process.env;
|
|
@@ -36,7 +36,9 @@ class XmlReader {
|
|
|
36
36
|
};
|
|
37
37
|
this.runId = opts.runId || TESTOMATIO_RUN;
|
|
38
38
|
this.adapter = adapterFactory(null, opts)
|
|
39
|
-
this.
|
|
39
|
+
if (!this.adapter) throw new Error('XML adapter for this format not found');
|
|
40
|
+
|
|
41
|
+
this.opts = opts || {};
|
|
40
42
|
const store = {}
|
|
41
43
|
this.pipes = pipesFactory(opts, store);
|
|
42
44
|
|
|
@@ -92,7 +94,7 @@ class XmlReader {
|
|
|
92
94
|
create_tests: true,
|
|
93
95
|
name,
|
|
94
96
|
tests_count: parseInt(tests, 10),
|
|
95
|
-
passed_count: parseInt(tests - failures, 10),
|
|
97
|
+
passed_count: parseInt(tests, 10) - parseInt(failures, 10),
|
|
96
98
|
failed_count: parseInt(failures, 10),
|
|
97
99
|
skipped_count: 0,
|
|
98
100
|
tests: resultTests,
|
|
@@ -119,49 +121,62 @@ class XmlReader {
|
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
processTRX(jsonSuite) {
|
|
122
|
-
|
|
124
|
+
let defs = jsonSuite?.TestRun?.TestDefinitions?.UnitTest;
|
|
125
|
+
if (!Array.isArray(defs)) defs = [defs].filter(d => !!d);
|
|
126
|
+
|
|
127
|
+
const tests = defs.map(td => {
|
|
123
128
|
const title = td.name.replace(/\(.*?\)/, '').trim();
|
|
124
129
|
let example = td.name.match(/\((.*?)\)/);
|
|
125
130
|
if (example) example = { ...example[1].split(',')};
|
|
126
|
-
const suite = td.TestMethod.className.split('.');
|
|
131
|
+
const suite = td.TestMethod.className.split(', ')[0].split('.');
|
|
127
132
|
const suite_title = suite.pop();
|
|
128
133
|
return {
|
|
129
134
|
title,
|
|
130
135
|
example,
|
|
131
136
|
file: suite.join('/'),
|
|
137
|
+
description: td.Description,
|
|
132
138
|
suite_title,
|
|
133
139
|
id: td.Execution.id,
|
|
134
140
|
}
|
|
135
141
|
}) || [];
|
|
136
142
|
|
|
137
|
-
|
|
143
|
+
let result = jsonSuite?.TestRun?.Results?.UnitTestResult;
|
|
144
|
+
if (!Array.isArray(result)) result = [result].filter(d => !!d);
|
|
145
|
+
|
|
146
|
+
const results = result.map(td => ({
|
|
138
147
|
id: td.executionId,
|
|
139
148
|
run_time: parseFloat(td.duration),
|
|
140
149
|
status: td.outcome,
|
|
141
|
-
stack: td.Output.StdOut
|
|
150
|
+
stack: td.Output.StdOut,
|
|
151
|
+
files: td?.ResultFiles?.ResultFile?.map(rf => rf.path)
|
|
142
152
|
}));
|
|
143
153
|
|
|
154
|
+
|
|
144
155
|
results.forEach(r => {
|
|
145
|
-
const test = tests.find(t => t.id === r.id) || {};
|
|
156
|
+
const test = tests.find(t => t.id === r.id) || { };
|
|
146
157
|
r.suite_title = test.suite_title;
|
|
147
158
|
r.title = test.title?.trim();
|
|
159
|
+
if (test.code) r.code = test.code;
|
|
160
|
+
if (test.description) r.description = test.description;
|
|
148
161
|
if (test.example) r.example = test.example;
|
|
149
162
|
if (test.file) r.file = test.file;
|
|
150
163
|
r.create = true;
|
|
151
|
-
if (r.status === 'Passed') r.status = PASSED;
|
|
152
|
-
if (r.status === 'Failed') r.status = FAILED;
|
|
153
|
-
if (r.status === 'Skipped') r.status = SKIPPED;
|
|
164
|
+
if (r.status === 'Passed') r.status = STATUS.PASSED;
|
|
165
|
+
if (r.status === 'Failed') r.status = STATUS.FAILED;
|
|
166
|
+
if (r.status === 'Skipped') r.status = STATUS.SKIPPED;
|
|
154
167
|
delete r.id;
|
|
155
168
|
});
|
|
169
|
+
|
|
170
|
+
debug(results);
|
|
156
171
|
|
|
157
172
|
const counters = jsonSuite?.TestRun?.ResultSummary?.Counters || {};
|
|
158
173
|
|
|
159
174
|
const failed_count = parseInt(counters.failed, 10) + parseInt(counters.error, 10);
|
|
160
175
|
|
|
161
|
-
let status = PASSED;
|
|
162
|
-
if (failed_count > 0) status = FAILED;
|
|
176
|
+
let status = STATUS.PASSED.toString();
|
|
177
|
+
if (failed_count > 0) status = STATUS.FAILED;
|
|
163
178
|
|
|
164
|
-
this.tests = results;
|
|
179
|
+
this.tests = results.filter(t => !!t.title);
|
|
165
180
|
|
|
166
181
|
return {
|
|
167
182
|
status,
|
|
@@ -212,9 +227,7 @@ class XmlReader {
|
|
|
212
227
|
const contents = fs.readFileSync(file).toString();
|
|
213
228
|
t.code = fetchSourceCode(contents, { ...t, lang: this.stats.language })
|
|
214
229
|
} catch (err) {
|
|
215
|
-
|
|
216
|
-
console.log(err)
|
|
217
|
-
}
|
|
230
|
+
debug(err)
|
|
218
231
|
}
|
|
219
232
|
});
|
|
220
233
|
}
|
|
@@ -264,7 +277,10 @@ class XmlReader {
|
|
|
264
277
|
|
|
265
278
|
async uploadArtifacts() {
|
|
266
279
|
for (const test of this.tests.filter(t => !!t.stack)) {
|
|
267
|
-
|
|
280
|
+
let files = [];
|
|
281
|
+
if (test.files.length) files = test.files.map(f => path.join(process.cwd(), f))
|
|
282
|
+
files = [...files, ...fetchFilesFromStackTrace(test.stack)];
|
|
283
|
+
debug('Uploading files', files)
|
|
268
284
|
test.artifacts = await Promise.all(files.map(f => upload.uploadFileByPath(f, this.runId)));
|
|
269
285
|
}
|
|
270
286
|
}
|
|
@@ -277,7 +293,7 @@ class XmlReader {
|
|
|
277
293
|
group_title: this.requestParams.group_title,
|
|
278
294
|
};
|
|
279
295
|
|
|
280
|
-
|
|
296
|
+
debug("Run", runParams);
|
|
281
297
|
|
|
282
298
|
return Promise.all(this.pipes.map(p => p.createRun(runParams)));
|
|
283
299
|
}
|
|
@@ -290,17 +306,17 @@ class XmlReader {
|
|
|
290
306
|
this.formatErrors();
|
|
291
307
|
this.formatTests();
|
|
292
308
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
309
|
+
debug(
|
|
310
|
+
'Uploading data',
|
|
311
|
+
{
|
|
312
|
+
...this.stats,
|
|
313
|
+
tests: this.tests,
|
|
314
|
+
})
|
|
299
315
|
|
|
300
316
|
const dataString = {
|
|
301
317
|
...this.stats,
|
|
302
318
|
api_key: this.requestParams.apiKey,
|
|
303
|
-
|
|
319
|
+
status: 'finished',
|
|
304
320
|
tests: this.tests,
|
|
305
321
|
};
|
|
306
322
|
|
|
@@ -335,9 +351,9 @@ function reduceTestCases(prev, item) {
|
|
|
335
351
|
// prepend system output
|
|
336
352
|
stack = `${testCaseItem['system-out'] || testCaseItem.output || testCaseItem.log || ''}\n\n${stack}`.trim()
|
|
337
353
|
|
|
338
|
-
let status = PASSED;
|
|
339
|
-
if ('failure' in testCaseItem || 'error' in testCaseItem) status = FAILED;
|
|
340
|
-
if ('skipped' in testCaseItem) status = SKIPPED;
|
|
354
|
+
let status = STATUS.PASSED.toString();
|
|
355
|
+
if ('failure' in testCaseItem || 'error' in testCaseItem) status = STATUS.FAILED;
|
|
356
|
+
if ('skipped' in testCaseItem) status = STATUS.SKIPPED;
|
|
341
357
|
|
|
342
358
|
prev.push({
|
|
343
359
|
create: true,
|
package/package.json
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/reporter",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Testomatio Reporter Client",
|
|
5
5
|
"main": "./lib/reporter.js",
|
|
6
|
+
"typings": "typings/index.d.ts",
|
|
6
7
|
"repository": "git@github.com:testomatio/reporter.git",
|
|
7
8
|
"author": "Michael Bodnarchuk <davert@testomat.io>,Koushik Mohan <koushikmohan1996@gmail.com>",
|
|
8
9
|
"license": "MIT",
|
|
9
10
|
"dependencies": {
|
|
11
|
+
"@aws-sdk/client-s3": "^3.279.0",
|
|
12
|
+
"@aws-sdk/lib-storage": "^3.279.0",
|
|
10
13
|
"@octokit/rest": "^19.0.5",
|
|
11
14
|
"aws-sdk": "^2.1072.0",
|
|
12
15
|
"axios": "^0.25.0",
|
|
13
16
|
"callsite-record": "^4.1.4",
|
|
14
17
|
"chalk": "^4.1.0",
|
|
15
18
|
"commander": "^4.1.1",
|
|
19
|
+
"csv-writer": "^1.6.0",
|
|
20
|
+
"debug": "^4.3.4",
|
|
16
21
|
"dotenv": "^16.0.1",
|
|
17
22
|
"fast-xml-parser": "^4.0.8",
|
|
18
23
|
"glob": "^8.0.3",
|
|
19
24
|
"has-flag": "^5.0.1",
|
|
25
|
+
"humanize-duration": "^3.27.3",
|
|
20
26
|
"is-valid-path": "^0.1.1",
|
|
21
27
|
"json-cycle": "^1.3.0",
|
|
22
28
|
"lodash.memoize": "^4.1.2",
|
|
23
|
-
"lodash.merge": "^4.6.2"
|
|
29
|
+
"lodash.merge": "^4.6.2",
|
|
30
|
+
"uuid": "^9.0.0"
|
|
24
31
|
},
|
|
25
32
|
"files": [
|
|
26
33
|
"bin",
|
|
@@ -28,6 +35,7 @@
|
|
|
28
35
|
"testcafe"
|
|
29
36
|
],
|
|
30
37
|
"scripts": {
|
|
38
|
+
"clear-exportdir": "rm -rf export/",
|
|
31
39
|
"pretty": "prettier --write .",
|
|
32
40
|
"lint": "eslint lib",
|
|
33
41
|
"lint:fix": "eslint lib --fix",
|
|
@@ -35,15 +43,16 @@
|
|
|
35
43
|
"init": "cd ./tests/adapter/examples/cucumber && npm i",
|
|
36
44
|
"test:unit": "mocha tests",
|
|
37
45
|
"test:adapter": "mocha './tests/adapter/index.test.js'",
|
|
46
|
+
"test:pipes": "mocha './tests/pipes/*_test.js'",
|
|
38
47
|
"test:adapter:jest:example": "jest './tests/adapter/examples/jest/index.test.js' --config='./tests/adapter/examples/jest/jest.config.js'",
|
|
39
48
|
"test:adapter:mocha:example": "mocha './tests/adapter/examples/mocha/index.test.js' --config='./tests/adapter/examples/mocha/mocha.config.js'",
|
|
40
49
|
"test:adapter:jasmine:example": "./tests/adapter/examples/jasmine/passReporterOpts.sh && jasmine './tests/adapter/examples/jasmine/index.test.js' --reporter=./../../../lib/adapter/jasmine.js",
|
|
41
50
|
"test:adapter:codecept:example": "codeceptjs run --config='./tests/adapter/examples/codecept/codecept.conf.js'",
|
|
42
51
|
"test:adapter:cucumber:example": "cd ./tests/adapter/examples/cucumber && npx cucumber-js"
|
|
43
52
|
},
|
|
44
|
-
"peerDependencies": {},
|
|
45
53
|
"devDependencies": {
|
|
46
54
|
"@cucumber/cucumber": "^8.6.0",
|
|
55
|
+
"@redocly/cli": "^1.0.0-beta.125",
|
|
47
56
|
"@wdio/reporter": "^7.16.13",
|
|
48
57
|
"chai": "^4.3.6",
|
|
49
58
|
"codeceptjs": "^3.2.3",
|
package/testcafe/index.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const TestomatClient = require('@testomatio/reporter/lib/client');
|
|
2
|
-
const TRConstants = require('@testomatio/reporter/lib/constants');
|
|
3
|
-
const util = require('@testomatio/reporter/lib/util');
|
|
4
|
-
|
|
5
|
-
module.exports = () => {
|
|
6
|
-
const apiKey = process.env.TESTOMATIO;
|
|
7
|
-
let failed = false;
|
|
8
|
-
|
|
9
|
-
if (apiKey === '' || apiKey === undefined) {
|
|
10
|
-
throw new Error('Testomat.io API key cannot be empty');
|
|
11
|
-
}
|
|
12
|
-
const client = new TestomatClient({ apiKey });
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
reportTaskStart(startTime, userAgents) {
|
|
16
|
-
console.log('TestCafe started with: ', userAgents);
|
|
17
|
-
client.createRun();
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
reportFixtureStart(name) {
|
|
21
|
-
console.log(`Suite : ${name}`);
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
reportTestDone(name, testRunInfo) {
|
|
25
|
-
let status = TRConstants.PASSED;
|
|
26
|
-
let message = '';
|
|
27
|
-
|
|
28
|
-
if (testRunInfo.skipped) {
|
|
29
|
-
status = TRConstants.SKIPPED;
|
|
30
|
-
}
|
|
31
|
-
if (testRunInfo.errs.length) {
|
|
32
|
-
status = TRConstants.FAILED;
|
|
33
|
-
message = this.renderErrors(testRunInfo.errs);
|
|
34
|
-
failed = true;
|
|
35
|
-
}
|
|
36
|
-
console.log(` - ${name} : ${status}`);
|
|
37
|
-
client.addTestRun(util.parseTest(name), status, {
|
|
38
|
-
error: testRunInfo.errs.length ? testRunInfo.errs[0] : null,
|
|
39
|
-
message,
|
|
40
|
-
title: name,
|
|
41
|
-
time: testRunInfo.durationMs,
|
|
42
|
-
});
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
renderErrors(errors) {
|
|
46
|
-
let errorMessage = '';
|
|
47
|
-
errors.forEach((error, id) => {
|
|
48
|
-
errorMessage = `${errorMessage}${this.formatError(error, `${id + 1} `)}\n`;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
console.log(errorMessage);
|
|
52
|
-
return errorMessage.replace(util.ansiRegExp(), '');
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
reportTaskDone() {
|
|
56
|
-
const status = failed ? TRConstants.FAILED : TRConstants.PASSED;
|
|
57
|
-
console.log(`Status : ${status}`);
|
|
58
|
-
client.updateRunStatus(status);
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
};
|
package/testcafe/package.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "testcafe-reporter-testomatio",
|
|
3
|
-
"version": "0.1.1",
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
-
},
|
|
9
|
-
"author": "koushikmohan1996@gmail.com",
|
|
10
|
-
"license": "ISC",
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@testomatio/reporter": "^0.6.10"
|
|
13
|
-
}
|
|
14
|
-
}
|