@allurereport/core 3.0.0-beta.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/report.js CHANGED
@@ -9,49 +9,67 @@ 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_reportUuid, _AllureReport_reportName, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_eventEmitter, _AllureReport_events, _AllureReport_qualityGate, _AllureReport_appendHistory, _AllureReport_historyPath, _AllureReport_realTime, _AllureReport_state, _AllureReport_stage, _AllureReport_update, _AllureReport_eachPlugin, _AllureReport_getPluginState;
13
- import { allure1, allure2, attachments, cucumberjson, junitXml } from "@allurereport/reader";
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;
13
+ import { detect } from "@allurereport/ci";
14
+ import { AllureStoreDumpFiles, } from "@allurereport/plugin-api";
15
+ import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
14
16
  import { PathResultFile } from "@allurereport/reader-api";
17
+ import { AllureRemoteHistory, AllureServiceClient, KnownError, UnknownError } from "@allurereport/service";
18
+ import { generateSummary } from "@allurereport/summary";
19
+ import ZipReadStream from "node-stream-zip";
15
20
  import console from "node:console";
16
21
  import { randomUUID } from "node:crypto";
17
22
  import { EventEmitter } from "node:events";
18
- import { readFileSync } from "node:fs";
19
- import { opendir, realpath } from "node:fs/promises";
20
- import { join, resolve } from "node:path";
21
- import { createHistory, writeHistory } from "./history.js";
23
+ import { createReadStream, createWriteStream, existsSync, readFileSync } from "node:fs";
24
+ import { lstat, mkdtemp, opendir, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
25
+ import { tmpdir } from "node:os";
26
+ import { basename, dirname, join, resolve } from "node:path";
27
+ import { promisify } from "node:util";
28
+ import pLimit from "p-limit";
29
+ import ProgressBar from "progress";
30
+ import ZipWriteStream from "zip-stream";
31
+ import { AllureLocalHistory, createHistory } from "./history.js";
22
32
  import { DefaultPluginState, PluginFiles } from "./plugin.js";
23
- import { QualityGate } from "./qualityGate.js";
33
+ import { QualityGate } from "./qualityGate/index.js";
24
34
  import { DefaultAllureStore } from "./store/store.js";
25
- import { Events } from "./utils/event.js";
35
+ import { RealtimeEventsDispatcher, RealtimeSubscriber } from "./utils/event.js";
26
36
  const { version } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
27
37
  const initRequired = "report is not initialised. Call the start() method first.";
28
38
  export class AllureReport {
29
39
  constructor(opts) {
30
40
  _AllureReport_instances.add(this);
31
- _AllureReport_reportUuid.set(this, void 0);
32
41
  _AllureReport_reportName.set(this, void 0);
42
+ _AllureReport_reportVariables.set(this, void 0);
43
+ _AllureReport_ci.set(this, void 0);
33
44
  _AllureReport_store.set(this, void 0);
34
45
  _AllureReport_readers.set(this, void 0);
35
46
  _AllureReport_plugins.set(this, void 0);
36
47
  _AllureReport_reportFiles.set(this, void 0);
37
48
  _AllureReport_eventEmitter.set(this, void 0);
38
- _AllureReport_events.set(this, void 0);
39
- _AllureReport_qualityGate.set(this, void 0);
40
- _AllureReport_appendHistory.set(this, void 0);
41
- _AllureReport_historyPath.set(this, void 0);
49
+ _AllureReport_realtimeSubscriber.set(this, void 0);
50
+ _AllureReport_realtimeDispatcher.set(this, void 0);
42
51
  _AllureReport_realTime.set(this, void 0);
52
+ _AllureReport_output.set(this, void 0);
53
+ _AllureReport_history.set(this, void 0);
54
+ _AllureReport_allureServiceClient.set(this, void 0);
55
+ _AllureReport_qualityGate.set(this, void 0);
56
+ _AllureReport_stage.set(this, void 0);
57
+ _AllureReport_stageTempDirs.set(this, []);
43
58
  _AllureReport_state.set(this, void 0);
44
- _AllureReport_stage.set(this, "init");
59
+ _AllureReport_executionStage.set(this, "init");
45
60
  this.readDirectory = async (resultsDir) => {
46
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
61
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
47
62
  throw new Error(initRequired);
48
63
  }
49
64
  const resultsDirPath = resolve(resultsDir);
65
+ if (await readXcResultBundle(__classPrivateFieldGet(this, _AllureReport_store, "f"), resultsDirPath)) {
66
+ return;
67
+ }
50
68
  const dir = await opendir(resultsDirPath);
51
69
  try {
52
70
  for await (const dirent of dir) {
53
71
  if (dirent.isFile()) {
54
- const path = await realpath(join(dirent.parentPath, dirent.name));
72
+ const path = await realpath(join(dirent.parentPath ?? dirent.path, dirent.name));
55
73
  await this.readResult(new PathResultFile(path, dirent.name));
56
74
  }
57
75
  }
@@ -61,13 +79,13 @@ export class AllureReport {
61
79
  }
62
80
  };
63
81
  this.readFile = async (resultsFile) => {
64
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
82
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
65
83
  throw new Error(initRequired);
66
84
  }
67
85
  await this.readResult(new PathResultFile(resultsFile));
68
86
  };
69
87
  this.readResult = async (data) => {
70
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
88
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
71
89
  throw new Error(initRequired);
72
90
  }
73
91
  for (const reader of __classPrivateFieldGet(this, _AllureReport_readers, "f")) {
@@ -80,70 +98,404 @@ export class AllureReport {
80
98
  catch (ignored) { }
81
99
  }
82
100
  };
101
+ this.validate = async (params) => {
102
+ const { trs, knownIssues, state } = params;
103
+ return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate({
104
+ trs: trs.filter(Boolean),
105
+ knownIssues,
106
+ state,
107
+ });
108
+ };
83
109
  this.start = async () => {
84
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") === "running") {
110
+ const branch = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunBranch;
111
+ await __classPrivateFieldGet(this, _AllureReport_store, "f").readHistory();
112
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") === "running") {
85
113
  throw new Error("the report is already started");
86
114
  }
87
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") === "done") {
115
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") === "done") {
88
116
  throw new Error("the report is already stopped, the restart isn't supported at the moment");
89
117
  }
90
- __classPrivateFieldSet(this, _AllureReport_stage, "running", "f");
118
+ __classPrivateFieldSet(this, _AllureReport_executionStage, "running", "f");
119
+ if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f") && __classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get) && branch) {
120
+ const { url } = await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").createReport({
121
+ reportUuid: this.reportUuid,
122
+ reportName: __classPrivateFieldGet(this, _AllureReport_reportName, "f"),
123
+ branch,
124
+ });
125
+ this.reportUrl = url;
126
+ }
91
127
  await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, true, async (plugin, context) => {
92
- await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_events, "f"));
128
+ await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f"));
93
129
  });
