@allurereport/core 3.1.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { DefaultLabelsConfig, EnvironmentsConfig, KnownTestFailure, ReportVariables } from "@allurereport/core-api";
1
+ import type { CategoriesConfig, DefaultLabelsConfig, EnvironmentsConfig, KnownTestFailure, ReportVariables } from "@allurereport/core-api";
2
2
  import type { Plugin, QualityGateConfig, ReportFiles } from "@allurereport/plugin-api";
3
3
  import type { ResultsReader } from "@allurereport/reader-api";
4
4
  export interface PluginInstance {
@@ -16,7 +16,7 @@ export interface FullConfig {
16
16
  historyLimit?: number;
17
17
  knownIssuesPath: string;
18
18
  defaultLabels?: DefaultLabelsConfig;
19
- stage?: string;
19
+ dump?: string;
20
20
  environment?: string;
21
21
  environments?: EnvironmentsConfig;
22
22
  variables?: ReportVariables;
@@ -27,6 +27,7 @@ export interface FullConfig {
27
27
  known?: KnownTestFailure[];
28
28
  realTime?: any;
29
29
  qualityGate?: QualityGateConfig;
30
+ categories?: CategoriesConfig;
30
31
  allureService?: {
31
32
  accessToken?: string;
32
33
  };
package/dist/config.js CHANGED
@@ -61,6 +61,7 @@ export const validateConfig = (config) => {
61
61
  "appendHistory",
62
62
  "qualityGate",
63
63
  "allureService",
64
+ "categories",
64
65
  ];
65
66
  const unsupportedFields = Object.keys(config).filter((key) => !supportedFields.includes(key));
66
67
  return {
@@ -138,6 +139,7 @@ export const resolveConfig = async (config, override = {}) => {
138
139
  defaultLabels: config.defaultLabels ?? {},
139
140
  qualityGate: config.qualityGate,
140
141
  allureService: config.allureService,
142
+ categories: config.categories,
141
143
  };
142
144
  };
143
145
  export const readConfig = async (cwd = process.cwd(), configPath, override) => {
package/dist/history.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { AllureHistory, HistoryDataPoint, TestCase, TestResult } from "@allurereport/core-api";
2
2
  export declare const createHistory: (reportUuid: string, reportName: string | undefined, testCases: TestCase[], testResults: TestResult[], remoteUrl?: string) => HistoryDataPoint;
3
- export declare const writeHistory: (historyPath: string, data: HistoryDataPoint) => Promise<void>;
4
3
  export declare class AllureLocalHistory implements AllureHistory {
4
+ #private;
5
5
  private readonly params;
6
6
  constructor(params: {
7
7
  historyPath: string;
package/dist/history.js CHANGED
@@ -1,5 +1,20 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
2
- import { dirname, resolve } from "node:path";
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 __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _AllureLocalHistory_cachedHistory, _AllureLocalHistory_openFileToReadIfExists, _AllureLocalHistory_ensureFileOpenedToAppend, _AllureLocalHistory_findFirstEntryAddress, _AllureLocalHistory_throwUnexpectedReadError;
13
+ import { once } from "node:events";
14
+ import { mkdir, open } from "node:fs/promises";
15
+ import path from "node:path";
16
+ import readline from "node:readline/promises";
17
+ import { pipeline } from "node:stream/promises";
3
18
  import { isFileNotFoundError } from "./utils/misc.js";
4
19
  const createHistoryItems = (testResults) => {
5
20
  return testResults
@@ -39,46 +54,143 @@ export const createHistory = (reportUuid, reportName = "Allure Report", testCase
39
54
  url: remoteUrl,
40
55
  };
41
56
  };
42
- export const writeHistory = async (historyPath, data) => {
43
- const path = resolve(historyPath);
44
- const parentDir = dirname(path);
45
- await mkdir(parentDir, { recursive: true });
46
- await writeFile(path, `${JSON.stringify(data)}\n`, { encoding: "utf-8", flag: "a+" });
47
- };
48
57
  export class AllureLocalHistory {
49
58
  constructor(params) {
50
59
  this.params = params;
60
+ _AllureLocalHistory_cachedHistory.set(this, []);
61
+ _AllureLocalHistory_openFileToReadIfExists.set(this, async (filePath) => {
62
+ try {
63
+ return await open(filePath, "r");
64
+ }
65
+ catch (e) {
66
+ if (isFileNotFoundError(e)) {
67
+ return undefined;
68
+ }
69
+ throw e;
70
+ }
71
+ });
72
+ _AllureLocalHistory_ensureFileOpenedToAppend.set(this, async (filePath) => {
73
+ try {
74
+ return {
75
+ file: await open(filePath, "r+"),
76
+ exists: true,
77
+ };
78
+ }
79
+ catch (e) {
80
+ if (isFileNotFoundError(e)) {
81
+ return {
82
+ file: await open(filePath, "w"),
83
+ exists: false,
84
+ };
85
+ }
86
+ throw e;
87
+ }
88
+ });
89
+ _AllureLocalHistory_findFirstEntryAddress.set(this, async (jsonlFile, limit) => {
90
+ if (limit === undefined) {
91
+ return 0;
92
+ }
93
+ if (limit < 0) {
94
+ throw new Error(`Invalid history limit ${limit}. A history limit must be a positive integer number`);
95
+ }
96
+ const stat = await jsonlFile.stat();
97
+ let { size: position } = stat;
98
+ const { mtimeMs: originalMtime } = stat;
99
+ if (position === 0 || limit === 0) {
100
+ return position;
101
+ }
102
+ const buffer = Buffer.alloc(Buffer.poolSize);
103
+ while (position) {
104
+ const bytesToRead = Math.min(position, buffer.byteLength);
105
+ position -= bytesToRead;
106
+ const { bytesRead } = await jsonlFile.read({ buffer, length: bytesToRead, position });
107
+ if (bytesRead !== bytesToRead) {
108
+ __classPrivateFieldGet(this, _AllureLocalHistory_throwUnexpectedReadError, "f").call(this, jsonlFile, originalMtime, bytesToRead, bytesRead);
109
+ }
110
+ for (let i = bytesToRead - 1; i >= 0; i--) {
111
+ if (buffer[i] === 0x0a) {
112
+ if (limit-- === 0) {
113
+ return position + i + 1;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ return 0;
119
+ });
120
+ _AllureLocalHistory_throwUnexpectedReadError.set(this, async (file, mtime, expectedBytes, actualBytes) => {
121
+ const { mtimeMs: currentMtime } = await file.stat();
122
+ if (currentMtime !== mtime) {
123
+ throw new Error("The history file was modified outside Allure. " +
124
+ "Please, make sure the file doesn't change while Allure is running");
125
+ }
126
+ throw new Error(`Can't read the history file: the expected number of bytes to read ${expectedBytes} ` +
127
+ `doesn't match the actual number ${actualBytes}`);
128
+ });
51
129
  }
52
130
  async readHistory() {
53
- const path = resolve(this.params.historyPath);
131
+ if (__classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f").length > 0) {
132
+ return __classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f");
133
+ }
134
+ const fullPath = path.resolve(this.params.historyPath);
135
+ const historyFile = await __classPrivateFieldGet(this, _AllureLocalHistory_openFileToReadIfExists, "f").call(this, fullPath);
136
+ if (historyFile === undefined) {
137
+ return [];
138
+ }
54
139
  try {
55
- const historyPoints = (await readFile(path, { encoding: "utf-8" }))
56
- .split("\n")
57
- .filter((line) => line && line.trim() !== "")
58
- .map((line) => JSON.parse(line));
59
- if (this.params.limit) {
60
- return historyPoints.slice(-this.params.limit);
61
- }
62
- return historyPoints;
140
+ const start = await __classPrivateFieldGet(this, _AllureLocalHistory_findFirstEntryAddress, "f").call(this, historyFile, this.params.limit);
141
+ const stream = historyFile.createReadStream({ start, encoding: "utf-8", autoClose: false });
142
+ const historyPoints = [];
143
+ const readlineInterface = readline
144
+ .createInterface({ input: stream, terminal: false, crlfDelay: Infinity })
145
+ .on("line", (line) => {
146
+ if (line && line.trim().length) {
147
+ const historyEntry = JSON.parse(line);
148
+ historyPoints.push(historyEntry);
149
+ }
150
+ });
151
+ await once(readlineInterface, "close");
152
+ __classPrivateFieldSet(this, _AllureLocalHistory_cachedHistory, historyPoints, "f");
153
+ return __classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f");
63
154
  }
64
- catch (e) {
65
- if (isFileNotFoundError(e)) {
66
- return [];
67
- }
68
- throw e;
155
+ finally {
156
+ await historyFile.close();
69
157
  }
70
158
  }
71
159
  async appendHistory(data) {
72
- const path = resolve(this.params.historyPath);
73
- const parentDir = dirname(path);
160
+ const fullPath = path.resolve(this.params.historyPath);
161
+ const parentDir = path.dirname(fullPath);
162
+ const { limit } = this.params;
74
163
  await mkdir(parentDir, { recursive: true });
75
- if (!this.params.limit) {
76
- await writeFile(path, `${JSON.stringify(data)}\n`, { encoding: "utf-8", flag: "a+" });
77
- return;
164
+ const { file: historyFile, exists: historyExists } = await __classPrivateFieldGet(this, _AllureLocalHistory_ensureFileOpenedToAppend, "f").call(this, fullPath);
165
+ try {
166
+ const dst = historyFile.createWriteStream({ encoding: "utf-8", start: 0, autoClose: false });
167
+ if (limit === 0 && historyExists) {
168
+ await historyFile.truncate(0);
169
+ return;
170
+ }
171
+ if (limit === 0 && !historyExists) {
172
+ return;
173
+ }
174
+ if (historyExists) {
175
+ const start = await __classPrivateFieldGet(this, _AllureLocalHistory_findFirstEntryAddress, "f").call(this, historyFile, limit ? limit - 1 : undefined);
176
+ const src = historyFile.createReadStream({ start, autoClose: false });
177
+ await pipeline(src, dst, { end: false });
178
+ }
179
+ const sources = [JSON.stringify(data), Buffer.from([0x0a])];
180
+ await pipeline(sources, dst);
181
+ if (historyExists) {
182
+ await historyFile.truncate(dst.bytesWritten);
183
+ }
184
+ }
185
+ finally {
186
+ await historyFile.close();
187
+ if (limit !== 0) {
188
+ __classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f").push(data);
189
+ }
190
+ if (limit) {
191
+ __classPrivateFieldGet(this, _AllureLocalHistory_cachedHistory, "f").splice(limit);
192
+ }
78
193
  }
79
- const existingHistory = await this.readHistory();
80
- const updatedHistory = [...existingHistory, data].slice(-this.params.limit);
81
- const fileContent = updatedHistory.reduce((acc, point) => `${acc}${JSON.stringify(point)}\n`, "");
82
- await writeFile(path, fileContent, "utf-8");
83
194
  }
84
195
  }
196
+ _AllureLocalHistory_cachedHistory = new WeakMap(), _AllureLocalHistory_openFileToReadIfExists = new WeakMap(), _AllureLocalHistory_ensureFileOpenedToAppend = new WeakMap(), _AllureLocalHistory_findFirstEntryAddress = new WeakMap(), _AllureLocalHistory_throwUnexpectedReadError = new WeakMap();
@@ -1,4 +1,4 @@
1
- import type { KnownTestFailure, TestError, TestResult } from "@allurereport/core-api";
1
+ import { type KnownTestFailure, type TestError, type TestResult } from "@allurereport/core-api";
2
2
  import type { QualityGateConfig, QualityGateValidationResult } from "@allurereport/plugin-api";
3
3
  export declare const stringifyQualityGateResults: (results: QualityGateValidationResult[]) => string;
4
4
  export declare const convertQualityGateResultsToTestErrors: (results: QualityGateValidationResult[]) => TestError[];
@@ -14,6 +14,7 @@ export declare class QualityGate {
14
14
  state?: QualityGateState;
15
15
  trs: TestResult[];
16
16
  knownIssues: KnownTestFailure[];
17
+ environment?: string;
17
18
  }): Promise<{
18
19
  fastFailed: boolean;
19
20
  results: QualityGateValidationResult[];
@@ -4,6 +4,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _QualityGateState_state;
7
+ import { DEFAULT_ENVIRONMENT } from "@allurereport/core-api";
7
8
  import { gray, red } from "yoctocolors";
8
9
  import { qualityGateDefaultRules } from "./rules.js";
9
10
  export const stringifyQualityGateResults = (results) => {
@@ -44,7 +45,7 @@ export class QualityGate {
44
45
  this.config = config;
45
46
  }
46
47
  async validate(payload) {
47
- const { state, trs, knownIssues } = payload;
48
+ const { state, trs, knownIssues, environment } = payload;
48
49
  const { rules, use = [...qualityGateDefaultRules] } = this.config;
49
50
  const results = [];
50
51
  let fastFailed = false;
@@ -88,6 +89,7 @@ export class QualityGate {
88
89
  actual: result.actual,
89
90
  expected,
90
91
  }),
92
+ environment: environment || DEFAULT_ENVIRONMENT,
91
93
  });
92
94
  if (ruleset.fastFail) {
93
95
  fastFailed = true;
package/dist/report.d.ts CHANGED
@@ -20,12 +20,13 @@ export declare class AllureReport {
20
20
  trs: TestResult[];
21
21
  knownIssues: KnownTestFailure[];
22
22
  state?: QualityGateState;
23
+ environment?: string;
23
24
  }) => Promise<{
24
25
  fastFailed: boolean;
25
26
  results: import("@allurereport/plugin-api").QualityGateValidationResult[];
26
27
  }>;
27
28
  start: () => Promise<void>;
28
29
  dumpState: () => Promise<void>;
29
- restoreState: (stages: string[]) => Promise<void>;
30
+ restoreState: (dumps: string[]) => Promise<void>;
30
31
  done: () => Promise<void>;
31
32
  }
package/dist/report.js CHANGED
@@ -9,8 +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 _AllureReport_instances, _AllureReport_reportName, _AllureReport_reportVariables, _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_stage, _AllureReport_stageTempDirs, _AllureReport_state, _AllureReport_executionStage, _AllureReport_publish_get, _AllureReport_update, _AllureReport_eachPlugin, _AllureReport_getPluginState;
12
+ var _AllureReport_instances, _AllureReport_reportName, _AllureReport_reportVariables, _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_dump, _AllureReport_categories, _AllureReport_dumpTempDirs, _AllureReport_state, _AllureReport_executionStage, _AllureReport_publish_get, _AllureReport_update, _AllureReport_eachPlugin, _AllureReport_getPluginState;
13
13
  import { detect } from "@allurereport/ci";
14
+ import { normalizeCategoriesConfig } from "@allurereport/core-api";
14
15
  import { AllureStoreDumpFiles, } from "@allurereport/plugin-api";
15
16
  import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
16
17
  import { PathResultFile } from "@allurereport/reader-api";
@@ -53,8 +54,9 @@ export class AllureReport {
53
54
  _AllureReport_history.set(this, void 0);
54
55
  _AllureReport_allureServiceClient.set(this, void 0);
55
56
  _AllureReport_qualityGate.set(this, void 0);
56
- _AllureReport_stage.set(this, void 0);
57
- _AllureReport_stageTempDirs.set(this, []);
57
+ _AllureReport_dump.set(this, void 0);
58
+ _AllureReport_categories.set(this, void 0);
59
+ _AllureReport_dumpTempDirs.set(this, []);
58
60
  _AllureReport_state.set(this, void 0);
59
61
  _AllureReport_executionStage.set(this, "init");
60
62
  this.readDirectory = async (resultsDir) => {
@@ -99,11 +101,12 @@ export class AllureReport {
99
101
  }
100
102
  };
101
103
  this.validate = async (params) => {
102
- const { trs, knownIssues, state } = params;
104
+ const { trs, knownIssues, state, environment } = params;
103
105
  return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate({
104
106
  trs: trs.filter(Boolean),
105
107
  knownIssues,
106
108
  state,
109
+ environment,
107
110
  });
108
111
  };
109
112
  this.start = async () => {
@@ -143,13 +146,13 @@ export class AllureReport {
143
146
  });
144
147
  });
145
148
  this.dumpState = async () => {
146
- const { testResults, testCases, fixtures, attachments: attachmentsLinks, environments, globalAttachments = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResultsByRules = {}, } = __classPrivateFieldGet(this, _AllureReport_store, "f").dumpState();
149
+ const { testResults, testCases, fixtures, attachments: attachmentsLinks, environments, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResults = [], } = __classPrivateFieldGet(this, _AllureReport_store, "f").dumpState();
147
150
  const allAttachments = await __classPrivateFieldGet(this, _AllureReport_store, "f").allAttachments();
148
151
  const dumpArchive = new ZipWriteStream({
149
152
  zlib: { level: 5 },
150
153
  });
151
154
  const addEntry = promisify(dumpArchive.entry.bind(dumpArchive));
152
- const dumpArchiveWriteStream = createWriteStream(`${__classPrivateFieldGet(this, _AllureReport_stage, "f")}.zip`);
155
+ const dumpArchiveWriteStream = createWriteStream(`${__classPrivateFieldGet(this, _AllureReport_dump, "f")}.zip`);
153
156
  const promise = new Promise((res, rej) => {
154
157
  dumpArchive.on("error", (err) => rej(err));
155
158
  dumpArchiveWriteStream.on("finish", () => res(void 0));
@@ -174,7 +177,7 @@ export class AllureReport {
174
177
  await addEntry(Buffer.from(JSON.stringify(__classPrivateFieldGet(this, _AllureReport_reportVariables, "f"))), {
175
178
  name: AllureStoreDumpFiles.ReportVariables,
176
179
  });
177
- await addEntry(Buffer.from(JSON.stringify(globalAttachments)), {
180
+ await addEntry(Buffer.from(JSON.stringify(globalAttachmentIds)), {
178
181
  name: AllureStoreDumpFiles.GlobalAttachments,
179
182
  });
180
183
  await addEntry(Buffer.from(JSON.stringify(globalErrors)), {
@@ -201,8 +204,8 @@ export class AllureReport {
201
204
  await addEntry(Buffer.from(JSON.stringify(indexKnownByHistoryId)), {
202
205
  name: AllureStoreDumpFiles.IndexKnownByHistoryId,
203
206
  });
204
- await addEntry(Buffer.from(JSON.stringify(qualityGateResultsByRules)), {
205
- name: AllureStoreDumpFiles.QualityGateResultsByRules,
207
+ await addEntry(Buffer.from(JSON.stringify(qualityGateResults)), {
208
+ name: AllureStoreDumpFiles.QualityGateResults,
206
209
  });
207
210
  for (const attachment of allAttachments) {
208
211
  const content = await __classPrivateFieldGet(this, _AllureReport_store, "f").attachmentContentById(attachment.id);
@@ -223,31 +226,31 @@ export class AllureReport {
223
226
  dumpArchive.finalize();
224
227
  return promise;
225
228
  };
226
- this.restoreState = async (stages) => {
227
- for (const stage of stages) {
228
- if (!existsSync(stage)) {
229
+ this.restoreState = async (dumps) => {
230
+ for (const dump of dumps) {
231
+ if (!existsSync(dump)) {
229
232
  continue;
230
233
  }
231
- const dump = new ZipReadStream.async({
232
- file: stage,
234
+ const dumpArchive = new ZipReadStream.async({
235
+ file: dump,
233
236
  });
234
- const testResultsEntry = await dump.entryData(AllureStoreDumpFiles.TestResults);
235
- const testCasesEntry = await dump.entryData(AllureStoreDumpFiles.TestCases);
236
- const fixturesEntry = await dump.entryData(AllureStoreDumpFiles.Fixtures);
237
- const attachmentsEntry = await dump.entryData(AllureStoreDumpFiles.Attachments);
238
- const environmentsEntry = await dump.entryData(AllureStoreDumpFiles.Environments);
239
- const reportVariablesEntry = await dump.entryData(AllureStoreDumpFiles.ReportVariables);
240
- const globalAttachmentsEntry = await dump.entryData(AllureStoreDumpFiles.GlobalAttachments);
241
- const globalErrorsEntry = await dump.entryData(AllureStoreDumpFiles.GlobalErrors);
242
- const indexAttachmentsEntry = await dump.entryData(AllureStoreDumpFiles.IndexAttachmentsByTestResults);
243
- const indexTestResultsByHistoryId = await dump.entryData(AllureStoreDumpFiles.IndexTestResultsByHistoryId);
244
- const indexTestResultsByTestCaseEntry = await dump.entryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
245
- const indexLatestEnvTestResultsByHistoryIdEntry = await dump.entryData(AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId);
246
- const indexAttachmentsByFixtureEntry = await dump.entryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
247
- const indexFixturesByTestResultEntry = await dump.entryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
248
- const indexKnownByHistoryIdEntry = await dump.entryData(AllureStoreDumpFiles.IndexKnownByHistoryId);
249
- const qualityGateResultsByRulesEntry = await dump.entryData(AllureStoreDumpFiles.QualityGateResultsByRules);
250
- const attachmentsEntries = Object.entries(await dump.entries()).reduce((acc, [entryName, entry]) => {
237
+ const testResultsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.TestResults);
238
+ const testCasesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.TestCases);
239
+ const fixturesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Fixtures);
240
+ const attachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Attachments);
241
+ const environmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Environments);
242
+ const reportVariablesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.ReportVariables);
243
+ const globalAttachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.GlobalAttachments);
244
+ const globalErrorsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.GlobalErrors);
245
+ const indexAttachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexAttachmentsByTestResults);
246
+ const indexTestResultsByHistoryId = await dumpArchive.entryData(AllureStoreDumpFiles.IndexTestResultsByHistoryId);
247
+ const indexTestResultsByTestCaseEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
248
+ const indexLatestEnvTestResultsByHistoryIdEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId);
249
+ const indexAttachmentsByFixtureEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
250
+ const indexFixturesByTestResultEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
251
+ const indexKnownByHistoryIdEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexKnownByHistoryId);
252
+ const qualityGateResultsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.QualityGateResults);
253
+ const attachmentsEntries = Object.entries(await dumpArchive.entries()).reduce((acc, [entryName, entry]) => {
251
254
  switch (entryName) {
252
255
  case AllureStoreDumpFiles.Attachments:
253
256
  case AllureStoreDumpFiles.TestResults:
@@ -264,7 +267,7 @@ export class AllureReport {
264
267
  case AllureStoreDumpFiles.IndexAttachmentsByFixture:
265
268
  case AllureStoreDumpFiles.IndexFixturesByTestResult:
266
269
  case AllureStoreDumpFiles.IndexKnownByHistoryId:
267
- case AllureStoreDumpFiles.QualityGateResultsByRules:
270
+ case AllureStoreDumpFiles.QualityGateResults:
268
271
  return acc;
269
272
  default:
270
273
  return Object.assign(acc, {
@@ -279,7 +282,7 @@ export class AllureReport {
279
282
  attachments: JSON.parse(attachmentsEntry.toString("utf8")),
280
283
  environments: JSON.parse(environmentsEntry.toString("utf8")),
281
284
  reportVariables: JSON.parse(reportVariablesEntry.toString("utf8")),
282
- globalAttachments: JSON.parse(globalAttachmentsEntry.toString("utf8")),
285
+ globalAttachmentIds: JSON.parse(globalAttachmentsEntry.toString("utf8")),
283
286
  globalErrors: JSON.parse(globalErrorsEntry.toString("utf8")),
284
287
  indexAttachmentByTestResult: JSON.parse(indexAttachmentsEntry.toString("utf8")),
285
288
  indexTestResultByHistoryId: JSON.parse(indexTestResultsByHistoryId.toString("utf8")),
@@ -288,25 +291,25 @@ export class AllureReport {
288
291
  indexAttachmentByFixture: JSON.parse(indexAttachmentsByFixtureEntry.toString("utf8")),
289
292
  indexFixturesByTestResult: JSON.parse(indexFixturesByTestResultEntry.toString("utf8")),
290
293
  indexKnownByHistoryId: JSON.parse(indexKnownByHistoryIdEntry.toString("utf8")),
291
- qualityGateResultsByRules: JSON.parse(qualityGateResultsByRulesEntry.toString("utf8")),
294
+ qualityGateResults: JSON.parse(qualityGateResultsEntry.toString("utf8")),
292
295
  };
293
- const stageTempDir = await mkdtemp(join(tmpdir(), basename(stage, ".zip")));
296
+ const dumpTempDir = await mkdtemp(join(tmpdir(), basename(dump, ".zip")));
294
297
  const resultsAttachments = {};
295
- __classPrivateFieldGet(this, _AllureReport_stageTempDirs, "f").push(stageTempDir);
298
+ __classPrivateFieldGet(this, _AllureReport_dumpTempDirs, "f").push(dumpTempDir);
296
299
  try {
297
300
  for (const [attachmentId] of Object.entries(attachmentsEntries)) {
298
- const attachmentContentEntry = await dump.entryData(attachmentId);
299
- const attachmentFilePath = join(stageTempDir, attachmentId);
301
+ const attachmentContentEntry = await dumpArchive.entryData(attachmentId);
302
+ const attachmentFilePath = join(dumpTempDir, attachmentId);
300
303
  await writeFile(attachmentFilePath, attachmentContentEntry);
301
304
  resultsAttachments[attachmentId] = new PathResultFile(attachmentFilePath, attachmentId);
302
305
  }
303
306
  }
304
307
  catch (err) {
305
- console.error(`Can't restore state from "${stage}", continuing without it`);
308
+ console.error(`Can't restore state from "${dump}", continuing without it`);
306
309
  console.error(err);
307
310
  }
308
311
  await __classPrivateFieldGet(this, _AllureReport_store, "f").restoreState(dumpState, resultsAttachments);
309
- console.info(`Successfully restored state from "${stage}"`);
312
+ console.info(`Successfully restored state from "${dump}"`);
310
313
  }
311
314
  };
312
315
  this.done = async () => {
@@ -321,7 +324,7 @@ export class AllureReport {
321
324
  const historyDataPoint = createHistory(this.reportUuid, __classPrivateFieldGet(this, _AllureReport_reportName, "f"), testCases, testResults, this.reportUrl);
322
325
  __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f").offAll();
323
326
  __classPrivateFieldSet(this, _AllureReport_executionStage, "done", "f");
324
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f")) {
327
+ if (__classPrivateFieldGet(this, _AllureReport_dump, "f")) {
325
328
  await this.dumpState();
326
329
  return;
327
330
  }
@@ -429,7 +432,7 @@ export class AllureReport {
429
432
  }
430
433
  await rm(reportPath, { recursive: true });
431
434
  }
432
- for (const dir of __classPrivateFieldGet(this, _AllureReport_stageTempDirs, "f")) {
435
+ for (const dir of __classPrivateFieldGet(this, _AllureReport_dumpTempDirs, "f")) {
433
436
  try {
434
437
  await rm(dir, { recursive: true });
435
438
  }
@@ -460,7 +463,7 @@ export class AllureReport {
460
463
  if (!__classPrivateFieldGet(this, _AllureReport_qualityGate, "f")) {
461
464
  return;
462
465
  }
463
- const qualityGateResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").qualityGateResults();
466
+ const qualityGateResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").qualityGateResultsByEnv();
464
467
  await writeFile(join(__classPrivateFieldGet(this, _AllureReport_output, "f"), "quality-gate.json"), JSON.stringify(qualityGateResults));
465
468
  };
466
469
  _AllureReport_eachPlugin.set(this, async (initState, consumer) => {
@@ -498,6 +501,8 @@ export class AllureReport {
498
501
  reportUrl: this.reportUrl,
499
502
  output: __classPrivateFieldGet(this, _AllureReport_output, "f"),
500
503
  ci: __classPrivateFieldGet(this, _AllureReport_ci, "f"),
504
+ categories: __classPrivateFieldGet(this, _AllureReport_categories, "f"),
505
+ history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
501
506
  };
502
507
  try {
503
508
  await consumer.call(this, plugin, pluginContext);
@@ -510,7 +515,7 @@ export class AllureReport {
510
515
  }
511
516
  }
512
517
  });
513
- const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, historyLimit, defaultLabels = {}, variables = {}, environment, environments, output, qualityGate, stage, allureService: allureServiceConfig, } = opts;
518
+ const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, historyLimit, defaultLabels = {}, variables = {}, environment, environments, output, qualityGate, dump, categories, allureService: allureServiceConfig, } = opts;
514
519
  __classPrivateFieldSet(this, _AllureReport_allureServiceClient, allureServiceConfig?.accessToken
515
520
  ? new AllureServiceClient(allureServiceConfig)
516
521
  : undefined, "f");
@@ -523,21 +528,22 @@ export class AllureReport {
523
528
  __classPrivateFieldSet(this, _AllureReport_realtimeDispatcher, new RealtimeEventsDispatcher(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
524
529
  __classPrivateFieldSet(this, _AllureReport_realtimeSubscriber, new RealtimeSubscriber(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
525
530
  __classPrivateFieldSet(this, _AllureReport_realTime, realTime, "f");
526
- __classPrivateFieldSet(this, _AllureReport_stage, stage, "f");
531
+ __classPrivateFieldSet(this, _AllureReport_dump, dump, "f");
527
532
  if (qualityGate) {
528
533
  __classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
529
534
  }
535
+ __classPrivateFieldSet(this, _AllureReport_categories, normalizeCategoriesConfig(categories), "f");
530
536
  if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")) {
531
537
  __classPrivateFieldSet(this, _AllureReport_history, new AllureRemoteHistory({
532
- allureServiceClient: __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f"),
533
- branch: __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunBranch,
534
538
  limit: historyLimit,
539
+ branch: __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunBranch,
540
+ allureServiceClient: __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f"),
535
541
  }), "f");
536
542
  }
537
543
  else if (historyPath) {
538
544
  __classPrivateFieldSet(this, _AllureReport_history, new AllureLocalHistory({
539
- historyPath,
540
545
  limit: historyLimit,
546
+ historyPath,
541
547
  }), "f");
542
548
  }
543
549
  __classPrivateFieldSet(this, _AllureReport_store, new DefaultAllureStore({
@@ -568,7 +574,7 @@ export class AllureReport {
568
574
  return __classPrivateFieldGet(this, _AllureReport_realtimeDispatcher, "f");
569
575
  }
570
576
  }
571
- _AllureReport_reportName = new WeakMap(), _AllureReport_reportVariables = 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_stage = new WeakMap(), _AllureReport_stageTempDirs = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_executionStage = new WeakMap(), _AllureReport_update = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_publish_get = function _AllureReport_publish_get() {
577
+ _AllureReport_reportName = new WeakMap(), _AllureReport_reportVariables = 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_dump = new WeakMap(), _AllureReport_categories = new WeakMap(), _AllureReport_dumpTempDirs = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_executionStage = new WeakMap(), _AllureReport_update = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_publish_get = function _AllureReport_publish_get() {
572
578
  return __classPrivateFieldGet(this, _AllureReport_plugins, "f").some(({ enabled, options }) => enabled && options.publish);
573
579
  }, _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
574
580
  return init ? new DefaultPluginState({}) : __classPrivateFieldGet(this, _AllureReport_state, "f")?.[id];
@@ -1,7 +1,6 @@
1
1
  import { findByLabelName, notNull } from "@allurereport/core-api";
2
2
  import { md5 } from "@allurereport/plugin-api";
3
3
  import { extension, lookupContentType } from "@allurereport/reader-api";
4
- import MarkdownIt from "markdown-it";
5
4
  import { randomUUID } from "node:crypto";
6
5
  const defaultStatus = "unknown";
7
6
  export const __unknown = "#___unknown_value___#";
@@ -47,11 +46,11 @@ export const testResultRawToState = (stateData, raw, context) => {
47
46
  },
48
47
  ...processTimings(raw),
49
48
  description: raw.description,
50
- descriptionHtml: raw.descriptionHtml ?? markdownToHtml(raw.description),
49
+ descriptionHtml: raw.descriptionHtml,
51
50
  precondition: raw.precondition,
52
- preconditionHtml: raw.preconditionHtml ?? markdownToHtml(raw.precondition),
51
+ preconditionHtml: raw.preconditionHtml,
53
52
  expectedResult: raw.expectedResult,
54
- expectedResultHtml: raw.expectedResultHtml ?? markdownToHtml(raw.expectedResult),
53
+ expectedResultHtml: raw.expectedResultHtml,
55
54
  flaky: raw.flaky ?? false,
56
55
  muted: raw.muted ?? false,
57
56
  known: raw.known ?? false,
@@ -235,7 +234,6 @@ const convertLink = (link) => ({
235
234
  url: link.url ?? __unknown,
236
235
  type: link.type,
237
236
  });
238
- const markdownToHtml = (value) => (value ? new MarkdownIt().render(value) : undefined);
239
237
  const calculateTestId = (raw) => {
240
238
  const maybeAllureId = raw.labels?.find((label) => label.name === "ALLURE_ID" || label.name === "AS_ID")?.value;
241
239
  if (maybeAllureId) {
@@ -1,6 +1,6 @@
1
- import { type AllureHistory, type AttachmentLink, type DefaultLabelsConfig, 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";
1
+ import { type AllureHistory, type AttachmentLink, type AttachmentLinkLinked, type DefaultLabelsConfig, 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
2
  import { type AllureStore, type AllureStoreDump, type ExitCode, type QualityGateValidationResult, type RealtimeEventsDispatcher, type RealtimeSubscriber, type ResultFile, type TestResultFilter } from "@allurereport/plugin-api";
3
- import type { RawFixtureResult, RawMetadata, RawTestResult, ReaderContext, ResultsVisitor } from "@allurereport/reader-api";
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 {
@@ -25,16 +25,19 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
25
25
  readHistory(): Promise<HistoryDataPoint[]>;
26
26
  appendHistory(history: HistoryDataPoint): Promise<void>;
27
27
  qualityGateResults(): Promise<QualityGateValidationResult[]>;
28
+ qualityGateResultsByEnv(): Promise<Record<string, QualityGateValidationResult[]>>;
28
29
  globalExitCode(): Promise<ExitCode | undefined>;
29
30
  allGlobalErrors(): Promise<TestError[]>;
30
- allGlobalAttachments(): Promise<AttachmentLink[]>;
31
+ allGlobalAttachments(): Promise<AttachmentLinkLinked[]>;
31
32
  visitTestResult(raw: RawTestResult, context: ReaderContext): Promise<void>;
32
33
  visitTestFixtureResult(result: RawFixtureResult, context: ReaderContext): Promise<void>;
33
- visitAttachmentFile(resultFile: ResultFile, context: ReaderContext): Promise<void>;
34
+ visitAttachmentFile(resultFile: ResultFile): Promise<void>;
34
35
  visitMetadata(metadata: RawMetadata): Promise<void>;
36
+ visitGlobals(globals: RawGlobals): Promise<void>;
35
37
  allTestCases(): Promise<TestCase[]>;
36
38
  allTestResults(options?: {
37
39
  includeHidden?: boolean;
40
+ filter?: TestResultFilter;
38
41
  }): Promise<TestResult[]>;
39
42
  allAttachments(options?: {
40
43
  includeMissed?: boolean;
@@ -45,7 +48,7 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
45
48
  allHistoryDataPoints(): Promise<HistoryDataPoint[]>;
46
49
  allHistoryDataPointsByEnvironment(environment: string): Promise<HistoryDataPoint[]>;
47
50
  allKnownIssues(): Promise<KnownTestFailure[]>;
48
- allNewTestResults(): Promise<TestResult[]>;
51
+ allNewTestResults(filter?: TestResultFilter, history?: HistoryDataPoint[]): Promise<TestResult[]>;
49
52
  testCaseById(tcId: string): Promise<TestCase | undefined>;
50
53
  testResultById(trId: string): Promise<TestResult | undefined>;
51
54
  attachmentById(attachmentId: string): Promise<AttachmentLink | undefined>;
@@ -61,8 +64,8 @@ export declare class DefaultAllureStore implements AllureStore, ResultsVisitor {
61
64
  failedTestResults(): Promise<TestResult[]>;
62
65
  unknownFailedTestResults(): Promise<TestResult[]>;
63
66
  testResultsByLabel(labelName: string): Promise<{
64
- [x: string]: TestResult[];
65
67
  _: TestResult[];
68
+ [x: string]: TestResult[];
66
69
  }>;
67
70
  testsStatistic(filter?: TestResultFilter): Promise<Statistic>;
68
71
  allEnvironments(): Promise<string[]>;
@@ -9,9 +9,10 @@ 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_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history, _DefaultAllureStore_known, _DefaultAllureStore_fixtures, _DefaultAllureStore_defaultLabels, _DefaultAllureStore_environment, _DefaultAllureStore_environmentsConfig, _DefaultAllureStore_reportVariables, _DefaultAllureStore_realtimeDispatcher, _DefaultAllureStore_realtimeSubscriber, _DefaultAllureStore_globalAttachments, _DefaultAllureStore_globalErrors, _DefaultAllureStore_globalExitCode, _DefaultAllureStore_qualityGateResultsByRules, _DefaultAllureStore_historyPoints, _DefaultAllureStore_environments, _DefaultAllureStore_addEnvironments;
13
- import { DEFAULT_ENVIRONMENT, compareBy, getWorstStatus, htrsByTr, matchEnvironment, nullsLast, ordinal, reverse, } from "@allurereport/core-api";
12
+ var _DefaultAllureStore_instances, _DefaultAllureStore_testResults, _DefaultAllureStore_attachments, _DefaultAllureStore_attachmentContents, _DefaultAllureStore_testCases, _DefaultAllureStore_metadata, _DefaultAllureStore_history, _DefaultAllureStore_known, _DefaultAllureStore_fixtures, _DefaultAllureStore_defaultLabels, _DefaultAllureStore_environment, _DefaultAllureStore_environmentsConfig, _DefaultAllureStore_reportVariables, _DefaultAllureStore_realtimeDispatcher, _DefaultAllureStore_realtimeSubscriber, _DefaultAllureStore_globalAttachmentIds, _DefaultAllureStore_globalErrors, _DefaultAllureStore_globalExitCode, _DefaultAllureStore_qualityGateResults, _DefaultAllureStore_historyPoints, _DefaultAllureStore_environments, _DefaultAllureStore_addEnvironments;
13
+ import { DEFAULT_ENVIRONMENT, compareBy, createDictionary, getWorstStatus, htrsByTr, matchEnvironment, nullsLast, ordinal, reverse, } from "@allurereport/core-api";
14
14
  import { md5, } from "@allurereport/plugin-api";
15
+ import { extname } from "node:path";
15
16
  import { isFlaky } from "../utils/flaky.js";
16
17
  import { getStatusTransition } from "../utils/new.js";
17
18
  import { testFixtureResultRawToState, testResultRawToState } from "./convert.js";
@@ -86,10 +87,10 @@ export class DefaultAllureStore {
86
87
  this.indexAttachmentByFixture = new Map();
87
88
  this.indexFixturesByTestResult = new Map();
88
89
  this.indexKnownByHistoryId = new Map();
89
- _DefaultAllureStore_globalAttachments.set(this, []);
90
+ _DefaultAllureStore_globalAttachmentIds.set(this, []);
90
91
  _DefaultAllureStore_globalErrors.set(this, []);
91
92
  _DefaultAllureStore_globalExitCode.set(this, void 0);
92
- _DefaultAllureStore_qualityGateResultsByRules.set(this, {});
93
+ _DefaultAllureStore_qualityGateResults.set(this, []);
93
94
  _DefaultAllureStore_historyPoints.set(this, []);
94
95
  _DefaultAllureStore_environments.set(this, []);
95
96
  const { history, known = [], realtimeDispatcher, realtimeSubscriber, defaultLabels = {}, environment, environmentsConfig = {}, reportVariables = {}, } = params ?? {};
@@ -113,9 +114,7 @@ export class DefaultAllureStore {
113
114
  __classPrivateFieldSet(this, _DefaultAllureStore_reportVariables, reportVariables, "f");
114
115
  __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addEnvironments).call(this, environments);
115
116
  __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onQualityGateResults(async (results) => {
116
- results.forEach((result) => {
117
- __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f")[result.rule] = result;
118
- });
117
+ __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f").push(...results);
119
118
  });
120
119
  __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalExitCode(async (exitCode) => {
121
120
  __classPrivateFieldSet(this, _DefaultAllureStore_globalExitCode, exitCode, "f");
@@ -123,18 +122,21 @@ export class DefaultAllureStore {
123
122
  __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalError(async (error) => {
124
123
  __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f").push(error);
125
124
  });
126
- __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalAttachment(async (attachment) => {
125
+ __classPrivateFieldGet(this, _DefaultAllureStore_realtimeSubscriber, "f")?.onGlobalAttachment(async ({ attachment, fileName }) => {
126
+ const originalFileName = attachment.getOriginalFileName();
127
127
  const attachmentLink = {
128
- id: md5(attachment.getOriginalFileName()),
128
+ id: md5(originalFileName),
129
+ name: fileName || originalFileName,
129
130
  missed: false,
130
- used: false,
131
+ used: true,
131
132
  ext: attachment.getExtension(),
132
- originalFileName: attachment.getOriginalFileName(),
133
133
  contentType: attachment.getContentType(),
134
134
  contentLength: attachment.getContentLength(),
135
+ originalFileName,
135
136
  };
137
+ __classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f").set(attachmentLink.id, attachmentLink);
136
138
  __classPrivateFieldGet(this, _DefaultAllureStore_attachmentContents, "f").set(attachmentLink.id, attachment);
137
- __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f").push(attachmentLink);
139
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIds, "f").push(attachmentLink.id);
138
140
  });
139
141
  }
140
142
  async readHistory() {
@@ -153,7 +155,18 @@ export class DefaultAllureStore {
153
155
  await __classPrivateFieldGet(this, _DefaultAllureStore_history, "f").appendHistory(history);
154
156
  }
155
157
  async qualityGateResults() {
156
- return Object.values(__classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f"));
158
+ return __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f");
159
+ }
160
+ async qualityGateResultsByEnv() {
161
+ const resultsByEnv = createDictionary();
162
+ for (const result of __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f")) {
163
+ const environment = result.environment || "default";
164
+ if (!resultsByEnv[environment]) {
165
+ resultsByEnv[environment] = [];
166
+ }
167
+ resultsByEnv[environment].push(result);
168
+ }
169
+ return resultsByEnv;
157
170
  }
158
171
  async globalExitCode() {
159
172
  return __classPrivateFieldGet(this, _DefaultAllureStore_globalExitCode, "f");
@@ -162,7 +175,14 @@ export class DefaultAllureStore {
162
175
  return __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f");
163
176
  }
164
177
  async allGlobalAttachments() {
165
- return __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f");
178
+ return __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIds, "f").reduce((acc, id) => {
179
+ const attachment = __classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f").get(id);
180
+ if (!attachment) {
181
+ return acc;
182
+ }
183
+ acc.push(attachment);
184
+ return acc;
185
+ }, []);
166
186
  }
167
187
  async visitTestResult(raw, context) {
168
188
  const attachmentLinks = [];
@@ -187,7 +207,7 @@ export class DefaultAllureStore {
187
207
  }
188
208
  testResult.environment = __classPrivateFieldGet(this, _DefaultAllureStore_environment, "f") || matchEnvironment(__classPrivateFieldGet(this, _DefaultAllureStore_environmentsConfig, "f"), testResult);
189
209
  const trHistory = await this.historyByTr(testResult);
190
- if (trHistory) {
210
+ if (trHistory !== undefined) {
191
211
  testResult.transition = getStatusTransition(testResult, trHistory);
192
212
  testResult.flaky = isFlaky(testResult, trHistory);
193
213
  }
@@ -211,7 +231,7 @@ export class DefaultAllureStore {
211
231
  index(this.indexAttachmentByFixture, testFixtureResult.id, ...attachmentLinks);
212
232
  __classPrivateFieldGet(this, _DefaultAllureStore_realtimeDispatcher, "f")?.sendTestFixtureResult(testFixtureResult.id);
213
233
  }
214
- async visitAttachmentFile(resultFile, context) {
234
+ async visitAttachmentFile(resultFile) {
215
235
  const originalFileName = resultFile.getOriginalFileName();
216
236
  const id = md5(originalFileName);
217
237
  __classPrivateFieldGet(this, _DefaultAllureStore_attachmentContents, "f").set(id, resultFile);
@@ -237,18 +257,42 @@ export class DefaultAllureStore {
237
257
  __classPrivateFieldGet(this, _DefaultAllureStore_realtimeDispatcher, "f")?.sendAttachmentFile(id);
238
258
  }
239
259
  async visitMetadata(metadata) {
240
- Object.keys(metadata).forEach((key) => __classPrivateFieldGet(this, _DefaultAllureStore_metadata, "f").set(key, metadata[key]));
260
+ Object.keys(metadata).forEach((key) => {
261
+ __classPrivateFieldGet(this, _DefaultAllureStore_metadata, "f").set(key, metadata[key]);
262
+ });
263
+ }
264
+ async visitGlobals(globals) {
265
+ const { errors, attachments } = globals;
266
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f").push(...errors);
267
+ attachments.forEach((attachment) => {
268
+ const originalFileName = attachment.originalFileName;
269
+ const id = md5(originalFileName);
270
+ const attachmentLink = {
271
+ id,
272
+ name: attachment?.name || originalFileName,
273
+ originalFileName,
274
+ ext: extname(originalFileName),
275
+ used: true,
276
+ missed: false,
277
+ contentType: attachment?.contentType,
278
+ };
279
+ __classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f").set(id, attachmentLink);
280
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIds, "f").push(id);
281
+ });
241
282
  }
242
283
  async allTestCases() {
243
284
  return Array.from(__classPrivateFieldGet(this, _DefaultAllureStore_testCases, "f").values());
244
285
  }
245
286
  async allTestResults(options = { includeHidden: false }) {
246
- const { includeHidden } = options;
287
+ const { includeHidden = false, filter } = options;
247
288
  const result = [];
248
289
  for (const [, tr] of __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f")) {
249
290
  if (!includeHidden && tr.hidden) {
250
291
  continue;
251
292
  }
293
+ if (typeof filter === "function" && !filter(tr)) {
294
+ continue;
295
+ }
252
296
  result.push(tr);
253
297
  }
254
298
  return result;
@@ -306,18 +350,24 @@ export class DefaultAllureStore {
306
350
  async allKnownIssues() {
307
351
  return __classPrivateFieldGet(this, _DefaultAllureStore_known, "f");
308
352
  }
309
- async allNewTestResults() {
353
+ async allNewTestResults(filter, history) {
354
+ if (!__classPrivateFieldGet(this, _DefaultAllureStore_history, "f") && !history) {
355
+ return [];
356
+ }
357
+ const allHistoryDps = history ?? (await this.allHistoryDataPoints());
358
+ if (allHistoryDps.length === 0) {
359
+ return Array.from(__classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f").values());
360
+ }
361
+ const historicalIds = new Set(allHistoryDps.flatMap((dp) => Object.keys(dp.testResults)));
310
362
  const newTrs = [];
311
- const allHistoryDps = await this.allHistoryDataPoints();
312
363
  for (const [, tr] of __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f")) {
313
364
  if (tr.hidden) {
314
365
  continue;
315
366
  }
316
- if (!tr.historyId) {
317
- newTrs.push(tr);
367
+ if (typeof filter === "function" && !filter(tr)) {
318
368
  continue;
319
369
  }
320
- if (!allHistoryDps.some((dp) => dp.testResults[tr.historyId])) {
370
+ if (!tr.historyId || !historicalIds.has(tr.historyId)) {
321
371
  newTrs.push(tr);
322
372
  }
323
373
  }
@@ -393,9 +443,8 @@ export class DefaultAllureStore {
393
443
  return failedTestResults.filter(({ historyId }) => historyId && !knownHistoryIds.includes(historyId));
394
444
  }
395
445
  async testResultsByLabel(labelName) {
396
- const results = {
397
- _: [],
398
- };
446
+ const results = createDictionary();
447
+ results._ = [];
399
448
  for (const [, test] of __classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f")) {
400
449
  if (test.hidden) {
401
450
  continue;
@@ -507,7 +556,7 @@ export class DefaultAllureStore {
507
556
  fixtures: mapToObject(__classPrivateFieldGet(this, _DefaultAllureStore_fixtures, "f")),
508
557
  environments: __classPrivateFieldGet(this, _DefaultAllureStore_environments, "f"),
509
558
  reportVariables: __classPrivateFieldGet(this, _DefaultAllureStore_reportVariables, "f"),
510
- globalAttachments: __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f"),
559
+ globalAttachmentIds: __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIds, "f"),
511
560
  globalErrors: __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f"),
512
561
  indexLatestEnvTestResultByHistoryId: {},
513
562
  indexAttachmentByTestResult: {},
@@ -516,7 +565,7 @@ export class DefaultAllureStore {
516
565
  indexAttachmentByFixture: {},
517
566
  indexFixturesByTestResult: {},
518
567
  indexKnownByHistoryId: {},
519
- qualityGateResultsByRules: __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f"),
568
+ qualityGateResults: __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f"),
520
569
  };
521
570
  this.indexLatestEnvTestResultByHistoryId.forEach((envMap) => {
522
571
  envMap.forEach((tr, historyId) => {
@@ -544,14 +593,14 @@ export class DefaultAllureStore {
544
593
  return storeDump;
545
594
  }
546
595
  async restoreState(stateDump, attachmentsContents = {}) {
547
- const { testResults, attachments, testCases, fixtures, reportVariables, environments, globalAttachments = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResultsByRules = {}, } = stateDump;
596
+ const { testResults, attachments, testCases, fixtures, reportVariables, environments, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResults = [], } = stateDump;
548
597
  updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_testResults, "f"), testResults);
549
598
  updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_attachments, "f"), attachments);
550
599
  updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_testCases, "f"), testCases);
551
600
  updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_fixtures, "f"), fixtures);
552
601
  updateMapWithRecord(__classPrivateFieldGet(this, _DefaultAllureStore_attachmentContents, "f"), attachmentsContents);
553
602
  __classPrivateFieldGet(this, _DefaultAllureStore_instances, "m", _DefaultAllureStore_addEnvironments).call(this, environments);
554
- __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachments, "f").push(...globalAttachments);
603
+ __classPrivateFieldGet(this, _DefaultAllureStore_globalAttachmentIds, "f").push(...globalAttachmentIds);
555
604
  __classPrivateFieldGet(this, _DefaultAllureStore_globalErrors, "f").push(...globalErrors);
556
605
  Object.assign(__classPrivateFieldGet(this, _DefaultAllureStore_reportVariables, "f"), reportVariables);
557
606
  Object.entries(indexAttachmentByTestResult).forEach(([trId, links]) => {
@@ -629,10 +678,10 @@ export class DefaultAllureStore {
629
678
  }
630
679
  hidePreviousAttempt(this.indexLatestEnvTestResultByHistoryId, tr);
631
680
  });
632
- Object.assign(__classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResultsByRules, "f"), qualityGateResultsByRules);
681
+ __classPrivateFieldGet(this, _DefaultAllureStore_qualityGateResults, "f").push(...qualityGateResults);
633
682
  }
634
683
  }
635
- _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_environment = 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_environments = new WeakMap(), _DefaultAllureStore_instances = new WeakSet(), _DefaultAllureStore_addEnvironments = function _DefaultAllureStore_addEnvironments(envs) {
684
+ _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_environment = new WeakMap(), _DefaultAllureStore_environmentsConfig = new WeakMap(), _DefaultAllureStore_reportVariables = new WeakMap(), _DefaultAllureStore_realtimeDispatcher = new WeakMap(), _DefaultAllureStore_realtimeSubscriber = new WeakMap(), _DefaultAllureStore_globalAttachmentIds = new WeakMap(), _DefaultAllureStore_globalErrors = new WeakMap(), _DefaultAllureStore_globalExitCode = new WeakMap(), _DefaultAllureStore_qualityGateResults = new WeakMap(), _DefaultAllureStore_historyPoints = new WeakMap(), _DefaultAllureStore_environments = new WeakMap(), _DefaultAllureStore_instances = new WeakSet(), _DefaultAllureStore_addEnvironments = function _DefaultAllureStore_addEnvironments(envs) {
636
685
  if (__classPrivateFieldGet(this, _DefaultAllureStore_environments, "f").length === 0) {
637
686
  __classPrivateFieldGet(this, _DefaultAllureStore_environments, "f").push(DEFAULT_ENVIRONMENT);
638
687
  }
@@ -15,14 +15,17 @@ export interface AllureStoreEvents {
15
15
  [RealtimeEvents.TestResult]: [string];
16
16
  [RealtimeEvents.TestFixtureResult]: [string];
17
17
  [RealtimeEvents.AttachmentFile]: [string];
18
- [RealtimeEvents.GlobalAttachment]: [ResultFile];
18
+ [RealtimeEvents.GlobalAttachment]: [{
19
+ attachment: ResultFile;
20
+ fileName?: string;
21
+ }];
19
22
  [RealtimeEvents.GlobalExitCode]: [ExitCode];
20
23
  [RealtimeEvents.GlobalError]: [TestError];
21
24
  }
22
25
  export declare class RealtimeEventsDispatcher implements RealtimeEventsDispatcherType {
23
26
  #private;
24
27
  constructor(emitter: EventEmitter<AllureStoreEvents>);
25
- sendGlobalAttachment(attachment: ResultFile): void;
28
+ sendGlobalAttachment(attachment: ResultFile, fileName?: string): void;
26
29
  sendGlobalExitCode(codes: ExitCode): void;
27
30
  sendGlobalError(error: TestError): void;
28
31
  sendQualityGateResults(payload: QualityGateValidationResult[]): void;
@@ -33,7 +36,10 @@ export declare class RealtimeEventsDispatcher implements RealtimeEventsDispatche
33
36
  export declare class RealtimeSubscriber implements RealtimeSubscriberType {
34
37
  #private;
35
38
  constructor(emitter: EventEmitter<AllureStoreEvents>);
36
- onGlobalAttachment(listener: (attachment: ResultFile) => Promise<void>): () => void;
39
+ onGlobalAttachment(listener: (payload: {
40
+ attachment: ResultFile;
41
+ fileName?: string;
42
+ }) => Promise<void>): () => void;
37
43
  onGlobalExitCode(listener: (payload: ExitCode) => Promise<void>): () => void;
38
44
  onGlobalError(listener: (error: TestError) => Promise<void>): () => void;
39
45
  onQualityGateResults(listener: (payload: QualityGateValidationResult[]) => Promise<void>): () => void;
@@ -27,8 +27,8 @@ export class RealtimeEventsDispatcher {
27
27
  _RealtimeEventsDispatcher_emitter.set(this, void 0);
28
28
  __classPrivateFieldSet(this, _RealtimeEventsDispatcher_emitter, emitter, "f");
29
29
  }
30
- sendGlobalAttachment(attachment) {
31
- __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalAttachment, attachment);
30
+ sendGlobalAttachment(attachment, fileName) {
31
+ __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalAttachment, { attachment, fileName });
32
32
  }
33
33
  sendGlobalExitCode(codes) {
34
34
  __classPrivateFieldGet(this, _RealtimeEventsDispatcher_emitter, "f").emit(RealtimeEvents.GlobalExitCode, codes);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/core",
3
- "version": "3.1.0",
3
+ "version": "3.3.1",
4
4
  "description": "Collection of generic Allure utilities used across the entire project",
5
5
  "keywords": [
6
6
  "allure"
@@ -25,26 +25,25 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "dependencies": {
28
- "@allurereport/ci": "3.1.0",
29
- "@allurereport/core-api": "3.1.0",
30
- "@allurereport/plugin-allure2": "3.1.0",
31
- "@allurereport/plugin-api": "3.1.0",
32
- "@allurereport/plugin-awesome": "3.1.0",
33
- "@allurereport/plugin-classic": "3.1.0",
34
- "@allurereport/plugin-csv": "3.1.0",
35
- "@allurereport/plugin-dashboard": "3.1.0",
36
- "@allurereport/plugin-jira": "3.1.0",
37
- "@allurereport/plugin-log": "3.1.0",
38
- "@allurereport/plugin-progress": "3.1.0",
39
- "@allurereport/plugin-slack": "3.1.0",
40
- "@allurereport/plugin-testops": "3.1.0",
41
- "@allurereport/plugin-testplan": "3.1.0",
42
- "@allurereport/reader": "3.1.0",
43
- "@allurereport/reader-api": "3.1.0",
44
- "@allurereport/service": "3.1.0",
45
- "@allurereport/summary": "3.1.0",
28
+ "@allurereport/ci": "3.3.1",
29
+ "@allurereport/core-api": "3.3.1",
30
+ "@allurereport/plugin-allure2": "3.3.1",
31
+ "@allurereport/plugin-api": "3.3.1",
32
+ "@allurereport/plugin-awesome": "3.3.1",
33
+ "@allurereport/plugin-classic": "3.3.1",
34
+ "@allurereport/plugin-csv": "3.3.1",
35
+ "@allurereport/plugin-dashboard": "3.3.1",
36
+ "@allurereport/plugin-jira": "3.3.1",
37
+ "@allurereport/plugin-log": "3.3.1",
38
+ "@allurereport/plugin-progress": "3.3.1",
39
+ "@allurereport/plugin-slack": "3.3.1",
40
+ "@allurereport/plugin-testops": "3.3.1",
41
+ "@allurereport/plugin-testplan": "3.3.1",
42
+ "@allurereport/reader": "3.3.1",
43
+ "@allurereport/reader-api": "3.3.1",
44
+ "@allurereport/service": "3.3.1",
45
+ "@allurereport/summary": "3.3.1",
46
46
  "handlebars": "^4.7.8",
47
- "markdown-it": "^14.1.0",
48
47
  "node-stream-zip": "^1.15.0",
49
48
  "p-limit": "^7.2.0",
50
49
  "progress": "^2.0.3",
@@ -56,7 +55,6 @@
56
55
  "@stylistic/eslint-plugin": "^2.6.1",
57
56
  "@types/eslint": "^8.56.11",
58
57
  "@types/handlebars": "^4.1.0",
59
- "@types/markdown-it": "^14.1.2",
60
58
  "@types/node": "^20.17.9",
61
59
  "@types/progress": "^2",
62
60
  "@types/zip-stream": "^7.0.0",