@testomatio/reporter 2.0.1-beta-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.
Files changed (63) hide show
  1. package/lib/adapter/codecept.js +0 -2
  2. package/lib/adapter/cypress-plugin/index.js +0 -2
  3. package/lib/adapter/mocha.js +0 -1
  4. package/lib/adapter/nightwatch.d.ts +4 -0
  5. package/lib/adapter/nightwatch.js +80 -0
  6. package/lib/adapter/webdriver.d.ts +1 -1
  7. package/lib/adapter/webdriver.js +17 -8
  8. package/lib/bin/cli.js +126 -8
  9. package/lib/bin/reportXml.js +4 -2
  10. package/lib/bin/startTest.js +3 -2
  11. package/lib/bin/uploadArtifacts.js +5 -4
  12. package/lib/client.js +18 -9
  13. package/lib/config.js +2 -2
  14. package/lib/data-storage.d.ts +1 -1
  15. package/lib/data-storage.js +17 -7
  16. package/lib/junit-adapter/csharp.d.ts +1 -0
  17. package/lib/junit-adapter/csharp.js +11 -1
  18. package/lib/pipe/bitbucket.d.ts +2 -0
  19. package/lib/pipe/bitbucket.js +38 -26
  20. package/lib/pipe/debug.js +17 -3
  21. package/lib/pipe/github.d.ts +2 -2
  22. package/lib/pipe/github.js +35 -3
  23. package/lib/pipe/gitlab.d.ts +2 -0
  24. package/lib/pipe/gitlab.js +27 -9
  25. package/lib/pipe/html.d.ts +1 -0
  26. package/lib/pipe/html.js +1 -3
  27. package/lib/pipe/index.js +17 -7
  28. package/lib/pipe/testomatio.d.ts +2 -1
  29. package/lib/pipe/testomatio.js +79 -73
  30. package/lib/reporter.d.ts +12 -12
  31. package/lib/services/artifacts.d.ts +1 -1
  32. package/lib/services/key-values.d.ts +1 -1
  33. package/lib/services/logger.d.ts +1 -1
  34. package/lib/services/logger.js +1 -2
  35. package/lib/template/testomatio.hbs +443 -68
  36. package/lib/uploader.js +2 -2
  37. package/lib/utils/utils.d.ts +2 -0
  38. package/lib/utils/utils.js +41 -18
  39. package/lib/xmlReader.js +54 -19
  40. package/package.json +8 -9
  41. package/src/adapter/codecept.js +0 -2
  42. package/src/adapter/cypress-plugin/index.js +0 -2
  43. package/src/adapter/mocha.js +0 -1
  44. package/src/adapter/nightwatch.js +88 -0
  45. package/src/adapter/webdriver.js +1 -2
  46. package/src/bin/cli.js +131 -2
  47. package/src/bin/reportXml.js +4 -1
  48. package/src/bin/startTest.js +2 -1
  49. package/src/bin/uploadArtifacts.js +2 -1
  50. package/src/client.js +1 -2
  51. package/src/config.js +2 -2
  52. package/src/junit-adapter/csharp.js +13 -1
  53. package/src/pipe/bitbucket.js +22 -24
  54. package/src/pipe/debug.js +18 -3
  55. package/src/pipe/github.js +1 -2
  56. package/src/pipe/gitlab.js +27 -9
  57. package/src/pipe/html.js +3 -4
  58. package/src/pipe/testomatio.js +98 -103
  59. package/src/services/logger.js +1 -2
  60. package/src/template/testomatio.hbs +443 -68
  61. package/src/uploader.js +2 -2
  62. package/src/utils/utils.js +19 -9
  63. package/src/xmlReader.js +69 -17