94
130
  if (__classPrivateFieldGet(this, _AllureReport_realTime, "f")) {
95
131
  await __classPrivateFieldGet(this, _AllureReport_update, "f").call(this);
96
- __classPrivateFieldGet(this, _AllureReport_events, "f").onAll(async () => {
132
+ __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f").onAll(async () => {
97
133
  await __classPrivateFieldGet(this, _AllureReport_update, "f").call(this);
98
134
  });
99
135
  }
100
136
  };
101
137
  _AllureReport_update.set(this, async () => {
102
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
138
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
103
139
  return;
104
140
  }
105
141
  await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, false, async (plugin, context) => {
106
142
  await plugin.update?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
107
143
  });
108
144
  });
145
+ 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();
147
+ const allAttachments = await __classPrivateFieldGet(this, _AllureReport_store, "f").allAttachments();
148
+ const dumpArchive = new ZipWriteStream({
149
+ zlib: { level: 5 },
150
+ });
151
+ const addEntry = promisify(dumpArchive.entry.bind(dumpArchive));
152
+ const dumpArchiveWriteStream = createWriteStream(`${__classPrivateFieldGet(this, _AllureReport_stage, "f")}.zip`);
153
+ const promise = new Promise((res, rej) => {
154
+ dumpArchive.on("error", (err) => rej(err));
155
+ dumpArchiveWriteStream.on("finish", () => res(void 0));
156
+ dumpArchiveWriteStream.on("error", (err) => rej(err));
157
+ });
158
+ dumpArchive.pipe(dumpArchiveWriteStream);
159
+ await addEntry(Buffer.from(JSON.stringify(testResults)), {
160
+ name: AllureStoreDumpFiles.TestResults,
161
+ });
162
+ await addEntry(Buffer.from(JSON.stringify(testCases)), {
163
+ name: AllureStoreDumpFiles.TestCases,
164
+ });
165
+ await addEntry(Buffer.from(JSON.stringify(fixtures)), {
166
+ name: AllureStoreDumpFiles.Fixtures,
167
+ });
168
+ await addEntry(Buffer.from(JSON.stringify(attachmentsLinks)), {
169
+ name: AllureStoreDumpFiles.Attachments,
170
+ });
171
+ await addEntry(Buffer.from(JSON.stringify(environments)), {
172
+ name: AllureStoreDumpFiles.Environments,
173
+ });
174
+ await addEntry(Buffer.from(JSON.stringify(__classPrivateFieldGet(this, _AllureReport_reportVariables, "f"))), {
175
+ name: AllureStoreDumpFiles.ReportVariables,
176
+ });
177
+ await addEntry(Buffer.from(JSON.stringify(globalAttachments)), {
178
+ name: AllureStoreDumpFiles.GlobalAttachments,
179
+ });
180
+ await addEntry(Buffer.from(JSON.stringify(globalErrors)), {
181
+ name: AllureStoreDumpFiles.GlobalErrors,
182
+ });
183
+ await addEntry(Buffer.from(JSON.stringify(indexAttachmentByTestResult)), {
184
+ name: AllureStoreDumpFiles.IndexAttachmentsByTestResults,
185
+ });
186
+ await addEntry(Buffer.from(JSON.stringify(indexTestResultByHistoryId)), {
187
+ name: AllureStoreDumpFiles.IndexTestResultsByHistoryId,
188
+ });
189
+ await addEntry(Buffer.from(JSON.stringify(indexTestResultByTestCase)), {
190
+ name: AllureStoreDumpFiles.IndexTestResultsByTestCase,
191
+ });
192
+ await addEntry(Buffer.from(JSON.stringify(indexLatestEnvTestResultByHistoryId)), {
193
+ name: AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId,
194
+ });
195
+ await addEntry(Buffer.from(JSON.stringify(indexAttachmentByFixture)), {
196
+ name: AllureStoreDumpFiles.IndexAttachmentsByFixture,
197
+ });
198
+ await addEntry(Buffer.from(JSON.stringify(indexFixturesByTestResult)), {
199
+ name: AllureStoreDumpFiles.IndexFixturesByTestResult,
200
+ });
201
+ await addEntry(Buffer.from(JSON.stringify(indexKnownByHistoryId)), {
202
+ name: AllureStoreDumpFiles.IndexKnownByHistoryId,
203
+ });
204
+ await addEntry(Buffer.from(JSON.stringify(qualityGateResultsByRules)), {
205
+ name: AllureStoreDumpFiles.QualityGateResultsByRules,
206
+ });
207
+ for (const attachment of allAttachments) {
208
+ const content = await __classPrivateFieldGet(this, _AllureReport_store, "f").attachmentContentById(attachment.id);
209
+ if (!content) {
210
+ continue;
211
+ }
212
+ if (content instanceof PathResultFile) {
213
+ await addEntry(createReadStream(content.path), {
214
+ name: attachment.id,
215
+ });
216
+ }
217
+ else {
218
+ await addEntry(await content.asBuffer(), {
219
+ name: attachment.id,
220
+ });
221
+ }
222
+ }
223
+ dumpArchive.finalize();
224
+ return promise;
225
+ };
226
+ this.restoreState = async (stages) => {
227
+ for (const stage of stages) {
228
+ if (!existsSync(stage)) {
229
+ continue;
230
+ }
231
+ const dump = new ZipReadStream.async({
232
+ file: stage,
233
+ });
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]) => {
251
+ switch (entryName) {
252
+ case AllureStoreDumpFiles.Attachments:
253
+ case AllureStoreDumpFiles.TestResults:
254
+ case AllureStoreDumpFiles.TestCases:
255
+ case AllureStoreDumpFiles.Fixtures:
256
+ case AllureStoreDumpFiles.Environments:
257
+ case AllureStoreDumpFiles.ReportVariables:
258
+ case AllureStoreDumpFiles.GlobalAttachments:
259
+ case AllureStoreDumpFiles.GlobalErrors:
260
+ case AllureStoreDumpFiles.IndexAttachmentsByTestResults:
261
+ case AllureStoreDumpFiles.IndexTestResultsByHistoryId:
262
+ case AllureStoreDumpFiles.IndexTestResultsByTestCase:
263
+ case AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId:
264
+ case AllureStoreDumpFiles.IndexAttachmentsByFixture:
265
+ case AllureStoreDumpFiles.IndexFixturesByTestResult:
266
+ case AllureStoreDumpFiles.IndexKnownByHistoryId:
267
+ case AllureStoreDumpFiles.QualityGateResultsByRules:
268
+ return acc;
269
+ default:
270
+ return Object.assign(acc, {
271
+ [entryName]: entry,
272
+ });
273
+ }
274
+ }, {});
275
+ const dumpState = {
276
+ testResults: JSON.parse(testResultsEntry.toString("utf8")),
277
+ testCases: JSON.parse(testCasesEntry.toString("utf8")),
278
+ fixtures: JSON.parse(fixturesEntry.toString("utf8")),
279
+ attachments: JSON.parse(attachmentsEntry.toString("utf8")),
280
+ environments: JSON.parse(environmentsEntry.toString("utf8")),
281
+ reportVariables: JSON.parse(reportVariablesEntry.toString("utf8")),
282
+ globalAttachments: JSON.parse(globalAttachmentsEntry.toString("utf8")),
283
+ globalErrors: JSON.parse(globalErrorsEntry.toString("utf8")),
284
+ indexAttachmentByTestResult: JSON.parse(indexAttachmentsEntry.toString("utf8")),
285
+ indexTestResultByHistoryId: JSON.parse(indexTestResultsByHistoryId.toString("utf8")),
286
+ indexTestResultByTestCase: JSON.parse(indexTestResultsByTestCaseEntry.toString("utf8")),
287
+ indexLatestEnvTestResultByHistoryId: JSON.parse(indexLatestEnvTestResultsByHistoryIdEntry.toString("utf8")),
288
+ indexAttachmentByFixture: JSON.parse(indexAttachmentsByFixtureEntry.toString("utf8")),
289
+ indexFixturesByTestResult: JSON.parse(indexFixturesByTestResultEntry.toString("utf8")),
290
+ indexKnownByHistoryId: JSON.parse(indexKnownByHistoryIdEntry.toString("utf8")),
291
+ qualityGateResultsByRules: JSON.parse(qualityGateResultsByRulesEntry.toString("utf8")),
292
+ };
293
+ const stageTempDir = await mkdtemp(join(tmpdir(), basename(stage, ".zip")));
294
+ const resultsAttachments = {};
295
+ __classPrivateFieldGet(this, _AllureReport_stageTempDirs, "f").push(stageTempDir);
296
+ try {
297
+ for (const [attachmentId] of Object.entries(attachmentsEntries)) {
298
+ const attachmentContentEntry = await dump.entryData(attachmentId);
299
+ const attachmentFilePath = join(stageTempDir, attachmentId);
300
+ await writeFile(attachmentFilePath, attachmentContentEntry);
301
+ resultsAttachments[attachmentId] = new PathResultFile(attachmentFilePath, attachmentId);
302
+ }
303
+ }
304
+ catch (err) {
305
+ console.error(`Can't restore state from "${stage}", continuing without it`);
306
+ console.error(err);
307
+ }
308
+ await __classPrivateFieldGet(this, _AllureReport_store, "f").restoreState(dumpState, resultsAttachments);
309
+ console.info(`Successfully restored state from "${stage}"`);
310
+ }
311
+ };
109
312
  this.done = async () => {
110
- if (__classPrivateFieldGet(this, _AllureReport_stage, "f") !== "running") {
313
+ const summaries = [];
314
+ const remoteHrefs = [];
315
+ const cancelledPluginsIds = new Set();
316
+ if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
111
317
  throw new Error(initRequired);
112
318
  }
113
- __classPrivateFieldGet(this, _AllureReport_events, "f").offAll();
114
- __classPrivateFieldSet(this, _AllureReport_stage, "done", "f");
319
+ const testResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestResults();
320
+ const testCases = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestCases();
321
+ const historyDataPoint = createHistory(this.reportUuid, __classPrivateFieldGet(this, _AllureReport_reportName, "f"), testCases, testResults, this.reportUrl);
322
+ __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f").offAll();
323
+ __classPrivateFieldSet(this, _AllureReport_executionStage, "done", "f");
324
+ if (__classPrivateFieldGet(this, _AllureReport_stage, "f")) {
325
+ await this.dumpState();
326
+ return;
327
+ }
115
328
  await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, false, async (plugin, context) => {
116
329
  await plugin.done?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
117
330
  });
