@allurereport/core 3.14.2 → 3.15.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/api.d.ts +2 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +25 -4
- package/dist/known.d.ts +5 -1
- package/dist/known.js +70 -16
- package/dist/qualityGate/qualityGate.d.ts +4 -1
- package/dist/qualityGate/qualityGate.js +33 -9
- package/dist/qualityGate/rules.d.ts +11 -3
- package/dist/qualityGate/rules.js +37 -17
- package/dist/report.js +68 -43
- package/dist/store/convert.js +1 -1
- package/dist/store/retrySubstore.d.ts +1 -0
- package/dist/store/retrySubstore.js +3 -1
- package/dist/store/store.d.ts +8 -5
- package/dist/store/store.js +55 -37
- package/package.json +23 -21
package/dist/api.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface PluginInstance {
|
|
|
7
7
|
plugin: Plugin;
|
|
8
8
|
options: Record<string, any>;
|
|
9
9
|
}
|
|
10
|
-
type FullConfigRequiredFromConfig = Required<Pick<Config, "name" | "output" | "open"
|
|
10
|
+
type FullConfigRequiredFromConfig = Required<Pick<Config, "name" | "output" | "open">>;
|
|
11
11
|
export interface FullConfig extends Omit<Config, "name" | "output" | "open" | "allureService" | "knownIssuesPath" | "plugins" | "port">, FullConfigRequiredFromConfig {
|
|
12
12
|
port: Config["port"] | undefined;
|
|
13
13
|
allowedEnvironments?: Config["allowedEnvironments"];
|
|
@@ -15,6 +15,7 @@ export interface FullConfig extends Omit<Config, "name" | "output" | "open" | "a
|
|
|
15
15
|
readers?: ResultsReader[];
|
|
16
16
|
plugins?: PluginInstance[];
|
|
17
17
|
known?: KnownTestFailure[];
|
|
18
|
+
knownIssuesPath?: Config["knownIssuesPath"];
|
|
18
19
|
realTime?: any;
|
|
19
20
|
qualityGate?: Config["qualityGate"];
|
|
20
21
|
allureService?: ResolvedAllureServiceConfig;
|
package/dist/config.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare const validateConfig: (config: Config) => {
|
|
|
25
25
|
export declare const loadYamlConfig: (configPath: string) => Promise<Config>;
|
|
26
26
|
export declare const loadJsonConfig: (configPath: string) => Promise<Config>;
|
|
27
27
|
export declare const loadJsConfig: (configPath: string) => Promise<Config>;
|
|
28
|
+
export declare const loadTsConfig: (configPath: string) => Promise<Config>;
|
|
28
29
|
export declare const resolveConfig: (config: Config, override?: ConfigOverride) => Promise<FullConfig>;
|
|
29
30
|
export declare const readConfig: (cwd?: string, configPath?: string, override?: ConfigOverride) => Promise<FullConfig>;
|
|
30
31
|
export declare const readRawConfig: (cwd?: string, configPath?: string) => Promise<Config>;
|
package/dist/config.js
CHANGED
|
@@ -2,8 +2,9 @@ import { readFile, stat } from "node:fs/promises";
|
|
|
2
2
|
import { extname, resolve } from "node:path";
|
|
3
3
|
import * as process from "node:process";
|
|
4
4
|
import { validateEnvironmentName } from "@allurereport/core-api";
|
|
5
|
+
import { createJiti } from "jiti";
|
|
5
6
|
import { parse } from "yaml";
|
|
6
|
-
import { readKnownIssues } from "./known.js";
|
|
7
|
+
import { DEFAULT_KNOWN_ISSUES_PATH, hasKnownIssueRules, readKnownIssues, resolveExactIssuesFilePath } from "./known.js";
|
|
7
8
|
import { FileSystemReportFiles } from "./plugin.js";
|
|
8
9
|
import { environmentIdentityById, environmentIdentityByName, validateAllowedEnvironmentIds, normalizeEnvironmentDescriptorMap, validateAllowedEnvironmentId, } from "./utils/environment.js";
|
|
9
10
|
import { importWrapper } from "./utils/module.js";
|
|
@@ -13,6 +14,9 @@ const CONFIG_FILENAMES = [
|
|
|
13
14
|
"allurerc.js",
|
|
14
15
|
"allurerc.mjs",
|
|
15
16
|
"allurerc.cjs",
|
|
17
|
+
"allurerc.ts",
|
|
18
|
+
"allurerc.mts",
|
|
19
|
+
"allurerc.cts",
|
|
16
20
|
"allurerc.json",
|
|
17
21
|
"allurerc.yaml",
|
|
18
22
|
"allurerc.yml",
|
|
@@ -80,7 +84,7 @@ export const findConfig = async (cwd, configPath) => {
|
|
|
80
84
|
return resolved;
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
catch
|
|
87
|
+
catch {
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
};
|
|
@@ -94,6 +98,7 @@ export const validateConfig = (config) => {
|
|
|
94
98
|
"historyPath",
|
|
95
99
|
"historyLimit",
|
|
96
100
|
"knownIssuesPath",
|
|
101
|
+
"knownIssues",
|
|
97
102
|
"plugins",
|
|
98
103
|
"defaultLabels",
|
|
99
104
|
"variables",
|
|
@@ -141,6 +146,10 @@ export const loadJsonConfig = async (configPath) => {
|
|
|
141
146
|
export const loadJsConfig = async (configPath) => {
|
|
142
147
|
return (await import(normalizeImportPath(configPath))).default;
|
|
143
148
|
};
|
|
149
|
+
export const loadTsConfig = async (configPath) => {
|
|
150
|
+
const jiti = createJiti(import.meta.url);
|
|
151
|
+
return await jiti.import(resolve(configPath), { default: true });
|
|
152
|
+
};
|
|
144
153
|
const resolveConfigEnvironments = (config) => {
|
|
145
154
|
const errors = [];
|
|
146
155
|
const { ids: allowedEnvironments, idsSet: allowedEnvironmentIds, errors: allowedEnvironmentErrors, } = validateAllowedEnvironmentIds(config.allowedEnvironments, "config.allowedEnvironments");
|
|
@@ -192,9 +201,11 @@ export const resolveConfig = async (config, override = {}) => {
|
|
|
192
201
|
const historyPath = override.historyPath ?? config.historyPath;
|
|
193
202
|
const historyLimit = override.historyLimit ?? config.historyLimit;
|
|
194
203
|
const appendHistory = config.appendHistory ?? true;
|
|
195
|
-
const
|
|
204
|
+
const configuredKnownIssuesPath = override.knownIssuesPath ?? config.knownIssuesPath;
|
|
205
|
+
const knownIssuesPathInput = configuredKnownIssuesPath ?? (hasKnownIssueRules(config.knownIssues) ? DEFAULT_KNOWN_ISSUES_PATH : undefined);
|
|
206
|
+
const knownIssuesPath = await resolveExactIssuesFilePath(knownIssuesPathInput, "known issues");
|
|
196
207
|
const output = resolve(override.output ?? config.output ?? "./allure-report");
|
|
197
|
-
const known = await readKnownIssues(knownIssuesPath);
|
|
208
|
+
const known = knownIssuesPath ? await readKnownIssues(knownIssuesPath) : undefined;
|
|
198
209
|
const variables = config.variables ?? {};
|
|
199
210
|
let pluginInstances = [];
|
|
200
211
|
const hasPluginsOverride = override.plugins !== undefined;
|
|
@@ -225,6 +236,7 @@ export const resolveConfig = async (config, override = {}) => {
|
|
|
225
236
|
hideLabels,
|
|
226
237
|
knownIssuesPath,
|
|
227
238
|
known,
|
|
239
|
+
knownIssues: config.knownIssues,
|
|
228
240
|
environment,
|
|
229
241
|
allowedEnvironments,
|
|
230
242
|
variables,
|
|
@@ -265,6 +277,11 @@ export const readConfig = async (cwd = process.cwd(), configPath, override) => {
|
|
|
265
277
|
case ".mjs":
|
|
266
278
|
config = await loadJsConfig(cfg);
|
|
267
279
|
break;
|
|
280
|
+
case ".ts":
|
|
281
|
+
case ".cts":
|
|
282
|
+
case ".mts":
|
|
283
|
+
config = await loadTsConfig(cfg);
|
|
284
|
+
break;
|
|
268
285
|
default:
|
|
269
286
|
config = DEFAULT_CONFIG;
|
|
270
287
|
}
|
|
@@ -283,6 +300,10 @@ export const readRawConfig = async (cwd = process.cwd(), configPath) => {
|
|
|
283
300
|
case ".cjs":
|
|
284
301
|
case ".mjs":
|
|
285
302
|
return loadJsConfig(cfg);
|
|
303
|
+
case ".ts":
|
|
304
|
+
case ".cts":
|
|
305
|
+
case ".mts":
|
|
306
|
+
return loadTsConfig(cfg);
|
|
286
307
|
default:
|
|
287
308
|
return DEFAULT_CONFIG;
|
|
288
309
|
}
|
package/dist/known.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type { KnownTestFailure } from "@allurereport/core-api";
|
|
1
|
+
import type { KnownIssuesConfig, KnownTestFailure, TestResult } from "@allurereport/core-api";
|
|
2
2
|
import type { AllureStore } from "@allurereport/plugin-api";
|
|
3
|
+
export declare const DEFAULT_KNOWN_ISSUES_PATH = "known-issues.json";
|
|
4
|
+
export declare const hasKnownIssueRules: (knownIssues?: KnownIssuesConfig) => boolean;
|
|
5
|
+
export declare const getKnownIssueByRules: (testResult: TestResult, knownIssues: KnownIssuesConfig | undefined, environmentId?: string) => KnownTestFailure | undefined;
|
|
6
|
+
export declare const resolveExactIssuesFilePath: (pathOrDir: string | undefined, label: string) => Promise<string | undefined>;
|
|
3
7
|
export declare const readKnownIssues: (knownIssuePath: string) => Promise<KnownTestFailure[]>;
|
|
4
8
|
export declare const writeKnownIssues: (store: AllureStore, knownIssuesPath?: string) => Promise<void>;
|
package/dist/known.js
CHANGED
|
@@ -1,9 +1,66 @@
|
|
|
1
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { resolve } from "node:path";
|
|
1
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, extname, resolve } from "node:path";
|
|
3
3
|
import { isFileNotFoundError } from "./utils/misc.js";
|
|
4
|
-
const
|
|
4
|
+
export const DEFAULT_KNOWN_ISSUES_PATH = "known-issues.json";
|
|
5
|
+
export const hasKnownIssueRules = (knownIssues) => (knownIssues?.rules?.length ?? 0) > 0;
|
|
6
|
+
const messageMatches = (rule, testResult) => {
|
|
7
|
+
if (!rule.messageRegexp) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const message = testResult.error?.message;
|
|
11
|
+
return typeof message === "string" && new RegExp(rule.messageRegexp).test(message);
|
|
12
|
+
};
|
|
13
|
+
const testCaseIdMatches = (rule, testResult) => {
|
|
14
|
+
const { id, allureId, externalId } = testResult.testCase ?? {};
|
|
15
|
+
return !rule.testCaseId || [id, allureId, externalId].includes(rule.testCaseId);
|
|
16
|
+
};
|
|
17
|
+
const retryHashMatches = (rule, testResult) => {
|
|
18
|
+
return !rule.retryHash || rule.retryHash === testResult.retryHash;
|
|
19
|
+
};
|
|
20
|
+
const environmentMatches = (rule, testResult) => {
|
|
21
|
+
return !rule.environmentId || rule.environmentId === testResult.environment;
|
|
22
|
+
};
|
|
23
|
+
export const getKnownIssueByRules = (testResult, knownIssues, environmentId) => {
|
|
24
|
+
if (!testResult.historyId || !hasKnownIssueRules(knownIssues)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const matchedRule = knownIssues.rules.find((rule) => [messageMatches, testCaseIdMatches, environmentMatches, retryHashMatches].every((matcher) => matcher(rule, testResult)));
|
|
28
|
+
if (!matchedRule) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
historyId: testResult.historyId,
|
|
33
|
+
reason: matchedRule.decision.reason,
|
|
34
|
+
links: matchedRule.decision.links,
|
|
35
|
+
error: testResult.error,
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export const resolveExactIssuesFilePath = async (pathOrDir, label) => {
|
|
39
|
+
if (!pathOrDir) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const path = resolve(pathOrDir);
|
|
43
|
+
if (extname(path).toLowerCase() !== ".json") {
|
|
44
|
+
throw new Error(`Invalid ${label} path ${JSON.stringify(pathOrDir)}: expected exact .json file path`);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const pathStats = await stat(path);
|
|
48
|
+
if (pathStats.isDirectory()) {
|
|
49
|
+
throw new Error(`Invalid ${label} path ${JSON.stringify(pathOrDir)}: expected file, got directory`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
if (!isFileNotFoundError(e)) {
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return path;
|
|
58
|
+
};
|
|
5
59
|
export const readKnownIssues = async (knownIssuePath) => {
|
|
6
|
-
const path =
|
|
60
|
+
const path = await resolveExactIssuesFilePath(knownIssuePath, "known issues");
|
|
61
|
+
if (!path) {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
7
64
|
try {
|
|
8
65
|
const content = await readFile(path, { encoding: "utf-8" });
|
|
9
66
|
return JSON.parse(content);
|
|
@@ -15,18 +72,15 @@ export const readKnownIssues = async (knownIssuePath) => {
|
|
|
15
72
|
throw e;
|
|
16
73
|
}
|
|
17
74
|
};
|
|
18
|
-
|
|
19
|
-
|
|
75
|
+
const writeKnownIssueRecords = async (knownIssues, knownIssuesPath) => {
|
|
76
|
+
const path = await resolveExactIssuesFilePath(knownIssuesPath, "known issues");
|
|
77
|
+
if (!path) {
|
|
20
78
|
return;
|
|
21
79
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
issues: links.filter((l) => l.type === "issue"),
|
|
29
|
-
comment: "automatically generated from failure by allure known-issue command",
|
|
30
|
-
}));
|
|
31
|
-
await writeFile(knownIssuesPath, JSON.stringify(knownIssues));
|
|
80
|
+
await mkdir(dirname(path), { recursive: true });
|
|
81
|
+
await writeFile(path, `${JSON.stringify(knownIssues)}\n`, "utf-8");
|
|
82
|
+
};
|
|
83
|
+
export const writeKnownIssues = async (store, knownIssuesPath) => {
|
|
84
|
+
const knownIssues = await store.allKnownIssues();
|
|
85
|
+
await writeKnownIssueRecords(knownIssues, knownIssuesPath);
|
|
32
86
|
};
|
|
@@ -4,8 +4,11 @@ export declare const stringifyQualityGateResults: (results: QualityGateValidatio
|
|
|
4
4
|
export declare const convertQualityGateResultsToTestErrors: (results: QualityGateValidationResult[]) => TestError[];
|
|
5
5
|
export declare class QualityGateState {
|
|
6
6
|
#private;
|
|
7
|
-
setResult(rule: string, value: any): void;
|
|
7
|
+
setResult(rule: string, value: any, testResults?: string[]): void;
|
|
8
8
|
getResult(rule: string): any;
|
|
9
|
+
getTestResults(rule: string): string[];
|
|
10
|
+
markTestResultsProcessed(testResults: TestResult[]): void;
|
|
11
|
+
isTestResultProcessed(trId: string): boolean;
|
|
9
12
|
}
|
|
10
13
|
export declare class QualityGate {
|
|
11
14
|
private readonly config;
|
|
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
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");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _QualityGateState_state;
|
|
6
|
+
var _QualityGateState_state, _QualityGateState_processedTestResultIds;
|
|
7
7
|
import { gray, red } from "yoctocolors";
|
|
8
8
|
import { qualityGateDefaultRules } from "./rules.js";
|
|
9
9
|
export const stringifyQualityGateResults = (results) => {
|
|
@@ -30,21 +30,43 @@ export const convertQualityGateResultsToTestErrors = (results) => {
|
|
|
30
30
|
export class QualityGateState {
|
|
31
31
|
constructor() {
|
|
32
32
|
_QualityGateState_state.set(this, {});
|
|
33
|
+
_QualityGateState_processedTestResultIds.set(this, new Set());
|
|
33
34
|
}
|
|
34
|
-
setResult(rule, value) {
|
|
35
|
-
__classPrivateFieldGet(this, _QualityGateState_state, "f")[rule]
|
|
35
|
+
setResult(rule, value, testResults = []) {
|
|
36
|
+
const previousTestResults = __classPrivateFieldGet(this, _QualityGateState_state, "f")[rule]?.testResults ?? [];
|
|
37
|
+
__classPrivateFieldGet(this, _QualityGateState_state, "f")[rule] = {
|
|
38
|
+
result: value,
|
|
39
|
+
testResults: [...new Set([...previousTestResults, ...testResults])],
|
|
40
|
+
};
|
|
36
41
|
}
|
|
37
42
|
getResult(rule) {
|
|
38
|
-
return __classPrivateFieldGet(this, _QualityGateState_state, "f")[rule];
|
|
43
|
+
return __classPrivateFieldGet(this, _QualityGateState_state, "f")[rule]?.result;
|
|
44
|
+
}
|
|
45
|
+
getTestResults(rule) {
|
|
46
|
+
return [...(__classPrivateFieldGet(this, _QualityGateState_state, "f")[rule]?.testResults ?? [])];
|
|
47
|
+
}
|
|
48
|
+
markTestResultsProcessed(testResults) {
|
|
49
|
+
testResults.forEach(({ id }) => __classPrivateFieldGet(this, _QualityGateState_processedTestResultIds, "f").add(id));
|
|
50
|
+
}
|
|
51
|
+
isTestResultProcessed(trId) {
|
|
52
|
+
return __classPrivateFieldGet(this, _QualityGateState_processedTestResultIds, "f").has(trId);
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
|
-
_QualityGateState_state = new WeakMap();
|
|
55
|
+
_QualityGateState_state = new WeakMap(), _QualityGateState_processedTestResultIds = new WeakMap();
|
|
42
56
|
export class QualityGate {
|
|
43
57
|
constructor(config) {
|
|
44
58
|
this.config = config;
|
|
45
59
|
}
|
|
46
60
|
async validate(payload) {
|
|
47
61
|
const { state, trs, knownIssues, environment } = payload;
|
|
62
|
+
const trsToValidateById = new Map();
|
|
63
|
+
for (const tr of trs) {
|
|
64
|
+
if (tr.isRetry || state?.isTestResultProcessed(tr.id)) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
trsToValidateById.set(tr.id, tr);
|
|
68
|
+
}
|
|
69
|
+
const trsToValidate = trsToValidateById.values().toArray();
|
|
48
70
|
const { rules, use = [...qualityGateDefaultRules] } = this.config;
|
|
49
71
|
const results = [];
|
|
50
72
|
let fastFailed = false;
|
|
@@ -58,6 +80,7 @@ export class QualityGate {
|
|
|
58
80
|
if (fastFailed) {
|
|
59
81
|
break;
|
|
60
82
|
}
|
|
83
|
+
const filteredTrs = ruleset.filter ? trsToValidate.filter(ruleset.filter) : trsToValidate;
|
|
61
84
|
for (const [key, expected] of Object.entries(ruleset)) {
|
|
62
85
|
if (key === "filter" || key === "id" || key === "fastFail") {
|
|
63
86
|
continue;
|
|
@@ -66,13 +89,12 @@ export class QualityGate {
|
|
|
66
89
|
if (!rule) {
|
|
67
90
|
throw new Error(`Rule ${key} is not provided. Make sure you have provided it in the "use" field of the quality gate config!`);
|
|
68
91
|
}
|
|
69
|
-
const trsToValidate = ruleset.filter ? trs.filter(ruleset.filter) : trs;
|
|
70
92
|
const ruleId = ruleset.id ? [ruleset.id, rule.rule].join("/") : rule.rule;
|
|
71
93
|
const result = await rule.validate({
|
|
72
|
-
trs:
|
|
94
|
+
trs: filteredTrs,
|
|
73
95
|
state: {
|
|
74
96
|
getResult: () => state?.getResult?.(ruleId),
|
|
75
|
-
setResult: (value) => state?.setResult?.(ruleId, value),
|
|
97
|
+
setResult: (value, testResults) => state?.setResult?.(ruleId, value, testResults),
|
|
76
98
|
},
|
|
77
99
|
expected,
|
|
78
100
|
knownIssues,
|
|
@@ -84,12 +106,13 @@ export class QualityGate {
|
|
|
84
106
|
results.push({
|
|
85
107
|
...result,
|
|
86
108
|
expected,
|
|
87
|
-
rule:
|
|
109
|
+
rule: ruleId,
|
|
88
110
|
message: rule.message({
|
|
89
111
|
actual: result.actual,
|
|
90
112
|
expected,
|
|
91
113
|
}),
|
|
92
114
|
environment,
|
|
115
|
+
testResults: [...new Set([...(state?.getTestResults(ruleId) ?? []), ...result.testResults])],
|
|
93
116
|
});
|
|
94
117
|
if (ruleset.fastFail) {
|
|
95
118
|
fastFailed = true;
|
|
@@ -97,6 +120,7 @@ export class QualityGate {
|
|
|
97
120
|
}
|
|
98
121
|
}
|
|
99
122
|
}
|
|
123
|
+
state?.markTestResultsProcessed(trsToValidate);
|
|
100
124
|
return {
|
|
101
125
|
fastFailed,
|
|
102
126
|
results,
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { type QualityGateRule } from "@allurereport/plugin-api";
|
|
2
2
|
export declare const maxFailuresRule: QualityGateRule<number>;
|
|
3
3
|
export declare const minTestsCountRule: QualityGateRule<number>;
|
|
4
|
-
export declare const successRateRule: QualityGateRule<number
|
|
4
|
+
export declare const successRateRule: QualityGateRule<number, {
|
|
5
|
+
totalCount: number;
|
|
6
|
+
unknownCount: number;
|
|
7
|
+
passedCount: number;
|
|
8
|
+
}>;
|
|
5
9
|
export declare const maxDurationRule: QualityGateRule<number>;
|
|
6
|
-
export declare const allTestsContainEnvRule: QualityGateRule<string>;
|
|
10
|
+
export declare const allTestsContainEnvRule: QualityGateRule<string, number>;
|
|
7
11
|
export declare const environmentsTestedRule: QualityGateRule<string[]>;
|
|
8
|
-
export declare const qualityGateDefaultRules: (QualityGateRule<number> | QualityGateRule<
|
|
12
|
+
export declare const qualityGateDefaultRules: (QualityGateRule<number> | QualityGateRule<number, {
|
|
13
|
+
totalCount: number;
|
|
14
|
+
unknownCount: number;
|
|
15
|
+
passedCount: number;
|
|
16
|
+
}> | QualityGateRule<string, number> | QualityGateRule<string[]>)[];
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { filterSuccessful,
|
|
1
|
+
import { filterSuccessful, filterUnsuccessful } from "@allurereport/core-api";
|
|
2
2
|
import { bold } from "yoctocolors";
|
|
3
3
|
export const maxFailuresRule = {
|
|
4
4
|
rule: "maxFailures",
|
|
5
5
|
message: ({ actual, expected }) => `The number of failed tests ${bold(String(actual))} exceeds the allowed threshold value ${bold(String(expected))}`,
|
|
6
|
-
validate: async ({ trs,
|
|
7
|
-
const
|
|
8
|
-
const unknown =
|
|
6
|
+
validate: async ({ trs, expected, state }) => {
|
|
7
|
+
const previous = state.getResult() ?? 0;
|
|
8
|
+
const unknown = trs.filter((tr) => !tr.known);
|
|
9
9
|
const failedTrs = unknown.filter(filterUnsuccessful);
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const testResults = failedTrs.map((tr) => tr.id);
|
|
11
|
+
const actual = previous + failedTrs.length;
|
|
12
|
+
state.setResult(actual, testResults);
|
|
12
13
|
return {
|
|
13
14
|
success: actual <= expected,
|
|
14
15
|
actual,
|
|
16
|
+
testResults,
|
|
15
17
|
};
|
|
16
18
|
},
|
|
17
19
|
};
|
|
@@ -20,47 +22,64 @@ export const minTestsCountRule = {
|
|
|
20
22
|
message: ({ actual, expected }) => `The total number of tests ${bold(String(actual))} is less than the expected threshold value ${bold(String(expected))}`,
|
|
21
23
|
validate: async ({ trs, expected, state }) => {
|
|
22
24
|
const actual = trs.length + (state.getResult() ?? 0);
|
|
23
|
-
state.setResult(actual);
|
|
25
|
+
state.setResult(actual, []);
|
|
24
26
|
return {
|
|
25
27
|
success: actual >= expected,
|
|
26
28
|
actual,
|
|
29
|
+
testResults: [],
|
|
27
30
|
};
|
|
28
31
|
},
|
|
29
32
|
};
|
|
30
33
|
export const successRateRule = {
|
|
31
34
|
rule: "successRate",
|
|
32
35
|
message: ({ actual, expected }) => `Success rate ${bold(String(actual))} is less, than expected ${bold(String(expected))}`,
|
|
33
|
-
validate: async ({ trs,
|
|
34
|
-
const
|
|
35
|
-
const unknown =
|
|
36
|
+
validate: async ({ trs, expected, state }) => {
|
|
37
|
+
const previous = state.getResult() ?? { totalCount: 0, unknownCount: 0, passedCount: 0 };
|
|
38
|
+
const unknown = trs.filter((tr) => !tr.known);
|
|
36
39
|
const passedTrs = unknown.filter(filterSuccessful);
|
|
37
|
-
const
|
|
40
|
+
const notPassedTrs = unknown.filter((tr) => !filterSuccessful(tr));
|
|
41
|
+
const totalCount = previous.totalCount + trs.length;
|
|
42
|
+
const unknownCount = previous.unknownCount + unknown.length;
|
|
43
|
+
const passedCount = previous.passedCount + passedTrs.length;
|
|
44
|
+
const testResults = notPassedTrs.map((tr) => tr.id);
|
|
45
|
+
const rate = totalCount === 0 ? 0 : unknownCount === 0 ? 1 : passedCount / unknownCount;
|
|
46
|
+
state.setResult({ totalCount, unknownCount, passedCount }, testResults);
|
|
38
47
|
return {
|
|
39
48
|
success: rate >= expected,
|
|
40
49
|
actual: rate,
|
|
50
|
+
testResults,
|
|
41
51
|
};
|
|
42
52
|
},
|
|
43
53
|
};
|
|
44
54
|
export const maxDurationRule = {
|
|
45
55
|
rule: "maxDuration",
|
|
46
56
|
message: ({ actual, expected }) => `Maximum duration of some tests exceed the defined limit; actual ${bold(String(actual))}, expected ${bold(String(expected))}`,
|
|
47
|
-
validate: async ({ trs, expected }) => {
|
|
48
|
-
const
|
|
57
|
+
validate: async ({ trs, expected, state }) => {
|
|
58
|
+
const previous = state.getResult() ?? 0;
|
|
59
|
+
const actual = Math.max(previous, ...trs.map((tr) => tr.duration ?? 0));
|
|
60
|
+
const tooLongTrs = trs.filter((tr) => (tr.duration ?? 0) > expected);
|
|
61
|
+
const testResults = tooLongTrs.map((tr) => tr.id);
|
|
62
|
+
state.setResult(actual, testResults);
|
|
49
63
|
return {
|
|
50
64
|
success: actual <= expected,
|
|
51
65
|
actual,
|
|
66
|
+
testResults,
|
|
52
67
|
};
|
|
53
68
|
},
|
|
54
69
|
};
|
|
55
70
|
export const allTestsContainEnvRule = {
|
|
56
71
|
rule: "allTestsContainEnv",
|
|
57
|
-
message: ({ actual, expected }) => `Not all tests contain the required
|
|
58
|
-
validate: async ({ trs, expected }) => {
|
|
72
|
+
message: ({ actual, expected }) => `Not all tests contain the required "${bold(expected)}" environment, ${bold(actual)} tests have different or missing environment`,
|
|
73
|
+
validate: async ({ trs, expected, state }) => {
|
|
74
|
+
const previous = state.getResult() ?? 0;
|
|
59
75
|
const testsWithoutEnv = trs.filter((tr) => (tr.environment ?? "") !== expected);
|
|
60
|
-
const
|
|
76
|
+
const testResults = testsWithoutEnv.map((tr) => tr.id);
|
|
77
|
+
const actual = testsWithoutEnv.length + previous;
|
|
78
|
+
state.setResult(actual, testResults);
|
|
61
79
|
return {
|
|
62
80
|
success: actual === 0,
|
|
63
81
|
actual,
|
|
82
|
+
testResults,
|
|
64
83
|
};
|
|
65
84
|
},
|
|
66
85
|
};
|
|
@@ -71,11 +90,12 @@ export const environmentsTestedRule = {
|
|
|
71
90
|
const previouslyTested = new Set(state.getResult() ?? []);
|
|
72
91
|
const batchTested = trs.map((tr) => tr.environment).filter((env) => env != null && env !== "");
|
|
73
92
|
const testedEnvs = new Set([...previouslyTested, ...batchTested]);
|
|
74
|
-
state.setResult([...testedEnvs]);
|
|
93
|
+
state.setResult([...testedEnvs], []);
|
|
75
94
|
const missing = expected.filter((env) => !testedEnvs.has(env));
|
|
76
95
|
return {
|
|
77
96
|
success: missing.length === 0,
|
|
78
97
|
actual: missing,
|
|
98
|
+
testResults: [],
|
|
79
99
|
};
|
|
80
100
|
},
|
|
81
101
|
};
|
package/dist/report.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 _AllureReport_instances, _AllureReport_ci, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_realtimeChannel, _AllureReport_realtimeUpdateScheduler, _AllureReport_realTime, _AllureReport_hideLabels, _AllureReport_output, _AllureReport_history, _AllureReport_allureServiceClient, _AllureReport_qualityGate, _AllureReport_dump, _AllureReport_categories, _AllureReport_environments, _AllureReport_globalAttachments, _AllureReport_dumpTempDirs, _AllureReport_state, _AllureReport_executionStage, _AllureReport_historyDataPoint, _AllureReport_summaryPath, _AllureReport_summariesByPluginId, _AllureReport_publishedRemoteHrefs, _AllureReport_published, _AllureReport_endGeneratePerfSpan, _AllureReport_publish, _AllureReport_runRealtimeUpdate, _AllureReport_getReportsToPublish, _AllureReport_cleanupFailedRemoteReport, _AllureReport_logPublishError, _AllureReport_applyPublishLinksToSummaries, _AllureReport_cloneSummariesByPluginId, _AllureReport_writeSummaryFiles, _AllureReport_generateRootSummary, _AllureReport_finishGeneratePerfSpan, _AllureReport_finishPerfMetrics, _AllureReport_eachPlugin, _AllureReport_getPluginState;
|
|
12
|
+
var _AllureReport_instances, _AllureReport_ci, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_realtimeChannel, _AllureReport_realtimeUpdateScheduler, _AllureReport_realTime, _AllureReport_hideLabels, _AllureReport_output, _AllureReport_history, _AllureReport_appendHistory, _AllureReport_allureServiceClient, _AllureReport_qualityGate, _AllureReport_dump, _AllureReport_categories, _AllureReport_environments, _AllureReport_globalAttachments, _AllureReport_knownIssuesPath, _AllureReport_dumpTempDirs, _AllureReport_state, _AllureReport_executionStage, _AllureReport_historyDataPoint, _AllureReport_summaryPath, _AllureReport_testResultsRegistryPath, _AllureReport_summariesByPluginId, _AllureReport_publishedRemoteHrefs, _AllureReport_published, _AllureReport_endGeneratePerfSpan, _AllureReport_publish, _AllureReport_runRealtimeUpdate, _AllureReport_restoreStateDumps, _AllureReport_getReportsToPublish, _AllureReport_cleanupFailedRemoteReport, _AllureReport_logPublishError, _AllureReport_applyPublishLinksToSummaries, _AllureReport_cloneSummariesByPluginId, _AllureReport_writeSummaryFiles, _AllureReport_writeTestResultRegistry, _AllureReport_generateRootSummary, _AllureReport_finishGeneratePerfSpan, _AllureReport_finishPerfMetrics, _AllureReport_eachPlugin, _AllureReport_getPluginState;
|
|
13
13
|
import console from "node:console";
|
|
14
14
|
import { randomUUID } from "node:crypto";
|
|
15
15
|
import { once } from "node:events";
|
|
@@ -19,8 +19,9 @@ import { tmpdir } from "node:os";
|
|
|
19
19
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
20
20
|
import { promisify } from "node:util";
|
|
21
21
|
import { detect } from "@allurereport/ci";
|
|
22
|
+
import { createProgressLogger } from "@allurereport/cli-commons";
|
|
22
23
|
import { normalizeCategoriesConfig } from "@allurereport/core-api";
|
|
23
|
-
import { AllureStoreDumpFiles, } from "@allurereport/plugin-api";
|
|
24
|
+
import { AllureStoreDumpFiles, createTestResultRegistry, } from "@allurereport/plugin-api";
|
|
24
25
|
import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
|
|
25
26
|
import { PathResultFile } from "@allurereport/reader-api";
|
|
26
27
|
import { AllureRemoteHistory, AllureServiceClient, AllureTestOpsClient, KnownError, UnknownError, } from "@allurereport/service";
|
|
@@ -30,6 +31,7 @@ import ZipReadStream from "node-stream-zip";
|
|
|
30
31
|
import pLimit from "p-limit";
|
|
31
32
|
import ZipWriteStream from "zip-stream";
|
|
32
33
|
import { AllureLocalHistory, createHistory } from "./history.js";
|
|
34
|
+
import { writeKnownIssues } from "./known.js";
|
|
33
35
|
import { DefaultPluginState, PluginFiles } from "./plugin.js";
|
|
34
36
|
import { QualityGate } from "./qualityGate/index.js";
|
|
35
37
|
import { DefaultAllureStore } from "./store/store.js";
|
|
@@ -42,6 +44,7 @@ const { version } = JSON.parse(readFileSync(new URL("../package.json", import.me
|
|
|
42
44
|
const INIT_REQUIRED_ERROR_MESSAGE = "report is not initialised. Call the start() method first.";
|
|
43
45
|
const DEFAULT_READ_CONCURRENCY = 64;
|
|
44
46
|
const MAX_READ_CONCURRENCY = 256;
|
|
47
|
+
const TEST_RESULTS_REGISTRY_FILENAME = "test-results.json";
|
|
45
48
|
const readConcurrency = () => {
|
|
46
49
|
const parsed = Number.parseInt(process.env.ALLURE_READ_CONCURRENCY ?? "", 10);
|
|
47
50
|
if (!Number.isFinite(parsed)) {
|
|
@@ -80,17 +83,20 @@ export class AllureReport {
|
|
|
80
83
|
_AllureReport_hideLabels.set(this, void 0);
|
|
81
84
|
_AllureReport_output.set(this, void 0);
|
|
82
85
|
_AllureReport_history.set(this, void 0);
|
|
86
|
+
_AllureReport_appendHistory.set(this, void 0);
|
|
83
87
|
_AllureReport_allureServiceClient.set(this, void 0);
|
|
84
88
|
_AllureReport_qualityGate.set(this, void 0);
|
|
85
89
|
_AllureReport_dump.set(this, void 0);
|
|
86
90
|
_AllureReport_categories.set(this, void 0);
|
|
87
91
|
_AllureReport_environments.set(this, void 0);
|
|
88
92
|
_AllureReport_globalAttachments.set(this, void 0);
|
|
93
|
+
_AllureReport_knownIssuesPath.set(this, void 0);
|
|
89
94
|
_AllureReport_dumpTempDirs.set(this, []);
|
|
90
95
|
_AllureReport_state.set(this, void 0);
|
|
91
96
|
_AllureReport_executionStage.set(this, "init");
|
|
92
97
|
_AllureReport_historyDataPoint.set(this, void 0);
|
|
93
98
|
_AllureReport_summaryPath.set(this, void 0);
|
|
99
|
+
_AllureReport_testResultsRegistryPath.set(this, void 0);
|
|
94
100
|
_AllureReport_summariesByPluginId.set(this, new Map());
|
|
95
101
|
_AllureReport_publishedRemoteHrefs.set(this, new Set());
|
|
96
102
|
_AllureReport_published.set(this, false);
|
|
@@ -109,6 +115,7 @@ export class AllureReport {
|
|
|
109
115
|
historyPoint = createHistory(this.reportUuid, this.reportName, allTcs, allTrs, this.reportUrl);
|
|
110
116
|
__classPrivateFieldSet(this, _AllureReport_historyDataPoint, historyPoint, "f");
|
|
111
117
|
}
|
|
118
|
+
await __classPrivateFieldGet(this, _AllureReport_writeTestResultRegistry, "f").call(this);
|
|
112
119
|
await __classPrivateFieldGet(this, _AllureReport_writeSummaryFiles, "f").call(this);
|
|
113
120
|
await __classPrivateFieldGet(this, _AllureReport_generateRootSummary, "f").call(this);
|
|
114
121
|
if (__classPrivateFieldGet(this, _AllureReport_realTime, "f") || !__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")) {
|
|
@@ -124,33 +131,20 @@ export class AllureReport {
|
|
|
124
131
|
const linksByPluginId = {};
|
|
125
132
|
const summariesSnapshot = __classPrivateFieldGet(this, _AllureReport_cloneSummariesByPluginId, "f").call(this);
|
|
126
133
|
const uploadProgressMessage = reportsToPublish.length === 1 ? `Publishing "${reportsToPublish[0].pluginId}" report` : "Publishing reports";
|
|
127
|
-
const totalFilesToUpload = reportsToPublish.reduce((acc, report) => acc + Object.keys(report.files).length, 0)
|
|
128
|
-
|
|
134
|
+
const totalFilesToUpload = reportsToPublish.reduce((acc, report) => acc + Object.keys(report.files).length, 0) +
|
|
135
|
+
(__classPrivateFieldGet(this, _AllureReport_testResultsRegistryPath, "f") ? 1 : 0);
|
|
129
136
|
let summariesMutated = false;
|
|
130
137
|
let reportCreated = false;
|
|
131
138
|
let publishErrorMessage = "Report upload has failed, the report won't be published";
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
const progressLogger = createProgressLogger({
|
|
140
|
+
total: totalFilesToUpload,
|
|
141
|
+
message: uploadProgressMessage,
|
|
142
|
+
unitLabel: "files uploaded",
|
|
143
|
+
prefix: "[AllureReport]",
|
|
144
|
+
});
|
|
135
145
|
const endPublishPerfSpan = startPerfSpan(PERF_METRIC_NAMES.publishUploadTotal);
|
|
136
|
-
const logUploadProgress =
|
|
137
|
-
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (!force && uploadedFiles < nextProgressLogAt && uploadedFiles !== totalFilesToUpload) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
if (!force && uploadedFiles === lastProgressLog) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
console.info(`[AllureReport]: ${uploadProgressMessage}: ${uploadedFiles}/${totalFilesToUpload} files uploaded`);
|
|
147
|
-
lastProgressLog = uploadedFiles;
|
|
148
|
-
nextProgressLogAt = Math.min(totalFilesToUpload, uploadedFiles + progressStep);
|
|
149
|
-
};
|
|
150
|
-
const incrementUploadProgress = (delta = 1) => {
|
|
151
|
-
uploadedFiles = Math.min(totalFilesToUpload, uploadedFiles + delta);
|
|
152
|
-
logUploadProgress();
|
|
153
|
-
};
|
|
146
|
+
const logUploadProgress = progressLogger.log;
|
|
147
|
+
const incrementUploadProgress = progressLogger.increment;
|
|
154
148
|
try {
|
|
155
149
|
logUploadProgress(true);
|
|
156
150
|
await client.createReport({
|
|
@@ -172,6 +166,14 @@ export class AllureReport {
|
|
|
172
166
|
linksByPluginId[report.pluginId] = uploadResult.indexHref;
|
|
173
167
|
}
|
|
174
168
|
}
|
|
169
|
+
if (__classPrivateFieldGet(this, _AllureReport_testResultsRegistryPath, "f")) {
|
|
170
|
+
publishErrorMessage = "Test results registry upload has failed, the report won't be published";
|
|
171
|
+
await client.uploadReport({
|
|
172
|
+
reportUuid: this.reportUuid,
|
|
173
|
+
files: { [TEST_RESULTS_REGISTRY_FILENAME]: __classPrivateFieldGet(this, _AllureReport_testResultsRegistryPath, "f") },
|
|
174
|
+
onProgress: incrementUploadProgress,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
175
177
|
const changedPluginIds = __classPrivateFieldGet(this, _AllureReport_applyPublishLinksToSummaries, "f").call(this, linksByPluginId);
|
|
176
178
|
summariesMutated = changedPluginIds.size > 0;
|
|
177
179
|
if (changedPluginIds.size > 0) {
|
|
@@ -225,6 +227,7 @@ export class AllureReport {
|
|
|
225
227
|
__classPrivateFieldGet(this, _AllureReport_logPublishError, "f").call(this, publishErrorMessage, err);
|
|
226
228
|
}
|
|
227
229
|
finally {
|
|
230
|
+
progressLogger.cancel?.();
|
|
228
231
|
endPublishPerfSpan();
|
|
229
232
|
}
|
|
230
233
|
});
|
|
@@ -238,7 +241,7 @@ export class AllureReport {
|
|
|
238
241
|
}
|
|
239
242
|
try {
|
|
240
243
|
const entries = (await readdir(resultsDirPath, { withFileTypes: true }))
|
|
241
|
-
.filter((dirent) => dirent.isFile())
|
|
244
|
+
.filter((dirent) => dirent.isFile() && !dirent.name.endsWith(".tmp"))
|
|
242
245
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
243
246
|
const limit = pLimit(readConcurrency());
|
|
244
247
|
await Promise.all(entries.map((dirent) => limit(async () => {
|
|
@@ -280,6 +283,11 @@ export class AllureReport {
|
|
|
280
283
|
};
|
|
281
284
|
this.validate = async (params) => {
|
|
282
285
|
const { trs, knownIssues, state, environment } = params;
|
|
286
|
+
const currentKnownIssues = await __classPrivateFieldGet(this, _AllureReport_store, "f").allKnownIssues();
|
|
287
|
+
const effectiveKnownIssues = new Map();
|
|
288
|
+
[...knownIssues, ...currentKnownIssues].forEach((issue) => {
|
|
289
|
+
effectiveKnownIssues.set(issue.historyId, issue);
|
|
290
|
+
});
|
|
283
291
|
const qualityGateEnvironment = environment === undefined
|
|
284
292
|
? undefined
|
|
285
293
|
: (environmentIdentityById(__classPrivateFieldGet(this, _AllureReport_environments, "f"), environment)?.name ??
|
|
@@ -287,7 +295,7 @@ export class AllureReport {
|
|
|
287
295
|
environment);
|
|
288
296
|
return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate({
|
|
289
297
|
trs: trs.filter(Boolean),
|
|
290
|
-
knownIssues,
|
|
298
|
+
knownIssues: [...effectiveKnownIssues.values()],
|
|
291
299
|
state,
|
|
292
300
|
environment: qualityGateEnvironment,
|
|
293
301
|
});
|
|
@@ -384,7 +392,7 @@ export class AllureReport {
|
|
|
384
392
|
const addJsonDumpEntry = async (entryName, value) => {
|
|
385
393
|
await addRequiredDumpEntry(Buffer.from(JSON.stringify(value)), entryName);
|
|
386
394
|
};
|
|
387
|
-
const dumpJsonEntries = ({ testResults, testCases, fixtures, attachments, environments, reportVariables, checkResults = {}, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {},
|
|
395
|
+
const dumpJsonEntries = ({ testResults, testCases, fixtures, attachments, environments, reportVariables, checkResults = {}, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, knownIssues = {}, qualityGateResults = [], testResultIdsIngestOrder = [], }) => [
|
|
388
396
|
[AllureStoreDumpFiles.TestResults, testResults],
|
|
389
397
|
[AllureStoreDumpFiles.TestCases, testCases],
|
|
390
398
|
[AllureStoreDumpFiles.Fixtures, fixtures],
|
|
@@ -392,6 +400,7 @@ export class AllureReport {
|
|
|
392
400
|
[AllureStoreDumpFiles.CheckResults, checkResults],
|
|
393
401
|
[AllureStoreDumpFiles.Environments, environments],
|
|
394
402
|
[AllureStoreDumpFiles.ReportVariables, reportVariables],
|
|
403
|
+
[AllureStoreDumpFiles.KnownIssues, knownIssues],
|
|
395
404
|
[AllureStoreDumpFiles.GlobalAttachments, globalAttachmentIds],
|
|
396
405
|
[AllureStoreDumpFiles.GlobalErrors, globalErrors],
|
|
397
406
|
[AllureStoreDumpFiles.IndexAttachmentsByTestResults, indexAttachmentByTestResult],
|
|
@@ -399,7 +408,6 @@ export class AllureReport {
|
|
|
399
408
|
[AllureStoreDumpFiles.IndexTestResultsByTestCase, indexTestResultByTestCase],
|
|
400
409
|
[AllureStoreDumpFiles.IndexAttachmentsByFixture, indexAttachmentByFixture],
|
|
401
410
|
[AllureStoreDumpFiles.IndexFixturesByTestResult, indexFixturesByTestResult],
|
|
402
|
-
[AllureStoreDumpFiles.IndexKnownByHistoryId, indexKnownByHistoryId],
|
|
403
411
|
[AllureStoreDumpFiles.QualityGateResults, qualityGateResults],
|
|
404
412
|
[AllureStoreDumpFiles.TestResultIngestOrder, testResultIdsIngestOrder],
|
|
405
413
|
];
|
|
@@ -467,7 +475,11 @@ export class AllureReport {
|
|
|
467
475
|
}
|
|
468
476
|
await rename(dumpTempPath, dumpPath);
|
|
469
477
|
};
|
|
470
|
-
this.restoreState = async (dumps) =>
|
|
478
|
+
this.restoreState = async (dumps) => {
|
|
479
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").resetIngestOrder();
|
|
480
|
+
await __classPrivateFieldGet(this, _AllureReport_restoreStateDumps, "f").call(this, dumps);
|
|
481
|
+
};
|
|
482
|
+
_AllureReport_restoreStateDumps.set(this, async (dumps) => measurePerf(PERF_METRIC_NAMES.restoreStateTotal, async () => {
|
|
471
483
|
for (const dump of dumps) {
|
|
472
484
|
await measurePerf(PERF_METRIC_NAMES.restoreStateDump, async () => {
|
|
473
485
|
if (!existsSync(dump)) {
|
|
@@ -504,7 +516,7 @@ export class AllureReport {
|
|
|
504
516
|
await writeFile(nestedDumpPath, await dumpArchive.entryData(entryName));
|
|
505
517
|
nestedDumpPaths.push(nestedDumpPath);
|
|
506
518
|
}
|
|
507
|
-
await this.
|
|
519
|
+
await __classPrivateFieldGet(this, _AllureReport_restoreStateDumps, "f").call(this, nestedDumpPaths);
|
|
508
520
|
return;
|
|
509
521
|
}
|
|
510
522
|
}
|
|
@@ -522,7 +534,7 @@ export class AllureReport {
|
|
|
522
534
|
const indexTestResultsByTestCaseEntry = await requiredEntryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
|
|
523
535
|
const indexAttachmentsByFixtureEntry = await requiredEntryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
|
|
524
536
|
const indexFixturesByTestResultEntry = await requiredEntryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
|
|
525
|
-
const
|
|
537
|
+
const knownIssuesEntry = await requiredEntryData(AllureStoreDumpFiles.KnownIssues);
|
|
526
538
|
const qualityGateResultsEntry = await requiredEntryData(AllureStoreDumpFiles.QualityGateResults);
|
|
527
539
|
const testResultIngestOrderEntry = await optionalEntryData(AllureStoreDumpFiles.TestResultIngestOrder);
|
|
528
540
|
const attachmentsLinks = JSON.parse(attachmentsEntry.toString("utf8"));
|
|
@@ -535,6 +547,7 @@ export class AllureReport {
|
|
|
535
547
|
case AllureStoreDumpFiles.Fixtures:
|
|
536
548
|
case AllureStoreDumpFiles.Environments:
|
|
537
549
|
case AllureStoreDumpFiles.ReportVariables:
|
|
550
|
+
case AllureStoreDumpFiles.KnownIssues:
|
|
538
551
|
case AllureStoreDumpFiles.GlobalAttachments:
|
|
539
552
|
case AllureStoreDumpFiles.GlobalErrors:
|
|
540
553
|
case AllureStoreDumpFiles.IndexAttachmentsByTestResults:
|
|
@@ -542,7 +555,6 @@ export class AllureReport {
|
|
|
542
555
|
case AllureStoreDumpFiles.IndexTestResultsByTestCase:
|
|
543
556
|
case AllureStoreDumpFiles.IndexAttachmentsByFixture:
|
|
544
557
|
case AllureStoreDumpFiles.IndexFixturesByTestResult:
|
|
545
|
-
case AllureStoreDumpFiles.IndexKnownByHistoryId:
|
|
546
558
|
case AllureStoreDumpFiles.QualityGateResults:
|
|
547
559
|
case AllureStoreDumpFiles.TestResultIngestOrder:
|
|
548
560
|
return acc;
|
|
@@ -570,7 +582,7 @@ export class AllureReport {
|
|
|
570
582
|
indexTestResultByTestCase: JSON.parse(indexTestResultsByTestCaseEntry.toString("utf8")),
|
|
571
583
|
indexAttachmentByFixture: JSON.parse(indexAttachmentsByFixtureEntry.toString("utf8")),
|
|
572
584
|
indexFixturesByTestResult: JSON.parse(indexFixturesByTestResultEntry.toString("utf8")),
|
|
573
|
-
|
|
585
|
+
knownIssues: JSON.parse(knownIssuesEntry.toString("utf8")),
|
|
574
586
|
qualityGateResults: JSON.parse(qualityGateResultsEntry.toString("utf8")),
|
|
575
587
|
testResultIdsIngestOrder: testResultIngestOrderEntry
|
|
576
588
|
? JSON.parse(testResultIngestOrderEntry.toString("utf8"))
|
|
@@ -624,7 +636,7 @@ export class AllureReport {
|
|
|
624
636
|
}
|
|
625
637
|
});
|
|
626
638
|
}
|
|
627
|
-
});
|
|
639
|
+
}));
|
|
628
640
|
_AllureReport_getReportsToPublish.set(this, async () => {
|
|
629
641
|
const reports = [];
|
|
630
642
|
for (const { enabled, id, options } of __classPrivateFieldGet(this, _AllureReport_plugins, "f")) {
|
|
@@ -691,6 +703,11 @@ export class AllureReport {
|
|
|
691
703
|
await context.reportFiles.addFile("summary.json", Buffer.from(JSON.stringify(summary)));
|
|
692
704
|
});
|
|
693
705
|
});
|
|
706
|
+
_AllureReport_writeTestResultRegistry.set(this, async () => {
|
|
707
|
+
const testResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestResults({ includeRetries: false });
|
|
708
|
+
const registry = createTestResultRegistry(testResults);
|
|
709
|
+
__classPrivateFieldSet(this, _AllureReport_testResultsRegistryPath, await __classPrivateFieldGet(this, _AllureReport_reportFiles, "f").addFile(TEST_RESULTS_REGISTRY_FILENAME, Buffer.from(JSON.stringify(registry))), "f");
|
|
710
|
+
});
|
|
694
711
|
_AllureReport_generateRootSummary.set(this, async () => {
|
|
695
712
|
const summaries = [...__classPrivateFieldGet(this, _AllureReport_summariesByPluginId, "f").values()].map(clonePluginSummary);
|
|
696
713
|
if (summaries.length > 1) {
|
|
@@ -751,16 +768,21 @@ export class AllureReport {
|
|
|
751
768
|
outputDirFiles = await readdir(__classPrivateFieldGet(this, _AllureReport_output, "f"));
|
|
752
769
|
}
|
|
753
770
|
catch { }
|
|
771
|
+
if (__classPrivateFieldGet(this, _AllureReport_knownIssuesPath, "f")) {
|
|
772
|
+
await writeKnownIssues(__classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_knownIssuesPath, "f"));
|
|
773
|
+
}
|
|
754
774
|
if (outputDirFiles.length === 0) {
|
|
755
775
|
return;
|
|
756
776
|
}
|
|
757
|
-
const
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
if (reportStats.isDirectory() && outputDirectoryEntries.length === 1) {
|
|
777
|
+
const outputEntries = await Promise.all(outputDirFiles.map(async (file) => ({ file, stats: await lstat(join(__classPrivateFieldGet(this, _AllureReport_output, "f"), file)) })));
|
|
778
|
+
const outputDirectoryEntries = outputEntries.filter(({ stats }) => stats.isDirectory());
|
|
779
|
+
if (outputDirectoryEntries.length === 1) {
|
|
780
|
+
const reportPath = join(__classPrivateFieldGet(this, _AllureReport_output, "f"), outputDirectoryEntries[0].file);
|
|
762
781
|
const reportContent = await readdir(reportPath);
|
|
763
782
|
for (const entry of reportContent) {
|
|
783
|
+
if (entry === TEST_RESULTS_REGISTRY_FILENAME) {
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
764
786
|
const currentFilePath = join(reportPath, entry);
|
|
765
787
|
const newFilePath = resolve(dirname(currentFilePath), "..", entry);
|
|
766
788
|
await rename(currentFilePath, newFilePath);
|
|
@@ -773,7 +795,7 @@ export class AllureReport {
|
|
|
773
795
|
}
|
|
774
796
|
catch { }
|
|
775
797
|
}
|
|
776
|
-
if (__classPrivateFieldGet(this, _AllureReport_history, "f")) {
|
|
798
|
+
if (__classPrivateFieldGet(this, _AllureReport_history, "f") && __classPrivateFieldGet(this, _AllureReport_appendHistory, "f")) {
|
|
777
799
|
try {
|
|
778
800
|
await __classPrivateFieldGet(this, _AllureReport_store, "f").appendHistory(__classPrivateFieldGet(this, _AllureReport_historyDataPoint, "f"));
|
|
779
801
|
}
|
|
@@ -870,7 +892,7 @@ export class AllureReport {
|
|
|
870
892
|
}
|
|
871
893
|
}
|
|
872
894
|
});
|
|
873
|
-
const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, historyLimit, defaultLabels = {}, variables = {}, environment, allowedEnvironments, environments, output, hideLabels, qualityGate, dump, categories, allureService, globalAttachments, } = opts;
|
|
895
|
+
const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, knownIssues, knownIssuesPath, reportFiles, realTime, historyPath, historyLimit, appendHistory, defaultLabels = {}, variables = {}, environment, allowedEnvironments, environments, output, hideLabels, qualityGate, dump, categories, allureService, globalAttachments, } = opts;
|
|
874
896
|
const allureServiceAccessToken = allureService?.accessToken;
|
|
875
897
|
if (allureServiceAccessToken) {
|
|
876
898
|
const allureServiceClientConfig = {
|
|
@@ -894,6 +916,8 @@ export class AllureReport {
|
|
|
894
916
|
__classPrivateFieldSet(this, _AllureReport_hideLabels, hideLabels, "f");
|
|
895
917
|
__classPrivateFieldSet(this, _AllureReport_environments, environments ?? {}, "f");
|
|
896
918
|
__classPrivateFieldSet(this, _AllureReport_globalAttachments, globalAttachments, "f");
|
|
919
|
+
__classPrivateFieldSet(this, _AllureReport_appendHistory, appendHistory ?? true, "f");
|
|
920
|
+
__classPrivateFieldSet(this, _AllureReport_knownIssuesPath, knownIssuesPath, "f");
|
|
897
921
|
if (qualityGate) {
|
|
898
922
|
__classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
|
|
899
923
|
}
|
|
@@ -918,6 +942,7 @@ export class AllureReport {
|
|
|
918
942
|
environmentsConfig: environments,
|
|
919
943
|
history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
|
|
920
944
|
known,
|
|
945
|
+
knownIssuesConfig: knownIssues,
|
|
921
946
|
defaultLabels,
|
|
922
947
|
environment,
|
|
923
948
|
allowedEnvironments,
|
|
@@ -940,6 +965,6 @@ export class AllureReport {
|
|
|
940
965
|
return __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").dispatcher;
|
|
941
966
|
}
|
|
942
967
|
}
|
|
943
|
-
_AllureReport_ci = new WeakMap(), _AllureReport_store = new WeakMap(), _AllureReport_readers = new WeakMap(), _AllureReport_plugins = new WeakMap(), _AllureReport_reportFiles = new WeakMap(), _AllureReport_realtimeChannel = new WeakMap(), _AllureReport_realtimeUpdateScheduler = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_hideLabels = new WeakMap(), _AllureReport_output = new WeakMap(), _AllureReport_history = new WeakMap(), _AllureReport_allureServiceClient = new WeakMap(), _AllureReport_qualityGate = new WeakMap(), _AllureReport_dump = new WeakMap(), _AllureReport_categories = new WeakMap(), _AllureReport_environments = new WeakMap(), _AllureReport_globalAttachments = new WeakMap(), _AllureReport_dumpTempDirs = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_executionStage = new WeakMap(), _AllureReport_historyDataPoint = new WeakMap(), _AllureReport_summaryPath = new WeakMap(), _AllureReport_summariesByPluginId = new WeakMap(), _AllureReport_publishedRemoteHrefs = new WeakMap(), _AllureReport_published = new WeakMap(), _AllureReport_endGeneratePerfSpan = new WeakMap(), _AllureReport_publish = new WeakMap(), _AllureReport_runRealtimeUpdate = new WeakMap(), _AllureReport_getReportsToPublish = new WeakMap(), _AllureReport_cleanupFailedRemoteReport = new WeakMap(), _AllureReport_logPublishError = new WeakMap(), _AllureReport_applyPublishLinksToSummaries = new WeakMap(), _AllureReport_cloneSummariesByPluginId = new WeakMap(), _AllureReport_writeSummaryFiles = new WeakMap(), _AllureReport_generateRootSummary = new WeakMap(), _AllureReport_finishGeneratePerfSpan = new WeakMap(), _AllureReport_finishPerfMetrics = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
|
|
968
|
+
_AllureReport_ci = new WeakMap(), _AllureReport_store = new WeakMap(), _AllureReport_readers = new WeakMap(), _AllureReport_plugins = new WeakMap(), _AllureReport_reportFiles = new WeakMap(), _AllureReport_realtimeChannel = new WeakMap(), _AllureReport_realtimeUpdateScheduler = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_hideLabels = new WeakMap(), _AllureReport_output = new WeakMap(), _AllureReport_history = new WeakMap(), _AllureReport_appendHistory = new WeakMap(), _AllureReport_allureServiceClient = new WeakMap(), _AllureReport_qualityGate = new WeakMap(), _AllureReport_dump = new WeakMap(), _AllureReport_categories = new WeakMap(), _AllureReport_environments = new WeakMap(), _AllureReport_globalAttachments = new WeakMap(), _AllureReport_knownIssuesPath = new WeakMap(), _AllureReport_dumpTempDirs = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_executionStage = new WeakMap(), _AllureReport_historyDataPoint = new WeakMap(), _AllureReport_summaryPath = new WeakMap(), _AllureReport_testResultsRegistryPath = new WeakMap(), _AllureReport_summariesByPluginId = new WeakMap(), _AllureReport_publishedRemoteHrefs = new WeakMap(), _AllureReport_published = new WeakMap(), _AllureReport_endGeneratePerfSpan = new WeakMap(), _AllureReport_publish = new WeakMap(), _AllureReport_runRealtimeUpdate = new WeakMap(), _AllureReport_restoreStateDumps = new WeakMap(), _AllureReport_getReportsToPublish = new WeakMap(), _AllureReport_cleanupFailedRemoteReport = new WeakMap(), _AllureReport_logPublishError = new WeakMap(), _AllureReport_applyPublishLinksToSummaries = new WeakMap(), _AllureReport_cloneSummariesByPluginId = new WeakMap(), _AllureReport_writeSummaryFiles = new WeakMap(), _AllureReport_writeTestResultRegistry = new WeakMap(), _AllureReport_generateRootSummary = new WeakMap(), _AllureReport_finishGeneratePerfSpan = new WeakMap(), _AllureReport_finishPerfMetrics = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
|
|
944
969
|
return init ? new DefaultPluginState({}) : __classPrivateFieldGet(this, _AllureReport_state, "f")?.[id];
|
|
945
970
|
};
|
package/dist/store/convert.js
CHANGED
|
@@ -236,7 +236,7 @@ const convertLink = (link) => ({
|
|
|
236
236
|
type: link.type,
|
|
237
237
|
});
|
|
238
238
|
const calculateTestId = (raw) => {
|
|
239
|
-
const maybeAllureId = raw.labels?.find((label) => label.name === "ALLURE_ID" || label.name === "AS_ID")?.value;
|
|
239
|
+
const maybeAllureId = raw.labels?.find((label) => (label.name === "ALLURE_ID" || label.name === "AS_ID") && label.value !== "-1")?.value;
|
|
240
240
|
if (maybeAllureId) {
|
|
241
241
|
return [md5(`ALLURE_ID=${maybeAllureId}`), maybeAllureId];
|
|
242
242
|
}
|
|
@@ -4,6 +4,7 @@ export declare const calculateRetryHash: (testCaseId: string | undefined, parame
|
|
|
4
4
|
export declare class RetrySubstore {
|
|
5
5
|
#private;
|
|
6
6
|
recordIngestOrder(testResultId: string): void;
|
|
7
|
+
resetIngestOrder(): void;
|
|
7
8
|
restoreIngestOrder(restoredIds: string[] | undefined, hasTestResult: (testResultId: string) => boolean): void;
|
|
8
9
|
ingestOrderIdsForDump(): string[];
|
|
9
10
|
upsert(testResult: TestResult): void;
|
|
@@ -31,8 +31,10 @@ export class RetrySubstore {
|
|
|
31
31
|
}
|
|
32
32
|
__classPrivateFieldGet(this, _RetrySubstore_testResultIngestIndexById, "f").set(testResultId, __classPrivateFieldGet(this, _RetrySubstore_testResultIngestIndexById, "f").size);
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
resetIngestOrder() {
|
|
35
35
|
__classPrivateFieldGet(this, _RetrySubstore_testResultIngestIndexById, "f").clear();
|
|
36
|
+
}
|
|
37
|
+
restoreIngestOrder(restoredIds, hasTestResult) {
|
|
36
38
|
for (const id of restoredIds ?? []) {
|
|
37
39
|
if (!hasTestResult(id) || __classPrivateFieldGet(this, _RetrySubstore_testResultIngestIndexById, "f").has(id)) {
|
|
38
40
|
continue;
|
package/dist/store/store.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { type AllureCheckResult, type AllureHistory, type AttachmentLink, type DefaultLabelsConfig, type EnvironmentIdentity, type EnvironmentsConfig, type HistoryDataPoint, type HistoryTestResult, type KnownTestFailure, type ReportVariables, type Statistic, type TestCase, type TestEnvGroup, type TestError, type TestFixtureResult, type TestResult } from "@allurereport/core-api";
|
|
2
|
-
import { type AllureStore, type AllureStoreDump, type ExitCode, type
|
|
1
|
+
import { type AllureCheckResult, type AllureHistory, type AttachmentLink, type DefaultLabelsConfig, type EnvironmentIdentity, type EnvironmentsConfig, type GlobalAttachmentLink, type HistoryDataPoint, type HistoryTestResult, type KnownIssuesConfig, type KnownTestFailure, type ReportVariables, type Statistic, type TestCase, type TestEnvGroup, type TestError, type TestFixtureResult, type TestResult } from "@allurereport/core-api";
|
|
2
|
+
import { type AllureStore, type AllureStoreDump, type ExitCode, type PluginGlobalError, type QualityGateValidationResult, type RealtimeEventsDispatcher, type RealtimeSubscriber, type ResultFile, type TestResultFilter } from "@allurereport/plugin-api";
|
|
3
3
|
import type { RawFixtureResult, RawGlobals, RawMetadata, RawTestResult, ReaderContext, ResultsVisitor } from "@allurereport/reader-api";
|
|
4
4
|
export declare const mapToObject: <K extends string | number | symbol, T = any>(map: Map<K, T>) => Record<K, T>;
|
|
5
5
|
export declare const updateMapWithRecord: <K extends string | number | symbol, T = any>(map: Map<K, T>, record: Record<K, T>) => Map<K, T>;
|
|
6
6
|
export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
|
|
7
7
|
#private;
|
|
8
|
+
readonly known: Map<string, KnownTestFailure>;
|
|
8
9
|
readonly indexTestResultByTestCase: Map<string, TestResult[]>;
|
|
9
10
|
readonly indexTestResultByEnvironmentId: Map<string, TestResult[]>;
|
|
10
11
|
readonly indexTestResultByHistoryId: Map<string, TestResult[]>;
|
|
11
12
|
readonly indexAttachmentByTestResult: Map<string, AttachmentLink[]>;
|
|
12
13
|
readonly indexAttachmentByFixture: Map<string, AttachmentLink[]>;
|
|
13
14
|
readonly indexFixturesByTestResult: Map<string, TestFixtureResult[]>;
|
|
14
|
-
readonly indexKnownByHistoryId: Map<string, KnownTestFailure[]>;
|
|
15
15
|
constructor(params?: {
|
|
16
16
|
history?: AllureHistory;
|
|
17
17
|
known?: KnownTestFailure[];
|
|
18
|
+
knownIssuesConfig?: KnownIssuesConfig;
|
|
18
19
|
realtimeDispatcher?: RealtimeEventsDispatcher;
|
|
19
20
|
realtimeSubscriber?: RealtimeSubscriber;
|
|
20
21
|
defaultLabels?: DefaultLabelsConfig;
|
|
@@ -33,8 +34,8 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
|
|
|
33
34
|
globalExitCode(): Promise<ExitCode | undefined>;
|
|
34
35
|
allGlobalErrors(): Promise<TestError[]>;
|
|
35
36
|
allGlobalErrorsByEnv(): Promise<Record<string, PluginGlobalError[]>>;
|
|
36
|
-
allGlobalAttachments(): Promise<
|
|
37
|
-
allGlobalAttachmentsByEnv(): Promise<Record<string,
|
|
37
|
+
allGlobalAttachments(): Promise<GlobalAttachmentLink[]>;
|
|
38
|
+
allGlobalAttachmentsByEnv(): Promise<Record<string, GlobalAttachmentLink[]>>;
|
|
38
39
|
visitCheckResult(result: AllureCheckResult): Promise<void>;
|
|
39
40
|
visitTestResult(raw: RawTestResult, context: ReaderContext): Promise<void>;
|
|
40
41
|
visitTestFixtureResult(result: RawFixtureResult, context: ReaderContext): Promise<void>;
|
|
@@ -68,6 +69,7 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
|
|
|
68
69
|
attachmentsByTrId(trId: string): Promise<AttachmentLink[]>;
|
|
69
70
|
retriesByTr(tr?: TestResult): Promise<TestResult[]>;
|
|
70
71
|
retriesByTrId(trId: string): Promise<TestResult[]>;
|
|
72
|
+
resetIngestOrder(): void;
|
|
71
73
|
historyByTr(tr: TestResult): Promise<HistoryTestResult[] | undefined>;
|
|
72
74
|
historyByTrId(trId: string): Promise<HistoryTestResult[] | undefined>;
|
|
73
75
|
fixturesByTrId(trId: string): Promise<TestFixtureResult[]>;
|
|
@@ -78,6 +80,7 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
|
|
|
78
80
|
retriesByTrId: Map<string, TestResult[]>;
|
|
79
81
|
}>;
|
|
80
82
|
failedTestResults(): Promise<TestResult[]>;
|
|
83
|
+
blockingFailedTestResults(): Promise<TestResult[]>;
|
|
81
84
|
unknownFailedTestResults(): Promise<TestResult[]>;
|
|
82
85
|
testResultsByLabel(labelName: string): Promise<{
|
|
83
86
|
_: TestResult[];
|
package/dist/store/store.js
CHANGED
|
@@ -9,10 +9,11 @@ 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 _DefaultAllureStore_instances, _DefaultAllureStore_testResults, _DefaultAllureStore_environmentDisplayNames, _DefaultAllureStore_environmentNameToId, _DefaultAllureStore_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history,
|
|
12
|
+
var _DefaultAllureStore_instances, _DefaultAllureStore_testResults, _DefaultAllureStore_environmentDisplayNames, _DefaultAllureStore_environmentNameToId, _DefaultAllureStore_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history, _DefaultAllureStore_knownIssuesConfig, _DefaultAllureStore_fixtures, _DefaultAllureStore_defaultLabels, _DefaultAllureStore_environment, _DefaultAllureStore_environmentsConfig, _DefaultAllureStore_reportVariables, _DefaultAllureStore_realtimeDispatcher, _DefaultAllureStore_realtimeSubscriber, _DefaultAllureStore_allowedEnvironmentIds, _DefaultAllureStore_retrySubstore, _DefaultAllureStore_testResultIdsByEnvironmentId, _DefaultAllureStore_cachedEnvironmentEntries, _DefaultAllureStore_globalAttachmentIds, _DefaultAllureStore_globalAttachmentIdsByEnv, _DefaultAllureStore_globalErrors, _DefaultAllureStore_globalErrorsByEnv, _DefaultAllureStore_globalExitCode, _DefaultAllureStore_checkResultsById, _DefaultAllureStore_qualityGateResults, _DefaultAllureStore_historyPoints, _DefaultAllureStore_environments, _DefaultAllureStore_historyIdMatches, _DefaultAllureStore_mergeEnvironmentIdentity, _DefaultAllureStore_environmentIdForLookup, _DefaultAllureStore_addEnvironments, _DefaultAllureStore_environmentIdByName, _DefaultAllureStore_setTestResultEnvironmentId, _DefaultAllureStore_assertAllowedEnvironmentId, _DefaultAllureStore_assertAllowedStoredEnvironment, _DefaultAllureStore_environmentIdByTestResult, _DefaultAllureStore_assignRetryHash, _DefaultAllureStore_setKnownIssue, _DefaultAllureStore_classifyKnownIssue, _DefaultAllureStore_rebuildRetrySubstore, _DefaultAllureStore_resolveGlobalEnvironmentIdentity, _DefaultAllureStore_globalAttachmentId, _DefaultAllureStore_indexGlobalError, _DefaultAllureStore_addGlobalError, _DefaultAllureStore_indexGlobalAttachment, _DefaultAllureStore_addGlobalAttachment, _DefaultAllureStore_restoreAttachmentContent, _DefaultAllureStore_relinkRestoredAttachmentSteps, _DefaultAllureStore_retriesByTr, _DefaultAllureStore_historyByTr;
|
|
13
13
|
import { extname } from "node:path";
|
|
14
14
|
import { DEFAULT_ENVIRONMENT, DEFAULT_ENVIRONMENT_IDENTITY, compareBy, createDictionary, getHistoryIdCandidates, getWorstStatus, normalizeHistoryDataPoint, ordinal, reverse, selectHistoryTestResults, validateEnvironmentId, validateEnvironmentName, } from "@allurereport/core-api";
|
|
15
15
|
import { md5, } from "@allurereport/plugin-api";
|
|
16
|
+
import { getKnownIssueByRules } from "../known.js";
|
|
16
17
|
import { environmentIdentityById, normalizeEnvironmentDescriptorMap, resolveEnvironmentIdentity, resolveStoredEnvironmentIdentity, validateAllowedEnvironmentId, } from "../utils/environment.js";
|
|
17
18
|
import { isFlaky } from "../utils/flaky.js";
|
|
18
19
|
import { getStatusTransition } from "../utils/new.js";
|
|
@@ -63,7 +64,8 @@ export class DefaultAllureStore {
|
|
|
63
64
|
_DefaultAllureStore_testCases.set(this, void 0);
|
|
64
65
|
_DefaultAllureStore_metadata.set(this, void 0);
|
|
65
66
|
_DefaultAllureStore_history.set(this, void 0);
|
|
66
|
-
|
|
67
|
+
_DefaultAllureStore_knownIssuesConfig.set(this, void 0);
|
|
68
|
+
this.known = new Map();
|
|
67
69
|
_DefaultAllureStore_fixtures.set(this, void 0);
|
|
68
70
|
_DefaultAllureStore_defaultLabels.set(this, {});
|
|
69
71
|
_DefaultAllureStore_environment.set(this, void 0);
|
|
@@ -81,7 +83,6 @@ export class DefaultAllureStore {
|
|
|
81
83
|
this.indexAttachmentByTestResult = new Map();
|
|
82
84
|
this.indexAttachmentByFixture = new Map();
|
|
83
85
|
this.indexFixturesByTestResult = new Map();
|
|
84
|
-
this.indexKnownByHistoryId = new Map();
|
|
85
86
|
_DefaultAllureStore_globalAttachmentIds.set(this, []);
|
|
86
87
|
_DefaultAllureStore_globalAttachmentIdsByEnv.set(this, new Map());
|
|
87
88
|
_DefaultAllureStore_globalErrors.set(this, []);
|
|
@@ -91,7 +92,7 @@ export class DefaultAllureStore {
|
|
|
91
92
|
_DefaultAllureStore_qualityGateResults.set(this, []);
|
|
92
93
|
_DefaultAllureStore_historyPoints.set(this, []);
|
|
93
94
|
_DefaultAllureStore_environments.set(this, []);
|
|
94
|
-
const { history, known = [], realtimeDispatcher, realtimeSubscriber, defaultLabels = {}, environment, allowedEnvironments, environmentsConfig = {}, reportVariables = {}, } = params ?? {};
|
|
95
|
+
const { history, known = [], knownIssuesConfig, realtimeDispatcher, realtimeSubscriber, defaultLabels = {}, environment, allowedEnvironments, environmentsConfig = {}, reportVariables = {}, } = params ?? {};
|
|
95
96
|
const errors = [];
|
|
96
97
|
const { normalized: normalizedEnvironmentsConfig, identities, errors: configErrors, } = normalizeEnvironmentDescriptorMap(environmentsConfig, "environmentsConfig");
|
|
97
98
|
errors.push(...configErrors);
|
|
@@ -116,8 +117,8 @@ export class DefaultAllureStore {
|
|
|
116
117
|
__classPrivateFieldSet(this, _DefaultAllureStore_metadata, new Map(), "f");
|
|
117
118
|
__classPrivateFieldSet(this, _DefaultAllureStore_fixtures, new Map(), "f");
|
|
118
119
|
__classPrivateFieldSet(this, _DefaultAllureStore_history, history, "f");
|
|
119
|
-
__classPrivateFieldSet(this,
|
|
120
|
-
|
|
120
|
+
__classPrivateFieldSet(this, _DefaultAllureStore_knownIssuesConfig, knownIssuesConfig, "f");
|
|
121
|
+
known.forEach((ktf) => this.known.set(ktf.historyId, ktf));
|
|
121
122
|
__classPrivateFieldSet(this, _DefaultAllureStore_realtimeDispatcher, realtimeDispatcher, "f");
|
|
122
123
|
__classPrivateFieldSet(this, _DefaultAllureStore_realtimeSubscriber, realtimeSubscriber, "f");
|
|
123
124
|
__classPrivateFieldSet(this, _DefaultAllureStore_defaultLabels, defaultLabels, "f");
|
|
@@ -153,13 +154,17 @@ export class DefaultAllureStore {
|
|
|
153
154
|
__classPrivateFieldSet(this, _DefaultAllureStore_globalExitCode, exitCode, "f");
|
|
154
155
|
});
|
|
155
156
|
__classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalError((error) => {
|
|
156
|
-
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m",
|
|
157
|
+
const resolvedEnvironment = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_resolveGlobalEnvironmentIdentity).call(this, error.environment);
|
|
158
|
+
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addGlobalError).call(this, {
|
|
159
|
+
...error,
|
|
160
|
+
environment: resolvedEnvironment.id,
|
|
161
|
+
});
|
|
157
162
|
});
|
|
158
163
|
__classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalAttachment(({ attachment, fileName, environment }) => {
|
|
159
164
|
const originalFileName = attachment.getOriginalFileName();
|
|
160
165
|
const resolvedEnvironment = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_resolveGlobalEnvironmentIdentity).call(this, environment);
|
|
161
166
|
const attachmentLink = {
|
|
162
|
-
id: __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_globalAttachmentId).call(this, originalFileName, resolvedEnvironment
|
|
167
|
+
id: __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_globalAttachmentId).call(this, originalFileName, resolvedEnvironment.id),
|
|
163
168
|
name: fileName || originalFileName,
|
|
164
169
|
missed: false,
|
|
165
170
|
used: true,
|
|
@@ -167,7 +172,7 @@ export class DefaultAllureStore {
|
|
|
167
172
|
contentType: attachment.getContentType(),
|
|
168
173
|
contentLength: attachment.getContentLength(),
|
|
169
174
|
originalFileName,
|
|
170
|
-
environment: resolvedEnvironment
|
|
175
|
+
environment: resolvedEnvironment.id,
|
|
171
176
|
};
|
|
172
177
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addGlobalAttachment).call(this, attachmentLink, attachment);
|
|
173
178
|
});
|
|
@@ -325,6 +330,7 @@ export class DefaultAllureStore {
|
|
|
325
330
|
testResult.transition = getStatusTransition(testResult, trHistory);
|
|
326
331
|
testResult.flaky = isFlaky(testResult, trHistory);
|
|
327
332
|
}
|
|
333
|
+
testResult.known = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_classifyKnownIssue).call(this, testResult, environmentIdentity.id);
|
|
328
334
|
__classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f").set(testResult.id, testResult);
|
|
329
335
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_setTestResultEnvironmentId).call(this, testResult, environmentIdentity.id);
|
|
330
336
|
__classPrivateFieldGet(this, _DefaultAllureStore_retrySubstore, "f").recordIngestOrder(testResult.id);
|
|
@@ -404,7 +410,7 @@ export class DefaultAllureStore {
|
|
|
404
410
|
const linkedAttachment = __classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f").get(md5(originalFileName));
|
|
405
411
|
const attachmentContent = __classPrivateFieldGet(this, _DefaultAllureStore_attachmentContents, "f").get(md5(originalFileName));
|
|
406
412
|
const attachmentLink = {
|
|
407
|
-
id: __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_globalAttachmentId).call(this, originalFileName, resolvedEnvironment
|
|
413
|
+
id: __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_globalAttachmentId).call(this, originalFileName, resolvedEnvironment.id),
|
|
408
414
|
name: attachment?.name || originalFileName,
|
|
409
415
|
originalFileName,
|
|
410
416
|
ext: extname(originalFileName),
|
|
@@ -412,7 +418,7 @@ export class DefaultAllureStore {
|
|
|
412
418
|
missed: !attachmentContent,
|
|
413
419
|
contentType: attachment?.contentType ?? linkedAttachment?.contentType,
|
|
414
420
|
contentLength: linkedAttachment?.contentLength,
|
|
415
|
-
environment: resolvedEnvironment
|
|
421
|
+
environment: resolvedEnvironment.name,
|
|
416
422
|
};
|
|
417
423
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addGlobalAttachment).call(this, attachmentLink, attachmentContent);
|
|
418
424
|
});
|
|
@@ -507,7 +513,7 @@ export class DefaultAllureStore {
|
|
|
507
513
|
}, []);
|
|
508
514
|
}
|
|
509
515
|
async allKnownIssues() {
|
|
510
|
-
return
|
|
516
|
+
return [...this.known.values()].flat();
|
|
511
517
|
}
|
|
512
518
|
async allNewTestResults(filter, history) {
|
|
513
519
|
if (!__classPrivateFieldGet(this, _DefaultAllureStore_history, "f") && !history) {
|
|
@@ -576,6 +582,9 @@ export class DefaultAllureStore {
|
|
|
576
582
|
const tr = __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f").get(trId);
|
|
577
583
|
return __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_retriesByTr).call(this, tr);
|
|
578
584
|
}
|
|
585
|
+
resetIngestOrder() {
|
|
586
|
+
__classPrivateFieldGet(this, _DefaultAllureStore_retrySubstore, "f").resetIngestOrder();
|
|
587
|
+
}
|
|
579
588
|
async historyByTr(tr) {
|
|
580
589
|
return __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_historyByTr).call(this, tr);
|
|
581
590
|
}
|
|
@@ -620,16 +629,12 @@ export class DefaultAllureStore {
|
|
|
620
629
|
}
|
|
621
630
|
return failedTrs;
|
|
622
631
|
}
|
|
623
|
-
async
|
|
632
|
+
async blockingFailedTestResults() {
|
|
624
633
|
const failedTestResults = await this.failedTestResults();
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
return failedTestResults.filter((tr) => {
|
|
630
|
-
const historyIdCandidates = getHistoryIdCandidates(tr);
|
|
631
|
-
return (historyIdCandidates.length > 0 && historyIdCandidates.every((historyId) => !knownHistoryIds.has(historyId)));
|
|
632
|
-
});
|
|
634
|
+
return failedTestResults.filter((tr) => !tr.known);
|
|
635
|
+
}
|
|
636
|
+
async unknownFailedTestResults() {
|
|
637
|
+
return this.blockingFailedTestResults();
|
|
633
638
|
}
|
|
634
639
|
async testResultsByLabel(labelName) {
|
|
635
640
|
const results = createDictionary();
|
|
@@ -789,7 +794,7 @@ export class DefaultAllureStore {
|
|
|
789
794
|
indexTestResultByTestCase: {},
|
|
790
795
|
indexAttachmentByFixture: {},
|
|
791
796
|
indexFixturesByTestResult: {},
|
|
792
|
-
|
|
797
|
+
knownIssues: {},
|
|
793
798
|
qualityGateResults: __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f"),
|
|
794
799
|
testResultIdsIngestOrder: __classPrivateFieldGet(this, _DefaultAllureStore_retrySubstore, "f").ingestOrderIdsForDump(),
|
|
795
800
|
};
|
|
@@ -808,13 +813,13 @@ export class DefaultAllureStore {
|
|
|
808
813
|
this.indexFixturesByTestResult.forEach((fixtures, trId) => {
|
|
809
814
|
storeDump.indexFixturesByTestResult[trId] = fixtures.map((f) => f.id);
|
|
810
815
|
});
|
|
811
|
-
this.
|
|
812
|
-
storeDump.
|
|
816
|
+
this.known.forEach((known, historyId) => {
|
|
817
|
+
storeDump.knownIssues[historyId] = known;
|
|
813
818
|
});
|
|
814
819
|
return storeDump;
|
|
815
820
|
}
|
|
816
821
|
async restoreState(stateDump, attachmentsContents = {}) {
|
|
817
|
-
const { testResults, attachments, testCases, fixtures, reportVariables, environments, globalAttachmentIds = [], globalErrors = [], checkResults, indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {},
|
|
822
|
+
const { testResults, attachments, testCases, fixtures, reportVariables, environments, globalAttachmentIds = [], globalErrors = [], checkResults, indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, knownIssues = {}, qualityGateResults = [], testResultIdsIngestOrder = [], } = stateDump;
|
|
818
823
|
const storedEnvironmentAliases = environments.flatMap((environmentValue) => {
|
|
819
824
|
if (typeof environmentValue === "string") {
|
|
820
825
|
return [{ id: environmentValue, name: environmentValue }];
|
|
@@ -864,6 +869,7 @@ export class DefaultAllureStore {
|
|
|
864
869
|
envNameToId.set(id, id);
|
|
865
870
|
}
|
|
866
871
|
Object.values(testResults).forEach((testResult) => {
|
|
872
|
+
testResult.known ?? (testResult.known = false);
|
|
867
873
|
__classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f").set(testResult.id, testResult);
|
|
868
874
|
const storedEnvKey = typeof testResult.environment === "string" ? testResult.environment : undefined;
|
|
869
875
|
const envId = (storedEnvKey ? envNameToId.get(storedEnvKey) : undefined) ?? __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_environmentIdByTestResult).call(this, testResult);
|
|
@@ -879,6 +885,7 @@ export class DefaultAllureStore {
|
|
|
879
885
|
updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f"), attachments);
|
|
880
886
|
updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_testCases, "f"), testCases);
|
|
881
887
|
updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_fixtures, "f"), fixtures);
|
|
888
|
+
updateMapWithRecord(this.known, knownIssues);
|
|
882
889
|
Object.entries(attachmentsContents).forEach(([id, content]) => {
|
|
883
890
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_restoreAttachmentContent).call(this, id, content);
|
|
884
891
|
});
|
|
@@ -967,15 +974,10 @@ export class DefaultAllureStore {
|
|
|
967
974
|
}
|
|
968
975
|
existingFixtures.push(...fxs);
|
|
969
976
|
});
|
|
970
|
-
Object.entries(indexKnownByHistoryId).forEach(([historyId, knownFailures]) => {
|
|
971
|
-
const existingKnown = this.indexKnownByHistoryId.get(historyId);
|
|
972
|
-
if (!existingKnown) {
|
|
973
|
-
this.indexKnownByHistoryId.set(historyId, knownFailures);
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
976
|
-
existingKnown.push(...knownFailures);
|
|
977
|
-
});
|
|
978
977
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_rebuildRetrySubstore).call(this);
|
|
978
|
+
for (const testResult of __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f").values()) {
|
|
979
|
+
testResult.known = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_classifyKnownIssue).call(this, testResult, __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_environmentIdByTestResult).call(this, testResult));
|
|
980
|
+
}
|
|
979
981
|
qualityGateResults.forEach((result, index) => {
|
|
980
982
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_assertAllowedStoredEnvironment).call(this, {
|
|
981
983
|
environment: result.environment,
|
|
@@ -987,7 +989,9 @@ export class DefaultAllureStore {
|
|
|
987
989
|
});
|
|
988
990
|
}
|
|
989
991
|
}
|
|
990
|
-
_DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_environmentDisplayNames = new WeakMap(), _DefaultAllureStore_environmentNameToId = new WeakMap(), _DefaultAllureStore_attachments = new WeakMap(), _DefaultAllureStore_attachmentContents = new WeakMap(), _DefaultAllureStore_testCases = new WeakMap(), _DefaultAllureStore_metadata = new WeakMap(), _DefaultAllureStore_history = new WeakMap(),
|
|
992
|
+
_DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_environmentDisplayNames = new WeakMap(), _DefaultAllureStore_environmentNameToId = new WeakMap(), _DefaultAllureStore_attachments = new WeakMap(), _DefaultAllureStore_attachmentContents = new WeakMap(), _DefaultAllureStore_testCases = new WeakMap(), _DefaultAllureStore_metadata = new WeakMap(), _DefaultAllureStore_history = new WeakMap(), _DefaultAllureStore_knownIssuesConfig = new WeakMap(), _DefaultAllureStore_fixtures = new WeakMap(), _DefaultAllureStore_defaultLabels = new WeakMap(), _DefaultAllureStore_environment = new WeakMap(), _DefaultAllureStore_environmentsConfig = new WeakMap(), _DefaultAllureStore_reportVariables = new WeakMap(), _DefaultAllureStore_realtimeDispatcher = new WeakMap(), _DefaultAllureStore_realtimeSubscriber = new WeakMap(), _DefaultAllureStore_allowedEnvironmentIds = new WeakMap(), _DefaultAllureStore_retrySubstore = new WeakMap(), _DefaultAllureStore_testResultIdsByEnvironmentId = new WeakMap(), _DefaultAllureStore_cachedEnvironmentEntries = new WeakMap(), _DefaultAllureStore_globalAttachmentIds = new WeakMap(), _DefaultAllureStore_globalAttachmentIdsByEnv = new WeakMap(), _DefaultAllureStore_globalErrors = new WeakMap(), _DefaultAllureStore_globalErrorsByEnv = new WeakMap(), _DefaultAllureStore_globalExitCode = new WeakMap(), _DefaultAllureStore_checkResultsById = new WeakMap(), _DefaultAllureStore_qualityGateResults = new WeakMap(), _DefaultAllureStore_historyPoints = new WeakMap(), _DefaultAllureStore_environments = new WeakMap(), _DefaultAllureStore_instances = new WeakSet(), _DefaultAllureStore_historyIdMatches = function _DefaultAllureStore_historyIdMatches(historyIdCandidates, indexByHistoryId) {
|
|
993
|
+
return historyIdCandidates.find((historyId) => indexByHistoryId.has(historyId));
|
|
994
|
+
}, _DefaultAllureStore_mergeEnvironmentIdentity = function _DefaultAllureStore_mergeEnvironmentIdentity(existingEnvironment, incomingEnvironment) {
|
|
991
995
|
const configuredEnvironment = environmentIdentityById(__classPrivateFieldGet(this, _DefaultAllureStore_environmentsConfig, "f"), incomingEnvironment.id);
|
|
992
996
|
if (configuredEnvironment) {
|
|
993
997
|
return configuredEnvironment;
|
|
@@ -1089,6 +1093,23 @@ _DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_environment
|
|
|
1089
1093
|
const environmentId = options?.environmentId ?? __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_environmentIdByTestResult).call(this, testResult);
|
|
1090
1094
|
const parametersHash = options?.parametersHash ?? calculateParametersHash(testResult.parameters);
|
|
1091
1095
|
testResult.retryHash = calculateRetryHash(testResult.testCase?.id, parametersHash, environmentId);
|
|
1096
|
+
}, _DefaultAllureStore_setKnownIssue = function _DefaultAllureStore_setKnownIssue(knownIssue) {
|
|
1097
|
+
this.known.set(knownIssue.historyId, knownIssue);
|
|
1098
|
+
}, _DefaultAllureStore_classifyKnownIssue = function _DefaultAllureStore_classifyKnownIssue(testResult, environmentId) {
|
|
1099
|
+
if (testResult.status !== "failed" && testResult.status !== "broken") {
|
|
1100
|
+
return false;
|
|
1101
|
+
}
|
|
1102
|
+
const historyIdCandidates = getHistoryIdCandidates(testResult);
|
|
1103
|
+
if (historyIdCandidates.length === 0) {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
const ruleKnownIssue = getKnownIssueByRules(testResult, __classPrivateFieldGet(this, _DefaultAllureStore_knownIssuesConfig, "f"), environmentId);
|
|
1107
|
+
if (ruleKnownIssue) {
|
|
1108
|
+
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_setKnownIssue).call(this, ruleKnownIssue);
|
|
1109
|
+
return true;
|
|
1110
|
+
}
|
|
1111
|
+
const knownHistoryId = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_historyIdMatches).call(this, historyIdCandidates, this.known);
|
|
1112
|
+
return !!knownHistoryId;
|
|
1092
1113
|
}, _DefaultAllureStore_rebuildRetrySubstore = function _DefaultAllureStore_rebuildRetrySubstore() {
|
|
1093
1114
|
__classPrivateFieldGet(this, _DefaultAllureStore_retrySubstore, "f").reset();
|
|
1094
1115
|
for (const [, testResult] of __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f")) {
|
|
@@ -1128,9 +1149,6 @@ _DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_environment
|
|
|
1128
1149
|
__classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f").push(__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_indexGlobalError).call(this, error));
|
|
1129
1150
|
}, _DefaultAllureStore_indexGlobalAttachment = function _DefaultAllureStore_indexGlobalAttachment(attachmentLink) {
|
|
1130
1151
|
const resolvedEnvironment = __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_resolveGlobalEnvironmentIdentity).call(this, attachmentLink.environment);
|
|
1131
|
-
if (!resolvedEnvironment) {
|
|
1132
|
-
return attachmentLink;
|
|
1133
|
-
}
|
|
1134
1152
|
attachmentLink.environment = resolvedEnvironment.name;
|
|
1135
1153
|
__classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addEnvironments).call(this, [resolvedEnvironment]);
|
|
1136
1154
|
index(__classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIdsByEnv, "f"), resolvedEnvironment.id, attachmentLink.id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0",
|
|
4
4
|
"description": "Collection of generic Allure utilities used across the entire project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure"
|
|
@@ -25,31 +25,33 @@
|
|
|
25
25
|
"lint:fix": "oxlint --import-plugin --fix src test features stories"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@allurereport/ci": "3.
|
|
29
|
-
"@allurereport/
|
|
30
|
-
"@allurereport/
|
|
31
|
-
"@allurereport/plugin-
|
|
32
|
-
"@allurereport/plugin-
|
|
33
|
-
"@allurereport/plugin-
|
|
34
|
-
"@allurereport/plugin-
|
|
35
|
-
"@allurereport/plugin-
|
|
36
|
-
"@allurereport/plugin-
|
|
37
|
-
"@allurereport/plugin-
|
|
38
|
-
"@allurereport/plugin-
|
|
39
|
-
"@allurereport/plugin-
|
|
40
|
-
"@allurereport/plugin-
|
|
41
|
-
"@allurereport/plugin-
|
|
42
|
-
"@allurereport/plugin-
|
|
43
|
-
"@allurereport/
|
|
44
|
-
"@allurereport/reader
|
|
45
|
-
"@allurereport/
|
|
46
|
-
"@allurereport/
|
|
28
|
+
"@allurereport/ci": "3.15.0",
|
|
29
|
+
"@allurereport/cli-commons": "3.15.0",
|
|
30
|
+
"@allurereport/core-api": "3.15.0",
|
|
31
|
+
"@allurereport/plugin-agent": "3.15.0",
|
|
32
|
+
"@allurereport/plugin-allure2": "3.15.0",
|
|
33
|
+
"@allurereport/plugin-api": "3.15.0",
|
|
34
|
+
"@allurereport/plugin-awesome": "3.15.0",
|
|
35
|
+
"@allurereport/plugin-classic": "3.15.0",
|
|
36
|
+
"@allurereport/plugin-csv": "3.15.0",
|
|
37
|
+
"@allurereport/plugin-dashboard": "3.15.0",
|
|
38
|
+
"@allurereport/plugin-jira": "3.15.0",
|
|
39
|
+
"@allurereport/plugin-log": "3.15.0",
|
|
40
|
+
"@allurereport/plugin-progress": "3.15.0",
|
|
41
|
+
"@allurereport/plugin-slack": "3.15.0",
|
|
42
|
+
"@allurereport/plugin-testops": "3.15.0",
|
|
43
|
+
"@allurereport/plugin-testplan": "3.15.0",
|
|
44
|
+
"@allurereport/reader": "3.15.0",
|
|
45
|
+
"@allurereport/reader-api": "3.15.0",
|
|
46
|
+
"@allurereport/service": "3.15.0",
|
|
47
|
+
"@allurereport/summary": "3.15.0",
|
|
47
48
|
"glob": "^13.0.6",
|
|
48
49
|
"handlebars": "^4.7.9",
|
|
50
|
+
"jiti": "^2.5.1",
|
|
49
51
|
"node-stream-zip": "^1.15.0",
|
|
50
52
|
"p-limit": "^7.3.0",
|
|
51
53
|
"yaml": "^2.8.3",
|
|
52
|
-
"yoctocolors": "^2.1.
|
|
54
|
+
"yoctocolors": "^2.1.2",
|
|
53
55
|
"zip-stream": "^7.0.5"
|
|
54
56
|
},
|
|
55
57
|
"devDependencies": {
|