@testomatio/reporter 1.6.13 → 2.0.1-beta-esm

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 (142) hide show
  1. package/lib/adapter/codecept.d.ts +2 -0
  2. package/lib/adapter/codecept.js +295 -335
  3. package/lib/adapter/cucumber/current.d.ts +14 -0
  4. package/lib/adapter/cucumber/current.js +195 -203
  5. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  6. package/lib/adapter/cucumber/legacy.js +130 -155
  7. package/lib/adapter/cucumber.d.ts +2 -0
  8. package/lib/adapter/cucumber.js +5 -16
  9. package/lib/adapter/cypress-plugin/index.d.ts +2 -0
  10. package/lib/adapter/cypress-plugin/index.js +93 -105
  11. package/lib/adapter/jasmine.d.ts +11 -0
  12. package/lib/adapter/jasmine.js +54 -53
  13. package/lib/adapter/jest.d.ts +13 -0
  14. package/lib/adapter/jest.js +97 -99
  15. package/lib/adapter/mocha.d.ts +2 -0
  16. package/lib/adapter/mocha.js +112 -140
  17. package/lib/adapter/playwright.d.ts +14 -0
  18. package/lib/adapter/playwright.js +195 -231
  19. package/lib/adapter/vitest.d.ts +35 -0
  20. package/lib/adapter/vitest.js +150 -149
  21. package/lib/adapter/webdriver.d.ts +24 -0
  22. package/lib/adapter/webdriver.js +134 -119
  23. package/lib/bin/cli.d.ts +2 -0
  24. package/lib/bin/cli.js +164 -211
  25. package/lib/bin/reportXml.d.ts +2 -0
  26. package/lib/bin/reportXml.js +49 -52
  27. package/lib/bin/startTest.d.ts +2 -0
  28. package/lib/bin/startTest.js +82 -95
  29. package/lib/bin/uploadArtifacts.d.ts +2 -0
  30. package/lib/bin/uploadArtifacts.js +55 -61
  31. package/lib/client.d.ts +76 -0
  32. package/lib/client.js +411 -465
  33. package/lib/config.d.ts +1 -0
  34. package/lib/config.js +16 -21
  35. package/lib/constants.d.ts +25 -0
  36. package/lib/constants.js +50 -44
  37. package/lib/data-storage.d.ts +34 -0
  38. package/lib/data-storage.js +206 -188
  39. package/lib/junit-adapter/adapter.d.ts +9 -0
  40. package/lib/junit-adapter/adapter.js +17 -20
  41. package/lib/junit-adapter/csharp.d.ts +4 -0
  42. package/lib/junit-adapter/csharp.js +18 -14
  43. package/lib/junit-adapter/index.d.ts +3 -0
  44. package/lib/junit-adapter/index.js +27 -25
  45. package/lib/junit-adapter/java.d.ts +5 -0
  46. package/lib/junit-adapter/java.js +41 -53
  47. package/lib/junit-adapter/javascript.d.ts +4 -0
  48. package/lib/junit-adapter/javascript.js +30 -27
  49. package/lib/junit-adapter/python.d.ts +5 -0
  50. package/lib/junit-adapter/python.js +38 -37
  51. package/lib/junit-adapter/ruby.d.ts +4 -0
  52. package/lib/junit-adapter/ruby.js +11 -8
  53. package/lib/output.d.ts +11 -0
  54. package/lib/output.js +44 -52
  55. package/lib/package.json +3 -0
  56. package/lib/pipe/bitbucket.d.ts +23 -0
  57. package/lib/pipe/bitbucket.js +210 -229
  58. package/lib/pipe/csv.d.ts +47 -0
  59. package/lib/pipe/csv.js +113 -126
  60. package/lib/pipe/debug.d.ts +29 -0
  61. package/lib/pipe/debug.js +104 -99
  62. package/lib/pipe/github.d.ts +30 -0
  63. package/lib/pipe/github.js +186 -213
  64. package/lib/pipe/gitlab.d.ts +23 -0
  65. package/lib/pipe/gitlab.js +166 -207
  66. package/lib/pipe/html.d.ts +34 -0
  67. package/lib/pipe/html.js +260 -319
  68. package/lib/pipe/index.d.ts +1 -0
  69. package/lib/pipe/index.js +84 -66
  70. package/lib/pipe/testomatio.d.ts +70 -0
  71. package/lib/pipe/testomatio.js +413 -462
  72. package/lib/reporter-functions.d.ts +34 -0
  73. package/lib/reporter-functions.js +28 -26
  74. package/lib/reporter.d.ts +232 -0
  75. package/lib/reporter.js +34 -29
  76. package/lib/services/artifacts.d.ts +33 -0
  77. package/lib/services/artifacts.js +55 -51
  78. package/lib/services/index.d.ts +9 -0
  79. package/lib/services/index.js +14 -12
  80. package/lib/services/key-values.d.ts +27 -0
  81. package/lib/services/key-values.js +56 -53
  82. package/lib/services/logger.d.ts +64 -0
  83. package/lib/services/logger.js +227 -245
  84. package/lib/template/testomatio.hbs +651 -1366
  85. package/lib/uploader.d.ts +60 -0
  86. package/lib/uploader.js +291 -360
  87. package/lib/utils/pipe_utils.d.ts +41 -0
  88. package/lib/utils/pipe_utils.js +89 -85
  89. package/lib/utils/utils.d.ts +45 -0
  90. package/lib/utils/utils.js +347 -307
  91. package/lib/xmlReader.d.ts +92 -0
  92. package/lib/xmlReader.js +490 -529
  93. package/package.json +57 -15
  94. package/src/adapter/codecept.js +375 -0
  95. package/src/adapter/cucumber/current.js +228 -0
  96. package/src/adapter/cucumber/legacy.js +158 -0
  97. package/src/adapter/cucumber.js +4 -0
  98. package/src/adapter/cypress-plugin/index.js +112 -0
  99. package/src/adapter/jasmine.js +60 -0
  100. package/src/adapter/jest.js +107 -0
  101. package/src/adapter/mocha.cjs +2 -0
  102. package/src/adapter/mocha.js +157 -0
  103. package/src/adapter/playwright.js +250 -0
  104. package/src/adapter/vitest.js +183 -0
  105. package/src/adapter/webdriver.js +142 -0
  106. package/src/bin/cli.js +280 -0
  107. package/src/bin/reportXml.js +74 -0
  108. package/src/bin/startTest.js +123 -0
  109. package/src/bin/uploadArtifacts.js +90 -0
  110. package/src/client.js +504 -0
  111. package/src/config.js +30 -0
  112. package/src/constants.js +53 -0
  113. package/src/data-storage.js +204 -0
  114. package/src/junit-adapter/adapter.js +23 -0
  115. package/src/junit-adapter/csharp.js +16 -0
  116. package/src/junit-adapter/index.js +28 -0
  117. package/src/junit-adapter/java.js +58 -0
  118. package/src/junit-adapter/javascript.js +31 -0
  119. package/src/junit-adapter/python.js +42 -0
  120. package/src/junit-adapter/ruby.js +10 -0
  121. package/src/output.js +57 -0
  122. package/src/pipe/bitbucket.js +254 -0
  123. package/src/pipe/csv.js +140 -0
  124. package/src/pipe/debug.js +104 -0
  125. package/src/pipe/github.js +233 -0
  126. package/src/pipe/gitlab.js +229 -0
  127. package/src/pipe/html.js +374 -0
  128. package/src/pipe/index.js +71 -0
  129. package/src/pipe/testomatio.js +503 -0
  130. package/src/reporter-functions.js +55 -0
  131. package/src/reporter.cjs_decprecated +21 -0
  132. package/src/reporter.js +33 -0
  133. package/src/services/artifacts.js +59 -0
  134. package/src/services/index.js +13 -0
  135. package/src/services/key-values.js +59 -0
  136. package/src/services/logger.js +316 -0
  137. package/src/template/emptyData.svg +23 -0
  138. package/src/template/testomatio.hbs +706 -0
  139. package/src/uploader.js +371 -0
  140. package/src/utils/pipe_utils.js +119 -0
  141. package/src/utils/utils.js +383 -0
  142. package/src/xmlReader.js +562 -0
