@allurereport/core 3.0.0-beta.17 → 3.0.0-beta.18

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 CHANGED
@@ -12,7 +12,6 @@ export interface FullConfig {
12
12
  output: string;
13
13
  historyPath: string;
14
14
  knownIssuesPath: string;
15
- qualityGate?: QualityGateConfig;
16
15
  defaultLabels?: DefaultLabelsConfig;
17
16
  environments?: EnvironmentsConfig;
18
17
  variables?: ReportVariables;
@@ -22,6 +21,7 @@ export interface FullConfig {
22
21
  appendHistory?: boolean;
23
22
  known?: KnownTestFailure[];
24
23
  realTime?: any;
24
+ qualityGate?: QualityGateConfig;
25
25
  allureService?: {
26
26
  url?: string;
27
27
  project?: string;
package/dist/config.js CHANGED
@@ -43,12 +43,12 @@ export const validateConfig = (config) => {
43
43
  "output",
44
44
  "historyPath",
45
45
  "knownIssuesPath",
46
- "qualityGate",
47
46
  "plugins",
48
47
  "defaultLabels",
49
48
  "variables",
50
49
  "environments",
51
50
  "appendHistory",
51
+ "qualityGate",
52
52
  "allureService",
53
53
  ];
54
54
  const unsupportedFields = Object.keys(config).filter((key) => !supportedFields.includes(key));
@@ -92,6 +92,7 @@ export const resolveConfig = async (config, override = {}) => {
92
92
  appendHistory,
93
93
  reportFiles: new FileSystemReportFiles(output),
94
94
  plugins: pluginInstances,
95
+ defaultLabels: config.defaultLabels ?? {},
95
96
  qualityGate: config.qualityGate,
96
97
  allureService: config.allureService,
97
98
  };
package/dist/index.d.ts CHANGED
@@ -11,4 +11,4 @@ export * from "./known.js";
11
11
  export { resolveConfig, readConfig, getPluginInstance } from "./config.js";
12
12
  export * from "./report.js";
13
13
  export * from "./plugin.js";
14
- export * from "./qualityGate.js";
14
+ export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, convertQualityGateResultsToTestErrors, stringifyQualityGateResults, } from "./qualityGate/index.js";
package/dist/index.js CHANGED
@@ -10,4 +10,4 @@ export * from "./known.js";
10
10
  export { resolveConfig, readConfig, getPluginInstance } from "./config.js";
11
11
  export * from "./report.js";
12
12
  export * from "./plugin.js";
13
- export * from "./qualityGate.js";
13
+ export { QualityGateState, qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, convertQualityGateResultsToTestErrors, stringifyQualityGateResults, } from "./qualityGate/index.js";
@@ -0,0 +1,2 @@
1
+ export * from "./qualityGate.js";
2
+ export * from "./rules.js";
@@ -0,0 +1,2 @@
1
+ export * from "./qualityGate.js";
2
+ export * from "./rules.js";
@@ -0,0 +1,21 @@
1
+ import type { KnownTestFailure, TestError, TestResult } from "@allurereport/core-api";
2
+ import type { QualityGateConfig, QualityGateValidationResult } from "@allurereport/plugin-api";
3
+ export declare const stringifyQualityGateResults: (results: QualityGateValidationResult[]) => string;
4
+ export declare const convertQualityGateResultsToTestErrors: (results: QualityGateValidationResult[]) => TestError[];
5
+ export declare class QualityGateState {
6
+ #private;
7
+ setResult(rule: string, value: any): void;
8
+ getResult(rule: string): any;
9
+ }
10
+ export declare class QualityGate {
11
+ private readonly config;
12
+ constructor(config: QualityGateConfig);
13
+ validate(payload: {
14
+ state?: QualityGateState;
15
+ trs: TestResult[];
16
+ knownIssues: KnownTestFailure[];
17
+ }): Promise<{
18
+ fastFailed: boolean;
19
+ results: QualityGateValidationResult[];
20
+ }>;
21
+ }
@@ -0,0 +1,96 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _QualityGateState_state;
7
+ import { gray, red } from "yoctocolors";
8
+ import { qualityGateDefaultRules } from "./rules.js";
9
+ export const stringifyQualityGateResults = (results) => {
10
+ if (results.length === 0) {
11
+ return "";
12
+ }
13
+ const lines = [red("Quality Gate failed with following issues:")];
14
+ const maxMessageLength = Math.max(...results.map((r) => r.message.length));
15
+ lines.push("");
16
+ results.forEach((result) => {
17
+ lines.push(` ${red("⨯")} ${result.message.padEnd(maxMessageLength, " ")} ${gray(result.rule)}`);
18
+ });
19
+ lines.push("");
20
+ lines.push(red(`${results.length} quality gate rules have been failed.`));
21
+ return lines.join("\n");
22
+ };
23
+ export const convertQualityGateResultsToTestErrors = (results) => {
24
+ return results.map((result) => ({
25
+ message: `Quality Gate (${result.rule}): ${result.message}`,
26
+ actual: result.actual,
27
+ expected: result.expected,
28
+ }));
29
+ };
30
+ export class QualityGateState {
31
+ constructor() {
32
+ _QualityGateState_state.set(this, {});
33
+ }
34
+ setResult(rule, value) {
35
+ __classPrivateFieldGet(this, _QualityGateState_state, "f")[rule] = value;
36
+ }
37
+ getResult(rule) {
38
+ return __classPrivateFieldGet(this, _QualityGateState_state, "f")[rule];
39
+ }
40
+ }
41
+ _QualityGateState_state = new WeakMap();
42
+ export class QualityGate {
43
+ constructor(config) {
44
+ this.config = config;
45
+ }
46
+ async validate(payload) {
47
+ const { state, trs, knownIssues } = payload;
48
+ const { rules, use = [...qualityGateDefaultRules] } = this.config;
49
+ const results = [];
50
+ let fastFailed = false;
51
+ if (!rules?.length) {
52
+ return {
53
+ fastFailed: false,
54
+ results,
55
+ };
56
+ }
57
+ for (const ruleset of rules) {
58
+ if (fastFailed) {
59
+ break;
60
+ }
61
+ for (const [key, value] of Object.entries(ruleset)) {
62
+ if (key === "filter" || key === "id" || key === "fastFail") {
63
+ continue;
64
+ }
65
+ const rule = use.filter((r) => r.rule === key).pop();
66
+ if (!rule) {
67
+ throw new Error(`Rule ${key} is not provided. Make sure you have provided it in the "use" field of the quality gate config!`);
68
+ }
69
+ const ruleId = ruleset.id ? [ruleset.id, rule.rule].join("/") : rule.rule;
70
+ const result = await rule.validate({
71
+ expected: value,
72
+ trs,
73
+ knownIssues,
74
+ state: state?.getResult?.(ruleId),
75
+ });
76
+ state?.setResult(ruleId, result.actual);
77
+ if (result.success) {
78
+ continue;
79
+ }
80
+ results.push({
81
+ ...result,
82
+ rule: ruleset.id ? [ruleset.id, rule.rule].join("/") : rule.rule,
83
+ message: rule.message(result),
84
+ });
85
+ if (ruleset.fastFail) {
86
+ fastFailed = true;
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ return {
92
+ fastFailed,
93
+ results,
94
+ };
95
+ }
96
+ }
@@ -0,0 +1,5 @@
1
+ import { type QualityGateRule } from "@allurereport/plugin-api";
2
+ export declare const maxFailuresRule: QualityGateRule<number>;
3
+ export declare const minTestsCountRule: QualityGateRule<number>;
4
+ export declare const successRateRule: QualityGateRule<number>;
5
+ export declare const qualityGateDefaultRules: QualityGateRule<number>[];
@@ -0,0 +1,45 @@
1
+ import { filterSuccessful, filterUnsuccessful } from "@allurereport/core-api";
2
+ import { bold } from "yoctocolors";
3
+ export const maxFailuresRule = {
4
+ rule: "maxFailures",
5
+ message: ({ actual, expected }) => `The number of failed tests ${bold(String(actual))} exceeds the allowed threshold value ${bold(String(expected))}`,
6
+ validate: async ({ trs, knownIssues, expected, state = 0 }) => {
7
+ const knownIssuesHistoryIds = knownIssues.map(({ historyId }) => historyId);
8
+ const unknown = trs.filter((tr) => !tr.historyId || !knownIssuesHistoryIds.includes(tr.historyId));
9
+ const failedTrs = unknown.filter(filterUnsuccessful);
10
+ const actual = failedTrs.length + state;
11
+ return {
12
+ success: actual <= expected,
13
+ actual,
14
+ expected,
15
+ };
16
+ },
17
+ };
18
+ export const minTestsCountRule = {
19
+ rule: "minTestsCount",
20
+ message: ({ actual, expected }) => `The total number of tests ${bold(String(actual))} is less than the expected threshold value ${bold(String(expected))}`,
21
+ validate: async ({ trs, expected, state = 0 }) => {
22
+ const actual = trs.length + state;
23
+ return {
24
+ success: actual >= expected,
25
+ actual,
26
+ expected,
27
+ };
28
+ },
29
+ };
30
+ export const successRateRule = {
31
+ rule: "successRate",
32
+ message: ({ actual, expected }) => `Success rate ${bold(String(actual))} is less, than expected ${bold(String(expected))}`,
33
+ validate: async ({ trs, knownIssues, expected }) => {
34
+ const knownIssuesHistoryIds = knownIssues.map(({ historyId }) => historyId);
35
+ const unknown = trs.filter((tr) => !tr.historyId || !knownIssuesHistoryIds.includes(tr.historyId));
36
+ const passedTrs = unknown.filter(filterSuccessful);
37
+ const rate = passedTrs.length === 0 ? 0 : passedTrs.length / unknown.length;
38
+ return {
39
+ success: rate >= expected,
40
+ actual: rate,
41
+ expected,
42
+ };
43
+ },
44
+ };
45
+ export const qualityGateDefaultRules = [maxFailuresRule, minTestsCountRule, successRateRule];
package/dist/report.d.ts CHANGED
@@ -1,18 +1,29 @@
1
+ import type { KnownTestFailure, TestResult } from "@allurereport/core-api";
1
2
  import type { ResultFile } from "@allurereport/plugin-api";
2
3
  import type { FullConfig } from "./api.js";
4
+ import { type QualityGateState } from "./qualityGate/index.js";
3
5
  import { DefaultAllureStore } from "./store/store.js";
6
+ import { RealtimeEventsDispatcher, RealtimeSubscriber } from "./utils/event.js";
4
7
  export declare class AllureReport {
5
8
  #private;
6
9
  readonly reportUuid: string;
7
10
  reportUrl?: string;
8
11
  constructor(opts: FullConfig);
12
+ get hasQualityGate(): boolean;
9
13
  get store(): DefaultAllureStore;
10
- get exitCode(): 0 | 1;
11
- get validationResults(): import("@allurereport/plugin-api").QualityGateValidationResult[];
14
+ get realtimeSubscriber(): RealtimeSubscriber;
15
+ get realtimeDispatcher(): RealtimeEventsDispatcher;
12
16
  readDirectory: (resultsDir: string) => Promise<void>;
13
17
  readFile: (resultsFile: string) => Promise<void>;
14
18
  readResult: (data: ResultFile) => Promise<void>;
19
+ validate: (params: {
20
+ trs: TestResult[];
21
+ knownIssues: KnownTestFailure[];
22
+ state?: QualityGateState;
23
+ }) => Promise<{
24
+ fastFailed: boolean;
25
+ results: import("@allurereport/plugin-api").QualityGateValidationResult[];
26
+ }>;
15
27
  start: () => Promise<void>;
16
28
  done: () => Promise<void>;
17
- validate: () => Promise<void>;
18
29
  }
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_reportName, _AllureReport_ci, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_eventEmitter, _AllureReport_events, _AllureReport_qualityGate, _AllureReport_realTime, _AllureReport_output, _AllureReport_history, _AllureReport_allureServiceClient, _AllureReport_state, _AllureReport_stage, _AllureReport_publish_get, _AllureReport_update, _AllureReport_eachPlugin, _AllureReport_getPluginState;
12
+ var _AllureReport_instances, _AllureReport_reportName, _AllureReport_ci, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_eventEmitter, _AllureReport_realtimeSubscriber, _AllureReport_realtimeDispatcher, _AllureReport_realTime, _AllureReport_output, _AllureReport_history, _AllureReport_allureServiceClient, _AllureReport_qualityGate, _AllureReport_state, _AllureReport_stage, _AllureReport_publish_get, _AllureReport_update, _AllureReport_eachPlugin, _AllureReport_getPluginState;
13
13
  import { detect } from "@allurereport/ci";
14
14
  import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
15
15
  import { PathResultFile } from "@allurereport/reader-api";
@@ -19,13 +19,13 @@ import console from "node:console";
19
19
  import { randomUUID } from "node:crypto";
20
20
  import { EventEmitter } from "node:events";
21
21
  import { readFileSync } from "node:fs";
22
- import { lstat, opendir, readdir, realpath, rename, rm } from "node:fs/promises";
22
+ import { lstat, opendir, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
23
23
  import { dirname, join, resolve } from "node:path";
24
24
  import { AllureLocalHistory, createHistory } from "./history.js";
25
25
  import { DefaultPluginState, PluginFiles } from "./plugin.js";
26
- import { QualityGate } from "./qualityGate.js";
26
+ import { QualityGate } from "./qualityGate/index.js";
27
27
  import { DefaultAllureStore } from "./store/store.js";
28
- import { Events } from "./utils/event.js";
28
+ import { RealtimeEventsDispatcher, RealtimeSubscriber } from "./utils/event.js";
29
29
  const { version } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
30
30
  const initRequired = "report is not initialised. Call the start() method first.";
31
31
  export class AllureReport {
@@ -38,12 +38,13 @@ export class AllureReport {
38
38
  _AllureReport_plugins.set(this, void 0);
39
39
  _AllureReport_reportFiles.set(this, void 0);
40
40
  _AllureReport_eventEmitter.set(this, void 0);
41
- _AllureReport_events.set(this, void 0);
42
- _AllureReport_qualityGate.set(this, void 0);
41
+ _AllureReport_realtimeSubscriber.set(this, void 0);
42
+ _AllureReport_realtimeDispatcher.set(this, void 0);
43
43
  _AllureReport_realTime.set(this, void 0);
44
44
  _AllureReport_output.set(this, void 0);
45
45
  _AllureReport_history.set(this, void 0);
46
46
  _AllureReport_allureServiceClient.set(this, void 0);
47
+ _AllureReport_qualityGate.set(this, void 0);
47
48
  _AllureReport_state.set(this, void 0);
48
49
  _AllureReport_stage.set(this, "init");
49
50
  this.readDirectory = async (resultsDir) => {
@@ -87,6 +88,14 @@ export class AllureReport {
87
88
  catch (ignored) { }
88
89
  }
89
90
  };
91
+ this.validate = async (params) => {
92
+ const { trs, knownIssues, state } = params;
93
+ return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate({
94
+ trs: trs.filter(Boolean),
95
+ knownIssues,
96
+ state,
97
+ });
98
+ };
90
99
  this.start = async () => {
91
100
  await __classPrivateFieldGet(this, _AllureReport_store, "f").readHistory();
92
101
  if (__classPrivateFieldGet(this, _AllureReport_stage, "f") === "running") {
@@ -104,11 +113,11 @@ export class AllureReport {
104
113
  this.reportUrl = url;
105
114
  }
106
115
  await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, true, async (plugin, context) => {
107
- await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_events, "f"));
116
+ await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f"));
108
117
  });
109
118
  if (__classPrivateFieldGet(this, _AllureReport_realTime, "f")) {
110
119
  await __classPrivateFieldGet(this, _AllureReport_update, "f").call(this);
111
- __classPrivateFieldGet(this, _AllureReport_events, "f").onAll(async () => {
120
+ __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f").onAll(async () => {
112
121
  await __classPrivateFieldGet(this, _AllureReport_update, "f").call(this);
113
122
  });
114
123
  }
@@ -127,7 +136,7 @@ export class AllureReport {
127
136
  if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
128
137
  throw new Error(initRequired);
129
138
  }
130
- __classPrivateFieldGet(this, _AllureReport_events, "f").offAll();
139
+ __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f").offAll();
131
140
  __classPrivateFieldSet(this, _AllureReport_stage, "done", "f");
132
141
  await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, false, async (plugin, context) => {
133
142
  await plugin.done?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
@@ -155,7 +164,7 @@ export class AllureReport {
155
164
  return;
156
165
  }
157
166
  summary.pullRequestHref = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestUrl;
158
- summary.jobHref = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobUrl;
167
+ summary.jobHref = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunUrl;
159
168
  if (context.publish) {
160
169
  summary.remoteHref = `${this.reportUrl}/${context.id}/`;
161
170
  remoteHrefs.push(summary.remoteHref);
@@ -171,7 +180,11 @@ export class AllureReport {
171
180
  reportUuid: this.reportUuid,
172
181
  });
173
182
  }
174
- const outputDirFiles = await readdir(__classPrivateFieldGet(this, _AllureReport_output, "f"));
183
+ let outputDirFiles = [];
184
+ try {
185
+ outputDirFiles = await readdir(__classPrivateFieldGet(this, _AllureReport_output, "f"));
186
+ }
187
+ catch (ignored) { }
175
188
  if (outputDirFiles.length === 0) {
176
189
  return;
177
190
  }
@@ -215,6 +228,11 @@ export class AllureReport {
215
228
  console.info(`- ${href}`);
216
229
  });
217
230
  }
231
+ if (!__classPrivateFieldGet(this, _AllureReport_qualityGate, "f")) {
232
+ return;
233
+ }
234
+ const qualityGateResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").qualityGateResults();
235
+ await writeFile(join(__classPrivateFieldGet(this, _AllureReport_output, "f"), "quality-gate.json"), JSON.stringify(qualityGateResults));
218
236
  };
219
237
  _AllureReport_eachPlugin.set(this, async (initState, consumer) => {
220
238
  if (initState) {
@@ -261,17 +279,15 @@ export class AllureReport {
261
279
  }
262
280
  }
263
281
  });
264
- this.validate = async () => {
265
- await __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate(__classPrivateFieldGet(this, _AllureReport_store, "f"));
266
- };
267
- const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, qualityGate, realTime, historyPath, defaultLabels = {}, variables = {}, environments, output, allureService: allureServiceConfig, } = opts;
282
+ const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, defaultLabels = {}, variables = {}, environments, output, qualityGate, allureService: allureServiceConfig, } = opts;
268
283
  __classPrivateFieldSet(this, _AllureReport_allureServiceClient, allureServiceConfig?.url ? new AllureServiceClient(allureServiceConfig) : undefined, "f");
269
284
  this.reportUuid = randomUUID();
270
285
  __classPrivateFieldSet(this, _AllureReport_ci, detect(), "f");
271
286
  const reportTitleSuffix = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestName ?? __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunName;
272
287
  __classPrivateFieldSet(this, _AllureReport_reportName, [name, reportTitleSuffix].filter(Boolean).join(" – "), "f");
273
288
  __classPrivateFieldSet(this, _AllureReport_eventEmitter, new EventEmitter(), "f");
274
- __classPrivateFieldSet(this, _AllureReport_events, new Events(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
289
+ __classPrivateFieldSet(this, _AllureReport_realtimeDispatcher, new RealtimeEventsDispatcher(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
290
+ __classPrivateFieldSet(this, _AllureReport_realtimeSubscriber, new RealtimeSubscriber(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
275
291
  __classPrivateFieldSet(this, _AllureReport_realTime, realTime, "f");
276
292
  if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")) {
277
293
  __classPrivateFieldSet(this, _AllureReport_history, new AllureRemoteHistory(__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")), "f");
@@ -279,8 +295,12 @@ export class AllureReport {
279
295
  else if (historyPath) {
280
296
  __classPrivateFieldSet(this, _AllureReport_history, new AllureLocalHistory(historyPath), "f");
281
297
  }
298
+ if (qualityGate) {
299
+ __classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
300
+ }
282
301
  __classPrivateFieldSet(this, _AllureReport_store, new DefaultAllureStore({
283
- eventEmitter: __classPrivateFieldGet(this, _AllureReport_eventEmitter, "f"),
302
+ realtimeSubscriber: __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f"),
303
+ realtimeDispatcher: __classPrivateFieldGet(this, _AllureReport_realtimeDispatcher, "f"),
284
304
  reportVariables: variables,
285
305
  environmentsConfig: environments,
286
306
  history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
@@ -291,22 +311,24 @@ export class AllureReport {
291
311
  __classPrivateFieldSet(this, _AllureReport_plugins, [...plugins], "f");
292
312
  __classPrivateFieldSet(this, _AllureReport_reportFiles, reportFiles, "f");
293
313
  __classPrivateFieldSet(this, _AllureReport_output, output, "f");
294
- __classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
295
314
  __classPrivateFieldSet(this, _AllureReport_history, __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")
296
315
  ? new AllureRemoteHistory(__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f"))
297
316
  : new AllureLocalHistory(historyPath), "f");
298
317
  }
318
+ get hasQualityGate() {
319
+ return !!__classPrivateFieldGet(this, _AllureReport_qualityGate, "f");
320
+ }
299
321
  get store() {
300
322
  return __classPrivateFieldGet(this, _AllureReport_store, "f");
301
323
  }
302
- get exitCode() {
303
- return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").exitCode;
324
+ get realtimeSubscriber() {
325
+ return __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f");
304
326
  }
305
- get validationResults() {
306
- return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").result;
327
+ get realtimeDispatcher() {
328
+ return __classPrivateFieldGet(this, _AllureReport_realtimeDispatcher, "f");
307
329
  }
308
330
  }
309
- _AllureReport_reportName = new WeakMap(), _AllureReport_ci = new WeakMap(), _AllureReport_store = new WeakMap(), _AllureReport_readers = new WeakMap(), _AllureReport_plugins = new WeakMap(), _AllureReport_reportFiles = new WeakMap(), _AllureReport_eventEmitter = new WeakMap(), _AllureReport_events = new WeakMap(), _AllureReport_qualityGate = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_output = new WeakMap(), _AllureReport_history = new WeakMap(), _AllureReport_allureServiceClient = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_stage = new WeakMap(), _AllureReport_update = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_publish_get = function _AllureReport_publish_get() {
331
+ _AllureReport_reportName = new WeakMap(), _AllureReport_ci = new WeakMap(), _AllureReport_store = new WeakMap(), _AllureReport_readers = new WeakMap(), _AllureReport_plugins = new WeakMap(), _AllureReport_reportFiles = new WeakMap(), _AllureReport_eventEmitter = new WeakMap(), _AllureReport_realtimeSubscriber = new WeakMap(), _AllureReport_realtimeDispatcher = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_output = new WeakMap(), _AllureReport_history = new WeakMap(), _AllureReport_allureServiceClient = new WeakMap(), _AllureReport_qualityGate = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_stage = new WeakMap(), _AllureReport_update = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_publish_get = function _AllureReport_publish_get() {
310
332
  return __classPrivateFieldGet(this, _AllureReport_plugins, "f").some(({ enabled, options }) => enabled && options.publish);
311
333
  }, _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
312
334
  return init ? new DefaultPluginState({}) : __classPrivateFieldGet(this, _AllureReport_state, "f")?.[id];
@@ -1,8 +1,6 @@
1
- import { type AllureHistory, type AttachmentLink, type DefaultLabelsConfig, type EnvironmentsConfig, type HistoryDataPoint, type HistoryTestResult, type KnownTestFailure, type RepoData, type ReportVariables, type TestCase, type TestEnvGroup, type TestFixtureResult, type TestResult } from "@allurereport/core-api";
2
- import { type AllureStore, type ResultFile, type TestResultFilter } from "@allurereport/plugin-api";
1
+ import { type AllureHistory, type AttachmentLink, type DefaultLabelsConfig, type EnvironmentsConfig, type HistoryDataPoint, type HistoryTestResult, type KnownTestFailure, type RepoData, type ReportVariables, type TestCase, type TestEnvGroup, type TestError, type TestFixtureResult, type TestResult } from "@allurereport/core-api";
2
+ import { type AllureStore, type ExitCode, type QualityGateValidationResult, type RealtimeEventsDispatcher, type RealtimeSubscriber, type ResultFile, type TestResultFilter } from "@allurereport/plugin-api";
3
3
  import type { RawFixtureResult, RawMetadata, RawTestResult, ReaderContext, ResultsVisitor } from "@allurereport/reader-api";
4
- import type { EventEmitter } from "node:events";
5
- import type { AllureStoreEvents } from "../utils/event.js";
6
4
  export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
7
5
  #private;
8
6
  readonly indexTestResultByTestCase: Map<string, TestResult[]>;
@@ -15,7 +13,8 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
15
13
  constructor(params?: {
16
14
  history?: AllureHistory;
17
15
  known?: KnownTestFailure[];
18
- eventEmitter?: EventEmitter<AllureStoreEvents>;
16
+ realtimeDispatcher?: RealtimeEventsDispatcher;
17
+ realtimeSubscriber?: RealtimeSubscriber;
19
18
  defaultLabels?: DefaultLabelsConfig;
20
19
  environmentsConfig?: EnvironmentsConfig;
21
20
  reportVariables?: ReportVariables;
@@ -23,6 +22,10 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
23
22
  readHistory(): Promise<HistoryDataPoint[]>;
24
23
  appendHistory(history: HistoryDataPoint): Promise<void>;
25
24
  repoData(): Promise<RepoData | undefined>;
25
+ qualityGateResults(): Promise<QualityGateValidationResult[]>;
26
+ globalExitCode(): Promise<ExitCode | undefined>;
27
+ allGlobalErrors(): Promise<TestError[]>;
28
+ allGlobalAttachments(): Promise<AttachmentLink[]>;
26
29
  visitTestResult(raw: RawTestResult, context: ReaderContext): Promise<void>;
27
30
  visitTestFixtureResult(result: RawFixtureResult, context: ReaderContext): Promise<void>;
28
31
  visitAttachmentFile(resultFile: ResultFile, context: ReaderContext): Promise<void>;
@@ -9,9 +9,9 @@ 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_testResults, _DefaultAllureStore_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history, _DefaultAllureStore_known, _DefaultAllureStore_fixtures, _DefaultAllureStore_defaultLabels, _DefaultAllureStore_environmentsConfig, _DefaultAllureStore_reportVariables, _DefaultAllureStore_eventEmitter, _DefaultAllureStore_historyPoints, _DefaultAllureStore_repoData;
12
+ var _DefaultAllureStore_testResults, _DefaultAllureStore_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history, _DefaultAllureStore_known, _DefaultAllureStore_fixtures, _DefaultAllureStore_defaultLabels, _DefaultAllureStore_environmentsConfig, _DefaultAllureStore_reportVariables, _DefaultAllureStore_realtimeDispatcher, _DefaultAllureStore_realtimeSubscriber, _DefaultAllureStore_globalAttachments, _DefaultAllureStore_globalErrors, _DefaultAllureStore_globalExitCode, _DefaultAllureStore_qualityGateResultsByRules, _DefaultAllureStore_historyPoints, _DefaultAllureStore_repoData;
13
13
  import { compareBy, getWorstStatus, matchEnvironment, nullsLast, ordinal, reverse, } from "@allurereport/core-api";
14
- import { md5 } from "@allurereport/plugin-api";
14
+ import { md5, } from "@allurereport/plugin-api";
15
15
  import { isFlaky } from "../utils/flaky.js";
16
16
  import { getGitBranch, getGitRepoName } from "../utils/git.js";
17
17
  import { getStatusTransition } from "../utils/new.js";
@@ -39,16 +39,21 @@ export class DefaultAllureStore {
39
39
  _DefaultAllureStore_defaultLabels.set(this, {});
40
40
  _DefaultAllureStore_environmentsConfig.set(this, {});
41
41
  _DefaultAllureStore_reportVariables.set(this, {});
42
- _DefaultAllureStore_eventEmitter.set(this, void 0);
42
+ _DefaultAllureStore_realtimeDispatcher.set(this, void 0);
43
+ _DefaultAllureStore_realtimeSubscriber.set(this, void 0);
43
44
  this.indexTestResultByTestCase = new Map();
44
45
  this.indexTestResultByHistoryId = new Map();
45
46
  this.indexAttachmentByTestResult = new Map();
46
47
  this.indexAttachmentByFixture = new Map();
47
48
  this.indexFixturesByTestResult = new Map();
48
49
  this.indexKnownByHistoryId = new Map();
50
+ _DefaultAllureStore_globalAttachments.set(this, []);
51
+ _DefaultAllureStore_globalErrors.set(this, []);
52
+ _DefaultAllureStore_globalExitCode.set(this, void 0);
53
+ _DefaultAllureStore_qualityGateResultsByRules.set(this, {});
49
54
  _DefaultAllureStore_historyPoints.set(this, []);
50
55
  _DefaultAllureStore_repoData.set(this, void 0);
51
- const { history, known = [], eventEmitter, defaultLabels = {}, environmentsConfig = {}, reportVariables = {}, } = params ?? {};
56
+ const { history, known = [], realtimeDispatcher, realtimeSubscriber, defaultLabels = {}, environmentsConfig = {}, reportVariables = {}, } = params ?? {};
52
57
  __classPrivateFieldSet(this, _DefaultAllureStore_testResults, new Map(), "f");
53
58
  __classPrivateFieldSet(this, _DefaultAllureStore_attachments, new Map(), "f");
54
59
  __classPrivateFieldSet(this, _DefaultAllureStore_attachmentContents, new Map(), "f");
@@ -58,7 +63,8 @@ export class DefaultAllureStore {
58
63
  __classPrivateFieldSet(this, _DefaultAllureStore_history, history, "f");
59
64
  __classPrivateFieldSet(this, _DefaultAllureStore_known, [...known], "f");
60
65
  __classPrivateFieldGet(this, _DefaultAllureStore_known, "f").forEach((ktf) => index(this.indexKnownByHistoryId, ktf.historyId, ktf));
61
- __classPrivateFieldSet(this, _DefaultAllureStore_eventEmitter, eventEmitter, "f");
66
+ __classPrivateFieldSet(this, _DefaultAllureStore_realtimeDispatcher, realtimeDispatcher, "f");
67
+ __classPrivateFieldSet(this, _DefaultAllureStore_realtimeSubscriber, realtimeSubscriber, "f");
62
68
  __classPrivateFieldSet(this, _DefaultAllureStore_defaultLabels, defaultLabels, "f");
63
69
  __classPrivateFieldSet(this, _DefaultAllureStore_environmentsConfig, environmentsConfig, "f");
64
70
  __classPrivateFieldSet(this, _DefaultAllureStore_reportVariables, reportVariables, "f");
@@ -68,6 +74,30 @@ export class DefaultAllureStore {
68
74
  .forEach((key) => {
69
75
  this.indexLatestEnvTestResultByHistoryId.set(key, new Map());
70
76
  });
77
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onQualityGateResults(async (results) => {
78
+ results.forEach((result) => {
79
+ __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f")[result.rule] = result;
80
+ });
81
+ });
82
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalExitCode(async (exitCode) => {
83
+ __classPrivateFieldSet(this, _DefaultAllureStore_globalExitCode, exitCode, "f");
84
+ });
85
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalError(async (error) => {
86
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f").push(error);
87
+ });
88
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalAttachment(async (attachment) => {
89
+ const attachmentLink = {
90
+ id: md5(attachment.getOriginalFileName()),
91
+ missed: false,
92
+ used: false,
93
+ ext: attachment.getExtension(),
94
+ originalFileName: attachment.getOriginalFileName(),
95
+ contentType: attachment.getContentType(),
96
+ contentLength: attachment.getContentLength(),
97
+ };
98
+ __classPrivateFieldGet(this, _DefaultAllureStore_attachmentContents, "f").set(attachmentLink.id, attachment);
99
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f").push(attachmentLink);
100
+ });
71
101
  }
72
102
  async readHistory() {
73
103
  if (!__classPrivateFieldGet(this, _DefaultAllureStore_history, "f")) {
@@ -101,6 +131,18 @@ export class DefaultAllureStore {
101
131
  return undefined;
102
132
  }
103
133
  }
134
+ async qualityGateResults() {
135
+ return Object.values(__classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f"));
136
+ }
137
+ async globalExitCode() {
138
+ return __classPrivateFieldGet(this, _DefaultAllureStore_globalExitCode, "f");
139
+ }
140
+ async allGlobalErrors() {
141
+ return __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f");
142
+ }
143
+ async allGlobalAttachments() {
144
+ return __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f");
145
+ }
104
146
  async visitTestResult(raw, context) {
105
147
  const attachmentLinks = [];
106
148
  const testResult = testResultRawToState({
@@ -147,7 +189,7 @@ export class DefaultAllureStore {
147
189
  index(this.indexTestResultByTestCase, testResult.testCase?.id, testResult);
148
190
  index(this.indexTestResultByHistoryId, testResult.historyId, testResult);
149
191
  index(this.indexAttachmentByTestResult, testResult.id, ...attachmentLinks);
150
- __classPrivateFieldGet(this, _DefaultAllureStore_eventEmitter, "f")?.emit("testResult", testResult.id);
192
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeDispatcher, "f")?.sendTestResult(testResult.id);
151
193
  }
152
194
  async visitTestFixtureResult(result, context) {
153
195
  const attachmentLinks = [];
@@ -160,7 +202,7 @@ export class DefaultAllureStore {
160
202
  index(this.indexFixturesByTestResult, trId, testFixtureResult);
161
203
  });
162
204
  index(this.indexAttachmentByFixture, testFixtureResult.id, ...attachmentLinks);
163
- __classPrivateFieldGet(this, _DefaultAllureStore_eventEmitter, "f")?.emit("testFixtureResult", testFixtureResult.id);
205
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeDispatcher, "f")?.sendTestFixtureResult(testFixtureResult.id);
164
206
  }
165
207
  async visitAttachmentFile(resultFile, context) {
166
208
  const originalFileName = resultFile.getOriginalFileName();
@@ -185,7 +227,7 @@ export class DefaultAllureStore {
185
227
  contentLength: resultFile.getContentLength(),
186
228
  });
187
229
  }
188
- __classPrivateFieldGet(this, _DefaultAllureStore_eventEmitter, "f")?.emit("attachmentFile", id);
230
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeDispatcher, "f")?.sendAttachmentFile(id);
189
231
  }
190
232
  async visitMetadata(metadata) {
191
233
  Object.keys(metadata).forEach((key) => __classPrivateFieldGet(this, _DefaultAllureStore_metadata, "f").set(key, metadata[key]));
@@ -382,4 +424,4 @@ export class DefaultAllureStore {
382
424
  };
383
425
  }
384
426
  }
385
- _DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_attachments = new WeakMap(), _DefaultAllureStore_attachmentContents = new WeakMap(), _DefaultAllureStore_testCases = new WeakMap(), _DefaultAllureStore_metadata = new WeakMap(), _DefaultAllureStore_history = new WeakMap(), _DefaultAllureStore_known = new WeakMap(), _DefaultAllureStore_fixtures = new WeakMap(), _DefaultAllureStore_defaultLabels = new WeakMap(), _DefaultAllureStore_environmentsConfig = new WeakMap(), _DefaultAllureStore_reportVariables = new WeakMap(), _DefaultAllureStore_eventEmitter = new WeakMap(), _DefaultAllureStore_historyPoints = new WeakMap(), _DefaultAllureStore_repoData = new WeakMap();
427
+ _DefaultAllureStore_testResults = new WeakMap(), _DefaultAllureStore_attachments = new WeakMap(), _DefaultAllureStore_attachmentContents = new WeakMap(), _DefaultAllureStore_testCases = new WeakMap(), _DefaultAllureStore_metadata = new WeakMap(), _DefaultAllureStore_history = new WeakMap(), _DefaultAllureStore_known = new WeakMap(), _DefaultAllureStore_fixtures = new WeakMap(), _DefaultAllureStore_defaultLabels = new WeakMap(), _DefaultAllureStore_environmentsConfig = new WeakMap(), _DefaultAllureStore_reportVariables = new WeakMap(), _DefaultAllureStore_realtimeDispatcher = new WeakMap(), _DefaultAllureStore_realtimeSubscriber = new WeakMap(), _DefaultAllureStore_globalAttachments = new WeakMap(), _DefaultAllureStore_globalErrors = new WeakMap(), _DefaultAllureStore_globalExitCode = new WeakMap(), _DefaultAllureStore_qualityGateResultsByRules = new WeakMap(), _DefaultAllureStore_historyPoints = new WeakMap(), _DefaultAllureStore_repoData = new WeakMap();
@@ -1,16 +1,45 @@
1
- import type { BatchOptions, Realtime } from "@allurereport/plugin-api";
1
+ import type { TestError } from "@allurereport/core-api";
2
+ import type { BatchOptions, ExitCode, QualityGateValidationResult, RealtimeEventsDispatcher as RealtimeEventsDispatcherType, RealtimeSubscriber as RealtimeSubscriberType, ResultFile } from "@allurereport/plugin-api";
2
3
  import type { EventEmitter } from "node:events";
4
+ export declare enum RealtimeEvents {
5
+ TestResult = "testResult",
6
+ TestFixtureResult = "testFixtureResult",
7
+ AttachmentFile = "attachmentFile",
8
+ QualityGateResults = "qualityGateResults",
9
+ GlobalAttachment = "globalAttachment",
10
+ GlobalError = "globalError",
11
+ GlobalExitCode = "globalExitCode"
12
+ }
3
13
  export interface AllureStoreEvents {
4
- testResult: [string];
5
- testFixtureResult: [string];
6
- attachmentFile: [string];
14
+ [RealtimeEvents.QualityGateResults]: [QualityGateValidationResult[]];
15
+ [RealtimeEvents.TestResult]: [string];
16
+ [RealtimeEvents.TestFixtureResult]: [string];
17
+ [RealtimeEvents.AttachmentFile]: [string];
18
+ [RealtimeEvents.GlobalAttachment]: [ResultFile];
19
+ [RealtimeEvents.GlobalExitCode]: [ExitCode];
20
+ [RealtimeEvents.GlobalError]: [TestError];
21
+ }
22
+ export declare class RealtimeEventsDispatcher implements RealtimeEventsDispatcherType {
23
+ #private;
24
+ constructor(emitter: EventEmitter<AllureStoreEvents>);
25
+ sendGlobalAttachment(attachment: ResultFile): void;
26
+ sendGlobalExitCode(codes: ExitCode): void;
27
+ sendGlobalError(error: TestError): void;
28
+ sendQualityGateResults(payload: QualityGateValidationResult[]): void;
29
+ sendTestResult(trId: string): void;
30
+ sendTestFixtureResult(tfrId: string): void;
31
+ sendAttachmentFile(afId: string): void;
7
32
  }
8
- export declare class Events implements Realtime {
33
+ export declare class RealtimeSubscriber implements RealtimeSubscriberType {
9
34
  #private;
10
35
  constructor(emitter: EventEmitter<AllureStoreEvents>);
11
- onTestResults: (listener: (trIds: string[]) => Promise<void>, options?: BatchOptions) => void;
12
- onTestFixtureResults: (listener: (tfrIds: string[]) => Promise<void>, options?: BatchOptions) => void;
13
- onAttachmentFiles(listener: (afIds: string[]) => Promise<void>, options?: BatchOptions): void;
14
- onAll(listener: () => Promise<void>, options?: BatchOptions): void;
36
+ onGlobalAttachment(listener: (attachment: ResultFile) => Promise<void>): () => void;
37
+ onGlobalExitCode(listener: (payload: ExitCode) => Promise<void>): () => void;
38
+ onGlobalError(listener: (error: TestError) => Promise<void>): () => void;
39
+ onQualityGateResults(listener: (payload: QualityGateValidationResult[]) => Promise<void>): () => void;
40
+ onTestResults(listener: (trIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
41
+ onTestFixtureResults(listener: (tfrIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
42
+ onAttachmentFiles(listener: (afIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
43
+ onAll(listener: () => Promise<void>, options?: BatchOptions): () => void;
15
44
  offAll(): void;
16
45
  }
@@ -9,51 +9,127 @@ 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 _Events_instances, _Events_emitter, _Events_handlers, _Events_createHandler;
12
+ var _RealtimeEventsDispatcher_emitter, _RealtimeSubscriber_instances, _RealtimeSubscriber_emitter, _RealtimeSubscriber_handlers, _RealtimeSubscriber_createBatchHandler;
13
13
  import console from "node:console";
14
14
  import { setTimeout } from "node:timers/promises";
15
- export class Events {
15
+ export var RealtimeEvents;
16
+ (function (RealtimeEvents) {
17
+ RealtimeEvents["TestResult"] = "testResult";
18
+ RealtimeEvents["TestFixtureResult"] = "testFixtureResult";
19
+ RealtimeEvents["AttachmentFile"] = "attachmentFile";
20
+ RealtimeEvents["QualityGateResults"] = "qualityGateResults";
21
+ RealtimeEvents["GlobalAttachment"] = "globalAttachment";
22
+ RealtimeEvents["GlobalError"] = "globalError";
23
+ RealtimeEvents["GlobalExitCode"] = "globalExitCode";
24
+ })(RealtimeEvents || (RealtimeEvents = {}));
25
+ export class RealtimeEventsDispatcher {
16
26
  constructor(emitter) {
17
- _Events_instances.add(this);
18
- _Events_emitter.set(this, void 0);
19
- _Events_handlers.set(this, []);
20
- this.onTestResults = (listener, options = {}) => {
21
- const { maxTimeout = 100 } = options;
22
- const handler = __classPrivateFieldGet(this, _Events_instances, "m", _Events_createHandler).call(this, maxTimeout, listener);
23
- __classPrivateFieldGet(this, _Events_emitter, "f").on("testResult", handler);
27
+ _RealtimeEventsDispatcher_emitter.set(this, void 0);
28
+ __classPrivateFieldSet(this, _RealtimeEventsDispatcher_emitter, emitter, "f");
29
+ }
30
+ sendGlobalAttachment(attachment) {
31
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalAttachment, attachment);
32
+ }
33
+ sendGlobalExitCode(codes) {
34
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalExitCode, codes);
35
+ }
36
+ sendGlobalError(error) {
37
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalError, error);
38
+ }
39
+ sendQualityGateResults(payload) {
40
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.QualityGateResults, payload ?? []);
41
+ }
42
+ sendTestResult(trId) {
43
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.TestResult, trId);
44
+ }
45
+ sendTestFixtureResult(tfrId) {
46
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.TestFixtureResult, tfrId);
47
+ }
48
+ sendAttachmentFile(afId) {
49
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.AttachmentFile, afId);
50
+ }
51
+ }
52
+ _RealtimeEventsDispatcher_emitter = new WeakMap();
53
+ export class RealtimeSubscriber {
54
+ constructor(emitter) {
55
+ _RealtimeSubscriber_instances.add(this);
56
+ _RealtimeSubscriber_emitter.set(this, void 0);
57
+ _RealtimeSubscriber_handlers.set(this, []);
58
+ __classPrivateFieldSet(this, _RealtimeSubscriber_emitter, emitter, "f");
59
+ }
60
+ onGlobalAttachment(listener) {
61
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.GlobalAttachment, listener);
62
+ return () => {
63
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.GlobalAttachment, listener);
64
+ };
65
+ }
66
+ onGlobalExitCode(listener) {
67
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.GlobalExitCode, listener);
68
+ return () => {
69
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.GlobalExitCode, listener);
70
+ };
71
+ }
72
+ onGlobalError(listener) {
73
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.GlobalError, listener);
74
+ return () => {
75
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.GlobalError, listener);
76
+ };
77
+ }
78
+ onQualityGateResults(listener) {
79
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.QualityGateResults, listener);
80
+ return () => {
81
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.QualityGateResults, listener);
82
+ };
83
+ }
84
+ onTestResults(listener, options = {}) {
85
+ const { maxTimeout = 100 } = options;
86
+ const handler = __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_createBatchHandler).call(this, maxTimeout, listener);
87
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.TestResult, handler);
88
+ return () => {
89
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.TestResult, handler);
24
90
  };
25
- this.onTestFixtureResults = (listener, options = {}) => {
26
- const { maxTimeout = 100 } = options;
27
- const handler = __classPrivateFieldGet(this, _Events_instances, "m", _Events_createHandler).call(this, maxTimeout, listener);
28
- __classPrivateFieldGet(this, _Events_emitter, "f").on("testFixtureResult", handler);
91
+ }
92
+ onTestFixtureResults(listener, options = {}) {
93
+ const { maxTimeout = 100 } = options;
94
+ const handler = __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_createBatchHandler).call(this, maxTimeout, listener);
95
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.TestFixtureResult, handler);
96
+ return () => {
97
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.TestFixtureResult, handler);
29
98
  };
30
- __classPrivateFieldSet(this, _Events_emitter, emitter, "f");
31
99
  }
32
100
  onAttachmentFiles(listener, options = {}) {
33
101
  const { maxTimeout = 100 } = options;
34
- const handler = __classPrivateFieldGet(this, _Events_instances, "m", _Events_createHandler).call(this, maxTimeout, listener);
35
- __classPrivateFieldGet(this, _Events_emitter, "f").on("attachmentFile", handler);
102
+ const handler = __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_createBatchHandler).call(this, maxTimeout, listener);
103
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.AttachmentFile, handler);
104
+ return () => {
105
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.AttachmentFile, handler);
106
+ };
36
107
  }
37
108
  onAll(listener, options = {}) {
38
109
  const { maxTimeout = 100 } = options;
39
- const handler = __classPrivateFieldGet(this, _Events_instances, "m", _Events_createHandler).call(this, maxTimeout, listener);
40
- __classPrivateFieldGet(this, _Events_emitter, "f").on("testResult", handler);
41
- __classPrivateFieldGet(this, _Events_emitter, "f").on("testFixtureResult", handler);
42
- __classPrivateFieldGet(this, _Events_emitter, "f").on("attachmentFile", handler);
110
+ const handler = __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_createBatchHandler).call(this, maxTimeout, listener);
111
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.TestResult, handler);
112
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.TestFixtureResult, handler);
113
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(RealtimeEvents.AttachmentFile, handler);
114
+ return () => {
115
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.TestResult, handler);
116
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.TestFixtureResult, handler);
117
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").off(RealtimeEvents.AttachmentFile, handler);
118
+ };
43
119
  }
44
120
  offAll() {
45
- __classPrivateFieldGet(this, _Events_emitter, "f").removeAllListeners();
46
- for (const handler of __classPrivateFieldGet(this, _Events_handlers, "f")) {
121
+ __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").removeAllListeners();
122
+ for (const handler of __classPrivateFieldGet(this, _RealtimeSubscriber_handlers, "f")) {
47
123
  handler.ac?.abort();
48
124
  }
49
- __classPrivateFieldSet(this, _Events_handlers, [], "f");
125
+ __classPrivateFieldSet(this, _RealtimeSubscriber_handlers, [], "f");
50
126
  }
51
127
  }
52
- _Events_emitter = new WeakMap(), _Events_handlers = new WeakMap(), _Events_instances = new WeakSet(), _Events_createHandler = function _Events_createHandler(maxTimeout, listener) {
128
+ _RealtimeSubscriber_emitter = new WeakMap(), _RealtimeSubscriber_handlers = new WeakMap(), _RealtimeSubscriber_instances = new WeakSet(), _RealtimeSubscriber_createBatchHandler = function _RealtimeSubscriber_createBatchHandler(maxTimeout, listener) {
53
129
  const handler = {
54
130
  buffer: [],
55
131
  };
56
- __classPrivateFieldGet(this, _Events_handlers, "f").push(handler);
132
+ __classPrivateFieldGet(this, _RealtimeSubscriber_handlers, "f").push(handler);
57
133
  return (trId) => {
58
134
  handler.buffer.push(trId);
59
135
  if (handler.timeout) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/core",
3
- "version": "3.0.0-beta.17",
3
+ "version": "3.0.0-beta.18",
4
4
  "description": "Collection of generic Allure utilities used across the entire project",
5
5
  "keywords": [
6
6
  "allure"
@@ -25,24 +25,25 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "dependencies": {
28
- "@allurereport/ci": "3.0.0-beta.17",
29
- "@allurereport/core-api": "3.0.0-beta.17",
30
- "@allurereport/plugin-allure2": "3.0.0-beta.17",
31
- "@allurereport/plugin-api": "3.0.0-beta.17",
32
- "@allurereport/plugin-awesome": "3.0.0-beta.17",
33
- "@allurereport/plugin-classic": "3.0.0-beta.17",
34
- "@allurereport/plugin-csv": "3.0.0-beta.17",
35
- "@allurereport/plugin-dashboard": "3.0.0-beta.17",
36
- "@allurereport/plugin-log": "3.0.0-beta.17",
37
- "@allurereport/plugin-progress": "3.0.0-beta.17",
38
- "@allurereport/plugin-slack": "3.0.0-beta.17",
39
- "@allurereport/plugin-testplan": "3.0.0-beta.17",
40
- "@allurereport/reader": "3.0.0-beta.17",
41
- "@allurereport/reader-api": "3.0.0-beta.17",
42
- "@allurereport/service": "3.0.0-beta.17",
43
- "@allurereport/summary": "3.0.0-beta.17",
28
+ "@allurereport/ci": "3.0.0-beta.18",
29
+ "@allurereport/core-api": "3.0.0-beta.18",
30
+ "@allurereport/plugin-allure2": "3.0.0-beta.18",
31
+ "@allurereport/plugin-api": "3.0.0-beta.18",
32
+ "@allurereport/plugin-awesome": "3.0.0-beta.18",
33
+ "@allurereport/plugin-classic": "3.0.0-beta.18",
34
+ "@allurereport/plugin-csv": "3.0.0-beta.18",
35
+ "@allurereport/plugin-dashboard": "3.0.0-beta.18",
36
+ "@allurereport/plugin-log": "3.0.0-beta.18",
37
+ "@allurereport/plugin-progress": "3.0.0-beta.18",
38
+ "@allurereport/plugin-slack": "3.0.0-beta.18",
39
+ "@allurereport/plugin-testplan": "3.0.0-beta.18",
40
+ "@allurereport/reader": "3.0.0-beta.18",
41
+ "@allurereport/reader-api": "3.0.0-beta.18",
42
+ "@allurereport/service": "3.0.0-beta.18",
43
+ "@allurereport/summary": "3.0.0-beta.18",
44
44
  "handlebars": "^4.7.8",
45
- "markdown-it": "^14.1.0"
45
+ "markdown-it": "^14.1.0",
46
+ "yoctocolors": "^2.1.1"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@stylistic/eslint-plugin": "^2.6.1",
@@ -54,8 +55,8 @@
54
55
  "@typescript-eslint/parser": "^8.0.0",
55
56
  "@vitest/runner": "^2.1.9",
56
57
  "@vitest/snapshot": "^2.1.9",
57
- "allure-js-commons": "^3.3.0",
58
- "allure-vitest": "^3.3.0",
58
+ "allure-js-commons": "^3.3.3",
59
+ "allure-vitest": "^3.3.3",
59
60
  "eslint": "^8.57.0",
60
61
  "eslint-config-prettier": "^9.1.0",
61
62
  "eslint-plugin-import": "^2.29.1",
@@ -1,25 +0,0 @@
1
- import { type AllureStore, type QualityGateConfig, type QualityGateRulesMeta, type QualityGateValidationResult, type QualityGateValidator } from "@allurereport/plugin-api";
2
- export declare abstract class AbstractQualityGateValidator implements QualityGateValidator {
3
- readonly limit: number;
4
- readonly meta?: QualityGateRulesMeta | undefined;
5
- constructor(limit: number, meta?: QualityGateRulesMeta | undefined);
6
- getTestResultsFilteredByMeta(store: AllureStore): Promise<import("@allurereport/core-api").TestResult[]>;
7
- abstract validate(store: AllureStore): Promise<QualityGateValidationResult>;
8
- }
9
- export declare class MaxFailuresValidator extends AbstractQualityGateValidator {
10
- validate(store: AllureStore): Promise<QualityGateValidationResult>;
11
- }
12
- export declare class MinTestsCountValidator extends AbstractQualityGateValidator {
13
- validate(store: AllureStore): Promise<QualityGateValidationResult>;
14
- }
15
- export declare class SuccessRateValidator extends AbstractQualityGateValidator {
16
- validate(store: AllureStore): Promise<QualityGateValidationResult>;
17
- }
18
- export declare class QualityGate {
19
- #private;
20
- readonly config?: QualityGateConfig | undefined;
21
- result: QualityGateValidationResult[];
22
- constructor(config?: QualityGateConfig | undefined);
23
- get exitCode(): 0 | 1;
24
- validate: (store: AllureStore) => Promise<void>;
25
- }
@@ -1,116 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _QualityGate_instances, _QualityGate_mappedValidators_get, _QualityGate_createRulesValidator;
7
- import { filterSuccessful, filterUnsuccessful } from "@allurereport/core-api";
8
- export class AbstractQualityGateValidator {
9
- constructor(limit, meta) {
10
- this.limit = limit;
11
- this.meta = meta;
12
- }
13
- async getTestResultsFilteredByMeta(store) {
14
- const allTrs = await store.allTestResults();
15
- if (!this.meta) {
16
- return allTrs;
17
- }
18
- return allTrs.filter((tr) => {
19
- switch (this.meta?.type) {
20
- case "label":
21
- return tr.labels.some((label) => label.name === this.meta.name && label.value === this.meta.value);
22
- case "parameter":
23
- return tr.parameters.some((parameter) => parameter.name === this.meta.name && parameter.value === this.meta.value);
24
- default:
25
- return tr;
26
- }
27
- });
28
- }
29
- }
30
- export class MaxFailuresValidator extends AbstractQualityGateValidator {
31
- async validate(store) {
32
- const trs = (await this.getTestResultsFilteredByMeta(store)).filter((tr) => !tr.hidden).filter(filterUnsuccessful);
33
- return {
34
- success: trs.length <= this.limit,
35
- rule: "maxFailures",
36
- meta: this.meta,
37
- expected: this.limit,
38
- actual: trs.length,
39
- };
40
- }
41
- }
42
- export class MinTestsCountValidator extends AbstractQualityGateValidator {
43
- async validate(store) {
44
- const trs = (await this.getTestResultsFilteredByMeta(store)).filter((tr) => !tr.hidden);
45
- return {
46
- success: trs.length >= this.limit,
47
- rule: "minTestsCount",
48
- meta: this.meta,
49
- expected: this.limit,
50
- actual: trs.length,
51
- };
52
- }
53
- }
54
- export class SuccessRateValidator extends AbstractQualityGateValidator {
55
- async validate(store) {
56
- const knownIssues = await store.allKnownIssues();
57
- const trs = (await this.getTestResultsFilteredByMeta(store)).filter((tr) => !tr.hidden);
58
- const knownIssuesHistoryIds = knownIssues.map((ki) => ki.historyId);
59
- const unknown = trs.filter((tr) => !tr.historyId || !knownIssuesHistoryIds.includes(tr.historyId));
60
- const passed = unknown.filter(filterSuccessful);
61
- const rate = passed.length === 0 ? 0 : passed.length / unknown.length;
62
- return {
63
- success: rate >= this.limit,
64
- rule: "successRate",
65
- meta: this.meta,
66
- expected: this.limit,
67
- actual: rate,
68
- };
69
- }
70
- }
71
- export class QualityGate {
72
- constructor(config) {
73
- _QualityGate_instances.add(this);
74
- this.config = config;
75
- this.result = [];
76
- _QualityGate_createRulesValidator.set(this, (rules, meta) => {
77
- const validators = [];
78
- Object.keys(rules).forEach((rule) => {
79
- const Validator = __classPrivateFieldGet(this, _QualityGate_instances, "a", _QualityGate_mappedValidators_get)[rule];
80
- if (!Validator) {
81
- return;
82
- }
83
- const validator = new Validator(rules[rule], meta);
84
- validators.push(validator);
85
- });
86
- return validators;
87
- });
88
- this.validate = async (store) => {
89
- const { rules, enforce = [] } = this.config ?? {};
90
- const validators = [];
91
- const result = [];
92
- if (rules) {
93
- validators.push(...__classPrivateFieldGet(this, _QualityGate_createRulesValidator, "f").call(this, rules));
94
- }
95
- enforce.forEach((enforceConfig) => {
96
- const { rules: enforceRules, ...meta } = enforceConfig;
97
- validators.push(...__classPrivateFieldGet(this, _QualityGate_createRulesValidator, "f").call(this, enforceRules, meta));
98
- });
99
- for (const validator of validators) {
100
- result.push(await validator.validate(store));
101
- }
102
- this.result = result;
103
- };
104
- }
105
- get exitCode() {
106
- return this.result.some((res) => !res.success) ? 1 : 0;
107
- }
108
- }
109
- _QualityGate_createRulesValidator = new WeakMap(), _QualityGate_instances = new WeakSet(), _QualityGate_mappedValidators_get = function _QualityGate_mappedValidators_get() {
110
- return {
111
- maxFailures: MaxFailuresValidator,
112
- minTestsCount: MinTestsCountValidator,
113
- successRate: SuccessRateValidator,
114
- ...this.config?.validators,
115
- };
116
- };