@@ -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
- // Retry interceptor function
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
- // process.env.runId = process.env.TESTOMATIO_RUN;
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 axios with a custom config
59
- this.axios = axios_1.default.create({
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
- host: proxy.hostname,
65
- port: parseInt(proxy.port, 10),
66
- protocol: proxy.protocol,
67
- }
68
- : false,
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
- default:
85
- break;
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
- return error.response?.status >= 401; // Retry on 401+ and 5xx
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.runId;
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.axios.get('/api/test_grep', q);
129
- const { data } = resp;
130
- if (Array.isArray(data?.tests) && data?.tests?.length > 0) {
131
- (0, utils_js_1.foundedTestLog)(constants_js_1.APP_PREFIX, data.tests);
132
- return data.tests;
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.axios.put(`/api/reporter/${this.runId}`, runParams);
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.axios.post(`/api/reporter`, runParams, {
183
+ const resp = await this.client.request({
184
+ method: 'POST',
185
+ url: '/api/reporter',
186
+ data: runParams,
192
187
  maxContentLength: Infinity,
193
- maxBodyLength: Infinity,
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.axios.post(`/api/reporter/${this.runId}/testrun`, json, axiosAddTestrunRequestConfig).catch(err => {
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.axios
295
- .post(`/api/reporter/${this.runId}/testrun`, { api_key: this.apiKey, tests: testsToSend, batch_index: this.batch.batchIndex }, axiosAddTestrunRequestConfig)
296
- .catch(err => {
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.axios.put(`/api/reporter/${this.runId}`, {
371
- api_key: this.apiKey,
372
- duration: params.duration,
373
- status_event,
374
- detach: params.detach,
375
- tests: params.tests,
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'); // eslint-disable-line max-len
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 { data, url, baseURL, method } = err?.config || {};
443
+ const { body, url, baseURL, method } = err?.config || {};
430
444
  console.log('```js');
431
- console.log({ data: data?.replace(/"(tstmt_[^"]+)"/g, 'tstmt_*'), url, baseURL, method, time });
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
- "__#12@#originalUserLogger": {
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
- "__#12@#userLoggerWithOverridenMethods": any;
56
+ "__#13@#userLoggerWithOverridenMethods": any;
57
57
  logLevel: string;
58
58
  step(strings: any, ...values: any[]): void;
59
59
  getLogs(context: string): string[];
60
- "__#12@#stringifyLogs"(...args: any[]): string;
60
+ "__#13@#stringifyLogs"(...args: any[]): string;
61
61
  _templateLiteralLog(strings: any, ...args: any[]): void;
62
- "__#12@#logWrapper"(argsArray: any, level: any): void;
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
- "__#12@#originalUserLogger": {
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
- "__#12@#userLoggerWithOverridenMethods": any;
131
+ "__#13@#userLoggerWithOverridenMethods": any;
132
132
  logLevel: string;
133
133
  step(strings: any, ...values: any[]): void;
134
134
  getLogs(context: string): string[];
135
- "__#12@#stringifyLogs"(...args: any[]): string;
135
+ "__#13@#stringifyLogs"(...args: any[]): string;
136
136
  _templateLiteralLog(strings: any, ...args: any[]): void;
137
- "__#12@#logWrapper"(argsArray: any, level: any): void;
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
- "__#12@#originalUserLogger": {
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
- "__#12@#userLoggerWithOverridenMethods": any;
205
+ "__#13@#userLoggerWithOverridenMethods": any;
206
206
  logLevel: string;
207
207
  step(strings: any, ...values: any[]): void;
208
208
  getLogs(context: string): string[];
209
- "__#12@#stringifyLogs"(...args: any[]): string;
209
+ "__#13@#stringifyLogs"(...args: any[]): string;
210
210
  _templateLiteralLog(strings: any, ...args: any[]): void;
211
- "__#12@#logWrapper"(argsArray: any, level: any): void;
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;
@@ -3,7 +3,7 @@ export const artifactStorage: ArtifactStorage;
3
3
  * Artifact storage is supposed to store file paths
4
4
  */
5
5
  declare class ArtifactStorage {
6
- static "__#13@#instance": any;
6
+ static "__#14@#instance": any;
7
7
  /**
8
8
  * Singleton
9
9
  * @returns {ArtifactStorage}
@@ -1,6 +1,6 @@
1
1
  export const keyValueStorage: KeyValueStorage;
2
2
  declare class KeyValueStorage {
3
- static "__#14@#instance": any;
3
+ static "__#15@#instance": any;
4
4
  /**
5
5
  *
6
6
  * @returns {KeyValueStorage}
@@ -5,7 +5,7 @@ export const logger: Logger;
5
5
  * Supports different syntaxes to satisfy any user preferences.
6
6
  */
7
7
  declare class Logger {
8
- static "__#12@#instance": any;
8
+ static "__#13@#instance": any;
9
9
  /**
10
10
  *
11
11
  * @returns {Logger}
@@ -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 // eslint-disable-line no-nested-ternary
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