@testomatio/reporter 0.8.0-beta.3 → 0.8.0-beta.31
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/Changelog.md +12 -0
- package/README.md +77 -7
- package/lib/ArtifactStorage.js +132 -0
- package/lib/adapter/codecept.js +1 -6
- package/lib/adapter/cucumber/current.js +1 -7
- package/lib/adapter/jasmine.js +1 -8
- package/lib/adapter/jest.js +1 -7
- package/lib/adapter/mocha.js +66 -16
- package/lib/adapter/playwright.js +2 -8
- package/lib/adapter/webdriver.js +1 -4
- package/lib/bin/reportXml.js +6 -2
- package/lib/client.js +52 -25
- package/lib/constants.js +11 -0
- package/lib/fileUploader.js +86 -49
- package/lib/pipe/csv.js +121 -0
- package/lib/pipe/github.js +135 -63
- package/lib/pipe/gitlab.js +225 -0
- package/lib/pipe/index.js +29 -13
- package/lib/pipe/testomatio.js +35 -33
- package/lib/reporter.js +2 -0
- package/lib/util.js +34 -3
- package/lib/xmlReader.js +34 -18
- package/package.json +10 -4
- package/testcafe/index.js +0 -61
- package/testcafe/package-lock.json +0 -863
- package/testcafe/package.json +0 -14
package/lib/pipe/testomatio.js
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
+
const debug = require('debug')('@testomatio/reporter:pipe:testomatio');
|
|
1
2
|
const chalk = require('chalk');
|
|
2
3
|
const axios = require('axios');
|
|
3
4
|
const JsonCycle = require('json-cycle');
|
|
5
|
+
|
|
4
6
|
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_RUN } = process.env;
|
|
5
7
|
const { APP_PREFIX } = require('../constants');
|
|
6
8
|
const { isValidUrl } = require('../util');
|
|
7
9
|
|
|
10
|
+
|
|
8
11
|
if (TESTOMATIO_RUN) {
|
|
9
12
|
process.env.runId = TESTOMATIO_RUN;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
class TestomatioPipe {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
constructor(params, store = {}) {
|
|
16
|
+
constructor(params, store = {}) {
|
|
17
|
+
this.isEnabled = false;
|
|
16
18
|
this.url = params.testomatioUrl || process.env.TESTOMATIO_URL || 'https://app.testomat.io';
|
|
17
19
|
this.apiKey = params.apiKey || process.env.TESTOMATIO;
|
|
20
|
+
debug('Testomatio Pipe: ', this.apiKey ? 'API KEY' : '*no api key*');
|
|
18
21
|
if (!this.apiKey) {
|
|
19
22
|
return;
|
|
20
23
|
}
|
|
24
|
+
debug('Testomatio Pipe: Enabled');
|
|
21
25
|
this.store = store;
|
|
22
26
|
this.title = params.title || process.env.TESTOMATIO_TITLE;
|
|
23
27
|
this.axios = axios.create();
|
|
@@ -26,14 +30,9 @@ class TestomatioPipe {
|
|
|
26
30
|
this.runId = params.runId || process.env.runId;
|
|
27
31
|
this.createNewTests = !!process.env.TESTOMATIO_CREATE;
|
|
28
32
|
|
|
29
|
-
|
|
30
33
|
if (!isValidUrl(this.url.trim())) {
|
|
31
34
|
this.isEnabled = false;
|
|
32
|
-
console.
|
|
33
|
-
APP_PREFIX,
|
|
34
|
-
chalk.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`),
|
|
35
|
-
);
|
|
36
|
-
return;
|
|
35
|
+
console.error(APP_PREFIX, chalk.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -42,54 +41,53 @@ class TestomatioPipe {
|
|
|
42
41
|
|
|
43
42
|
runParams.api_key = this.apiKey.trim();
|
|
44
43
|
runParams.group_title = TESTOMATIO_RUNGROUP_TITLE;
|
|
45
|
-
|
|
44
|
+
|
|
46
45
|
if (this.runId) {
|
|
47
|
-
return this.axios.put(`${this.url.trim()}/api/reporter/${this.runId}`, runParams)
|
|
46
|
+
return this.axios.put(`${this.url.trim()}/api/reporter/${this.runId}`, runParams);
|
|
48
47
|
}
|
|
49
|
-
|
|
48
|
+
|
|
50
49
|
try {
|
|
51
50
|
const resp = await this.axios.post(`${this.url.trim()}/api/reporter`, runParams, {
|
|
52
51
|
maxContentLength: Infinity,
|
|
53
52
|
maxBodyLength: Infinity,
|
|
54
|
-
})
|
|
53
|
+
});
|
|
55
54
|
this.runId = resp.data.uid;
|
|
56
55
|
this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
|
|
57
56
|
this.store.runUrl = this.runUrl;
|
|
58
|
-
this.store.runId = this.runId;
|
|
59
|
-
console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId
|
|
57
|
+
this.store.runId = this.runId;
|
|
58
|
+
console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId);
|
|
60
59
|
process.env.runId = this.runId;
|
|
61
60
|
} catch (err) {
|
|
62
|
-
console.
|
|
61
|
+
console.error(
|
|
63
62
|
APP_PREFIX,
|
|
64
63
|
'Error creating Testomat.io report, please check if your API key is valid. Skipping report',
|
|
65
64
|
);
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
addTest(data) {
|
|
70
69
|
if (!this.isEnabled) return;
|
|
71
70
|
if (!this.runId) return;
|
|
72
71
|
data.api_key = this.apiKey;
|
|
73
72
|
data.create = this.createNewTests;
|
|
74
73
|
const json = JsonCycle.stringify(data);
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} catch (err) {
|
|
75
|
+
return this.axios.post(`${this.url}/api/reporter/${this.runId}/testrun`, json, {
|
|
76
|
+
maxContentLength: Infinity,
|
|
77
|
+
maxBodyLength: Infinity,
|
|
78
|
+
headers: {
|
|
79
|
+
// Overwrite Axios's automatically set Content-Type
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
.catch((err) => {
|
|
86
84
|
if (err.response) {
|
|
87
85
|
if (err.response.status >= 400) {
|
|
88
|
-
const
|
|
86
|
+
const responseData = err.response.data || { message: '' };
|
|
89
87
|
console.log(
|
|
90
88
|
APP_PREFIX,
|
|
91
89
|
chalk.blue(this.title),
|
|
92
|
-
`Report couldn't be processed: (${err.response.status}) ${
|
|
90
|
+
`Report couldn't be processed: (${err.response.status}) ${responseData.message}`,
|
|
93
91
|
);
|
|
94
92
|
return;
|
|
95
93
|
}
|
|
@@ -97,8 +95,7 @@ class TestomatioPipe {
|
|
|
97
95
|
} else {
|
|
98
96
|
console.log(APP_PREFIX, chalk.blue(this.title), "Report couldn't be processed", err);
|
|
99
97
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
98
|
+
});
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
async finishRun(params) {
|
|
@@ -109,6 +106,7 @@ class TestomatioPipe {
|
|
|
109
106
|
api_key: this.apiKey,
|
|
110
107
|
status_event: params.statusEvent,
|
|
111
108
|
status: params.status,
|
|
109
|
+
tests: params.tests,
|
|
112
110
|
});
|
|
113
111
|
if (this.runUrl) {
|
|
114
112
|
console.log(APP_PREFIX, '📊 Report Saved. Report URL:', chalk.magenta(this.runUrl));
|
|
@@ -122,7 +120,11 @@ class TestomatioPipe {
|
|
|
122
120
|
} catch (err) {
|
|
123
121
|
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
124
122
|
}
|
|
125
|
-
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
toString() {
|
|
126
|
+
return 'Testomatio Reporter';
|
|
127
|
+
}
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
module.exports = TestomatioPipe;
|
|
130
|
+
module.exports = TestomatioPipe;
|
package/lib/reporter.js
CHANGED
package/lib/util.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { URL } = require('url');
|
|
2
|
-
const { sep } = require('path');
|
|
2
|
+
const { sep, basename } = require('path');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const isValid = require('is-valid-path');
|
|
@@ -79,6 +79,8 @@ const fetchSourceCodeFromStackTrace = (stack = '') => {
|
|
|
79
79
|
const prepend = 3;
|
|
80
80
|
const source = fetchSourceCode(fs.readFileSync(file).toString(), { line, prepend, limit: 7 })
|
|
81
81
|
|
|
82
|
+
if (!source) return '';
|
|
83
|
+
|
|
82
84
|
return source.split('\n')
|
|
83
85
|
.map((l, i) => {
|
|
84
86
|
if (i === prepend) return `${line} > ${chalk.bold(l)}`;
|
|
@@ -137,10 +139,37 @@ const fetchSourceCode = (contents, opts = {}) => {
|
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
const isSameTest = (test, t) =>
|
|
141
|
-
|
|
142
|
+
const isSameTest = (test, t) => (typeof t === 'object')
|
|
143
|
+
&& (typeof test === 'object')
|
|
144
|
+
&& t.title === test.title
|
|
145
|
+
&& t.suite_title === test.suite_title
|
|
146
|
+
&& Object.values(t.example || {}) === Object.values(test.example || {})
|
|
147
|
+
&& t.test_id === test.test_id;
|
|
148
|
+
|
|
149
|
+
const getCurrentDateTime = () => {
|
|
150
|
+
const today = new Date();
|
|
151
|
+
|
|
152
|
+
return `${today.getFullYear() }_${ today.getMonth() + 1 }_${ today.getDate() }_${
|
|
153
|
+
today.getHours() }_${ today.getMinutes() }_${ today.getSeconds()}`;
|
|
142
154
|
}
|
|
143
155
|
|
|
156
|
+
/**
|
|
157
|
+
* @param {String} test - Test adapter object
|
|
158
|
+
*
|
|
159
|
+
* @returns {String} testInfo as one string
|
|
160
|
+
*/
|
|
161
|
+
const specificTestInfo = test => {
|
|
162
|
+
//TODO: afterEach has another context.... need to add specific handler, maybe...
|
|
163
|
+
if (test?.title && test?.file) {
|
|
164
|
+
|
|
165
|
+
return basename(test.file).split(".").join("#")
|
|
166
|
+
+ "#"
|
|
167
|
+
+ test.title.split(" ").join("#");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return null;
|
|
171
|
+
};
|
|
172
|
+
|
|
144
173
|
module.exports = {
|
|
145
174
|
parseTest,
|
|
146
175
|
parseSuite,
|
|
@@ -150,4 +179,6 @@ module.exports = {
|
|
|
150
179
|
fetchSourceCode,
|
|
151
180
|
fetchSourceCodeFromStackTrace,
|
|
152
181
|
fetchFilesFromStackTrace,
|
|
182
|
+
getCurrentDateTime,
|
|
183
|
+
specificTestInfo
|
|
153
184
|
};
|
package/lib/xmlReader.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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
|
|
|
5
6
|
// const util = require("util"); // you can see a result
|
|
6
7
|
const { XMLParser } = require("fast-xml-parser");
|
|
7
|
-
const { PASSED, FAILED, SKIPPED } = require('./constants');
|
|
8
|
+
const { APP_PREFIX, PASSED, FAILED, SKIPPED } = require('./constants');
|
|
8
9
|
const { fetchFilesFromStackTrace, fetchSourceCode, fetchSourceCodeFromStackTrace } = require('./util');
|
|
9
10
|
const upload = require('./fileUploader');
|
|
10
11
|
const pipesFactory = require('./pipe');
|
|
@@ -45,6 +46,9 @@ class XmlReader {
|
|
|
45
46
|
this.stats = {}
|
|
46
47
|
this.stats.language = opts.lang?.toLowerCase();
|
|
47
48
|
this.filesToUpload = {}
|
|
49
|
+
|
|
50
|
+
this.version = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json')).toString()).version;
|
|
51
|
+
console.log(APP_PREFIX, `Testomatio Reporter v${this.version}`);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
connectAdapter() {
|
|
@@ -116,32 +120,43 @@ class XmlReader {
|
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
processTRX(jsonSuite) {
|
|
119
|
-
|
|
123
|
+
let defs = jsonSuite?.TestRun?.TestDefinitions?.UnitTest;
|
|
124
|
+
if (!Array.isArray(defs)) defs = [defs].filter(d => !!d);
|
|
125
|
+
|
|
126
|
+
const tests = defs.map(td => {
|
|
120
127
|
const title = td.name.replace(/\(.*?\)/, '').trim();
|
|
121
128
|
let example = td.name.match(/\((.*?)\)/);
|
|
122
129
|
if (example) example = { ...example[1].split(',')};
|
|
123
|
-
const suite = td.TestMethod.className.split('.');
|
|
130
|
+
const suite = td.TestMethod.className.split(', ')[0].split('.');
|
|
124
131
|
const suite_title = suite.pop();
|
|
125
132
|
return {
|
|
126
133
|
title,
|
|
127
134
|
example,
|
|
128
135
|
file: suite.join('/'),
|
|
136
|
+
description: td.Description,
|
|
129
137
|
suite_title,
|
|
130
138
|
id: td.Execution.id,
|
|
131
139
|
}
|
|
132
140
|
}) || [];
|
|
133
141
|
|
|
134
|
-
|
|
142
|
+
let result = jsonSuite?.TestRun?.Results?.UnitTestResult;
|
|
143
|
+
if (!Array.isArray(result)) result = [result].filter(d => !!d);
|
|
144
|
+
|
|
145
|
+
const results = result.map(td => ({
|
|
135
146
|
id: td.executionId,
|
|
136
147
|
run_time: parseFloat(td.duration),
|
|
137
148
|
status: td.outcome,
|
|
138
|
-
stack: td.Output.StdOut
|
|
149
|
+
stack: td.Output.StdOut,
|
|
150
|
+
files: td?.ResultFiles?.ResultFile?.map(rf => rf.path)
|
|
139
151
|
}));
|
|
140
152
|
|
|
153
|
+
|
|
141
154
|
results.forEach(r => {
|
|
142
|
-
const test = tests.find(t => t.id === r.id) || {};
|
|
155
|
+
const test = tests.find(t => t.id === r.id) || { };
|
|
143
156
|
r.suite_title = test.suite_title;
|
|
144
157
|
r.title = test.title?.trim();
|
|
158
|
+
if (test.code) r.code = test.code;
|
|
159
|
+
if (test.description) r.description = test.description;
|
|
145
160
|
if (test.example) r.example = test.example;
|
|
146
161
|
if (test.file) r.file = test.file;
|
|
147
162
|
r.create = true;
|
|
@@ -150,6 +165,8 @@ class XmlReader {
|
|
|
150
165
|
if (r.status === 'Skipped') r.status = SKIPPED;
|
|
151
166
|
delete r.id;
|
|
152
167
|
});
|
|
168
|
+
|
|
169
|
+
debug(results);
|
|
153
170
|
|
|
154
171
|
const counters = jsonSuite?.TestRun?.ResultSummary?.Counters || {};
|
|
155
172
|
|
|
@@ -158,7 +175,7 @@ class XmlReader {
|
|
|
158
175
|
let status = PASSED;
|
|
159
176
|
if (failed_count > 0) status = FAILED;
|
|
160
177
|
|
|
161
|
-
this.tests = results;
|
|
178
|
+
this.tests = results.filter(t => !!t.title);
|
|
162
179
|
|
|
163
180
|
return {
|
|
164
181
|
status,
|
|
@@ -209,9 +226,7 @@ class XmlReader {
|
|
|
209
226
|
const contents = fs.readFileSync(file).toString();
|
|
210
227
|
t.code = fetchSourceCode(contents, { ...t, lang: this.stats.language })
|
|
211
228
|
} catch (err) {
|
|
212
|
-
|
|
213
|
-
console.log(err)
|
|
214
|
-
}
|
|
229
|
+
debug(err)
|
|
215
230
|
}
|
|
216
231
|
});
|
|
217
232
|
}
|
|
@@ -261,7 +276,8 @@ class XmlReader {
|
|
|
261
276
|
|
|
262
277
|
async uploadArtifacts() {
|
|
263
278
|
for (const test of this.tests.filter(t => !!t.stack)) {
|
|
264
|
-
const files = fetchFilesFromStackTrace(test.stack);
|
|
279
|
+
const files = [...test.files.map(f => path.join(process.cwd(), f)), ...fetchFilesFromStackTrace(test.stack)];
|
|
280
|
+
debug('Uploading files', files)
|
|
265
281
|
test.artifacts = await Promise.all(files.map(f => upload.uploadFileByPath(f, this.runId)));
|
|
266
282
|
}
|
|
267
283
|
}
|
|
@@ -274,7 +290,7 @@ class XmlReader {
|
|
|
274
290
|
group_title: this.requestParams.group_title,
|
|
275
291
|
};
|
|
276
292
|
|
|
277
|
-
|
|
293
|
+
debug("Run", runParams);
|
|
278
294
|
|
|
279
295
|
return Promise.all(this.pipes.map(p => p.createRun(runParams)));
|
|
280
296
|
}
|
|
@@ -287,12 +303,12 @@ class XmlReader {
|
|
|
287
303
|
this.formatErrors();
|
|
288
304
|
this.formatTests();
|
|
289
305
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
306
|
+
debug(
|
|
307
|
+
'Uploading data',
|
|
308
|
+
{
|
|
309
|
+
...this.stats,
|
|
310
|
+
tests: this.tests,
|
|
311
|
+
})
|
|
296
312
|
|
|
297
313
|
const dataString = {
|
|
298
314
|
...this.stats,
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/reporter",
|
|
3
|
-
"version": "0.8.0-beta.
|
|
3
|
+
"version": "0.8.0-beta.31",
|
|
4
4
|
"description": "Testomatio Reporter Client",
|
|
5
5
|
"main": "./lib/reporter.js",
|
|
6
6
|
"repository": "git@github.com:testomatio/reporter.git",
|
|
7
7
|
"author": "Michael Bodnarchuk <davert@testomat.io>,Koushik Mohan <koushikmohan1996@gmail.com>",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"dependencies": {
|
|
10
|
+
"@aws-sdk/client-s3": "^3.279.0",
|
|
11
|
+
"@aws-sdk/lib-storage": "^3.279.0",
|
|
10
12
|
"@octokit/rest": "^19.0.5",
|
|
11
13
|
"aws-sdk": "^2.1072.0",
|
|
12
14
|
"axios": "^0.25.0",
|
|
@@ -17,10 +19,13 @@
|
|
|
17
19
|
"fast-xml-parser": "^4.0.8",
|
|
18
20
|
"glob": "^8.0.3",
|
|
19
21
|
"has-flag": "^5.0.1",
|
|
22
|
+
"humanize-duration": "^3.27.3",
|
|
20
23
|
"is-valid-path": "^0.1.1",
|
|
21
24
|
"json-cycle": "^1.3.0",
|
|
22
25
|
"lodash.memoize": "^4.1.2",
|
|
23
|
-
"lodash.merge": "^4.6.2"
|
|
26
|
+
"lodash.merge": "^4.6.2",
|
|
27
|
+
"csv-writer": "^1.6.0",
|
|
28
|
+
"uuid": "^9.0.0"
|
|
24
29
|
},
|
|
25
30
|
"files": [
|
|
26
31
|
"bin",
|
|
@@ -28,20 +33,21 @@
|
|
|
28
33
|
"testcafe"
|
|
29
34
|
],
|
|
30
35
|
"scripts": {
|
|
36
|
+
"clear-exportdir": "rm -rf export/",
|
|
31
37
|
"pretty": "prettier --write .",
|
|
32
38
|
"lint": "eslint lib",
|
|
33
39
|
"lint:fix": "eslint lib --fix",
|
|
34
|
-
"test": "mocha tests/**
|
|
40
|
+
"test": "mocha tests/**",
|
|
35
41
|
"init": "cd ./tests/adapter/examples/cucumber && npm i",
|
|
36
42
|
"test:unit": "mocha tests",
|
|
37
43
|
"test:adapter": "mocha './tests/adapter/index.test.js'",
|
|
44
|
+
"test:pipes": "mocha './tests/pipes/*_test.js'",
|
|
38
45
|
"test:adapter:jest:example": "jest './tests/adapter/examples/jest/index.test.js' --config='./tests/adapter/examples/jest/jest.config.js'",
|
|
39
46
|
"test:adapter:mocha:example": "mocha './tests/adapter/examples/mocha/index.test.js' --config='./tests/adapter/examples/mocha/mocha.config.js'",
|
|
40
47
|
"test:adapter:jasmine:example": "./tests/adapter/examples/jasmine/passReporterOpts.sh && jasmine './tests/adapter/examples/jasmine/index.test.js' --reporter=./../../../lib/adapter/jasmine.js",
|
|
41
48
|
"test:adapter:codecept:example": "codeceptjs run --config='./tests/adapter/examples/codecept/codecept.conf.js'",
|
|
42
49
|
"test:adapter:cucumber:example": "cd ./tests/adapter/examples/cucumber && npx cucumber-js"
|
|
43
50
|
},
|
|
44
|
-
"peerDependencies": {},
|
|
45
51
|
"devDependencies": {
|
|
46
52
|
"@cucumber/cucumber": "^8.6.0",
|
|
47
53
|
"@wdio/reporter": "^7.16.13",
|
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
|
-
};
|