@@ -1,492 +1,443 @@
1
- const debug = require('debug')('@testomatio/reporter:pipe:testomatio');
2
- const chalk = require('chalk');
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const debug_1 = __importDefault(require("debug"));
7
+ const picocolors_1 = __importDefault(require("picocolors"));
3
8
  // Retry interceptor function
4
- const axiosRetry = require('axios-retry');
9
+ const axios_retry_1 = __importDefault(require("axios-retry"));
5
10
  // Default axios instance
6
- const axios = require('axios');
7
- const JsonCycle = require('json-cycle');
8
-
9
- const { APP_PREFIX, STATUS, AXIOS_TIMEOUT, REPORTER_REQUEST_RETRIES } = require('../constants');
10
- const { isValidUrl, foundedTestLog } = require('../utils/utils');
11
- const { parseFilterParams, generateFilterRequestParams, setS3Credentials } = require('../utils/pipe_utils');
12
- const config = require('../config');
13
-
11
+ const axios_1 = __importDefault(require("axios"));
12
+ const json_cycle_1 = __importDefault(require("json-cycle"));
13
+ const constants_js_1 = require("../constants.js");
14
+ const utils_js_1 = require("../utils/utils.js");
15
+ const pipe_utils_js_1 = require("../utils/pipe_utils.js");
16
+ const config_js_1 = require("../config.js");
17
+ const debug = (0, debug_1.default)('@testomatio/reporter:pipe:testomatio');
14
18
  if (process.env.TESTOMATIO_RUN) {
15
- process.env.runId = process.env.TESTOMATIO_RUN;
19
+ // process.env.runId = process.env.TESTOMATIO_RUN;
16
20
  }
17
-
18
21
  /**
19
- * @typedef {import('../../types').Pipe} Pipe
20
- * @typedef {import('../../types').TestData} TestData
22
+ * @typedef {import('../../types/types.js').Pipe} Pipe
23
+ * @typedef {import('../../types/types.js').TestData} TestData
21
24
  * @class TestomatioPipe
22
25
  * @implements {Pipe}
23
26
  */