118
- if (__classPrivateFieldGet(this, _AllureReport_appendHistory, "f")) {
119
- const testResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestResults();
120
- const testCases = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestCases();
121
- const historyDataPoint = createHistory(__classPrivateFieldGet(this, _AllureReport_reportUuid, "f"), __classPrivateFieldGet(this, _AllureReport_reportName, "f"), testCases, testResults);
122
- await writeHistory(__classPrivateFieldGet(this, _AllureReport_historyPath, "f"), historyDataPoint);
331
+ await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, false, async (plugin, context) => {
332
+ if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f") && context.publish) {
333
+ const pluginFiles = (await context.state.get("files")) ?? {};
334
+ const pluginFilesEntries = Object.entries(pluginFiles);
335
+ const progressBar = pluginFilesEntries?.length > 0
336
+ ? new ProgressBar(`Publishing "${context.id}" report [:bar] :current/:total`, {
337
+ total: pluginFilesEntries.length,
338
+ width: 20,
339
+ })
340
+ : undefined;
341
+ const limitFn = pLimit(50);
342
+ const fns = pluginFilesEntries.map(([filename, filepath]) => limitFn(async () => {
343
+ if (cancelledPluginsIds.has(context.id)) {
344
+ return;
345
+ }
346
+ if (/^(data|widgets|index\.html$|summary\.json$)/.test(filename)) {
347
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportFile({
348
+ reportUuid: this.reportUuid,
349
+ pluginId: context.id,
350
+ filename,
351
+ filepath,
352
+ });
353
+ }
354
+ else {
355
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportAsset({
356
+ filename,
357
+ filepath,
358
+ });
359
+ }
360
+ progressBar?.tick?.();
361
+ }));
362
+ progressBar?.render?.();
363
+ try {
364
+ await Promise.all(fns);
365
+ }
366
+ catch (err) {
367
+ cancelledPluginsIds.add(context.id);
368
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").deleteReport({
369
+ reportUuid: this.reportUuid,
370
+ pluginId: context.id,
371
+ });
372
+ console.error(`Plugin "${context.id}" upload has failed, the plugin won't be published`);
373
+ console.error(err);
374
+ }
375
+ }
376
+ const summary = await plugin?.info?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
377
+ if (!summary) {
378
+ return;
379
+ }
380
+ summary.pullRequestHref = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestUrl;
381
+ summary.jobHref = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunUrl;
382
+ if (context.publish && this.reportUrl && !cancelledPluginsIds.has(context.id)) {
383
+ summary.remoteHref = `${this.reportUrl}/${context.id}/`;
384
+ remoteHrefs.push(summary.remoteHref);
385
+ }
386
+ summaries.push({
387
+ ...summary,
388
+ href: `${context.id}/`,
389
+ });
390
+ await context.reportFiles.addFile("summary.json", Buffer.from(JSON.stringify(summary)));
391
+ });
392
+ if (summaries.length > 1) {
393
+ const summaryPath = await generateSummary(__classPrivateFieldGet(this, _AllureReport_output, "f"), summaries);
394
+ const publishedReports = __classPrivateFieldGet(this, _AllureReport_plugins, "f")
395
+ .map((plugin) => !!plugin?.options?.publish && !cancelledPluginsIds.has(plugin.id))
396
+ .filter(Boolean);
397
+ if (__classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get) && summaryPath && publishedReports.length > 1) {
398
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")?.addReportFile({
399
+ reportUuid: this.reportUuid,
400
+ filename: "index.html",
401
+ filepath: summaryPath,
402
+ });
403
+ }
404
+ }
405
+ if (__classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get)) {
406
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")?.completeReport({
407
+ reportUuid: this.reportUuid,
408
+ historyPoint: historyDataPoint,
409
+ });
410
+ }
411
+ let outputDirFiles = [];
412
+ try {
413
+ outputDirFiles = await readdir(__classPrivateFieldGet(this, _AllureReport_output, "f"));
414
+ }
415
+ catch (ignored) { }
416
+ if (outputDirFiles.length === 0) {
417
+ return;
418
+ }
419
+ const reportPath = join(__classPrivateFieldGet(this, _AllureReport_output, "f"), outputDirFiles[0]);
420
+ const outputEntriesStats = await Promise.all(outputDirFiles.map((file) => lstat(join(__classPrivateFieldGet(this, _AllureReport_output, "f"), file))));
421
+ const outputDirectoryEntries = outputEntriesStats.filter((entry) => entry.isDirectory());
422
+ if (outputDirectoryEntries.length === 1) {
423
+ const reportContent = await readdir(reportPath);
424
+ for (const entry of reportContent) {
425
+ const currentFilePath = join(reportPath, entry);
426
+ const newFilePath = resolve(dirname(currentFilePath), "..", entry);
427
+ await rename(currentFilePath, newFilePath);
428
+ }
429
+ await rm(reportPath, { recursive: true });
123
430
  }
