@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.
- package/lib/adapter/codecept.d.ts +2 -0
- package/lib/adapter/codecept.js +295 -335
- package/lib/adapter/cucumber/current.d.ts +14 -0
- package/lib/adapter/cucumber/current.js +195 -203
- package/lib/adapter/cucumber/legacy.d.ts +0 -0
- package/lib/adapter/cucumber/legacy.js +130 -155
- package/lib/adapter/cucumber.d.ts +2 -0
- package/lib/adapter/cucumber.js +5 -16
- package/lib/adapter/cypress-plugin/index.d.ts +2 -0
- package/lib/adapter/cypress-plugin/index.js +93 -105
- package/lib/adapter/jasmine.d.ts +11 -0
- package/lib/adapter/jasmine.js +54 -53
- package/lib/adapter/jest.d.ts +13 -0
- package/lib/adapter/jest.js +97 -99
- package/lib/adapter/mocha.d.ts +2 -0
- package/lib/adapter/mocha.js +112 -140
- package/lib/adapter/playwright.d.ts +14 -0
- package/lib/adapter/playwright.js +195 -231
- package/lib/adapter/vitest.d.ts +35 -0
- package/lib/adapter/vitest.js +150 -149
- package/lib/adapter/webdriver.d.ts +24 -0
- package/lib/adapter/webdriver.js +134 -119
- package/lib/bin/cli.d.ts +2 -0
- package/lib/bin/cli.js +164 -211
- package/lib/bin/reportXml.d.ts +2 -0
- package/lib/bin/reportXml.js +49 -52
- package/lib/bin/startTest.d.ts +2 -0
- package/lib/bin/startTest.js +82 -95
- package/lib/bin/uploadArtifacts.d.ts +2 -0
- package/lib/bin/uploadArtifacts.js +55 -61
- package/lib/client.d.ts +76 -0
- package/lib/client.js +411 -465
- package/lib/config.d.ts +1 -0
- package/lib/config.js +16 -21
- package/lib/constants.d.ts +25 -0
- package/lib/constants.js +50 -44
- package/lib/data-storage.d.ts +34 -0
- package/lib/data-storage.js +206 -188
- package/lib/junit-adapter/adapter.d.ts +9 -0
- package/lib/junit-adapter/adapter.js +17 -20
- package/lib/junit-adapter/csharp.d.ts +4 -0
- package/lib/junit-adapter/csharp.js +18 -14
- package/lib/junit-adapter/index.d.ts +3 -0
- package/lib/junit-adapter/index.js +27 -25
- package/lib/junit-adapter/java.d.ts +5 -0
- package/lib/junit-adapter/java.js +41 -53
- package/lib/junit-adapter/javascript.d.ts +4 -0
- package/lib/junit-adapter/javascript.js +30 -27
- package/lib/junit-adapter/python.d.ts +5 -0
- package/lib/junit-adapter/python.js +38 -37
- package/lib/junit-adapter/ruby.d.ts +4 -0
- package/lib/junit-adapter/ruby.js +11 -8
- package/lib/output.d.ts +11 -0
- package/lib/output.js +44 -52
- package/lib/package.json +3 -0
- package/lib/pipe/bitbucket.d.ts +23 -0
- package/lib/pipe/bitbucket.js +210 -229
- package/lib/pipe/csv.d.ts +47 -0
- package/lib/pipe/csv.js +113 -126
- package/lib/pipe/debug.d.ts +29 -0
- package/lib/pipe/debug.js +104 -99
- package/lib/pipe/github.d.ts +30 -0
- package/lib/pipe/github.js +186 -213
- package/lib/pipe/gitlab.d.ts +23 -0
- package/lib/pipe/gitlab.js +166 -207
- package/lib/pipe/html.d.ts +34 -0
- package/lib/pipe/html.js +260 -319
- package/lib/pipe/index.d.ts +1 -0
- package/lib/pipe/index.js +84 -66
- package/lib/pipe/testomatio.d.ts +70 -0
- package/lib/pipe/testomatio.js +413 -462
- package/lib/reporter-functions.d.ts +34 -0
- package/lib/reporter-functions.js +28 -26
- package/lib/reporter.d.ts +232 -0
- package/lib/reporter.js +34 -29
- package/lib/services/artifacts.d.ts +33 -0
- package/lib/services/artifacts.js +55 -51
- package/lib/services/index.d.ts +9 -0
- package/lib/services/index.js +14 -12
- package/lib/services/key-values.d.ts +27 -0
- package/lib/services/key-values.js +56 -53
- package/lib/services/logger.d.ts +64 -0
- package/lib/services/logger.js +227 -245
- package/lib/template/testomatio.hbs +651 -1366
- package/lib/uploader.d.ts +60 -0
- package/lib/uploader.js +291 -360
- package/lib/utils/pipe_utils.d.ts +41 -0
- package/lib/utils/pipe_utils.js +89 -85
- package/lib/utils/utils.d.ts +45 -0
- package/lib/utils/utils.js +347 -307
- package/lib/xmlReader.d.ts +92 -0
- package/lib/xmlReader.js +490 -529
- package/package.json +57 -15
- package/src/adapter/codecept.js +375 -0
- package/src/adapter/cucumber/current.js +228 -0
- package/src/adapter/cucumber/legacy.js +158 -0
- package/src/adapter/cucumber.js +4 -0
- package/src/adapter/cypress-plugin/index.js +112 -0
- package/src/adapter/jasmine.js +60 -0
- package/src/adapter/jest.js +107 -0
- package/src/adapter/mocha.cjs +2 -0
- package/src/adapter/mocha.js +157 -0
- package/src/adapter/playwright.js +250 -0
- package/src/adapter/vitest.js +183 -0
- package/src/adapter/webdriver.js +142 -0
- package/src/bin/cli.js +280 -0
- package/src/bin/reportXml.js +74 -0
- package/src/bin/startTest.js +123 -0
- package/src/bin/uploadArtifacts.js +90 -0
- package/src/client.js +504 -0
- package/src/config.js +30 -0
- package/src/constants.js +53 -0
- package/src/data-storage.js +204 -0
- package/src/junit-adapter/adapter.js +23 -0
- package/src/junit-adapter/csharp.js +16 -0
- package/src/junit-adapter/index.js +28 -0
- package/src/junit-adapter/java.js +58 -0
- package/src/junit-adapter/javascript.js +31 -0
- package/src/junit-adapter/python.js +42 -0
- package/src/junit-adapter/ruby.js +10 -0
- package/src/output.js +57 -0
- package/src/pipe/bitbucket.js +254 -0
- package/src/pipe/csv.js +140 -0
- package/src/pipe/debug.js +104 -0
- package/src/pipe/github.js +233 -0
- package/src/pipe/gitlab.js +229 -0
- package/src/pipe/html.js +374 -0
- package/src/pipe/index.js +71 -0
- package/src/pipe/testomatio.js +503 -0
- package/src/reporter-functions.js +55 -0
- package/src/reporter.cjs_decprecated +21 -0
- package/src/reporter.js +33 -0
- package/src/services/artifacts.js +59 -0
- package/src/services/index.js +13 -0
- package/src/services/key-values.js +59 -0
- package/src/services/logger.js +316 -0
- package/src/template/emptyData.svg +23 -0
- package/src/template/testomatio.hbs +706 -0
- package/src/uploader.js +371 -0
- package/src/utils/pipe_utils.js +119 -0
- package/src/utils/utils.js +383 -0
- package/src/xmlReader.js +562 -0
package/lib/pipe/testomatio.js
CHANGED
|
@@ -1,492 +1,443 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
9
|
+
const axios_retry_1 = __importDefault(require("axios-retry"));
|
|
5
10
|
// Default axios instance
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
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
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
|
|
411
|
-
|
|
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
|
-
|
|
414
|
-
|
|
405
|
+
catch (err) {
|
|
406
|
+
console.log(constants_js_1.APP_PREFIX, 'Error updating status, skipping...', err);
|
|
407
|
+
printCreateIssue(err);
|
|
415
408
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
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
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
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;
|