@allurereport/core 3.18.0 → 3.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +15 -0
- package/dist/history.js +7 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/qualityGate/qualityGate.js +1 -1
- package/dist/qualityGate/rules.d.ts +2 -1
- package/dist/qualityGate/rules.js +29 -4
- package/dist/report.js +56 -16
- package/dist/store/convert.d.ts +0 -1
- package/dist/store/convert.js +71 -58
- package/dist/store/retrySubstore.d.ts +1 -3
- package/dist/store/retrySubstore.js +0 -14
- package/dist/store/store.d.ts +4 -2
- package/dist/store/store.js +223 -197
- package/dist/utils/event.d.ts +1 -1
- package/dist/utils/event.js +9 -4
- package/dist/utils/flaky.d.ts +2 -2
- package/dist/utils/flaky.js +36 -8
- package/dist/utils/perf.d.ts +24 -12
- package/dist/utils/perf.js +116 -16
- package/dist/utils/realtimeChannel.d.ts +1 -0
- package/dist/utils/realtimeChannel.js +2 -2
- package/package.json +22 -22
package/dist/config.js
CHANGED
|
@@ -91,6 +91,7 @@ export const validateConfig = (config) => {
|
|
|
91
91
|
"historyPath",
|
|
92
92
|
"historyBaseUrl",
|
|
93
93
|
"historyLimit",
|
|
94
|
+
"flakyDetection",
|
|
94
95
|
"resolutions",
|
|
95
96
|
"plugins",
|
|
96
97
|
"defaultLabels",
|
|
@@ -184,12 +185,25 @@ const resolveConfigEnvironments = (config) => {
|
|
|
184
185
|
allowedEnvironments,
|
|
185
186
|
};
|
|
186
187
|
};
|
|
188
|
+
const validateFlakyDetectionConfig = (config) => {
|
|
189
|
+
if (config === undefined) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const { historyDepth, includePassedTests } = config;
|
|
193
|
+
if (historyDepth !== undefined && (!Number.isInteger(historyDepth) || historyDepth < -1)) {
|
|
194
|
+
throw new Error("flakyDetection.historyDepth must be an integer greater than or equal to -1");
|
|
195
|
+
}
|
|
196
|
+
if (includePassedTests !== undefined && typeof includePassedTests !== "boolean") {
|
|
197
|
+
throw new TypeError("flakyDetection.includePassedTests must be a boolean");
|
|
198
|
+
}
|
|
199
|
+
};
|
|
187
200
|
export const resolveConfig = async (config, override = {}) => {
|
|
188
201
|
const validationResult = validateConfig(config);
|
|
189
202
|
if (!validationResult.valid) {
|
|
190
203
|
throw new Error(`The provided Allure config contains unsupported fields: ${validationResult.fields.join(", ")}`);
|
|
191
204
|
}
|
|
192
205
|
validateResolutionsConfig(config.resolutions);
|
|
206
|
+
validateFlakyDetectionConfig(config.flakyDetection);
|
|
193
207
|
const { environments, environment, allowedEnvironments } = resolveConfigEnvironments(config);
|
|
194
208
|
const name = override.name ?? config.name ?? "Allure Report";
|
|
195
209
|
const open = override.open ?? config.open ?? false;
|
|
@@ -246,6 +260,7 @@ export const resolveConfig = async (config, override = {}) => {
|
|
|
246
260
|
environments,
|
|
247
261
|
appendHistory,
|
|
248
262
|
historyLimit,
|
|
263
|
+
flakyDetection: config.flakyDetection,
|
|
249
264
|
historyPath: historyPath ? resolve(historyPath) : undefined,
|
|
250
265
|
historyBaseUrl,
|
|
251
266
|
dump,
|
package/dist/history.js
CHANGED
|
@@ -19,8 +19,8 @@ import { normalizeHistoryDataPointUrls, } from "@allurereport/core-api";
|
|
|
19
19
|
import { isFileNotFoundError } from "./utils/misc.js";
|
|
20
20
|
const createHistoryItems = (testResults, remoteUrl) => {
|
|
21
21
|
return testResults
|
|
22
|
-
.filter((tr) => tr.
|
|
23
|
-
.map(({ id, name, fullName, environment,
|
|
22
|
+
.filter((tr) => tr.retryHash)
|
|
23
|
+
.map(({ id, name, fullName, environment, retryHash, status, error: { message, trace } = {}, start, stop, duration, labels, }) => {
|
|
24
24
|
return {
|
|
25
25
|
id,
|
|
26
26
|
name,
|
|
@@ -34,12 +34,12 @@ const createHistoryItems = (testResults, remoteUrl) => {
|
|
|
34
34
|
duration,
|
|
35
35
|
labels,
|
|
36
36
|
url: remoteUrl,
|
|
37
|
-
|
|
37
|
+
retryHash: retryHash,
|
|
38
38
|
reportLinks: [],
|
|
39
39
|
};
|
|
40
40
|
})
|
|
41
41
|
.reduce((acc, item) => {
|
|
42
|
-
acc[item.
|
|
42
|
+
acc[item.retryHash] = item;
|
|
43
43
|
return acc;
|
|
44
44
|
}, {});
|
|
45
45
|
};
|
|
@@ -228,7 +228,9 @@ export class AllureLocalHistory {
|
|
|
228
228
|
}
|
|
229
229
|
finally {
|
|
230
230
|
const closing = historyFile.close();
|
|
231
|
-
|
|
231
|
+
if (historyFile.fd !== -1) {
|
|
232
|
+
dst?.destroy();
|
|
233
|
+
}
|
|
232
234
|
await closing;
|
|
233
235
|
if (limit !== 0) {
|
|
234
236
|
__classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f").push(normalizedData);
|
package/dist/index.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export * from "./resolutions.js";
|
|
|
11
11
|
export { resolveConfig, readConfig, readRawConfig, getPluginInstance } from "./config.js";
|
|
12
12
|
export * from "./report.js";
|
|
13
13
|
export * from "./plugin.js";
|
|
14
|
-
export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, maxDurationRule, allTestsContainEnvRule, environmentsTestedRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, convertQualityGateResultsToTestErrors, filterFailedQualityGateResults, stringifyQualityGateResults, } from "./qualityGate/index.js";
|
|
14
|
+
export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, newTestsRule, successRateRule, maxDurationRule, allTestsContainEnvRule, environmentsTestedRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, convertQualityGateResultsToTestErrors, filterFailedQualityGateResults, stringifyQualityGateResults, } from "./qualityGate/index.js";
|
package/dist/index.js
CHANGED
|
@@ -10,4 +10,4 @@ export * from "./resolutions.js";
|
|
|
10
10
|
export { resolveConfig, readConfig, readRawConfig, getPluginInstance } from "./config.js";
|
|
11
11
|
export * from "./report.js";
|
|
12
12
|
export * from "./plugin.js";
|
|
13
|
-
export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, maxDurationRule, allTestsContainEnvRule, environmentsTestedRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, convertQualityGateResultsToTestErrors, filterFailedQualityGateResults, stringifyQualityGateResults, } from "./qualityGate/index.js";
|
|
13
|
+
export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, newTestsRule, successRateRule, maxDurationRule, allTestsContainEnvRule, environmentsTestedRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, convertQualityGateResultsToTestErrors, filterFailedQualityGateResults, stringifyQualityGateResults, } from "./qualityGate/index.js";
|
|
@@ -71,7 +71,7 @@ export class QualityGate {
|
|
|
71
71
|
}
|
|
72
72
|
trsToValidateById.set(tr.id, tr);
|
|
73
73
|
}
|
|
74
|
-
const trsToValidate = trsToValidateById.values()
|
|
74
|
+
const trsToValidate = [...trsToValidateById.values()];
|
|
75
75
|
const { rules, use = [...qualityGateDefaultRules] } = this.config;
|
|
76
76
|
const results = [];
|
|
77
77
|
let fastFailed = false;
|
|
@@ -7,6 +7,7 @@ type MetricRuleConfig = {
|
|
|
7
7
|
};
|
|
8
8
|
export declare const maxFailuresRule: QualityGateRule<number>;
|
|
9
9
|
export declare const minTestsCountRule: QualityGateRule<number>;
|
|
10
|
+
export declare const newTestsRule: QualityGateRule<boolean, number>;
|
|
10
11
|
export declare const successRateRule: QualityGateRule<number>;
|
|
11
12
|
export declare const maxDurationRule: QualityGateRule<number>;
|
|
12
13
|
export declare const allTestsContainEnvRule: QualityGateRule<string, number>;
|
|
@@ -15,5 +16,5 @@ export declare const metricMaxRule: QualityGateRule<MetricRuleConfig>;
|
|
|
15
16
|
export declare const metricMinRule: QualityGateRule<MetricRuleConfig>;
|
|
16
17
|
export declare const metricMaxDeltaRule: QualityGateRule<MetricRuleConfig>;
|
|
17
18
|
export declare const metricMaxDeltaPercentRule: QualityGateRule<MetricRuleConfig>;
|
|
18
|
-
export declare const qualityGateDefaultRules: (QualityGateRule<number> | QualityGateRule<string, number> | QualityGateRule<string[]> | QualityGateRule<MetricRuleConfig>)[];
|
|
19
|
+
export declare const qualityGateDefaultRules: (QualityGateRule<number> | QualityGateRule<boolean, number> | QualityGateRule<string, number> | QualityGateRule<string[]> | QualityGateRule<MetricRuleConfig>)[];
|
|
19
20
|
export {};
|
|
@@ -41,12 +41,17 @@ const metricActual = (metrics, key, value) => {
|
|
|
41
41
|
...(sample?.unit ? { unit: sample.unit } : {}),
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
|
+
const formatQualityGateNumber = (value) => {
|
|
45
|
+
if (!Number.isFinite(value)) {
|
|
46
|
+
return String(value);
|
|
47
|
+
}
|
|
48
|
+
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(3)));
|
|
49
|
+
};
|
|
44
50
|
const formatMetricValue = (value, unit) => {
|
|
45
51
|
if (!Number.isFinite(value)) {
|
|
46
52
|
return "n/a";
|
|
47
53
|
}
|
|
48
|
-
const
|
|
49
|
-
const formatted = Number.isInteger(finiteValue) ? String(finiteValue) : String(Number(finiteValue.toFixed(3)));
|
|
54
|
+
const formatted = formatQualityGateNumber(value);
|
|
50
55
|
return unit ? `${formatted} ${unit}` : formatted;
|
|
51
56
|
};
|
|
52
57
|
const metricRuleTitle = (actual) => actual.title ?? actual.key;
|
|
@@ -101,10 +106,29 @@ export const minTestsCountRule = {
|
|
|
101
106
|
};
|
|
102
107
|
},
|
|
103
108
|
};
|
|
109
|
+
export const newTestsRule = {
|
|
110
|
+
rule: "newTests",
|
|
111
|
+
message: ({ actual, expected }) => expected
|
|
112
|
+
? `No new tests were found; expected at least one new test`
|
|
113
|
+
: `The number of new tests ${bold(String(actual))} does not match the expected policy`,
|
|
114
|
+
successMessage: ({ actual }) => `New tests were found: ${bold(String(actual))}`,
|
|
115
|
+
validate: async ({ trs, expected, state }) => {
|
|
116
|
+
const previous = numberStateValue(state.getResult());
|
|
117
|
+
const newTrs = trs.filter((tr) => tr.transition === "new");
|
|
118
|
+
const testResults = newTrs.map((tr) => tr.id);
|
|
119
|
+
const actual = previous + newTrs.length;
|
|
120
|
+
state.setResult(actual, testResults);
|
|
121
|
+
return {
|
|
122
|
+
success: !expected || actual > 0,
|
|
123
|
+
actual,
|
|
124
|
+
testResults,
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
};
|
|
104
128
|
export const successRateRule = {
|
|
105
129
|
rule: "successRate",
|
|
106
|
-
message: ({ actual, expected }) => `Success rate ${bold(
|
|
107
|
-
successMessage: ({ actual, expected }) => `Success rate ${bold(
|
|
130
|
+
message: ({ actual, expected }) => `Success rate ${bold(formatQualityGateNumber(actual))} is less, than expected ${bold(formatQualityGateNumber(expected))}`,
|
|
131
|
+
successMessage: ({ actual, expected }) => `Success rate ${bold(formatQualityGateNumber(actual))} is not less, than expected ${bold(formatQualityGateNumber(expected))}`,
|
|
108
132
|
validate: async ({ trs, expected, state }) => {
|
|
109
133
|
const previous = successRateStateValue(state.getResult());
|
|
110
134
|
const eligibleTrs = trs.filter(filterIncludedInSuccessRate);
|
|
@@ -232,6 +256,7 @@ export const metricMaxDeltaPercentRule = {
|
|
|
232
256
|
export const qualityGateDefaultRules = [
|
|
233
257
|
maxFailuresRule,
|
|
234
258
|
minTestsCountRule,
|
|
259
|
+
newTestsRule,
|
|
235
260
|
successRateRule,
|
|
236
261
|
maxDurationRule,
|
|
237
262
|
allTestsContainEnvRule,
|
package/dist/report.js
CHANGED
|
@@ -22,7 +22,7 @@ import { detect } from "@allurereport/ci";
|
|
|
22
22
|
import { createProgressLogger } from "@allurereport/cli-commons";
|
|
23
23
|
import { normalizeCategoriesConfig, parseIntegerConfigValue } from "@allurereport/core-api";
|
|
24
24
|
import { AllureStoreDumpFiles, createTestResultRegistry, } from "@allurereport/plugin-api";
|
|
25
|
-
import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
|
|
25
|
+
import { allure1, allure2, attachments, cucumberjson, cucumberMessages, junitXml, readXcResultBundle, } from "@allurereport/reader";
|
|
26
26
|
import { PathResultFile } from "@allurereport/reader-api";
|
|
27
27
|
import { AllureRemoteHistory, AllureServiceClient, AllureTestOpsClient, KnownError, UnknownError, } from "@allurereport/service";
|
|
28
28
|
import { generateSummary } from "@allurereport/summary";
|
|
@@ -37,7 +37,7 @@ import { writeKnownIssues } from "./resolutions.js";
|
|
|
37
37
|
import { DefaultAllureStore } from "./store/store.js";
|
|
38
38
|
import { ARTIFACTS_MANIFEST_FILENAME, createReportArtifact, deduplicateDumpInputs, } from "./utils/artifacts.js";
|
|
39
39
|
import { environmentIdentityById, environmentIdentityByName } from "./utils/environment.js";
|
|
40
|
-
import { getPerfMetricsResults, isPerfMetricsEnabled, measurePerf, PERF_METRIC_NAMES, PERF_METRIC_PREFIXES, perfMetricsFileName, startPerfSpan, writePerfMetrics, } from "./utils/perf.js";
|
|
40
|
+
import { getPerfMetricsResults, incrementPerfCounter, isPerfMetricsEnabled, measurePerfAggregate, measurePerf, PERF_METRIC_NAMES, PERF_METRIC_PREFIXES, perfMetricsFileName, startPerfSpan, writePerfMetrics, } from "./utils/perf.js";
|
|
41
41
|
import { RealtimeChannel } from "./utils/realtimeChannel.js";
|
|
42
42
|
import { RealtimeUpdateScheduler } from "./utils/realtimeUpdateScheduler.js";
|
|
43
43
|
import { resolveDumpAttachmentPath, UnsafeDumpPathError } from "./utils/safeDumpPath.js";
|
|
@@ -53,6 +53,11 @@ const ROOT_INTEGRATION_FILENAMES = new Set([
|
|
|
53
53
|
QUALITY_GATE_RESULTS_FILENAME,
|
|
54
54
|
ARTIFACTS_MANIFEST_FILENAME,
|
|
55
55
|
]);
|
|
56
|
+
const WORKLOAD_PERF_METRIC = {
|
|
57
|
+
group: "workload",
|
|
58
|
+
groupTitle: "Workload",
|
|
59
|
+
better: "neutral",
|
|
60
|
+
};
|
|
56
61
|
const readConcurrency = () => {
|
|
57
62
|
const parsed = Number.parseInt(process.env.ALLURE_READ_CONCURRENCY ?? "", 10);
|
|
58
63
|
if (!Number.isFinite(parsed)) {
|
|
@@ -298,17 +303,23 @@ export class AllureReport {
|
|
|
298
303
|
throw new Error(INIT_REQUIRED_ERROR_MESSAGE);
|
|
299
304
|
}
|
|
300
305
|
const resultsDirPath = resolve(resultsDir);
|
|
301
|
-
if (await readXcResultBundle(__classPrivateFieldGet(this, _AllureReport_store, "f"), resultsDirPath)) {
|
|
306
|
+
if (await measurePerf(PERF_METRIC_NAMES.generateReadResultsXcresultCheck, () => readXcResultBundle(__classPrivateFieldGet(this, _AllureReport_store, "f"), resultsDirPath))) {
|
|
307
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
302
308
|
return;
|
|
303
309
|
}
|
|
304
310
|
try {
|
|
305
|
-
const entries = (await readdir(resultsDirPath, { withFileTypes: true }))
|
|
311
|
+
const entries = await measurePerf(PERF_METRIC_NAMES.generateReadResultsReaddir, async () => (await readdir(resultsDirPath, { withFileTypes: true }))
|
|
306
312
|
.filter((dirent) => dirent.isFile() && !dirent.name.endsWith(".tmp"))
|
|
307
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
313
|
+
.sort((a, b) => a.name.localeCompare(b.name)));
|
|
308
314
|
const limit = pLimit(readConcurrency());
|
|
315
|
+
incrementPerfCounter(PERF_METRIC_NAMES.generateReadResultsFiles, entries.length, {
|
|
316
|
+
...WORKLOAD_PERF_METRIC,
|
|
317
|
+
title: "Input files",
|
|
318
|
+
unit: "files",
|
|
319
|
+
});
|
|
309
320
|
await Promise.all(entries.map((dirent) => limit(async () => {
|
|
310
321
|
try {
|
|
311
|
-
const path = await realpath(join(resultsDirPath, dirent.name));
|
|
322
|
+
const path = await measurePerfAggregate(PERF_METRIC_NAMES.generateReadResultsRealpath, () => realpath(join(resultsDirPath, dirent.name)));
|
|
312
323
|
await this.readResult(new PathResultFile(path, dirent.name));
|
|
313
324
|
}
|
|
314
325
|
catch (e) {
|
|
@@ -319,12 +330,14 @@ export class AllureReport {
|
|
|
319
330
|
catch (e) {
|
|
320
331
|
console.error("can't read directory", e);
|
|
321
332
|
}
|
|
333
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
322
334
|
});
|
|
323
335
|
this.readFile = async (resultsFile) => measurePerf(PERF_METRIC_NAMES.generateReadResults, async () => {
|
|
324
336
|
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
|
|
325
337
|
throw new Error(INIT_REQUIRED_ERROR_MESSAGE);
|
|
326
338
|
}
|
|
327
339
|
await this.readResult(new PathResultFile(resultsFile));
|
|
340
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
328
341
|
});
|
|
329
342
|
this.readResult = async (data) => {
|
|
330
343
|
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
|
|
@@ -335,7 +348,7 @@ export class AllureReport {
|
|
|
335
348
|
if (reader.matches && !(await reader.matches(data))) {
|
|
336
349
|
continue;
|
|
337
350
|
}
|
|
338
|
-
const processed = await reader.read(__classPrivateFieldGet(this, _AllureReport_store, "f"), data);
|
|
351
|
+
const processed = await measurePerfAggregate(PERF_METRIC_NAMES.generateReadResultsReaderRead, () => reader.read(__classPrivateFieldGet(this, _AllureReport_store, "f"), data));
|
|
339
352
|
if (processed) {
|
|
340
353
|
return;
|
|
341
354
|
}
|
|
@@ -345,6 +358,9 @@ export class AllureReport {
|
|
|
345
358
|
};
|
|
346
359
|
this.validate = async (params) => {
|
|
347
360
|
const { trs, state, environment } = params;
|
|
361
|
+
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "done") {
|
|
362
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags(trs.filter(Boolean));
|
|
363
|
+
}
|
|
348
364
|
const qualityGateEnvironment = environment === undefined
|
|
349
365
|
? undefined
|
|
350
366
|
: (environmentIdentityById(__classPrivateFieldGet(this, _AllureReport_environments, "f"), environment)?.name ??
|
|
@@ -370,6 +386,7 @@ export class AllureReport {
|
|
|
370
386
|
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") === "done") {
|
|
371
387
|
throw new Error("the report is already stopped, the restart isn't supported at the moment");
|
|
372
388
|
}
|
|
389
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
373
390
|
__classPrivateFieldSet(this, _AllureReport_executionStage, "running", "f");
|
|
374
391
|
__classPrivateFieldSet(this, _AllureReport_endGeneratePerfSpan, startPerfSpan(PERF_METRIC_NAMES.generateTotal), "f");
|
|
375
392
|
if (__classPrivateFieldGet(this, _AllureReport_globalAttachments, "f")?.length) {
|
|
@@ -399,6 +416,7 @@ export class AllureReport {
|
|
|
399
416
|
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
|
|
400
417
|
return;
|
|
401
418
|
}
|
|
419
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
402
420
|
await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, false, async (plugin, context) => {
|
|
403
421
|
await plugin.update?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
|
|
404
422
|
});
|
|
@@ -449,7 +467,7 @@ export class AllureReport {
|
|
|
449
467
|
const addJsonDumpEntry = async (entryName, value) => {
|
|
450
468
|
await addRequiredDumpEntry(Buffer.from(JSON.stringify(value)), entryName);
|
|
451
469
|
};
|
|
452
|
-
const dumpJsonEntries = ({ testResults, testCases, fixtures, attachments, environments, reportVariables, checkResults = {}, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {},
|
|
470
|
+
const dumpJsonEntries = ({ testResults, testCases, fixtures, attachments, environments, reportVariables, metadata = {}, checkResults = {}, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByRetryHash = {}, indexTestResultByTestCase = {}, indexTestResultByResolutionIssue = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, resolutionIssues = {}, qualityGateResults = [], testResultIdsIngestOrder = [], metrics = [], }) => [
|
|
453
471
|
[AllureStoreDumpFiles.TestResults, testResults],
|
|
454
472
|
[AllureStoreDumpFiles.TestCases, testCases],
|
|
455
473
|
[AllureStoreDumpFiles.Fixtures, fixtures],
|
|
@@ -457,11 +475,12 @@ export class AllureReport {
|
|
|
457
475
|
[AllureStoreDumpFiles.CheckResults, checkResults],
|
|
458
476
|
[AllureStoreDumpFiles.Environments, environments],
|
|
459
477
|
[AllureStoreDumpFiles.ReportVariables, reportVariables],
|
|
478
|
+
[AllureStoreDumpFiles.Metadata, metadata],
|
|
460
479
|
[AllureStoreDumpFiles.ResolutionIssues, resolutionIssues],
|
|
461
480
|
[AllureStoreDumpFiles.GlobalAttachments, globalAttachmentIds],
|
|
462
481
|
[AllureStoreDumpFiles.GlobalErrors, globalErrors],
|
|
463
482
|
[AllureStoreDumpFiles.IndexAttachmentsByTestResults, indexAttachmentByTestResult],
|
|
464
|
-
[AllureStoreDumpFiles.
|
|
483
|
+
[AllureStoreDumpFiles.IndexTestResultsByRetryHash, indexTestResultByRetryHash],
|
|
465
484
|
[AllureStoreDumpFiles.IndexTestResultsByTestCase, indexTestResultByTestCase],
|
|
466
485
|
[AllureStoreDumpFiles.IndexTestResultsByResolutionIssue, indexTestResultByResolutionIssue],
|
|
467
486
|
[AllureStoreDumpFiles.IndexAttachmentsByFixture, indexAttachmentByFixture],
|
|
@@ -537,6 +556,7 @@ export class AllureReport {
|
|
|
537
556
|
this.restoreState = async (dumps) => {
|
|
538
557
|
__classPrivateFieldGet(this, _AllureReport_store, "f").resetIngestOrder();
|
|
539
558
|
await __classPrivateFieldGet(this, _AllureReport_restoreStateDumps, "f").call(this, dumps.map((path) => ({ artifactPath: path, path })));
|
|
559
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
540
560
|
};
|
|
541
561
|
_AllureReport_recordArtifact.set(this, (filePath, name = basename(filePath)) => {
|
|
542
562
|
const artifact = createReportArtifact(filePath, __classPrivateFieldGet(this, _AllureReport_getCwd, "f").call(this), name);
|
|
@@ -604,11 +624,10 @@ export class AllureReport {
|
|
|
604
624
|
const checkResultsEntry = await optionalEntryData(AllureStoreDumpFiles.CheckResults);
|
|
605
625
|
const environmentsEntry = await requiredEntryData(AllureStoreDumpFiles.Environments);
|
|
606
626
|
const reportVariablesEntry = await requiredEntryData(AllureStoreDumpFiles.ReportVariables);
|
|
627
|
+
const metadataEntry = await optionalEntryData(AllureStoreDumpFiles.Metadata);
|
|
607
628
|
const globalAttachmentsEntry = await requiredEntryData(AllureStoreDumpFiles.GlobalAttachments);
|
|
608
629
|
const globalErrorsEntry = await requiredEntryData(AllureStoreDumpFiles.GlobalErrors);
|
|
609
630
|
const indexAttachmentsEntry = await requiredEntryData(AllureStoreDumpFiles.IndexAttachmentsByTestResults);
|
|
610
|
-
const indexTestResultsByHistoryId = await requiredEntryData(AllureStoreDumpFiles.IndexTestResultsByHistoryId);
|
|
611
|
-
const indexTestResultsByTestCaseEntry = await requiredEntryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
|
|
612
631
|
const indexTestResultsByResolutionIssueEntry = await optionalEntryData(AllureStoreDumpFiles.IndexTestResultsByResolutionIssue);
|
|
613
632
|
const indexAttachmentsByFixtureEntry = await requiredEntryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
|
|
614
633
|
const indexFixturesByTestResultEntry = await requiredEntryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
|
|
@@ -626,11 +645,12 @@ export class AllureReport {
|
|
|
626
645
|
case AllureStoreDumpFiles.Fixtures:
|
|
627
646
|
case AllureStoreDumpFiles.Environments:
|
|
628
647
|
case AllureStoreDumpFiles.ReportVariables:
|
|
648
|
+
case AllureStoreDumpFiles.Metadata:
|
|
629
649
|
case AllureStoreDumpFiles.ResolutionIssues:
|
|
630
650
|
case AllureStoreDumpFiles.GlobalAttachments:
|
|
631
651
|
case AllureStoreDumpFiles.GlobalErrors:
|
|
632
652
|
case AllureStoreDumpFiles.IndexAttachmentsByTestResults:
|
|
633
|
-
case AllureStoreDumpFiles.
|
|
653
|
+
case AllureStoreDumpFiles.IndexTestResultsByRetryHash:
|
|
634
654
|
case AllureStoreDumpFiles.IndexTestResultsByTestCase:
|
|
635
655
|
case AllureStoreDumpFiles.IndexTestResultsByResolutionIssue:
|
|
636
656
|
case AllureStoreDumpFiles.IndexAttachmentsByFixture:
|
|
@@ -656,11 +676,12 @@ export class AllureReport {
|
|
|
656
676
|
checkResults: checkResultsEntry ? JSON.parse(checkResultsEntry.toString("utf8")) : [],
|
|
657
677
|
environments: JSON.parse(environmentsEntry.toString("utf8")),
|
|
658
678
|
reportVariables: JSON.parse(reportVariablesEntry.toString("utf8")),
|
|
679
|
+
metadata: metadataEntry ? JSON.parse(metadataEntry.toString("utf8")) : {},
|
|
659
680
|
globalAttachmentIds: JSON.parse(globalAttachmentsEntry.toString("utf8")),
|
|
660
681
|
globalErrors: JSON.parse(globalErrorsEntry.toString("utf8")),
|
|
661
682
|
indexAttachmentByTestResult: JSON.parse(indexAttachmentsEntry.toString("utf8")),
|
|
662
|
-
|
|
663
|
-
indexTestResultByTestCase:
|
|
683
|
+
indexTestResultByRetryHash: {},
|
|
684
|
+
indexTestResultByTestCase: {},
|
|
664
685
|
indexTestResultByResolutionIssue: indexTestResultsByResolutionIssueEntry
|
|
665
686
|
? JSON.parse(indexTestResultsByResolutionIssueEntry.toString("utf8"))
|
|
666
687
|
: {},
|
|
@@ -840,6 +861,7 @@ export class AllureReport {
|
|
|
840
861
|
console.error("realtime update failed during shutdown", e);
|
|
841
862
|
}
|
|
842
863
|
__classPrivateFieldSet(this, _AllureReport_executionStage, "done", "f");
|
|
864
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
843
865
|
if (__classPrivateFieldGet(this, _AllureReport_dump, "f")) {
|
|
844
866
|
await this.dumpState();
|
|
845
867
|
return;
|
|
@@ -970,6 +992,11 @@ export class AllureReport {
|
|
|
970
992
|
await pluginState.set("files", {});
|
|
971
993
|
}
|
|
972
994
|
const pluginFiles = new PluginFiles(__classPrivateFieldGet(this, _AllureReport_reportFiles, "f"), id, async (key, filepath) => {
|
|
995
|
+
incrementPerfCounter(`${PERF_METRIC_PREFIXES.generatePlugin}${id}.generatedFiles`, 1, {
|
|
996
|
+
...WORKLOAD_PERF_METRIC,
|
|
997
|
+
title: `Generated ${id} files`,
|
|
998
|
+
unit: "files",
|
|
999
|
+
});
|
|
973
1000
|
const currentPluginState = __classPrivateFieldGet(this, _AllureReport_instances, "m", _AllureReport_getPluginState).call(this, false, id);
|
|
974
1001
|
const files = await currentPluginState?.get("files");
|
|
975
1002
|
if (!files) {
|
|
@@ -986,6 +1013,14 @@ export class AllureReport {
|
|
|
986
1013
|
hideLabels: __classPrivateFieldGet(this, _AllureReport_hideLabels, "f"),
|
|
987
1014
|
state: pluginState,
|
|
988
1015
|
reportFiles: pluginFiles,
|
|
1016
|
+
...(isPerfMetricsEnabled()
|
|
1017
|
+
? {
|
|
1018
|
+
perf: {
|
|
1019
|
+
measure: (name, fn) => measurePerf(`${PERF_METRIC_PREFIXES.generatePlugin}${id}.${name}`, fn),
|
|
1020
|
+
count: (name, value, metadata) => incrementPerfCounter(`${PERF_METRIC_PREFIXES.generatePlugin}${id}.${name}`, value, metadata),
|
|
1021
|
+
},
|
|
1022
|
+
}
|
|
1023
|
+
: {}),
|
|
989
1024
|
reportUrl: this.reportUrl,
|
|
990
1025
|
realTime: !!__classPrivateFieldGet(this, _AllureReport_realTime, "f"),
|
|
991
1026
|
output: __classPrivateFieldGet(this, _AllureReport_output, "f"),
|
|
@@ -1005,7 +1040,7 @@ export class AllureReport {
|
|
|
1005
1040
|
}
|
|
1006
1041
|
}
|
|
1007
1042
|
});
|
|
1008
|
-
const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], resolutions, reportFiles, realTime, historyPath, historyBaseUrl, historyLimit, appendHistory, defaultLabels = {}, variables = {}, environment, allowedEnvironments, environments, output, hideLabels, qualityGate, performance, dump, categories, allureService, globalAttachments, cwd, } = opts;
|
|
1043
|
+
const { name, readers = [allure1, allure2, cucumberjson, cucumberMessages, junitXml, attachments], plugins = [], resolutions, reportFiles, realTime, historyPath, historyBaseUrl, historyLimit, flakyDetection, appendHistory, defaultLabels = {}, variables = {}, environment, allowedEnvironments, environments, output, hideLabels, qualityGate, performance, dump, categories, allureService, globalAttachments, cwd, } = opts;
|
|
1009
1044
|
const allureServiceAccessToken = allureService?.accessToken;
|
|
1010
1045
|
if (allureServiceAccessToken) {
|
|
1011
1046
|
const allureServiceClientConfig = {
|
|
@@ -1024,7 +1059,11 @@ export class AllureReport {
|
|
|
1024
1059
|
__classPrivateFieldSet(this, _AllureReport_ci, detect(), "f");
|
|
1025
1060
|
const reportTitleSuffix = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestName ?? __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunName;
|
|
1026
1061
|
this.reportName = [name, reportTitleSuffix].filter(Boolean).join(" – ");
|
|
1027
|
-
__classPrivateFieldSet(this, _AllureReport_realtimeChannel, new RealtimeChannel()
|
|
1062
|
+
__classPrivateFieldSet(this, _AllureReport_realtimeChannel, new RealtimeChannel(() => {
|
|
1063
|
+
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") === "running") {
|
|
1064
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").updateHistoryFlags();
|
|
1065
|
+
}
|
|
1066
|
+
}), "f");
|
|
1028
1067
|
__classPrivateFieldSet(this, _AllureReport_realtimeUpdateScheduler, new RealtimeUpdateScheduler(__classPrivateFieldGet(this, _AllureReport_runRealtimeUpdate, "f")), "f");
|
|
1029
1068
|
__classPrivateFieldSet(this, _AllureReport_realTime, realTime, "f");
|
|
1030
1069
|
__classPrivateFieldSet(this, _AllureReport_dump, dump, "f");
|
|
@@ -1057,6 +1096,7 @@ export class AllureReport {
|
|
|
1057
1096
|
reportVariables: variables,
|
|
1058
1097
|
environmentsConfig: environments,
|
|
1059
1098
|
history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
|
|
1099
|
+
flakyDetection,
|
|
1060
1100
|
resolutionsConfig: resolutions,
|
|
1061
1101
|
defaultLabels,
|
|
1062
1102
|
environment,
|
package/dist/store/convert.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { AttachmentLink, TestCase, TestFixtureResult, TestResult } from "@allurereport/core-api";
|
|
2
2
|
import type { RawFixtureResult, RawTestResult, ReaderContext } from "@allurereport/reader-api";
|
|
3
|
-
export declare const __unknown = "#___unknown_value___#";
|
|
4
3
|
export type StateData = {
|
|
5
4
|
testCases: Map<string, TestCase>;
|
|
6
5
|
attachments: Map<string, AttachmentLink>;
|