431
+ for (const dir of __classPrivateFieldGet(this, _AllureReport_stageTempDirs, "f")) {
432
+ try {
433
+ await rm(dir, { recursive: true });
434
+ }
435
+ catch (ignored) { }
436
+ }
437
+ if (__classPrivateFieldGet(this, _AllureReport_history, "f")) {
438
+ try {
439
+ await __classPrivateFieldGet(this, _AllureReport_store, "f").appendHistory(historyDataPoint);
440
+ }
441
+ catch (err) {
442
+ if (err instanceof KnownError) {
443
+ console.error("Failed to append history", err.message);
444
+ }
445
+ else if (err instanceof UnknownError) {
446
+ console.error("Failed to append history due to unexpected error", err.message);
447
+ }
448
+ else {
449
+ throw err;
450
+ }
451
+ }
452
+ }
453
+ if (remoteHrefs.length > 0) {
454
+ console.info("Next reports have been published:");
455
+ remoteHrefs.forEach((href) => {
456
+ console.info(`- ${href}`);
457
+ });
458
+ }
459
+ if (!__classPrivateFieldGet(this, _AllureReport_qualityGate, "f")) {
460
+ return;
461
+ }
462
+ const qualityGateResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").qualityGateResults();
463
+ await writeFile(join(__classPrivateFieldGet(this, _AllureReport_output, "f"), "quality-gate.json"), JSON.stringify(qualityGateResults));
124
464
  };
