@testomatio/reporter 2.0.1-beta-2-ignore-xml → 2.0.1-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.
- package/lib/adapter/codecept.js +0 -2
- package/lib/adapter/cypress-plugin/index.js +0 -2
- package/lib/adapter/mocha.js +0 -1
- package/lib/adapter/nightwatch.d.ts +4 -0
- package/lib/adapter/nightwatch.js +80 -0
- package/lib/adapter/webdriver.d.ts +1 -1
- package/lib/adapter/webdriver.js +17 -8
- package/lib/bin/cli.js +126 -8
- package/lib/bin/reportXml.js +4 -2
- package/lib/bin/startTest.js +3 -2
- package/lib/bin/uploadArtifacts.js +5 -4
- package/lib/client.js +18 -9
- package/lib/config.js +2 -2
- package/lib/data-storage.d.ts +1 -1
- package/lib/data-storage.js +17 -7
- package/lib/junit-adapter/csharp.d.ts +1 -0
- package/lib/junit-adapter/csharp.js +11 -1
- package/lib/pipe/bitbucket.d.ts +2 -0
- package/lib/pipe/bitbucket.js +38 -26
- package/lib/pipe/debug.js +17 -3
- package/lib/pipe/github.d.ts +2 -2
- package/lib/pipe/github.js +35 -3
- package/lib/pipe/gitlab.d.ts +2 -0
- package/lib/pipe/gitlab.js +27 -9
- package/lib/pipe/html.d.ts +1 -0
- package/lib/pipe/html.js +1 -3
- package/lib/pipe/index.js +17 -7
- package/lib/pipe/testomatio.d.ts +2 -1
- package/lib/pipe/testomatio.js +79 -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/services/logger.js +1 -2
- package/lib/template/testomatio.hbs +443 -68
- package/lib/uploader.js +2 -2
- package/lib/utils/utils.d.ts +2 -0
- package/lib/utils/utils.js +41 -18
- package/lib/xmlReader.js +54 -19
- package/package.json +8 -9
- package/src/adapter/codecept.js +0 -2
- package/src/adapter/cypress-plugin/index.js +0 -2
- package/src/adapter/mocha.js +0 -1
- package/src/adapter/nightwatch.js +88 -0
- package/src/adapter/webdriver.js +1 -2
- package/src/bin/cli.js +131 -2
- package/src/bin/reportXml.js +4 -1
- package/src/bin/startTest.js +2 -1
- package/src/bin/uploadArtifacts.js +2 -1
- package/src/client.js +1 -2
- package/src/config.js +2 -2
- package/src/junit-adapter/csharp.js +13 -1
- package/src/pipe/bitbucket.js +22 -24
- package/src/pipe/debug.js +18 -3
- package/src/pipe/github.js +1 -2
- package/src/pipe/gitlab.js +27 -9
- package/src/pipe/html.js +3 -4
- package/src/pipe/testomatio.js +98 -103
- package/src/services/logger.js +1 -2
- package/src/template/testomatio.hbs +443 -68
- package/src/uploader.js +2 -2
- package/src/utils/utils.js +19 -9
- package/src/xmlReader.js +69 -17
package/lib/pipe/testomatio.js
CHANGED
|
@@ -5,19 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const debug_1 = __importDefault(require("debug"));
|
|
7
7
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
8
|
-
|
|
9
|
-
const axios_retry_1 = __importDefault(require("axios-retry"));
|
|
10
|
-
// Default axios instance
|
|
11
|
-
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const gaxios_1 = require("gaxios");
|
|
12
9
|
const json_cycle_1 = __importDefault(require("json-cycle"));
|
|
13
10
|
const constants_js_1 = require("../constants.js");
|
|
14
11
|
const utils_js_1 = require("../utils/utils.js");
|
|
15
12
|
const pipe_utils_js_1 = require("../utils/pipe_utils.js");
|
|
16
13
|
const config_js_1 = require("../config.js");
|
|
17
14
|
const debug = (0, debug_1.default)('@testomatio/reporter:pipe:testomatio');
|
|
18
|
-
if (process.env.TESTOMATIO_RUN)
|
|
19
|
-
|
|
20
|
-
}
|
|
15
|
+
if (process.env.TESTOMATIO_RUN)
|
|
16
|
+
process.env.runId = process.env.TESTOMATIO_RUN;
|
|
21
17
|
/**
|
|
22
18
|
* @typedef {import('../../types/types.js').Pipe} Pipe
|
|
23
19
|
* @typedef {import('../../types/types.js').TestData} TestData
|
|
@@ -55,48 +51,37 @@ class TestomatioPipe {
|
|
|
55
51
|
this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
|
|
56
52
|
this.env = process.env.TESTOMATIO_ENV;
|
|
57
53
|
this.label = process.env.TESTOMATIO_LABEL;
|
|
58
|
-
// Create a new instance of
|
|
59
|
-
this.
|
|
54
|
+
// Create a new instance of gaxios with a custom config
|
|
55
|
+
this.client = new gaxios_1.Gaxios({
|
|
60
56
|
baseURL: `${this.url.trim()}`,
|
|
61
57
|
timeout: constants_js_1.AXIOS_TIMEOUT,
|
|
62
|
-
proxy: proxy
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
:
|
|
69
|
-
|
|
70
|
-
// Pass the axios instance to the retry function
|
|
71
|
-
(0, axios_retry_1.default)(this.axios, {
|
|
72
|
-
// do not use retries for unit tests
|
|
73
|
-
retries: constants_js_1.REPORTER_REQUEST_RETRIES.retriesPerRequest, // Number of retries
|
|
74
|
-
shouldResetTimeout: true,
|
|
75
|
-
retryCondition: error => {
|
|
76
|
-
if (!error.response)
|
|
77
|
-
return false;
|
|
78
|
-
switch (error.response?.status) {
|
|
79
|
-
case 400: // Bad request (probably wrong API key)
|
|
80
|
-
case 404: // Test not matched
|
|
81
|
-
case 429: // Rate limit exceeded
|
|
82
|
-
case 500: // Internal server error
|
|
58
|
+
proxy: proxy ? proxy.toString() : undefined,
|
|
59
|
+
retry: true,
|
|
60
|
+
retryConfig: {
|
|
61
|
+
retry: constants_js_1.REPORTER_REQUEST_RETRIES.retriesPerRequest,
|
|
62
|
+
retryDelay: constants_js_1.REPORTER_REQUEST_RETRIES.retryTimeout,
|
|
63
|
+
httpMethodsToRetry: ['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE', 'POST'],
|
|
64
|
+
shouldRetry: (error) => {
|
|
65
|
+
if (!error.response)
|
|
83
66
|
return false;
|
|
84
|
-
|
|
85
|
-
|
|
67
|
+
switch (error.response?.status) {
|
|
68
|
+
case 400: // Bad request (probably wrong API key)
|
|
69
|
+
case 404: // Test not matched
|
|
70
|
+
case 429: // Rate limit exceeded
|
|
71
|
+
case 500: // Internal server error
|
|
72
|
+
return false;
|
|
73
|
+
default:
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
return error.response?.status >= 401; // Retry on 401+ and 5xx
|
|
86
77
|
}
|
|
87
|
-
|
|
88
|
-
},
|
|
89
|
-
retryDelay: () => constants_js_1.REPORTER_REQUEST_RETRIES.retryTimeout, // sum = 15sec
|
|
90
|
-
onRetry: async (retryCount, error) => {
|
|
91
|
-
this.retriesTimestamps.push(Date.now());
|
|
92
|
-
debug(`${error.message || `Request failed ${error.status}`}. Retry #${retryCount} ...`);
|
|
93
|
-
},
|
|
78
|
+
}
|
|
94
79
|
});
|
|
95
80
|
this.isEnabled = true;
|
|
96
81
|
// do not finish this run (for parallel testing)
|
|
97
82
|
this.proceed = process.env.TESTOMATIO_PROCEED;
|
|
98
83
|
this.jiraId = process.env.TESTOMATIO_JIRA_ID;
|
|
99
|
-
this.runId = params.runId || process.env.
|
|
84
|
+
this.runId = params.runId || process.env.TESTOMATIO_RUN;
|
|
100
85
|
this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
|
|
101
86
|
this.hasUnmatchedTests = false;
|
|
102
87
|
this.requestFailures = 0;
|
|
@@ -125,11 +110,14 @@ class TestomatioPipe {
|
|
|
125
110
|
if (!q) {
|
|
126
111
|
return;
|
|
127
112
|
}
|
|
128
|
-
const resp = await this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
113
|
+
const resp = await this.client.request({
|
|
114
|
+
method: 'GET',
|
|
115
|
+
url: '/api/test_grep',
|
|
116
|
+
params: q
|
|
117
|
+
});
|
|
118
|
+
if (Array.isArray(resp.data?.tests) && resp.data?.tests?.length > 0) {
|
|
119
|
+
(0, utils_js_1.foundedTestLog)(constants_js_1.APP_PREFIX, resp.data.tests);
|
|
120
|
+
return resp.data.tests;
|
|
133
121
|
}
|
|
134
122
|
console.log(constants_js_1.APP_PREFIX, `⛔ No tests found for your --filter --> ${type}=${id}`);
|
|
135
123
|
}
|
|
@@ -181,16 +169,23 @@ class TestomatioPipe {
|
|
|
181
169
|
if (this.runId) {
|
|
182
170
|
this.store.runId = this.runId;
|
|
183
171
|
debug(`Run with id ${this.runId} already created, updating...`);
|
|
184
|
-
const resp = await this.
|
|
172
|
+
const resp = await this.client.request({
|
|
173
|
+
method: 'PUT',
|
|
174
|
+
url: `/api/reporter/${this.runId}`,
|
|
175
|
+
data: runParams
|
|
176
|
+
});
|
|
185
177
|
if (resp.data.artifacts)
|
|
186
178
|
(0, pipe_utils_js_1.setS3Credentials)(resp.data.artifacts);
|
|
187
179
|
return;
|
|
188
180
|
}
|
|
189
181
|
debug('Creating run...');
|
|
190
182
|
try {
|
|
191
|
-
const resp = await this.
|
|
183
|
+
const resp = await this.client.request({
|
|
184
|
+
method: 'POST',
|
|
185
|
+
url: '/api/reporter',
|
|
186
|
+
data: runParams,
|
|
192
187
|
maxContentLength: Infinity,
|
|
193
|
-
|
|
188
|
+
responseType: 'json'
|
|
194
189
|
});
|
|
195
190
|
this.runId = resp.data.uid;
|
|
196
191
|
this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
|
|
@@ -206,6 +201,7 @@ class TestomatioPipe {
|
|
|
206
201
|
}
|
|
207
202
|
catch (err) {
|
|
208
203
|
const errorText = err.response?.data?.message || err.message;
|
|
204
|
+
debug('Error creating run', err);
|
|
209
205
|
console.log(errorText || err);
|
|
210
206
|
if (!this.apiKey)
|
|
211
207
|
console.error('Testomat.io API key is not set');
|
|
@@ -246,7 +242,15 @@ class TestomatioPipe {
|
|
|
246
242
|
}
|
|
247
243
|
const json = json_cycle_1.default.stringify(data);
|
|
248
244
|
debug('Adding test', json);
|
|
249
|
-
return this.
|
|
245
|
+
return this.client.request({
|
|
246
|
+
method: 'POST',
|
|
247
|
+
url: `/api/reporter/${this.runId}/testrun`,
|
|
248
|
+
data: json,
|
|
249
|
+
headers: {
|
|
250
|
+
'Content-Type': 'application/json',
|
|
251
|
+
},
|
|
252
|
+
maxContentLength: Infinity
|
|
253
|
+
}).catch(err => {
|
|
250
254
|
this.requestFailures++;
|
|
251
255
|
this.notReportedTestsCount++;
|
|
252
256
|
if (err.response) {
|
|
@@ -291,9 +295,19 @@ class TestomatioPipe {
|
|
|
291
295
|
// get tests from batch and clear batch
|
|
292
296
|
const testsToSend = this.batch.tests.splice(0);
|
|
293
297
|
debug('📨 Batch upload', testsToSend.length, 'tests');
|
|
294
|
-
return this.
|
|
295
|
-
|
|
296
|
-
|
|
298
|
+
return this.client.request({
|
|
299
|
+
method: 'POST',
|
|
300
|
+
url: `/api/reporter/${this.runId}/testrun`,
|
|
301
|
+
data: {
|
|
302
|
+
api_key: this.apiKey,
|
|
303
|
+
tests: testsToSend,
|
|
304
|
+
batch_index: this.batch.batchIndex
|
|
305
|
+
},
|
|
306
|
+
headers: {
|
|
307
|
+
'Content-Type': 'application/json',
|
|
308
|
+
},
|
|
309
|
+
maxContentLength: Infinity
|
|
310
|
+
}).catch(err => {
|
|
297
311
|
this.requestFailures++;
|
|
298
312
|
this.notReportedTestsCount += testsToSend.length;
|
|
299
313
|
if (err.response) {
|
|
@@ -367,12 +381,16 @@ class TestomatioPipe {
|
|
|
367
381
|
status_event += '_parallel';
|
|
368
382
|
try {
|
|
369
383
|
if (this.runId && !this.proceed) {
|
|
370
|
-
await this.
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
384
|
+
await this.client.request({
|
|
385
|
+
method: 'PUT',
|
|
386
|
+
url: `/api/reporter/${this.runId}`,
|
|
387
|
+
data: {
|
|
388
|
+
api_key: this.apiKey,
|
|
389
|
+
duration: params.duration,
|
|
390
|
+
status_event,
|
|
391
|
+
detach: params.detach,
|
|
392
|
+
tests: params.tests,
|
|
393
|
+
}
|
|
376
394
|
});
|
|
377
395
|
if (this.runUrl) {
|
|
378
396
|
console.log(constants_js_1.APP_PREFIX, '📊 Report Saved. Report URL:', picocolors_1.default.magenta(this.runUrl));
|
|
@@ -388,17 +406,13 @@ class TestomatioPipe {
|
|
|
388
406
|
}
|
|
389
407
|
if (this.hasUnmatchedTests) {
|
|
390
408
|
console.log('');
|
|
391
|
-
// eslint-disable-next-line max-len
|
|
392
409
|
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')));
|
|
393
|
-
// eslint-disable-next-line max-len
|
|
394
410
|
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')}`);
|
|
395
|
-
// eslint-disable-next-line max-len
|
|
396
411
|
console.log(constants_js_1.APP_PREFIX, `But to keep your tests consistent it is recommended to ${picocolors_1.default.bold('import tests first')}`);
|
|
397
412
|
console.log(constants_js_1.APP_PREFIX, 'If tests were imported but still not matched, assign test IDs to your tests.');
|
|
398
413
|
console.log(constants_js_1.APP_PREFIX, 'You can do that automatically via command line tools:');
|
|
399
414
|
console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids');
|
|
400
415
|
console.log(constants_js_1.APP_PREFIX, 'or for Cucumber:');
|
|
401
|
-
// eslint-disable-next-line max-len
|
|
402
416
|
console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-cucumber ... --update-ids'), 'See: https://bit.ly/bdd-update-ids');
|
|
403
417
|
}
|
|
404
418
|
}
|
|
@@ -420,24 +434,16 @@ function printCreateIssue(err) {
|
|
|
420
434
|
process.on('exit', () => {
|
|
421
435
|
console.log();
|
|
422
436
|
console.log(constants_js_1.APP_PREFIX, 'There was an error reporting to Testomat.io:');
|
|
423
|
-
console.log(constants_js_1.APP_PREFIX, 'If you think this is a bug please create an issue: https://github.com/testomatio/reporter/issues/new');
|
|
437
|
+
console.log(constants_js_1.APP_PREFIX, 'If you think this is a bug please create an issue: https://github.com/testomatio/reporter/issues/new');
|
|
424
438
|
console.log(constants_js_1.APP_PREFIX, 'Provide this information:');
|
|
425
439
|
console.log('Error:', err.message || err.code);
|
|
426
440
|
if (!err.config)
|
|
427
441
|
return;
|
|
428
442
|
const time = new Date().toUTCString();
|
|
429
|
-
const {
|
|
443
|
+
const { body, url, baseURL, method } = err?.config || {};
|
|
430
444
|
console.log('```js');
|
|
431
|
-
console.log({
|
|
445
|
+
console.log({ body: body?.replace(/"(tstmt_[^"]+)"/g, 'tstmt_*'), url, baseURL, method, time });
|
|
432
446
|
console.log('```');
|
|
433
447
|
});
|
|
434
448
|
}
|
|
435
|
-
const axiosAddTestrunRequestConfig = {
|
|
436
|
-
maxContentLength: Infinity,
|
|
437
|
-
maxBodyLength: Infinity,
|
|
438
|
-
headers: {
|
|
439
|
-
// Overwrite Axios's automatically set Content-Type
|
|
440
|
-
'Content-Type': 'application/json',
|
|
441
|
-
},
|
|
442
|
-
};
|
|
443
449
|
module.exports = TestomatioPipe;
|
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
|
+
"__#13@#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
|
+
"__#13@#userLoggerWithOverridenMethods": any;
|
|
57
57
|
logLevel: string;
|
|
58
58
|
step(strings: any, ...values: any[]): void;
|
|
59
59
|
getLogs(context: string): string[];
|
|
60
|
-
"__#
|
|
60
|
+
"__#13@#stringifyLogs"(...args: any[]): string;
|
|
61
61
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
62
|
-
"__#
|
|
62
|
+
"__#13@#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
|
+
"__#13@#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
|
+
"__#13@#userLoggerWithOverridenMethods": any;
|
|
132
132
|
logLevel: string;
|
|
133
133
|
step(strings: any, ...values: any[]): void;
|
|
134
134
|
getLogs(context: string): string[];
|
|
135
|
-
"__#
|
|
135
|
+
"__#13@#stringifyLogs"(...args: any[]): string;
|
|
136
136
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
137
|
-
"__#
|
|
137
|
+
"__#13@#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
|
+
"__#13@#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
|
+
"__#13@#userLoggerWithOverridenMethods": any;
|
|
206
206
|
logLevel: string;
|
|
207
207
|
step(strings: any, ...values: any[]): void;
|
|
208
208
|
getLogs(context: string): string[];
|
|
209
|
-
"__#
|
|
209
|
+
"__#13@#stringifyLogs"(...args: any[]): string;
|
|
210
210
|
_templateLiteralLog(strings: any, ...args: any[]): void;
|
|
211
|
-
"__#
|
|
211
|
+
"__#13@#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/services/logger.js
CHANGED
|
@@ -90,7 +90,6 @@ class Logger {
|
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
92
|
try {
|
|
93
|
-
// eslint-disable-next-line no-unused-expressions
|
|
94
93
|
this.prettyObjects ? logs.push(JSON.stringify(arg, null, 2)) : logs.push(JSON.stringify(arg));
|
|
95
94
|
}
|
|
96
95
|
catch (e) {
|
|
@@ -119,7 +118,7 @@ class Logger {
|
|
|
119
118
|
current +
|
|
120
119
|
// strings are splitted by args when use tagged template, thus we add arg after each string
|
|
121
120
|
// it looks like: `string1 arg1 string2 arg2 string3`
|
|
122
|
-
(args[index] !== undefined
|
|
121
|
+
(args[index] !== undefined
|
|
123
122
|
? typeof args[index] === 'string'
|
|
124
123
|
? args[index] // add arg as it is
|
|
125
124
|
: this.#stringifyLogs(args[index]) // stringify arg
|