24
27
  class TestomatioPipe {
25
- constructor(params, store) {
26
- this.batch = {
27
- isEnabled: params.isBatchEnabled ?? !process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD ?? true,
28
- intervalFunction: null, // will be created in createRun by setInterval function
29
- intervalTime: 5000, // how often tests are sent
30
- tests: [], // array of tests in batch
31
- batchIndex: 0, // represents the current batch index (starts from 1 and increments by 1 for each batch)
32
- };
33
- this.retriesTimestamps = [];
34
- this.reportingCanceledDueToReqFailures = false;
35
- this.notReportedTestsCount = 0;
36
-
37
- this.isEnabled = false;
38
- this.url = params.testomatioUrl || process.env.TESTOMATIO_URL || 'https://app.testomat.io';
39
- this.apiKey = params.apiKey || config.TESTOMATIO;
40
-
41
- if (!this.apiKey) {
42
- return;
43
- }
44
- debug('Testomatio Pipe: Enabled');
45
-
46
- const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
47
- const proxy = proxyUrl ? new URL(proxyUrl) : null;
48
-
49
- this.parallel = params.parallel;
50
- this.store = store || {};
51
- this.title = params.title || process.env.TESTOMATIO_TITLE;
52
- this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
53
- this.sharedRunTimeout = !!process.env.TESTOMATIO_SHARED_RUN_TIMEOUT;
54
- this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
55
- this.env = process.env.TESTOMATIO_ENV;
56
- this.label = process.env.TESTOMATIO_LABEL;
57
- // Create a new instance of axios with a custom config
58
- this.axios = axios.create({
59
- baseURL: `${this.url.trim()}`,
60
- timeout: AXIOS_TIMEOUT,
61
- proxy: proxy ? {
62
- host: proxy.hostname,
63
- port: proxy.port,
64
- protocol: proxy.protocol,
65
- } : false,
66
- });
67
-
68
- // Pass the axios instance to the retry function
69
- axiosRetry(this.axios, {
70
- // do not use retries for unit tests
71
- retries: REPORTER_REQUEST_RETRIES.retriesPerRequest, // Number of retries
72
- shouldResetTimeout: true,
73
- retryCondition: error => {
74
- if (!error.response) return false;
75
- switch (error.response?.status) {
76
- case 400: // Bad request (probably wrong API key)
77
- case 404: // Test not matched
78
- case 429: // Rate limit exceeded
79
- case 500: // Internal server error
80
- return false;
81
- default:
82
- break;
28
+ constructor(params, store) {
29
+ this.batch = {
30
+ isEnabled: params?.isBatchEnabled ?? !process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD ?? true,
31
+ intervalFunction: null, // will be created in createRun by setInterval function
32
+ intervalTime: 5000, // how often tests are sent
33
+ tests: [], // array of tests in batch
34
+ batchIndex: 0, // represents the current batch index (starts from 1 and increments by 1 for each batch)
35
+ numberOfTimesCalledWithoutTests: 0, // how many times batch was called without tests
36
+ };
37
+ this.retriesTimestamps = [];
38
+ this.reportingCanceledDueToReqFailures = false;
39
+ this.notReportedTestsCount = 0;
40
+ this.isEnabled = false;
41
+ this.url = params.testomatioUrl || process.env.TESTOMATIO_URL || 'https://app.testomat.io';
42
+ this.apiKey = params.apiKey || config_js_1.config.TESTOMATIO;
43
+ debug('Testomatio Pipe: ', this.apiKey ? 'API KEY' : '*no api key*');
44
+ if (!this.apiKey) {
45
+ return;
46
+ }
47
+ debug('Testomatio Pipe: Enabled');
48
+ const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
49
+ const proxy = proxyUrl ? new URL(proxyUrl) : null;
50
+ this.parallel = params.parallel;
51
+ this.store = store || {};
52
+ this.title = params.title || process.env.TESTOMATIO_TITLE;
53
+ this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
54
+ this.sharedRunTimeout = !!process.env.TESTOMATIO_SHARED_RUN_TIMEOUT;
55
+ this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
56
+ this.env = process.env.TESTOMATIO_ENV;
57
+ this.label = process.env.TESTOMATIO_LABEL;
58
+ // Create a new instance of axios with a custom config
59
+ this.axios = axios_1.default.create({
60
+ baseURL: `${this.url.trim()}`,
61
+ 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
83
+ return false;
84
+ default:
85
+ break;
86
+ }
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
+ },
94
+ });
95
+ this.isEnabled = true;
96
+ // do not finish this run (for parallel testing)
97
+ this.proceed = process.env.TESTOMATIO_PROCEED;
98
+ this.jiraId = process.env.TESTOMATIO_JIRA_ID;
99
+ this.runId = params.runId || process.env.runId;
100
+ this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
101
+ this.hasUnmatchedTests = false;
102
+ this.requestFailures = 0;
103
+ if (!(0, utils_js_1.isValidUrl)(this.url.trim())) {
104
+ this.isEnabled = false;
105
+ console.error(constants_js_1.APP_PREFIX, picocolors_1.default.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
83
106
  }
84
- return error.response?.status >= 401; // Retry on 401+ and 5xx
85
- },
86
- retryDelay: () => REPORTER_REQUEST_RETRIES.retryTimeout, // sum = 15sec
87
- onRetry: async (retryCount, error) => {
88
- this.retriesTimestamps.push(Date.now());
89
-
90
- debug(`${error.message || `Request failed ${error.status}`}. Retry #${retryCount} ...`);
91
- },
92
- });
93
-
94
- this.isEnabled = true;
95
- // do not finish this run (for parallel testing)
96
- this.proceed = process.env.TESTOMATIO_PROCEED;
97
- this.jiraId = process.env.TESTOMATIO_JIRA_ID;
98
- this.runId = params.runId || process.env.runId;
99
- this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
100
- this.hasUnmatchedTests = false;
101
- this.requestFailures = 0;
102
-
103
- if (!isValidUrl(this.url.trim())) {
104
- this.isEnabled = false;
105
- console.error(APP_PREFIX, chalk.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
106
- }
107
- }
108
-
109
- /**
110
- * Asynchronously prepares and retrieves the Testomat.io test grepList based on the provided options.
111
- * @param {Object} opts - The options for preparing the test grepList.
112
- * @returns {Promise<string[]>} - An array containing the retrieved
113
- * test grepList, or an empty array if no tests are found or the request is disabled.
114
- * @throws {Error} - Throws an error if there was a problem while making the request.
115
- */
116
- async prepareRun(opts) {
117
- if (!this.isEnabled) return [];
118
-
119
- const { type, id } = parseFilterParams(opts);
120
-
121
- try {
122
- const q = generateFilterRequestParams({
123
- type,
124
- id,
125
- apiKey: this.apiKey.trim(),
126
- });
127
-
128
- if (!q) {
129
- return;
130
- }
131
-
132
- const resp = await this.axios.get('/api/test_grep', q);
133
- const { data } = resp;
134
-
135
- if (Array.isArray(data?.tests) && data?.tests?.length > 0) {
136
- foundedTestLog(APP_PREFIX, data.tests);
137
- return data.tests;
138
- }
139
-
140
- console.log(APP_PREFIX, `⛔ No tests found for your --filter --> ${type}=${id}`);
141
- } catch (err) {
142
- console.error(APP_PREFIX, `🚩 Error getting Testomat.io test grepList: ${err}`);
143
- }
144
- }
145
-
146
- /**
147
- * Creates a new run on Testomat.io
148
- * @param {{isBatchEnabled?: boolean}} params
149
- * @returns Promise<void>
150
- */
151
- async createRun(params = {}) {
152
- this.batch.isEnabled = params.isBatchEnabled ?? this.batch.isEnabled;
153
- if (!this.isEnabled) return;
154
- if (this.batch.isEnabled) this.batch.intervalFunction = setInterval(this.#batchUpload, this.batch.intervalTime);
155
-
156
- let buildUrl = process.env.BUILD_URL || process.env.CI_JOB_URL || process.env.CIRCLE_BUILD_URL;
157
-
158
- // GitHub Actions Url
159
- if (!buildUrl && process.env.GITHUB_RUN_ID) {
160
- // eslint-disable-next-line max-len
161
- buildUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
162
- }
163
-
164
- // Azure DevOps Url
165
- if (!buildUrl && process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
166
- const collectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
167
- const project = process.env.SYSTEM_TEAMPROJECT;
168
- const buildId = process.env.BUILD_BUILDID;
169
- buildUrl = `${collectionUri}/${project}/_build/results?buildId=${buildId}`;
170
- }
171
-
172
- if (buildUrl && !buildUrl.startsWith('http')) buildUrl = undefined;
173
-
174
- const accessEvent = process.env.TESTOMATIO_PUBLISH ? 'publish' : null;
175
-
176
- const runParams = Object.fromEntries(
177
- Object.entries({
178
- ci_build_url: buildUrl,
179
- parallel: this.parallel,
180
- api_key: this.apiKey.trim(),
181
- group_title: this.groupTitle,
182
- access_event: accessEvent,
183
- jira_id: this.jiraId,
184
- env: this.env,
185
- title: this.title,
186
- label: this.label,
187
- shared_run: this.sharedRun,
188
- shared_run_timeout: this.sharedRunTimeout,
189
- }).filter(([, value]) => !!value),
190
- );
191
- debug('Run params', JSON.stringify(runParams, null, 2));
192
-
193
- if (this.runId) {
194
- this.store.runId = this.runId;
195
- debug(`Run with id ${this.runId} already created, updating...`);
196
- const resp = await this.axios.put(`/api/reporter/${this.runId}`, runParams);
197
- if (resp.data.artifacts) setS3Credentials(resp.data.artifacts);
198
- return;
199
107
  }
200
-
201
- debug('Creating run...');
202
- try {
203
- const resp = await this.axios.post(`/api/reporter`, runParams, {
204
- maxContentLength: Infinity,
205
- maxBodyLength: Infinity,
206
- });
207
-
208
- this.runId = resp.data.uid;
209
- this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
210
- this.runPublicUrl = resp.data.public_url;
211
-
212
- if (resp.data.artifacts) setS3Credentials(resp.data.artifacts);
213
-
214
- this.store.runUrl = this.runUrl;
215
- this.store.runPublicUrl = this.runPublicUrl;
216
- this.store.runId = this.runId;
217
- console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId);
218
- process.env.runId = this.runId;
219
- debug('Run created', this.runId);
220
- } catch (err) {
221
- const errorText = err.response?.data?.message || err.message;
222
- console.log(errorText || err);
223
- if (!this.apiKey) console.error('Testomat.io API key is not set');
224
- if (!this.apiKey?.startsWith('tstmt')) console.error('Testomat.io API key is invalid');
225
- console.error(
226
- APP_PREFIX,
227
- 'Error creating Testomat.io report (see details above), please check if your API key is valid. Skipping report'
228
- );
229
- printCreateIssue(err);
108
+ /**
109
+ * Asynchronously prepares and retrieves the Testomat.io test grepList based on the provided options.
110
+ * @param {Object} opts - The options for preparing the test grepList.
111
+ * @returns {Promise<string[]>} - An array containing the retrieved
112
+ * test grepList, or an empty array if no tests are found or the request is disabled.
113
+ * @throws {Error} - Throws an error if there was a problem while making the request.
114
+ */
115
+ async prepareRun(opts) {
116
+ if (!this.isEnabled)
117
+ return [];
118
+ const { type, id } = (0, pipe_utils_js_1.parseFilterParams)(opts);
119
+ try {
120
+ const q = (0, pipe_utils_js_1.generateFilterRequestParams)({
121
+ type,
122
+ id,
123
+ apiKey: this.apiKey.trim(),
124
+ });
125
+ if (!q) {
126
+ return;
127
+ }
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;
133
+ }
134
+ console.log(constants_js_1.APP_PREFIX, `⛔ No tests found for your --filter --> ${type}=${id}`);
135
+ }
136
+ catch (err) {
137
+ console.error(constants_js_1.APP_PREFIX, `🚩 Error getting Testomat.io test grepList: ${err}`);
138
+ }
230
139
  }
231
- debug('"createRun" function finished');
232
- }
233
-
234
- /**
235
- * Decides whether to skip test reporting in case of too many request failures
236
- * @returns {boolean}
237
- */
238
- #cancelTestReportingInCaseOfTooManyReqFailures() {
239
- if (!process.env.TESTOMATIO_MAX_REQUEST_FAILURES) return;
240
-
241
- const cancelReporting = this.requestFailures >= parseInt(process.env.TESTOMATIO_MAX_REQUEST_FAILURES, 10);
242
- if (cancelReporting) {
243
- this.reportingCanceledDueToReqFailures = true;
244
- const errorMessage =
245
- `⚠️ ${process.env.TESTOMATIO_MAX_REQUEST_FAILURES} requests were failed, reporting to Testomat aborted.`;
246
- console.warn(`${APP_PREFIX} ${chalk.yellow(errorMessage)}`);
140
+ /**
141
+ * Creates a new run on Testomat.io
142
+ * @param {{isBatchEnabled?: boolean}} params
143
+ * @returns Promise<void>
144
+ */
145
+ async createRun(params = {}) {
146
+ this.batch.isEnabled = params.isBatchEnabled ?? this.batch.isEnabled;
147
+ if (!this.isEnabled)
148
+ return;
149
+ if (this.batch.isEnabled && this.isEnabled)
150
+ this.batch.intervalFunction = setInterval(this.#batchUpload, this.batch.intervalTime);
151
+ let buildUrl = process.env.BUILD_URL || process.env.CI_JOB_URL || process.env.CIRCLE_BUILD_URL;
152
+ // GitHub Actions Url
153
+ if (!buildUrl && process.env.GITHUB_RUN_ID) {
154
+ // eslint-disable-next-line max-len
155
+ buildUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
156
+ }
157
+ // Azure DevOps Url
158
+ if (!buildUrl && process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
159
+ const collectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
160
+ const project = process.env.SYSTEM_TEAMPROJECT;
161
+ const buildId = process.env.BUILD_BUILDID;
162
+ buildUrl = `${collectionUri}/${project}/_build/results?buildId=${buildId}`;
163
+ }
164
+ if (buildUrl && !buildUrl.startsWith('http'))
165
+ buildUrl = undefined;
166
+ const accessEvent = process.env.TESTOMATIO_PUBLISH ? 'publish' : null;
167
+ const runParams = Object.fromEntries(Object.entries({
168
+ ci_build_url: buildUrl,
169
+ parallel: this.parallel,
170
+ api_key: this.apiKey.trim(),
171
+ group_title: this.groupTitle,
172
+ access_event: accessEvent,
173
+ jira_id: this.jiraId,
174
+ env: this.env,
175
+ title: this.title,
176
+ label: this.label,
177
+ shared_run: this.sharedRun,
178
+ shared_run_timeout: this.sharedRunTimeout,
179
+ }).filter(([, value]) => !!value));
180
+ debug(' >>>>>> Run params', JSON.stringify(runParams, null, 2));
181
+ if (this.runId) {
182
+ this.store.runId = this.runId;
183
+ debug(`Run with id ${this.runId} already created, updating...`);
184
+ const resp = await this.axios.put(`/api/reporter/${this.runId}`, runParams);
185
+ if (resp.data.artifacts)
186
+ (0, pipe_utils_js_1.setS3Credentials)(resp.data.artifacts);
187
+ return;
188
+ }
189
+ debug('Creating run...');
190
+ try {
191
+ const resp = await this.axios.post(`/api/reporter`, runParams, {
192
+ maxContentLength: Infinity,
193
+ maxBodyLength: Infinity,
194
+ });
195
+ this.runId = resp.data.uid;
196
+ this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
197
+ this.runPublicUrl = resp.data.public_url;
198
+ if (resp.data.artifacts)
199
+ (0, pipe_utils_js_1.setS3Credentials)(resp.data.artifacts);
200
+ this.store.runUrl = this.runUrl;
201
+ this.store.runPublicUrl = this.runPublicUrl;
202
+ this.store.runId = this.runId;
203
+ console.log(constants_js_1.APP_PREFIX, '📊 Report created. Report ID:', this.runId);
204
+ process.env.runId = this.runId;
205
+ debug('Run created', this.runId);
206
+ }
207
+ catch (err) {
208
+ const errorText = err.response?.data?.message || err.message;
209
+ console.log(errorText || err);
210
+ if (!this.apiKey)
211
+ console.error('Testomat.io API key is not set');
212
+ if (!this.apiKey?.startsWith('tstmt'))
213
+ console.error('Testomat.io API key is invalid');
214
+ console.error(constants_js_1.APP_PREFIX, 'Error creating Testomat.io report (see details above), please check if your API key is valid. Skipping report');
215
+ printCreateIssue(err);
216
+ }
217
+ debug('"createRun" function finished');
247
218
  }
248
- return cancelReporting;
249
- }
250
-
251
- #uploadSingleTest = async data => {
252
- if (!this.isEnabled) return;
253
- if (!this.runId) return;
254
- if (this.#cancelTestReportingInCaseOfTooManyReqFailures()) return;
255
-
256
- data.api_key = this.apiKey;
257
- data.create = this.createNewTests;
258
-
259
- if (!process.env.TESTOMATIO_STACK_PASSED && data.status === STATUS.PASSED) {
260
- data.stack = null;
219
+ /**
220
+ * Decides whether to skip test reporting in case of too many request failures
221
+ * @returns {boolean}
222
+ */
223
+ #cancelTestReportingInCaseOfTooManyReqFailures() {
224
+ if (!process.env.TESTOMATIO_MAX_REQUEST_FAILURES)
225
+ return;
226
+ const cancelReporting = this.requestFailures >= parseInt(process.env.TESTOMATIO_MAX_REQUEST_FAILURES, 10);
227
+ if (cancelReporting) {
228
+ this.reportingCanceledDueToReqFailures = true;
229
+ let errorMessage = `⚠️ ${process.env.TESTOMATIO_MAX_REQUEST_FAILURES}`;
230
+ errorMessage += ' requests were failed, reporting to Testomat aborted.';
231
+ console.warn(`${constants_js_1.APP_PREFIX} ${picocolors_1.default.yellow(errorMessage)}`);
232
+ }
233
+ return cancelReporting;
261
234
  }
262
-
263
- const json = JsonCycle.stringify(data);
264
-
265
- debug('Adding test', json);
266
-
267
- return this.axios
268
- .post(`/api/reporter/${this.runId}/testrun`, json, axiosAddTestrunRequestConfig)
269
- .catch(err => {
270
- this.requestFailures++;
271
- this.notReportedTestsCount++;
272
- if (err.response) {
273
- if (err.response.status >= 400) {
274
- const responseData = err.response.data || { message: '' };
275
- console.log(
276
- APP_PREFIX,
277
- chalk.yellow(`Warning: ${responseData.message} (${err.response.status})`),
278
- chalk.grey(data?.title || ''),
279
- );
280
- if (err.response?.data?.message?.includes('could not be matched')) {
281
- this.hasUnmatchedTests = true;
282
- }
235
+ #uploadSingleTest = async (data) => {
236
+ if (!this.isEnabled)
283
237
  return;
284
- }
285
- console.log(
286
- APP_PREFIX,
287
- chalk.yellow(`Warning: ${data?.title || ''} (${err.response?.status})`),
288
- `Report couldn't be processed: ${err?.response?.data?.message}`,
289
- );
290
- printCreateIssue(err);
291
- } else {
292
- console.log(APP_PREFIX, chalk.blue(data?.title || ''), "Report couldn't be processed", err);
238
+ if (!this.runId)
239
+ return;
240
+ if (this.#cancelTestReportingInCaseOfTooManyReqFailures())
241
+ return;
242
+ data.api_key = this.apiKey;
243
+ data.create = this.createNewTests;
244
+ if (!process.env.TESTOMATIO_STACK_PASSED && data.status === constants_js_1.STATUS.PASSED) {
245
+ data.stack = null;
293
246
  }
294
- });
295
- };
296
-
297
-
298
- /**
299
- * Uploads tests as a batch (multiple tests at once). Intended to be used with a setInterval
300
- */
301
- #batchUpload = async () => {
302
- this.batch.batchIndex++;
303
- if (!this.batch.isEnabled) return;
304
- if (!this.batch.tests.length) return;
305
- if (this.#cancelTestReportingInCaseOfTooManyReqFailures()) return;
306
-
307
- // get tests from batch and clear batch
308
- const testsToSend = this.batch.tests.splice(0);
309
- debug('📨 Batch upload', testsToSend.length, 'tests');
310
-
311
- testsToSend.forEach(debug);
312
-
313
- return this.axios
314
- .post(
315
- `/api/reporter/${this.runId}/testrun`,
316
- { api_key: this.apiKey, tests: testsToSend, batch_index: this.batch.batchIndex },
317
- axiosAddTestrunRequestConfig,
318
- )
319
- .catch(err => {
320
- this.requestFailures++;
321
- this.notReportedTestsCount += testsToSend.length;
322
- if (err.response) {
323
- if (err.response.status >= 400) {
324
- const responseData = err.response.data || { message: '' };
325
- console.log(
326
- APP_PREFIX,
327
- chalk.yellow(`Warning: ${responseData.message} (${err.response.status})`),
328
- // chalk.grey(data?.title || ''),
329
- );
330
- if (err.response?.data?.message?.includes('could not be matched')) {
331
- this.hasUnmatchedTests = true;
247
+ const json = json_cycle_1.default.stringify(data);
248
+ debug('Adding test', json);
249
+ return this.axios.post(`/api/reporter/${this.runId}/testrun`, json, axiosAddTestrunRequestConfig).catch(err => {
250
+ this.requestFailures++;
251
+ this.notReportedTestsCount++;
252
+ if (err.response) {
253
+ if (err.response.status >= 400) {
254
+ const responseData = err.response.data || { message: '' };
255
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow(`Warning: ${responseData.message} (${err.response.status})`), picocolors_1.default.gray(data?.title || ''));
256
+ if (err.response?.data?.message?.includes('could not be matched')) {
257
+ this.hasUnmatchedTests = true;
258
+ }
259
+ return;
260
+ }
261
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow(`Warning: ${data?.title || ''} (${err.response?.status})`), `Report couldn't be processed: ${err?.response?.data?.message}`);
262
+ printCreateIssue(err);
263
+ }
264
+ else {
265
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.blue(data?.title || ''), "Report couldn't be processed", err);
332
266
  }
267
+ });
268
+ };
269
+ /**
270
+ * Uploads tests as a batch (multiple tests at once). Intended to be used with a setInterval
271
+ */
272
+ #batchUpload = async () => {
273
+ if (!this.batch.isEnabled)
274
+ return;
275
+ if (!this.batch.tests.length)
333
276
  return;
334
- }
335
- console.log(
336
- APP_PREFIX,
337
- chalk.yellow(`Warning: (${err.response?.status})`),
338
- `Report couldn't be processed: ${err?.response?.data?.message}`,
339
- );
340
- printCreateIssue(err);
341
- } else {
342
- console.log(APP_PREFIX, "Report couldn't be processed", err);
277
+ if (this.#cancelTestReportingInCaseOfTooManyReqFailures())
278
+ return;
279
+ // prevent infinite loop
280
+ if (this.batch.numberOfTimesCalledWithoutTests > 10) {
281
+ debug('📨 Batch upload: no tests to send for 10 times, stopping batch');
282
+ clearInterval(this.batch.intervalFunction);
283
+ this.batch.isEnabled = false;
343
284
  }
344
- });
345
- };
346
-
347
- /**
348
- * Adds a test to the batch uploader (or reports a single test if batch uploading is disabled)
349
- */
350
- addTest(data) {
351
- if (!this.isEnabled) return;
352
- if (!this.runId) return;
353
-
354
- // add test ID + run ID
355
- if (data.rid) data.rid = `${this.runId}-${data.rid}`;
356
- data.api_key = this.apiKey;
357
- data.create = this.createNewTests;
358
-
359
- if (!this.batch.isEnabled) this.#uploadSingleTest(data);
360
- else this.batch.tests.push(data);
361
-
362
- // if test is added after run already finished
363
- if (!this.batch.intervalFunction) this.#batchUpload();
364
- }
365
-
366
- /**
367
- * @param {import('../../types').RunData} params
368
- * @returns
369
- */
370
- async finishRun(params) {
371
- if (!this.isEnabled) return;
372
-
373
- await this.#batchUpload();
374
- if (this.batch.intervalFunction) {
375
- clearInterval(this.batch.intervalFunction);
376
- // this code is required in case test is added after run is finished
377
- // (e.g. if test has artifacts, add test function will be invoked only after artifacts are uploaded)
378
- // batch stops working after run is finished; thus, disable it to use single test uploading
379
- this.batch.intervalFunction = null;
380
- this.batch.isEnabled = false;
381
- }
382
-
383
- debug('Finishing run...');
384
-
385
- if (this.reportingCanceledDueToReqFailures) {
386
- const errorMessage = chalk.red(
387
- `⚠️ Due to request failures, ${this.notReportedTestsCount} test(s) were not reported to Testomat.io`,
388
- );
389
- console.warn(`${APP_PREFIX} ${errorMessage}`);
390
- }
391
-
392
- const { status, parallel } = params;
393
-
394
- let status_event;
395
-
396
- if (status === STATUS.FINISHED) status_event = 'finish';
397
- if (status === STATUS.PASSED) status_event = 'pass';
398
- if (status === STATUS.FAILED) status_event = 'fail';
399
- if (parallel) status_event += '_parallel';
400
-
401
- try {
402
- if (this.runId && !this.proceed) {
403
- await this.axios.put(`/api/reporter/${this.runId}`, {
404
- api_key: this.apiKey,
405
- status_event,
406
- detach: params.detach,
407
- duration: params.duration,
408
- tests: params.tests,
285
+ if (!this.batch.tests.length) {
286
+ debug('📨 Batch upload: no tests to send');
287
+ this.batch.numberOfTimesCalledWithoutTests++;
288
+ return;
289
+ }
290
+ this.batch.batchIndex++;
291
+ // get tests from batch and clear batch
292
+ const testsToSend = this.batch.tests.splice(0);
293
+ 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 => {
297
+ this.requestFailures++;
298
+ this.notReportedTestsCount += testsToSend.length;
299
+ if (err.response) {
300
+ if (err.response.status >= 400) {
301
+ const responseData = err.response.data || { message: '' };
302
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow(`Warning: ${responseData.message} (${err.response.status})`));
303
+ if (err.response?.data?.message?.includes('could not be matched')) {
304
+ this.hasUnmatchedTests = true;
305
+ }
306
+ return;
307
+ }
308
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.yellow(`Warning: (${err.response?.status})`), `Report couldn't be processed: ${err?.response?.data?.message}`);
309
+ printCreateIssue(err);
310
+ }
311
+ else {
312
+ console.log(constants_js_1.APP_PREFIX, "Report couldn't be processed", err);
313
+ }
409
314
  });
410
- if (this.runUrl) {
411
- console.log(APP_PREFIX, '📊 Report Saved. Report URL:', chalk.magenta(this.runUrl));
315
+ };
316
+ /**
317
+ * Adds a test to the batch uploader (or reports a single test if batch uploading is disabled)
318
+ */
319
+ addTest(data) {
320
+ if (!this.isEnabled)
321
+ return;
322
+ if (!this.runId)
323
+ return;
324
+ // add test ID + run ID
325
+ if (data.rid)
326
+ data.rid = `${this.runId}-${data.rid}`;
327
+ data.api_key = this.apiKey;
328
+ data.create = this.createNewTests;
329
+ if (!this.batch.isEnabled)
330
+ this.#uploadSingleTest(data);
331
+ else
332
+ this.batch.tests.push(data);
333
+ // if test is added after run which is already finished
334
+ if (!this.batch.intervalFunction)
335
+ this.#batchUpload();
336
+ }
337
+ /**
338
+ * @param {import('../../types/types.js').RunData} params
339
+ * @returns
340
+ */
341
+ async finishRun(params) {
342
+ if (!this.isEnabled)
343
+ return;
344
+ await this.#batchUpload();
345
+ if (this.batch.intervalFunction) {
346
+ clearInterval(this.batch.intervalFunction);
347
+ // this code is required in case test is added after run is finished
348
+ // (e.g. if test has artifacts, add test function will be invoked only after artifacts are uploaded)
349
+ // batch stops working after run is finished; thus, disable it to use single test uploading
350
+ this.batch.intervalFunction = null;
351
+ this.batch.isEnabled = false;
352
+ }
353
+ debug('Finishing run...');
354
+ if (this.reportingCanceledDueToReqFailures) {
355
+ const errorMessage = picocolors_1.default.red(`⚠️ Due to request failures, ${this.notReportedTestsCount} test(s) were not reported to Testomat.io`);
356
+ console.warn(`${constants_js_1.APP_PREFIX} ${errorMessage}`);
357
+ }
358
+ const { status, parallel } = params;
359
+ let status_event;
360
+ if (status === constants_js_1.STATUS.FINISHED)
361
+ status_event = 'finish';
362
+ if (status === constants_js_1.STATUS.PASSED)
363
+ status_event = 'pass';
364
+ if (status === constants_js_1.STATUS.FAILED)
365
+ status_event = 'fail';
366
+ if (parallel)
367
+ status_event += '_parallel';
368
+ try {
369
+ 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,
376
+ });
377
+ if (this.runUrl) {
378
+ console.log(constants_js_1.APP_PREFIX, '📊 Report Saved. Report URL:', picocolors_1.default.magenta(this.runUrl));
379
+ }
380
+ if (this.runPublicUrl) {
381
+ console.log(constants_js_1.APP_PREFIX, '🌟 Public URL:', picocolors_1.default.magenta(this.runPublicUrl));
382
+ }
383
+ }
384
+ if (this.runUrl && this.proceed) {
385
+ const notFinishedMessage = picocolors_1.default.yellow(picocolors_1.default.bold('Run was not finished because of $TESTOMATIO_PROCEED'));
386
+ console.log(constants_js_1.APP_PREFIX, `📊 ${notFinishedMessage}. Report URL: ${picocolors_1.default.magenta(this.runUrl)}`);
387
+ console.log(constants_js_1.APP_PREFIX, `🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx start-test-run --finish`);
388
+ }
389
+ if (this.hasUnmatchedTests) {
390
+ console.log('');
391
+ // eslint-disable-next-line max-len
392
+ 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
+ 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
+ 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
+ console.log(constants_js_1.APP_PREFIX, 'If tests were imported but still not matched, assign test IDs to your tests.');
398
+ console.log(constants_js_1.APP_PREFIX, 'You can do that automatically via command line tools:');
399
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids');
400
+ console.log(constants_js_1.APP_PREFIX, 'or for Cucumber:');
401
+ // eslint-disable-next-line max-len
402
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold('npx check-cucumber ... --update-ids'), 'See: https://bit.ly/bdd-update-ids');
403
+ }
412
404
  }
413
- if (this.runPublicUrl) {
414
- console.log(APP_PREFIX, '🌟 Public URL:', chalk.magenta(this.runPublicUrl));
405
+ catch (err) {
406
+ console.log(constants_js_1.APP_PREFIX, 'Error updating status, skipping...', err);
407
+ printCreateIssue(err);
415
408
  }
416
- }
417
- if (this.runUrl && this.proceed) {
418
- const notFinishedMessage = chalk.yellow.bold('Run was not finished because of $TESTOMATIO_PROCEED');
419
- console.log(APP_PREFIX, `📊 ${notFinishedMessage}. Report URL: ${chalk.magenta(this.runUrl)}`);
420
- console.log(APP_PREFIX, `🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx start-test-run --finish`);
421
- }
422
-
423
- if (this.hasUnmatchedTests) {
424
- console.log('');
425
- // eslint-disable-next-line max-len
426
- console.log(APP_PREFIX, chalk.yellow.bold('⚠️ Some reported tests were not found in Testomat.io project'));
427
- // eslint-disable-next-line max-len
428
- console.log(
429
- APP_PREFIX,
430
- `If you use Testomat.io as a reporter only, please re-run tests using ${chalk.bold('TESTOMATIO_CREATE=1')}`,
431
- );
432
- // eslint-disable-next-line max-len
433
- console.log(
434
- APP_PREFIX,
435
- `But to keep your tests consistent it is recommended to ${chalk.bold('import tests first')}`,
436
- );
437
- console.log(APP_PREFIX, 'If tests were imported but still not matched, assign test IDs to your tests.');
438
- console.log(APP_PREFIX, 'You can do that automatically via command line tools:');
439
- console.log(APP_PREFIX, chalk.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids');
440
- console.log(APP_PREFIX, 'or for Cucumber:');
441
- // eslint-disable-next-line max-len
442
- console.log(
443
- APP_PREFIX,
444
- chalk.bold('npx check-cucumber ... --update-ids'),
445
- 'See: https://bit.ly/bdd-update-ids',
446
- );
447
- }
448
- } catch (err) {
449
- console.log(APP_PREFIX, 'Error updating status, skipping...', err);
450
- printCreateIssue(err);
409
+ debug('Run finished');
410
+ }
411
+ toString() {
412
+ return 'Testomatio Reporter';
451
413
  }
452
- debug('Run finished');
453
- }
454
-
455
- toString() {
456
- return 'Testomatio Reporter';
457
- }
458
414
  }
459
-
460
415
  let registeredErrorHints = false;
461
416
  function printCreateIssue(err) {
462
- if (registeredErrorHints) return;
463
- registeredErrorHints = true;
464
- process.on('exit', () => {
465
- console.log();
466
- console.log(APP_PREFIX, 'There was an error reporting to Testomat.io:');
467
- console.log(
468
- APP_PREFIX,
469
- 'If you think this is a bug please create an issue: https://github.com/testomatio/reporter/issues/new',
470
- ); // eslint-disable-line max-len
471
- console.log(APP_PREFIX, 'Provide this information:');
472
- console.log('Error:', err.message || err.code);
473
- if (!err.config) return;
474
-
475
- const time = new Date().toUTCString();
476
- const { data, url, baseURL, method } = err?.config || {};
477
- console.log('```js');
478
- console.log({ data: data?.replace(/"(tstmt_[^"]+)"/g, 'tstmt_*'), url, baseURL, method, time });
479
- console.log('```');
480
- });
417
+ if (registeredErrorHints)
418
+ return;
419
+ registeredErrorHints = true;
420
+ process.on('exit', () => {
421
+ console.log();
422
+ 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
424
+ console.log(constants_js_1.APP_PREFIX, 'Provide this information:');
425
+ console.log('Error:', err.message || err.code);
426
+ if (!err.config)
427
+ return;
428
+ const time = new Date().toUTCString();
429
+ const { data, url, baseURL, method } = err?.config || {};
430
+ console.log('```js');
431
+ console.log({ data: data?.replace(/"(tstmt_[^"]+)"/g, 'tstmt_*'), url, baseURL, method, time });
432
+ console.log('```');
433
+ });
481
434
  }
482
-
483
435
  const axiosAddTestrunRequestConfig = {
484
- maxContentLength: Infinity,
485
- maxBodyLength: Infinity,
486
- headers: {
487
- // Overwrite Axios's automatically set Content-Type
488
- 'Content-Type': 'application/json',
489
- },
436
+ maxContentLength: Infinity,
437
+ maxBodyLength: Infinity,
438
+ headers: {
439
+ // Overwrite Axios's automatically set Content-Type
440
+ 'Content-Type': 'application/json',
441
+ },
490
442
  };
491
-
492
443
  module.exports = TestomatioPipe;