125
465
  _AllureReport_eachPlugin.set(this, async (initState, consumer) => {
126
466
  if (initState) {
127
467
  __classPrivateFieldSet(this, _AllureReport_state, {}, "f");
128
468
  }
129
- for (const descriptor of __classPrivateFieldGet(this, _AllureReport_plugins, "f")) {
130
- if (!descriptor.enabled) {
469
+ for (const { enabled, id, plugin, options } of __classPrivateFieldGet(this, _AllureReport_plugins, "f")) {
470
+ if (!enabled) {
131
471
  continue;
132
472
  }
133
- const id = descriptor.id;
134
- const plugin = descriptor.plugin;
135
473
  const pluginState = __classPrivateFieldGet(this, _AllureReport_instances, "m", _AllureReport_getPluginState).call(this, initState, id);
136
474
  if (!pluginState) {
137
475
  console.error("plugin error: state is empty");
138
476
  continue;
139
477
  }
140
- const pluginFiles = new PluginFiles(__classPrivateFieldGet(this, _AllureReport_reportFiles, "f"), id);
478
+ if (initState) {
479
+ await pluginState.set("files", {});
480
+ }
481
+ const pluginFiles = new PluginFiles(__classPrivateFieldGet(this, _AllureReport_reportFiles, "f"), id, async (key, filepath) => {
482
+ const currentPluginState = __classPrivateFieldGet(this, _AllureReport_instances, "m", _AllureReport_getPluginState).call(this, false, id);
483
+ const files = await currentPluginState?.get("files");
484
+ if (!files) {
485
+ return;
486
+ }
487
+ files[key] = filepath;
488
+ });
141
489
  const pluginContext = {
490
+ id,
491
+ publish: !!options?.publish,
142
492
  allureVersion: version,
143
- reportUuid: __classPrivateFieldGet(this, _AllureReport_reportUuid, "f"),
493
+ reportUuid: this.reportUuid,
144
494
  reportName: __classPrivateFieldGet(this, _AllureReport_reportName, "f"),
145
495
  state: pluginState,
146
496
  reportFiles: pluginFiles,
497
+ reportUrl: this.reportUrl,
498
+ ci: __classPrivateFieldGet(this, _AllureReport_ci, "f"),
147
499
  };
148
500
  try {
149
501
  await consumer.call(this, plugin, pluginContext);
@@ -156,38 +508,63 @@ export class AllureReport {
156
508
  }
157
509
  }
158
510
  });
159
- this.validate = async () => {
160
- await __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").validate(__classPrivateFieldGet(this, _AllureReport_store, "f"));
161
- };
162
- const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], history, known, reportFiles, qualityGate, realTime, appendHistory, historyPath, defaultLabels = {}, } = opts;
163
- __classPrivateFieldSet(this, _AllureReport_reportUuid, randomUUID(), "f");
164
- __classPrivateFieldSet(this, _AllureReport_reportName, name, "f");
511
+ const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, defaultLabels = {}, variables = {}, environment, environments, output, qualityGate, stage, allureService: allureServiceConfig, } = opts;
512
+ __classPrivateFieldSet(this, _AllureReport_allureServiceClient, allureServiceConfig?.url ? new AllureServiceClient(allureServiceConfig) : undefined, "f");
513
+ this.reportUuid = randomUUID();
514
+ __classPrivateFieldSet(this, _AllureReport_ci, detect(), "f");
515
+ const reportTitleSuffix = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestName ?? __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunName;
516
+ __classPrivateFieldSet(this, _AllureReport_reportName, [name, reportTitleSuffix].filter(Boolean).join(" – "), "f");
517
+ __classPrivateFieldSet(this, _AllureReport_reportVariables, variables, "f");
165
518
  __classPrivateFieldSet(this, _AllureReport_eventEmitter, new EventEmitter(), "f");
