@allurereport/plugin-testops 3.15.0 → 3.16.0
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/dist/client.js +61 -10
- package/dist/logger.d.ts +3 -1
- package/dist/logger.js +6 -2
- package/dist/plugin.js +52 -23
- package/package.json +8 -8
package/dist/client.js
CHANGED
|
@@ -25,6 +25,49 @@ class TestOpsClientError extends AxiosError {
|
|
|
25
25
|
}
|
|
26
26
|
const CHUNK_SIZE = 100;
|
|
27
27
|
const BULK_UPLOAD_CHUNK_SIZE = 1000;
|
|
28
|
+
const MAX_REQUEST_RETRIES = 3;
|
|
29
|
+
const RETRY_BASE_DELAY_MS = 500;
|
|
30
|
+
const getAxiosCause = (error) => {
|
|
31
|
+
if (isAxiosError(error)) {
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
return error instanceof Error && isAxiosError(error.cause) ? error.cause : undefined;
|
|
35
|
+
};
|
|
36
|
+
const isRetryableRequestError = (error) => {
|
|
37
|
+
const cause = getAxiosCause(error);
|
|
38
|
+
if (!cause || cause.code === "ERR_CANCELED" || cause.name === "CanceledError") {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const status = cause.response?.status;
|
|
42
|
+
return status === undefined || status === 408 || status === 429 || status >= 500;
|
|
43
|
+
};
|
|
44
|
+
const retryAfterMs = (error) => {
|
|
45
|
+
const headers = getAxiosCause(error)?.response?.headers;
|
|
46
|
+
const value = typeof headers?.get === "function" ? headers.get("retry-after") : headers?.["retry-after"];
|
|
47
|
+
const normalized = Array.isArray(value) ? value[0] : value;
|
|
48
|
+
if (typeof normalized !== "string" && typeof normalized !== "number") {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const seconds = Number(normalized);
|
|
52
|
+
if (Number.isFinite(seconds)) {
|
|
53
|
+
return Math.max(0, seconds * 1000);
|
|
54
|
+
}
|
|
55
|
+
const date = Date.parse(String(normalized));
|
|
56
|
+
return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());
|
|
57
|
+
};
|
|
58
|
+
const retryRequest = async (request) => {
|
|
59
|
+
for (let attempt = 0;; attempt += 1) {
|
|
60
|
+
try {
|
|
61
|
+
return await request();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (attempt >= MAX_REQUEST_RETRIES || !isRetryableRequestError(error)) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, retryAfterMs(error) ?? RETRY_BASE_DELAY_MS * 2 ** attempt));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
28
71
|
export class TestOpsClient {
|
|
29
72
|
constructor(params) {
|
|
30
73
|
_TestOpsClient_instances.add(this);
|
|
@@ -175,7 +218,7 @@ export class TestOpsClient {
|
|
|
175
218
|
throw new Error("Launch isn't created! Call createLaunch first");
|
|
176
219
|
}
|
|
177
220
|
__classPrivateFieldGet(this, _TestOpsClient_logger, "f").verbose("Retrieving launch progress status…");
|
|
178
|
-
const data = await __classPrivateFieldGet(this, _TestOpsClient_client, "f").get(`/api/launch/${__classPrivateFieldGet(this, _TestOpsClient_launch, "f").id}/progress`);
|
|
221
|
+
const data = await retryRequest(() => __classPrivateFieldGet(this, _TestOpsClient_client, "f").get(`/api/launch/${__classPrivateFieldGet(this, _TestOpsClient_launch, "f").id}/progress`));
|
|
179
222
|
return data.ready;
|
|
180
223
|
}
|
|
181
224
|
async createSession(environment = {}) {
|
|
@@ -247,7 +290,9 @@ export class TestOpsClient {
|
|
|
247
290
|
if (!__classPrivateFieldGet(this, _TestOpsClient_launch, "f")) {
|
|
248
291
|
throw new Error("Launch isn't created! Call createLaunch first");
|
|
249
292
|
}
|
|
293
|
+
const launchId = __classPrivateFieldGet(this, _TestOpsClient_launch, "f").id;
|
|
250
294
|
const formData = new FormData();
|
|
295
|
+
let hasResolvedAttachments = false;
|
|
251
296
|
for (const attachmentLink of attachments) {
|
|
252
297
|
const attachment = await attachmentsResolver(attachmentLink);
|
|
253
298
|
if (!attachment) {
|
|
@@ -257,6 +302,10 @@ export class TestOpsClient {
|
|
|
257
302
|
filename: attachment.originalFileName,
|
|
258
303
|
contentType: attachment.contentType,
|
|
259
304
|
});
|
|
305
|
+
hasResolvedAttachments = true;
|
|
306
|
+
}
|
|
307
|
+
if (!hasResolvedAttachments) {
|
|
308
|
+
return;
|
|
260
309
|
}
|
|
261
310
|
await __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/launch/attachment", {
|
|
262
311
|
body: formData,
|
|
@@ -265,7 +314,7 @@ export class TestOpsClient {
|
|
|
265
314
|
const percent = total > 0 ? Math.min(100, Math.max(0, (progressEvent.loaded / total) * 100)) : 0;
|
|
266
315
|
onProgress?.(percent, total);
|
|
267
316
|
},
|
|
268
|
-
params: { launchId
|
|
317
|
+
params: { launchId },
|
|
269
318
|
headers: formData.getHeaders(),
|
|
270
319
|
});
|
|
271
320
|
}
|
|
@@ -276,9 +325,10 @@ export class TestOpsClient {
|
|
|
276
325
|
if (!__classPrivateFieldGet(this, _TestOpsClient_launch, "f")) {
|
|
277
326
|
throw new Error("Launch isn't created! Call createLaunch first");
|
|
278
327
|
}
|
|
328
|
+
const launchId = __classPrivateFieldGet(this, _TestOpsClient_launch, "f").id;
|
|
279
329
|
await __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/launch/error/bulk", {
|
|
280
330
|
body: {
|
|
281
|
-
launchId
|
|
331
|
+
launchId,
|
|
282
332
|
items: errors,
|
|
283
333
|
},
|
|
284
334
|
onUploadProgress(progressEvent) {
|
|
@@ -343,6 +393,7 @@ export class TestOpsClient {
|
|
|
343
393
|
if (!__classPrivateFieldGet(this, _TestOpsClient_launch, "f")) {
|
|
344
394
|
throw new Error("Launch isn't created! Call createLaunch first");
|
|
345
395
|
}
|
|
396
|
+
const launchId = __classPrivateFieldGet(this, _TestOpsClient_launch, "f").id;
|
|
346
397
|
const items = results.map((result) => {
|
|
347
398
|
const item = {
|
|
348
399
|
name: result.rule,
|
|
@@ -354,9 +405,9 @@ export class TestOpsClient {
|
|
|
354
405
|
}
|
|
355
406
|
return item;
|
|
356
407
|
});
|
|
357
|
-
await __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/launch/quality-gate/bulk", {
|
|
408
|
+
await retryRequest(() => __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/launch/quality-gate/bulk", {
|
|
358
409
|
body: {
|
|
359
|
-
launchId
|
|
410
|
+
launchId,
|
|
360
411
|
items,
|
|
361
412
|
},
|
|
362
413
|
onUploadProgress(progressEvent) {
|
|
@@ -364,7 +415,7 @@ export class TestOpsClient {
|
|
|
364
415
|
const percent = total > 0 ? Math.min(100, Math.max(0, (progressEvent.loaded / total) * 100)) : 0;
|
|
365
416
|
onProgress?.(percent, total);
|
|
366
417
|
},
|
|
367
|
-
});
|
|
418
|
+
}));
|
|
368
419
|
}
|
|
369
420
|
}
|
|
370
421
|
_TestOpsClient_baseUrl = new WeakMap(), _TestOpsClient_logger = new WeakMap(), _TestOpsClient_accessToken = new WeakMap(), _TestOpsClient_projectId = new WeakMap(), _TestOpsClient_client = new WeakMap(), _TestOpsClient_launch = new WeakMap(), _TestOpsClient_session = new WeakMap(), _TestOpsClient_uploadInProgress = new WeakMap(), _TestOpsClient_uploadLimit = new WeakMap(), _TestOpsClient_namedEnvsIdsByEnv = new WeakMap(), _TestOpsClient_instances = new WeakSet(), _TestOpsClient_postTestResultsChunk = async function _TestOpsClient_postTestResultsChunk(trsChunk) {
|
|
@@ -387,10 +438,10 @@ _TestOpsClient_baseUrl = new WeakMap(), _TestOpsClient_logger = new WeakMap(), _
|
|
|
387
438
|
return extendedTestResult;
|
|
388
439
|
});
|
|
389
440
|
const body = toUploadResultsDto(__classPrivateFieldGet(this, _TestOpsClient_session, "f").id, extendedChunk);
|
|
390
|
-
const data = await __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/upload/test-result", {
|
|
441
|
+
const data = await retryRequest(() => __classPrivateFieldGet(this, _TestOpsClient_client, "f").post("/api/upload/test-result", {
|
|
391
442
|
body,
|
|
392
443
|
headers: { "Content-Type": "application/json" },
|
|
393
|
-
});
|
|
444
|
+
}));
|
|
394
445
|
const reportIdsToTestOpsIds = {};
|
|
395
446
|
for (const { id, uuid } of data.results ?? []) {
|
|
396
447
|
if (typeof uuid === "string" && typeof id === "number") {
|
|
@@ -451,7 +502,7 @@ _TestOpsClient_baseUrl = new WeakMap(), _TestOpsClient_logger = new WeakMap(), _
|
|
|
451
502
|
if (fixtures.length === 0)
|
|
452
503
|
return;
|
|
453
504
|
const body = toUploadFixturesResultsDto(fixtures);
|
|
454
|
-
await __classPrivateFieldGet(this, _TestOpsClient_client, "f").post(`/api/upload/test-result/${testOpsResultId}/test-fixture-result`, {
|
|
505
|
+
await retryRequest(() => __classPrivateFieldGet(this, _TestOpsClient_client, "f").post(`/api/upload/test-result/${testOpsResultId}/test-fixture-result`, {
|
|
455
506
|
body,
|
|
456
|
-
});
|
|
507
|
+
}));
|
|
457
508
|
};
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
type LogLevel = "silent" | "verbose" | "debug" | "info" | "warn" | "error";
|
|
1
2
|
type JSONMessage = Record<string, unknown> | Array<unknown>;
|
|
2
3
|
export declare class Logger {
|
|
3
4
|
#private;
|
|
4
5
|
private readonly loggerName;
|
|
5
|
-
constructor(loggerName: string);
|
|
6
|
+
constructor(loggerName: string, logLevel?: LogLevel);
|
|
7
|
+
setLogLevel(logLevel: LogLevel): void;
|
|
6
8
|
verbose(message: string | JSONMessage): void;
|
|
7
9
|
debug(message: string | JSONMessage): void;
|
|
8
10
|
newLine(): void;
|
package/dist/logger.js
CHANGED
|
@@ -35,13 +35,17 @@ function getLogLevelFromEnv() {
|
|
|
35
35
|
return "info";
|
|
36
36
|
}
|
|
37
37
|
export class Logger {
|
|
38
|
-
constructor(loggerName) {
|
|
38
|
+
constructor(loggerName, logLevel) {
|
|
39
39
|
_Logger_instances.add(this);
|
|
40
40
|
this.loggerName = loggerName;
|
|
41
|
-
_Logger_level.set(this,
|
|
41
|
+
_Logger_level.set(this, void 0);
|
|
42
42
|
_Logger_prefix.set(this, void 0);
|
|
43
|
+
__classPrivateFieldSet(this, _Logger_level, logLevel ?? getLogLevelFromEnv(), "f");
|
|
43
44
|
__classPrivateFieldSet(this, _Logger_prefix, cyan(bold(`[${this.loggerName}]:`)), "f");
|
|
44
45
|
}
|
|
46
|
+
setLogLevel(logLevel) {
|
|
47
|
+
__classPrivateFieldSet(this, _Logger_level, logLevel, "f");
|
|
48
|
+
}
|
|
45
49
|
verbose(message) {
|
|
46
50
|
if (!__classPrivateFieldGet(this, _Logger_instances, "m", _Logger_isLogLevel).call(this, "verbose")) {
|
|
47
51
|
return;
|
package/dist/plugin.js
CHANGED
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _TestOpsPlugin_instances, _TestOpsPlugin_logger, _TestOpsPlugin_ci, _TestOpsPlugin_client, _TestOpsPlugin_launchName, _TestOpsPlugin_launchTags, _TestOpsPlugin_uploadedTestResultsIds, _TestOpsPlugin_autocloseLaunch, _TestOpsPlugin_launchStarted, _TestOpsPlugin_gitFlow, _TestOpsPlugin_enabledByConfig, _TestOpsPlugin_uploadQualityGateResults, _TestOpsPlugin_uploadGlobalErrors, _TestOpsPlugin_uploadGlobalAttachments, _TestOpsPlugin_uploadTestResults, _TestOpsPlugin_upload, _TestOpsPlugin_trsToUpload, _TestOpsPlugin_enrichWithCategories, _TestOpsPlugin_syncLaunchCategories, _TestOpsPlugin_collectCategoryNamesByExternalId, _TestOpsPlugin_assignCreatedCategoryIds, _TestOpsPlugin_startUpload, _TestOpsPlugin_stopUpload;
|
|
12
|
+
var _TestOpsPlugin_instances, _TestOpsPlugin_logger, _TestOpsPlugin_ci, _TestOpsPlugin_client, _TestOpsPlugin_launchName, _TestOpsPlugin_launchTags, _TestOpsPlugin_uploadedTestResultsIds, _TestOpsPlugin_uploadedGlobalAttachmentIds, _TestOpsPlugin_uploadedGlobalErrors, _TestOpsPlugin_autocloseLaunch, _TestOpsPlugin_launchStarted, _TestOpsPlugin_gitFlow, _TestOpsPlugin_enabledByConfig, _TestOpsPlugin_uploadQualityGateResults, _TestOpsPlugin_uploadGlobalErrors, _TestOpsPlugin_uploadGlobalAttachments, _TestOpsPlugin_uploadTestResults, _TestOpsPlugin_upload, _TestOpsPlugin_trsToUpload, _TestOpsPlugin_enrichWithCategories, _TestOpsPlugin_syncLaunchCategories, _TestOpsPlugin_collectCategoryNamesByExternalId, _TestOpsPlugin_assignCreatedCategoryIds, _TestOpsPlugin_startUpload, _TestOpsPlugin_stopUpload;
|
|
13
13
|
import { env } from "node:process";
|
|
14
14
|
import { detect, isLocalCiDescriptor } from "@allurereport/ci";
|
|
15
15
|
import { createProgressLogger } from "@allurereport/cli-commons";
|
|
@@ -38,6 +38,8 @@ export class TestOpsPlugin {
|
|
|
38
38
|
_TestOpsPlugin_launchName.set(this, "");
|
|
39
39
|
_TestOpsPlugin_launchTags.set(this, []);
|
|
40
40
|
_TestOpsPlugin_uploadedTestResultsIds.set(this, new Set());
|
|
41
|
+
_TestOpsPlugin_uploadedGlobalAttachmentIds.set(this, new Set());
|
|
42
|
+
_TestOpsPlugin_uploadedGlobalErrors.set(this, new Set());
|
|
41
43
|
_TestOpsPlugin_autocloseLaunch.set(this, false);
|
|
42
44
|
_TestOpsPlugin_launchStarted.set(this, false);
|
|
43
45
|
_TestOpsPlugin_gitFlow.set(this, void 0);
|
|
@@ -106,6 +108,9 @@ export class TestOpsPlugin {
|
|
|
106
108
|
if (!this.enabled) {
|
|
107
109
|
return;
|
|
108
110
|
}
|
|
111
|
+
if (context.realTime) {
|
|
112
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").setLogLevel("info");
|
|
113
|
+
}
|
|
109
114
|
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("Starting upload…");
|
|
110
115
|
if (!(await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_startUpload).call(this))) {
|
|
111
116
|
return;
|
|
@@ -209,7 +214,7 @@ export class TestOpsPlugin {
|
|
|
209
214
|
return summary;
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
|
-
_TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestOpsPlugin_client = new WeakMap(), _TestOpsPlugin_launchName = new WeakMap(), _TestOpsPlugin_launchTags = new WeakMap(), _TestOpsPlugin_uploadedTestResultsIds = new WeakMap(), _TestOpsPlugin_autocloseLaunch = new WeakMap(), _TestOpsPlugin_launchStarted = new WeakMap(), _TestOpsPlugin_gitFlow = new WeakMap(), _TestOpsPlugin_enabledByConfig = new WeakMap(), _TestOpsPlugin_instances = new WeakSet(), _TestOpsPlugin_uploadQualityGateResults = async function _TestOpsPlugin_uploadQualityGateResults(store) {
|
|
217
|
+
_TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestOpsPlugin_client = new WeakMap(), _TestOpsPlugin_launchName = new WeakMap(), _TestOpsPlugin_launchTags = new WeakMap(), _TestOpsPlugin_uploadedTestResultsIds = new WeakMap(), _TestOpsPlugin_uploadedGlobalAttachmentIds = new WeakMap(), _TestOpsPlugin_uploadedGlobalErrors = new WeakMap(), _TestOpsPlugin_autocloseLaunch = new WeakMap(), _TestOpsPlugin_launchStarted = new WeakMap(), _TestOpsPlugin_gitFlow = new WeakMap(), _TestOpsPlugin_enabledByConfig = new WeakMap(), _TestOpsPlugin_instances = new WeakSet(), _TestOpsPlugin_uploadQualityGateResults = async function _TestOpsPlugin_uploadQualityGateResults(store) {
|
|
213
218
|
const results = await store.qualityGateResults();
|
|
214
219
|
const uniqueResults = uniqBy(results.filter(({ success }) => !success), ({ rule, environment }) => `${rule}-${environment}`);
|
|
215
220
|
if (uniqueResults.length === 0) {
|
|
@@ -251,10 +256,9 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
251
256
|
finally {
|
|
252
257
|
progressLogger.cancel?.();
|
|
253
258
|
}
|
|
254
|
-
}, _TestOpsPlugin_uploadGlobalErrors = async function _TestOpsPlugin_uploadGlobalErrors(
|
|
255
|
-
const results = await store.allGlobalErrors();
|
|
259
|
+
}, _TestOpsPlugin_uploadGlobalErrors = async function _TestOpsPlugin_uploadGlobalErrors(results) {
|
|
256
260
|
if (results.length === 0) {
|
|
257
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("No global errors to upload");
|
|
261
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("No new global errors to upload");
|
|
258
262
|
return;
|
|
259
263
|
}
|
|
260
264
|
const progressLogger = createProgressLogger({
|
|
@@ -275,6 +279,9 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
275
279
|
if (!completed) {
|
|
276
280
|
progressLogger.increment();
|
|
277
281
|
}
|
|
282
|
+
results.forEach((error) => {
|
|
283
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_uploadedGlobalErrors, "f").add(error);
|
|
284
|
+
});
|
|
278
285
|
progressLogger.log(true);
|
|
279
286
|
}
|
|
280
287
|
catch (error) {
|
|
@@ -292,10 +299,9 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
292
299
|
finally {
|
|
293
300
|
progressLogger.cancel?.();
|
|
294
301
|
}
|
|
295
|
-
}, _TestOpsPlugin_uploadGlobalAttachments = async function _TestOpsPlugin_uploadGlobalAttachments(store) {
|
|
296
|
-
const attachments = await store.allGlobalAttachments();
|
|
302
|
+
}, _TestOpsPlugin_uploadGlobalAttachments = async function _TestOpsPlugin_uploadGlobalAttachments(store, attachments) {
|
|
297
303
|
if (attachments.length === 0) {
|
|
298
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").debug("No global attachments to upload");
|
|
304
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").debug("No new global attachments to upload");
|
|
299
305
|
return;
|
|
300
306
|
}
|
|
301
307
|
const progressLogger = createProgressLogger({
|
|
@@ -332,6 +338,9 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
332
338
|
if (!completed) {
|
|
333
339
|
progressLogger.increment();
|
|
334
340
|
}
|
|
341
|
+
attachments.forEach((attachment) => {
|
|
342
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_uploadedGlobalAttachmentIds, "f").add(attachment.id);
|
|
343
|
+
});
|
|
335
344
|
progressLogger.log(true);
|
|
336
345
|
}
|
|
337
346
|
catch (error) {
|
|
@@ -349,36 +358,35 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
349
358
|
finally {
|
|
350
359
|
progressLogger.cancel?.();
|
|
351
360
|
}
|
|
352
|
-
}, _TestOpsPlugin_uploadTestResults = async function _TestOpsPlugin_uploadTestResults(store, trsToUpload, environments) {
|
|
361
|
+
}, _TestOpsPlugin_uploadTestResults = async function _TestOpsPlugin_uploadTestResults(store, trsToUpload, environments, options) {
|
|
353
362
|
const totalCount = trsToUpload.length;
|
|
354
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").
|
|
363
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose(`Preparing to upload ${bold(totalCount.toString())} ${totalCount > 1 ? "test results" : "test result"}`);
|
|
355
364
|
const progressLogger = createProgressLogger({
|
|
356
365
|
total: totalCount,
|
|
357
366
|
message: "Uploading test results",
|
|
358
367
|
unitLabel: totalCount === 1 ? "test result uploaded" : "test results uploaded",
|
|
359
368
|
prefix: "[TestOpsPlugin]",
|
|
369
|
+
silent: !!options?.silent,
|
|
360
370
|
});
|
|
361
|
-
const logProgress = progressLogger.log;
|
|
362
|
-
const incrementProgress = progressLogger.increment;
|
|
363
371
|
try {
|
|
364
|
-
|
|
372
|
+
progressLogger.log(true);
|
|
365
373
|
const uploadedTrs = await __classPrivateFieldGet(this, _TestOpsPlugin_client, "f").uploadTestResults({
|
|
366
374
|
attachmentsResolver: attachmentsResolverFactory(store),
|
|
367
375
|
fixturesResolver: fixturesResolverFactory(store),
|
|
368
376
|
environments,
|
|
369
377
|
trs: trsToUpload,
|
|
370
|
-
onProgress: () =>
|
|
378
|
+
onProgress: () => progressLogger.increment(),
|
|
371
379
|
});
|
|
372
|
-
|
|
380
|
+
progressLogger.log(true);
|
|
373
381
|
uploadedTrs.forEach((tr) => {
|
|
374
382
|
__classPrivateFieldGet(this, _TestOpsPlugin_uploadedTestResultsIds, "f").add(tr.id);
|
|
375
383
|
});
|
|
376
384
|
const uploadedCount = uploadedTrs.length;
|
|
377
385
|
if (uploadedCount === 0) {
|
|
378
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").
|
|
386
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("No test results were uploaded");
|
|
379
387
|
return;
|
|
380
388
|
}
|
|
381
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").
|
|
389
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose(`Uploaded ${uploadedCount} ${uploadedCount > 1 ? "test results" : "test result"}`);
|
|
382
390
|
}
|
|
383
391
|
finally {
|
|
384
392
|
progressLogger.cancel?.();
|
|
@@ -386,14 +394,30 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
386
394
|
}, _TestOpsPlugin_upload = async function _TestOpsPlugin_upload(store, options = {}) {
|
|
387
395
|
const { context, stage } = options;
|
|
388
396
|
const trsToUpload = await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_trsToUpload).call(this, store);
|
|
397
|
+
const shouldUploadGlobalArtifacts = stage === "done" || !context?.realTime;
|
|
398
|
+
let globalErrors = [];
|
|
399
|
+
let globalAttachments = [];
|
|
400
|
+
if (shouldUploadGlobalArtifacts) {
|
|
401
|
+
const [allGlobalErrors, allGlobalAttachments] = await Promise.all([
|
|
402
|
+
store.allGlobalErrors(),
|
|
403
|
+
store.allGlobalAttachments(),
|
|
404
|
+
]);
|
|
405
|
+
globalErrors = allGlobalErrors.filter((error) => !__classPrivateFieldGet(this, _TestOpsPlugin_uploadedGlobalErrors, "f").has(error));
|
|
406
|
+
globalAttachments = allGlobalAttachments.filter((attachment) => !__classPrivateFieldGet(this, _TestOpsPlugin_uploadedGlobalAttachmentIds, "f").has(attachment.id));
|
|
407
|
+
}
|
|
389
408
|
if (trsToUpload.length === 0) {
|
|
390
409
|
if (stage == "update") {
|
|
391
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").
|
|
410
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("No new test results to upload");
|
|
392
411
|
}
|
|
393
412
|
if (stage === "done") {
|
|
394
|
-
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").
|
|
413
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose("No test results to upload");
|
|
414
|
+
}
|
|
415
|
+
if (globalErrors.length === 0 && globalAttachments.length === 0) {
|
|
416
|
+
return;
|
|
395
417
|
}
|
|
396
|
-
|
|
418
|
+
}
|
|
419
|
+
if (stage === "update" && trsToUpload.length > 0) {
|
|
420
|
+
__classPrivateFieldGet(this, _TestOpsPlugin_logger, "f").verbose(`Found ${bold(trsToUpload.length.toString())} new test ${trsToUpload.length > 1 ? "results" : "result"}, uploading…`);
|
|
397
421
|
}
|
|
398
422
|
try {
|
|
399
423
|
await __classPrivateFieldGet(this, _TestOpsPlugin_client, "f").createSession(env);
|
|
@@ -411,14 +435,19 @@ _TestOpsPlugin_logger = new WeakMap(), _TestOpsPlugin_ci = new WeakMap(), _TestO
|
|
|
411
435
|
}
|
|
412
436
|
return;
|
|
413
437
|
}
|
|
414
|
-
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadGlobalAttachments).call(this, store);
|
|
415
|
-
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadGlobalErrors).call(this,
|
|
438
|
+
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadGlobalAttachments).call(this, store, globalAttachments);
|
|
439
|
+
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadGlobalErrors).call(this, globalErrors);
|
|
440
|
+
if (trsToUpload.length === 0) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
416
443
|
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadQualityGateResults).call(this, store);
|
|
417
444
|
const environments = await store.allEnvironmentIdentities();
|
|
418
445
|
const contextCategories = context?.categories ?? [];
|
|
419
446
|
const trsEnrichedWithCategories = await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_enrichWithCategories).call(this, store, trsToUpload, contextCategories);
|
|
420
447
|
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_syncLaunchCategories).call(this, trsEnrichedWithCategories, contextCategories);
|
|
421
|
-
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadTestResults).call(this, store, trsEnrichedWithCategories, environments
|
|
448
|
+
await __classPrivateFieldGet(this, _TestOpsPlugin_instances, "m", _TestOpsPlugin_uploadTestResults).call(this, store, trsEnrichedWithCategories, environments, {
|
|
449
|
+
silent: !!context?.realTime,
|
|
450
|
+
});
|
|
422
451
|
}, _TestOpsPlugin_trsToUpload = async function _TestOpsPlugin_trsToUpload(store) {
|
|
423
452
|
const filter = this.options.filter ?? stubTrue;
|
|
424
453
|
const filteredTrs = await store.allTestResults({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/plugin-testops",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Allure Plugin TestOps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"lint:fix": "oxlint --import-plugin --fix src test features stories"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@allurereport/ci": "3.
|
|
36
|
-
"@allurereport/cli-commons": "3.
|
|
37
|
-
"@allurereport/core-api": "3.
|
|
38
|
-
"@allurereport/git": "3.
|
|
39
|
-
"@allurereport/plugin-api": "3.
|
|
40
|
-
"@allurereport/reader-api": "3.
|
|
41
|
-
"@allurereport/service": "3.
|
|
35
|
+
"@allurereport/ci": "3.16.0",
|
|
36
|
+
"@allurereport/cli-commons": "3.16.0",
|
|
37
|
+
"@allurereport/core-api": "3.16.0",
|
|
38
|
+
"@allurereport/git": "3.16.0",
|
|
39
|
+
"@allurereport/plugin-api": "3.16.0",
|
|
40
|
+
"@allurereport/reader-api": "3.16.0",
|
|
41
|
+
"@allurereport/service": "3.16.0",
|
|
42
42
|
"axios": "^1.18.1",
|
|
43
43
|
"form-data": "^4.0.6",
|
|
44
44
|
"lodash-es": "^4.18.1",
|