166
- __classPrivateFieldSet(this, _AllureReport_events, new Events(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
519
+ __classPrivateFieldSet(this, _AllureReport_realtimeDispatcher, new RealtimeEventsDispatcher(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
520
+ __classPrivateFieldSet(this, _AllureReport_realtimeSubscriber, new RealtimeSubscriber(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
167
521
  __classPrivateFieldSet(this, _AllureReport_realTime, realTime, "f");
168
- __classPrivateFieldSet(this, _AllureReport_appendHistory, appendHistory ?? true, "f");
169
- __classPrivateFieldSet(this, _AllureReport_historyPath, historyPath, "f");
522
+ __classPrivateFieldSet(this, _AllureReport_stage, stage, "f");
523
+ if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")) {
524
+ __classPrivateFieldSet(this, _AllureReport_history, new AllureRemoteHistory(__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f"), __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunBranch), "f");
525
+ }
526
+ else if (historyPath) {
527
+ __classPrivateFieldSet(this, _AllureReport_history, new AllureLocalHistory(historyPath), "f");
528
+ }
529
+ if (qualityGate) {
530
+ __classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
531
+ }
170
532
  __classPrivateFieldSet(this, _AllureReport_store, new DefaultAllureStore({
171
- history,
533
+ realtimeSubscriber: __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f"),
534
+ realtimeDispatcher: __classPrivateFieldGet(this, _AllureReport_realtimeDispatcher, "f"),
535
+ reportVariables: variables,
536
+ environmentsConfig: environments,
537
+ history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
172
538
  known,
173
- eventEmitter: __classPrivateFieldGet(this, _AllureReport_eventEmitter, "f"),
174
539
  defaultLabels,
540
+ environment,
175
541
  }), "f");
176
542
  __classPrivateFieldSet(this, _AllureReport_readers, [...readers], "f");
177
543
  __classPrivateFieldSet(this, _AllureReport_plugins, [...plugins], "f");
178
544
  __classPrivateFieldSet(this, _AllureReport_reportFiles, reportFiles, "f");
179
- __classPrivateFieldSet(this, _AllureReport_qualityGate, new QualityGate(qualityGate), "f");
545
+ __classPrivateFieldSet(this, _AllureReport_output, output, "f");
546
+ if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")) {
547
+ __classPrivateFieldSet(this, _AllureReport_history, new AllureRemoteHistory(__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f"), __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunBranch), "f");
548
+ }
549
+ else if (historyPath) {
550
+ __classPrivateFieldSet(this, _AllureReport_history, new AllureLocalHistory(historyPath), "f");
551
+ }
552
+ }
553
+ get hasQualityGate() {
554
+ return !!__classPrivateFieldGet(this, _AllureReport_qualityGate, "f");
180
555
  }
181
556
  get store() {
182
557
  return __classPrivateFieldGet(this, _AllureReport_store, "f");
183
558
  }
184
- get exitCode() {
185
- return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").exitCode;
559
+ get realtimeSubscriber() {
560
+ return __classPrivateFieldGet(this, _AllureReport_realtimeSubscriber, "f");
186
561
  }
187
- get validationResults() {
188
- return __classPrivateFieldGet(this, _AllureReport_qualityGate, "f").result;
562
+ get realtimeDispatcher() {
563
+ return __classPrivateFieldGet(this, _AllureReport_realtimeDispatcher, "f");
189
564
  }
190
565
  }
191
- _AllureReport_reportUuid = new WeakMap(), _AllureReport_reportName = 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_appendHistory = new WeakMap(), _AllureReport_historyPath = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_stage = new WeakMap(), _AllureReport_update = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
566
+ _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() {
567
+ return __classPrivateFieldGet(this, _AllureReport_plugins, "f").some(({ enabled, options }) => enabled && options.publish);
568
+ }, _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
192
569
  return init ? new DefaultPluginState({}) : __classPrivateFieldGet(this, _AllureReport_state, "f")?.[id];
193
570
  };