@allurereport/core 3.7.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +21 -17
- package/dist/report.js +276 -174
- package/dist/store/store.d.ts +5 -1
- package/dist/store/store.js +97 -12
- package/dist/utils/event.d.ts +9 -10
- package/dist/utils/event.js +77 -65
- package/dist/utils/realtimeChannel.d.ts +8 -0
- package/dist/utils/realtimeChannel.js +29 -0
- package/dist/utils/realtimeUpdateScheduler.d.ts +10 -0
- package/dist/utils/realtimeUpdateScheduler.js +81 -0
- package/package.json +20 -20
package/dist/config.js
CHANGED
|
@@ -189,23 +189,27 @@ export const resolveConfig = async (config, override = {}) => {
|
|
|
189
189
|
const output = resolve(override.output ?? config.output ?? "./allure-report");
|
|
190
190
|
const known = await readKnownIssues(knownIssuesPath);
|
|
191
191
|
const variables = config.variables ?? {};
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
192
|
+
let pluginInstances = [];
|
|
193
|
+
const hasPluginsOverride = override.plugins !== undefined;
|
|
194
|
+
if (!hasPluginsOverride || Object.keys(override.plugins ?? {}).length > 0) {
|
|
195
|
+
const configuredPlugins = hasPluginsOverride ? override.plugins : config.plugins;
|
|
196
|
+
const basePlugins = !hasPluginsOverride && Object.keys(configuredPlugins ?? {}).length === 0
|
|
197
|
+
? {
|
|
198
|
+
awesome: {
|
|
199
|
+
options: {},
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
: configuredPlugins;
|
|
203
|
+
const plugins = hasConfiguredAgent(basePlugins)
|
|
204
|
+
? basePlugins
|
|
205
|
+
: {
|
|
206
|
+
...basePlugins,
|
|
207
|
+
agent: {
|
|
208
|
+
options: {},
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
pluginInstances = await resolvePlugins(plugins);
|
|
212
|
+
}
|
|
209
213
|
return {
|
|
210
214
|
name,
|
|
211
215
|
output,
|
package/dist/report.js
CHANGED
|
@@ -9,11 +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 _AllureReport_instances, _AllureReport_reportName,
|
|
12
|
+
var _AllureReport_instances, _AllureReport_reportName, _AllureReport_ci, _AllureReport_store, _AllureReport_readers, _AllureReport_plugins, _AllureReport_reportFiles, _AllureReport_realtimeChannel, _AllureReport_realtimeUpdateScheduler, _AllureReport_realTime, _AllureReport_hideLabels, _AllureReport_output, _AllureReport_history, _AllureReport_allureServiceClient, _AllureReport_qualityGate, _AllureReport_dump, _AllureReport_categories, _AllureReport_environments, _AllureReport_globalAttachments, _AllureReport_dumpTempDirs, _AllureReport_state, _AllureReport_executionStage, _AllureReport_publish_get, _AllureReport_runRealtimeUpdate, _AllureReport_eachPlugin, _AllureReport_getPluginState;
|
|
13
13
|
import console from "node:console";
|
|
14
14
|
import { randomUUID } from "node:crypto";
|
|
15
|
-
import {
|
|
16
|
-
import { createReadStream, createWriteStream, existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import { createWriteStream, existsSync, readFileSync } from "node:fs";
|
|
17
16
|
import { lstat, mkdtemp, opendir, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
18
17
|
import { tmpdir } from "node:os";
|
|
19
18
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
@@ -35,7 +34,8 @@ import { DefaultPluginState, PluginFiles } from "./plugin.js";
|
|
|
35
34
|
import { QualityGate } from "./qualityGate/index.js";
|
|
36
35
|
import { DefaultAllureStore } from "./store/store.js";
|
|
37
36
|
import { environmentIdentityById, environmentIdentityByName } from "./utils/environment.js";
|
|
38
|
-
import {
|
|
37
|
+
import { RealtimeChannel } from "./utils/realtimeChannel.js";
|
|
38
|
+
import { RealtimeUpdateScheduler } from "./utils/realtimeUpdateScheduler.js";
|
|
39
39
|
import { resolveDumpAttachmentPath, UnsafeDumpPathError } from "./utils/safeDumpPath.js";
|
|
40
40
|
const { version } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
41
41
|
const initRequired = "report is not initialised. Call the start() method first.";
|
|
@@ -44,19 +44,18 @@ const remoteReportParams = (ci) => {
|
|
|
44
44
|
const branch = ci?.jobRunBranch;
|
|
45
45
|
return repo && branch ? { repo, branch } : {};
|
|
46
46
|
};
|
|
47
|
+
const errorDetails = (err) => (err instanceof Error ? (err.stack ?? err.message) : String(err));
|
|
47
48
|
export class AllureReport {
|
|
48
49
|
constructor(opts) {
|
|
49
50
|
_AllureReport_instances.add(this);
|
|
50
51
|
_AllureReport_reportName.set(this, void 0);
|
|
51
|
-
_AllureReport_reportVariables.set(this, void 0);
|
|
52
52
|
_AllureReport_ci.set(this, void 0);
|
|
53
53
|
_AllureReport_store.set(this, void 0);
|
|
54
54
|
_AllureReport_readers.set(this, void 0);
|
|
55
55
|
_AllureReport_plugins.set(this, void 0);
|
|
56
56
|
_AllureReport_reportFiles.set(this, void 0);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
_AllureReport_realtimeDispatcher.set(this, void 0);
|
|
57
|
+
_AllureReport_realtimeChannel.set(this, void 0);
|
|
58
|
+
_AllureReport_realtimeUpdateScheduler.set(this, void 0);
|
|
60
59
|
_AllureReport_realTime.set(this, void 0);
|
|
61
60
|
_AllureReport_hideLabels.set(this, void 0);
|
|
62
61
|
_AllureReport_output.set(this, void 0);
|
|
@@ -150,7 +149,7 @@ export class AllureReport {
|
|
|
150
149
|
continue;
|
|
151
150
|
}
|
|
152
151
|
const originalFileName = basename(absoluteFilePath);
|
|
153
|
-
__classPrivateFieldGet(this,
|
|
152
|
+
__classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").dispatcher.sendGlobalAttachment(new PathResultFile(absoluteFilePath, originalFileName), originalFileName);
|
|
154
153
|
}
|
|
155
154
|
}
|
|
156
155
|
if (__classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f") && __classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get)) {
|
|
@@ -162,16 +161,16 @@ export class AllureReport {
|
|
|
162
161
|
this.reportUrl = url.href;
|
|
163
162
|
}
|
|
164
163
|
await __classPrivateFieldGet(this, _AllureReport_eachPlugin, "f").call(this, true, async (plugin, context) => {
|
|
165
|
-
await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this,
|
|
164
|
+
await plugin.start?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"), __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").subscriber);
|
|
166
165
|
});
|
|
167
166
|
if (__classPrivateFieldGet(this, _AllureReport_realTime, "f")) {
|
|
168
|
-
await __classPrivateFieldGet(this,
|
|
169
|
-
__classPrivateFieldGet(this,
|
|
170
|
-
|
|
167
|
+
await __classPrivateFieldGet(this, _AllureReport_runRealtimeUpdate, "f").call(this);
|
|
168
|
+
__classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").onResultLikeChanged(() => {
|
|
169
|
+
__classPrivateFieldGet(this, _AllureReport_realtimeUpdateScheduler, "f").request();
|
|
171
170
|
});
|
|
172
171
|
}
|
|
173
172
|
};
|
|
174
|
-
|
|
173
|
+
_AllureReport_runRealtimeUpdate.set(this, async () => {
|
|
175
174
|
if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
|
|
176
175
|
return;
|
|
177
176
|
}
|
|
@@ -180,176 +179,275 @@ export class AllureReport {
|
|
|
180
179
|
});
|
|
181
180
|
});
|
|
182
181
|
this.dumpState = async () => {
|
|
183
|
-
const { testResults, testCases, fixtures, attachments: attachmentsLinks, environments, globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResults = [], } = __classPrivateFieldGet(this, _AllureReport_store, "f").dumpState();
|
|
184
|
-
const allAttachments = await __classPrivateFieldGet(this, _AllureReport_store, "f").allAttachments();
|
|
185
182
|
const dumpArchive = new ZipWriteStream({
|
|
186
183
|
zlib: { level: 5 },
|
|
187
184
|
});
|
|
188
185
|
const addEntry = promisify(dumpArchive.entry.bind(dumpArchive));
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
186
|
+
const dumpPath = `${__classPrivateFieldGet(this, _AllureReport_dump, "f")}.zip`;
|
|
187
|
+
const dumpTempPath = `${dumpPath}.${randomUUID()}.tmp`;
|
|
188
|
+
const dumpArchiveWriteStream = createWriteStream(dumpTempPath);
|
|
189
|
+
let dumpArchiveError;
|
|
190
|
+
let dumpArchiveFinished = false;
|
|
191
|
+
let resolveDumpArchivePromise;
|
|
192
|
+
const finishDumpArchive = (err) => {
|
|
193
|
+
dumpArchiveError ?? (dumpArchiveError = err);
|
|
194
|
+
if (!dumpArchiveFinished) {
|
|
195
|
+
dumpArchiveFinished = true;
|
|
196
|
+
resolveDumpArchivePromise?.();
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const dumpArchivePromise = new Promise((res) => {
|
|
200
|
+
resolveDumpArchivePromise = res;
|
|
201
|
+
dumpArchive.on("error", (err) => {
|
|
202
|
+
dumpArchiveWriteStream.destroy();
|
|
203
|
+
finishDumpArchive(err);
|
|
204
|
+
});
|
|
205
|
+
dumpArchiveWriteStream.on("finish", () => finishDumpArchive());
|
|
206
|
+
dumpArchiveWriteStream.on("error", (err) => finishDumpArchive(err));
|
|
194
207
|
});
|
|
208
|
+
const errMessage = (err) => (err instanceof Error ? err.message : String(err));
|
|
209
|
+
const addDumpEntry = async (data, entryName) => {
|
|
210
|
+
try {
|
|
211
|
+
await addEntry(data, { name: entryName });
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
return err;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const addRequiredDumpEntry = async (data, entryName) => {
|
|
219
|
+
const err = await addDumpEntry(data, entryName);
|
|
220
|
+
if (err) {
|
|
221
|
+
throw new Error(`Failed to write dump entry "${entryName}": ${errMessage(err)}`);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const addJsonDumpEntry = async (entryName, value) => {
|
|
225
|
+
await addRequiredDumpEntry(Buffer.from(JSON.stringify(value)), entryName);
|
|
226
|
+
};
|
|
227
|
+
const dumpJsonEntries = ({ testResults, testCases, fixtures, attachments, environments, reportVariables, checkResults = [], globalAttachmentIds = [], globalErrors = [], indexAttachmentByTestResult = {}, indexTestResultByHistoryId = {}, indexTestResultByTestCase = {}, indexLatestEnvTestResultByHistoryId = {}, indexAttachmentByFixture = {}, indexFixturesByTestResult = {}, indexKnownByHistoryId = {}, qualityGateResults = [], }) => [
|
|
228
|
+
[AllureStoreDumpFiles.TestResults, testResults],
|
|
229
|
+
[AllureStoreDumpFiles.TestCases, testCases],
|
|
230
|
+
[AllureStoreDumpFiles.Fixtures, fixtures],
|
|
231
|
+
[AllureStoreDumpFiles.Attachments, attachments],
|
|
232
|
+
[AllureStoreDumpFiles.CheckResults, checkResults],
|
|
233
|
+
[AllureStoreDumpFiles.Environments, environments],
|
|
234
|
+
[AllureStoreDumpFiles.ReportVariables, reportVariables],
|
|
235
|
+
[AllureStoreDumpFiles.GlobalAttachments, globalAttachmentIds],
|
|
236
|
+
[AllureStoreDumpFiles.GlobalErrors, globalErrors],
|
|
237
|
+
[AllureStoreDumpFiles.IndexAttachmentsByTestResults, indexAttachmentByTestResult],
|
|
238
|
+
[AllureStoreDumpFiles.IndexTestResultsByHistoryId, indexTestResultByHistoryId],
|
|
239
|
+
[AllureStoreDumpFiles.IndexTestResultsByTestCase, indexTestResultByTestCase],
|
|
240
|
+
[AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId, indexLatestEnvTestResultByHistoryId],
|
|
241
|
+
[AllureStoreDumpFiles.IndexAttachmentsByFixture, indexAttachmentByFixture],
|
|
242
|
+
[AllureStoreDumpFiles.IndexFixturesByTestResult, indexFixturesByTestResult],
|
|
243
|
+
[AllureStoreDumpFiles.IndexKnownByHistoryId, indexKnownByHistoryId],
|
|
244
|
+
[AllureStoreDumpFiles.QualityGateResults, qualityGateResults],
|
|
245
|
+
];
|
|
246
|
+
let dumpError;
|
|
195
247
|
dumpArchive.pipe(dumpArchiveWriteStream);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
await addEntry(Buffer.from(JSON.stringify(indexTestResultByHistoryId)), {
|
|
224
|
-
name: AllureStoreDumpFiles.IndexTestResultsByHistoryId,
|
|
225
|
-
});
|
|
226
|
-
await addEntry(Buffer.from(JSON.stringify(indexTestResultByTestCase)), {
|
|
227
|
-
name: AllureStoreDumpFiles.IndexTestResultsByTestCase,
|
|
228
|
-
});
|
|
229
|
-
await addEntry(Buffer.from(JSON.stringify(indexLatestEnvTestResultByHistoryId)), {
|
|
230
|
-
name: AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId,
|
|
231
|
-
});
|
|
232
|
-
await addEntry(Buffer.from(JSON.stringify(indexAttachmentByFixture)), {
|
|
233
|
-
name: AllureStoreDumpFiles.IndexAttachmentsByFixture,
|
|
234
|
-
});
|
|
235
|
-
await addEntry(Buffer.from(JSON.stringify(indexFixturesByTestResult)), {
|
|
236
|
-
name: AllureStoreDumpFiles.IndexFixturesByTestResult,
|
|
237
|
-
});
|
|
238
|
-
await addEntry(Buffer.from(JSON.stringify(indexKnownByHistoryId)), {
|
|
239
|
-
name: AllureStoreDumpFiles.IndexKnownByHistoryId,
|
|
240
|
-
});
|
|
241
|
-
await addEntry(Buffer.from(JSON.stringify(qualityGateResults)), {
|
|
242
|
-
name: AllureStoreDumpFiles.QualityGateResults,
|
|
243
|
-
});
|
|
244
|
-
for (const attachment of allAttachments) {
|
|
245
|
-
const content = await __classPrivateFieldGet(this, _AllureReport_store, "f").attachmentContentById(attachment.id);
|
|
246
|
-
if (!content) {
|
|
247
|
-
continue;
|
|
248
|
+
try {
|
|
249
|
+
const allAttachments = await __classPrivateFieldGet(this, _AllureReport_store, "f").allAttachments();
|
|
250
|
+
for (const attachment of allAttachments) {
|
|
251
|
+
const skipAttachment = (message) => {
|
|
252
|
+
const originalFileName = attachment.originalFileName ? ` (${attachment.originalFileName})` : "";
|
|
253
|
+
__classPrivateFieldGet(this, _AllureReport_store, "f").markAttachmentMissed(attachment.id);
|
|
254
|
+
console.warn(`Skipping attachment while writing dump: ${attachment.id}${originalFileName}. ${message}`);
|
|
255
|
+
};
|
|
256
|
+
try {
|
|
257
|
+
const content = await __classPrivateFieldGet(this, _AllureReport_store, "f").attachmentContentById(attachment.id);
|
|
258
|
+
if (!content) {
|
|
259
|
+
skipAttachment("attachment content is missing");
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
const data = await content.asBuffer();
|
|
263
|
+
if (data === undefined) {
|
|
264
|
+
skipAttachment("attachment content is missing");
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const err = await addDumpEntry(data, attachment.id);
|
|
268
|
+
if (err) {
|
|
269
|
+
skipAttachment(`failed to add attachment entry: ${errMessage(err)}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
skipAttachment(errMessage(err));
|
|
274
|
+
}
|
|
248
275
|
}
|
|
249
|
-
|
|
250
|
-
await
|
|
251
|
-
name: attachment.id,
|
|
252
|
-
});
|
|
276
|
+
for (const [entryName, value] of dumpJsonEntries(__classPrivateFieldGet(this, _AllureReport_store, "f").dumpState())) {
|
|
277
|
+
await addJsonDumpEntry(entryName, value);
|
|
253
278
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
dumpError = err;
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
try {
|
|
285
|
+
dumpArchive.finalize();
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
dumpError ?? (dumpError = err);
|
|
289
|
+
dumpArchiveWriteStream.destroy();
|
|
290
|
+
finishDumpArchive(err);
|
|
258
291
|
}
|
|
292
|
+
await dumpArchivePromise;
|
|
259
293
|
}
|
|
260
|
-
|
|
261
|
-
|
|
294
|
+
dumpError ?? (dumpError = dumpArchiveError);
|
|
295
|
+
if (dumpError) {
|
|
296
|
+
await rm(dumpTempPath, { force: true });
|
|
297
|
+
throw dumpError;
|
|
298
|
+
}
|
|
299
|
+
await rename(dumpTempPath, dumpPath);
|
|
262
300
|
};
|
|
263
301
|
this.restoreState = async (dumps) => {
|
|
264
302
|
for (const dump of dumps) {
|
|
265
303
|
if (!existsSync(dump)) {
|
|
304
|
+
console.error(`Failed to restore state from "${dump}", continuing without it`);
|
|
305
|
+
console.error("Dump file does not exist");
|
|
266
306
|
continue;
|
|
267
307
|
}
|
|
268
|
-
const dumpArchive = new ZipReadStream.async({
|
|
269
|
-
file: dump,
|
|
270
|
-
});
|
|
271
|
-
const testResultsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.TestResults);
|
|
272
|
-
const testCasesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.TestCases);
|
|
273
|
-
const fixturesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Fixtures);
|
|
274
|
-
const attachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Attachments);
|
|
275
|
-
const environmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.Environments);
|
|
276
|
-
const reportVariablesEntry = await dumpArchive.entryData(AllureStoreDumpFiles.ReportVariables);
|
|
277
|
-
const globalAttachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.GlobalAttachments);
|
|
278
|
-
const globalErrorsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.GlobalErrors);
|
|
279
|
-
const indexAttachmentsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexAttachmentsByTestResults);
|
|
280
|
-
const indexTestResultsByHistoryId = await dumpArchive.entryData(AllureStoreDumpFiles.IndexTestResultsByHistoryId);
|
|
281
|
-
const indexTestResultsByTestCaseEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
|
|
282
|
-
const indexLatestEnvTestResultsByHistoryIdEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId);
|
|
283
|
-
const indexAttachmentsByFixtureEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
|
|
284
|
-
const indexFixturesByTestResultEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
|
|
285
|
-
const indexKnownByHistoryIdEntry = await dumpArchive.entryData(AllureStoreDumpFiles.IndexKnownByHistoryId);
|
|
286
|
-
const qualityGateResultsEntry = await dumpArchive.entryData(AllureStoreDumpFiles.QualityGateResults);
|
|
287
|
-
const attachmentsEntries = Object.entries(await dumpArchive.entries()).reduce((acc, [entryName, entry]) => {
|
|
288
|
-
switch (entryName) {
|
|
289
|
-
case AllureStoreDumpFiles.Attachments:
|
|
290
|
-
case AllureStoreDumpFiles.TestResults:
|
|
291
|
-
case AllureStoreDumpFiles.TestCases:
|
|
292
|
-
case AllureStoreDumpFiles.Fixtures:
|
|
293
|
-
case AllureStoreDumpFiles.Environments:
|
|
294
|
-
case AllureStoreDumpFiles.ReportVariables:
|
|
295
|
-
case AllureStoreDumpFiles.GlobalAttachments:
|
|
296
|
-
case AllureStoreDumpFiles.GlobalErrors:
|
|
297
|
-
case AllureStoreDumpFiles.IndexAttachmentsByTestResults:
|
|
298
|
-
case AllureStoreDumpFiles.IndexTestResultsByHistoryId:
|
|
299
|
-
case AllureStoreDumpFiles.IndexTestResultsByTestCase:
|
|
300
|
-
case AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId:
|
|
301
|
-
case AllureStoreDumpFiles.IndexAttachmentsByFixture:
|
|
302
|
-
case AllureStoreDumpFiles.IndexFixturesByTestResult:
|
|
303
|
-
case AllureStoreDumpFiles.IndexKnownByHistoryId:
|
|
304
|
-
case AllureStoreDumpFiles.QualityGateResults:
|
|
305
|
-
return acc;
|
|
306
|
-
default:
|
|
307
|
-
return Object.assign(acc, {
|
|
308
|
-
[entryName]: entry,
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
}, {});
|
|
312
|
-
const dumpState = {
|
|
313
|
-
testResults: JSON.parse(testResultsEntry.toString("utf8")),
|
|
314
|
-
testCases: JSON.parse(testCasesEntry.toString("utf8")),
|
|
315
|
-
fixtures: JSON.parse(fixturesEntry.toString("utf8")),
|
|
316
|
-
attachments: JSON.parse(attachmentsEntry.toString("utf8")),
|
|
317
|
-
environments: JSON.parse(environmentsEntry.toString("utf8")),
|
|
318
|
-
reportVariables: JSON.parse(reportVariablesEntry.toString("utf8")),
|
|
319
|
-
globalAttachmentIds: JSON.parse(globalAttachmentsEntry.toString("utf8")),
|
|
320
|
-
globalErrors: JSON.parse(globalErrorsEntry.toString("utf8")),
|
|
321
|
-
indexAttachmentByTestResult: JSON.parse(indexAttachmentsEntry.toString("utf8")),
|
|
322
|
-
indexTestResultByHistoryId: JSON.parse(indexTestResultsByHistoryId.toString("utf8")),
|
|
323
|
-
indexTestResultByTestCase: JSON.parse(indexTestResultsByTestCaseEntry.toString("utf8")),
|
|
324
|
-
indexLatestEnvTestResultByHistoryId: JSON.parse(indexLatestEnvTestResultsByHistoryIdEntry.toString("utf8")),
|
|
325
|
-
indexAttachmentByFixture: JSON.parse(indexAttachmentsByFixtureEntry.toString("utf8")),
|
|
326
|
-
indexFixturesByTestResult: JSON.parse(indexFixturesByTestResultEntry.toString("utf8")),
|
|
327
|
-
indexKnownByHistoryId: JSON.parse(indexKnownByHistoryIdEntry.toString("utf8")),
|
|
328
|
-
qualityGateResults: JSON.parse(qualityGateResultsEntry.toString("utf8")),
|
|
329
|
-
};
|
|
330
|
-
const dumpTempDir = await mkdtemp(join(tmpdir(), basename(dump, ".zip")));
|
|
331
|
-
const resultsAttachments = {};
|
|
332
|
-
__classPrivateFieldGet(this, _AllureReport_dumpTempDirs, "f").push(dumpTempDir);
|
|
333
308
|
try {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
309
|
+
const dumpArchive = new ZipReadStream.async({
|
|
310
|
+
file: dump,
|
|
311
|
+
});
|
|
312
|
+
let restoreError;
|
|
313
|
+
try {
|
|
314
|
+
const dumpEntries = await dumpArchive.entries();
|
|
315
|
+
const dumpEntriesList = Object.entries(dumpEntries);
|
|
316
|
+
const requiredEntryData = async (entryName) => {
|
|
317
|
+
if (!dumpEntries[entryName]) {
|
|
318
|
+
throw new Error(`Missing required dump entry "${entryName}"`);
|
|
319
|
+
}
|
|
320
|
+
return dumpArchive.entryData(entryName);
|
|
321
|
+
};
|
|
322
|
+
const optionalEntryData = async (entryName) => dumpEntries[entryName] ? dumpArchive.entryData(entryName) : undefined;
|
|
323
|
+
if (!dumpEntries[AllureStoreDumpFiles.TestResults]) {
|
|
324
|
+
const nestedDumpEntries = dumpEntriesList.filter(([entryName, entry]) => !entry.isDirectory &&
|
|
325
|
+
!entryName.startsWith("__MACOSX/") &&
|
|
326
|
+
!basename(entryName).startsWith("._") &&
|
|
327
|
+
entryName.toLowerCase().endsWith(".zip"));
|
|
328
|
+
if (nestedDumpEntries.length > 0) {
|
|
329
|
+
const nestedDumpsTempDir = await mkdtemp(join(tmpdir(), `${basename(dump, ".zip")}-nested-`));
|
|
330
|
+
const nestedDumpPaths = [];
|
|
331
|
+
__classPrivateFieldGet(this, _AllureReport_dumpTempDirs, "f").push(nestedDumpsTempDir);
|
|
332
|
+
for (const [entryName] of nestedDumpEntries) {
|
|
333
|
+
const nestedDumpPath = join(nestedDumpsTempDir, `${nestedDumpPaths.length}-${basename(entryName)}`);
|
|
334
|
+
await writeFile(nestedDumpPath, await dumpArchive.entryData(entryName));
|
|
335
|
+
nestedDumpPaths.push(nestedDumpPath);
|
|
336
|
+
}
|
|
337
|
+
await this.restoreState(nestedDumpPaths);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const testResultsEntry = await requiredEntryData(AllureStoreDumpFiles.TestResults);
|
|
342
|
+
const testCasesEntry = await requiredEntryData(AllureStoreDumpFiles.TestCases);
|
|
343
|
+
const fixturesEntry = await requiredEntryData(AllureStoreDumpFiles.Fixtures);
|
|
344
|
+
const attachmentsEntry = await requiredEntryData(AllureStoreDumpFiles.Attachments);
|
|
345
|
+
const checkResultsEntry = await optionalEntryData(AllureStoreDumpFiles.CheckResults);
|
|
346
|
+
const environmentsEntry = await requiredEntryData(AllureStoreDumpFiles.Environments);
|
|
347
|
+
const reportVariablesEntry = await requiredEntryData(AllureStoreDumpFiles.ReportVariables);
|
|
348
|
+
const globalAttachmentsEntry = await requiredEntryData(AllureStoreDumpFiles.GlobalAttachments);
|
|
349
|
+
const globalErrorsEntry = await requiredEntryData(AllureStoreDumpFiles.GlobalErrors);
|
|
350
|
+
const indexAttachmentsEntry = await requiredEntryData(AllureStoreDumpFiles.IndexAttachmentsByTestResults);
|
|
351
|
+
const indexTestResultsByHistoryId = await requiredEntryData(AllureStoreDumpFiles.IndexTestResultsByHistoryId);
|
|
352
|
+
const indexTestResultsByTestCaseEntry = await requiredEntryData(AllureStoreDumpFiles.IndexTestResultsByTestCase);
|
|
353
|
+
const indexLatestEnvTestResultsByHistoryIdEntry = await requiredEntryData(AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId);
|
|
354
|
+
const indexAttachmentsByFixtureEntry = await requiredEntryData(AllureStoreDumpFiles.IndexAttachmentsByFixture);
|
|
355
|
+
const indexFixturesByTestResultEntry = await requiredEntryData(AllureStoreDumpFiles.IndexFixturesByTestResult);
|
|
356
|
+
const indexKnownByHistoryIdEntry = await requiredEntryData(AllureStoreDumpFiles.IndexKnownByHistoryId);
|
|
357
|
+
const qualityGateResultsEntry = await requiredEntryData(AllureStoreDumpFiles.QualityGateResults);
|
|
358
|
+
const attachmentsLinks = JSON.parse(attachmentsEntry.toString("utf8"));
|
|
359
|
+
const attachmentsEntries = dumpEntriesList.reduce((acc, [entryName, entry]) => {
|
|
360
|
+
switch (entryName) {
|
|
361
|
+
case AllureStoreDumpFiles.Attachments:
|
|
362
|
+
case AllureStoreDumpFiles.CheckResults:
|
|
363
|
+
case AllureStoreDumpFiles.TestResults:
|
|
364
|
+
case AllureStoreDumpFiles.TestCases:
|
|
365
|
+
case AllureStoreDumpFiles.Fixtures:
|
|
366
|
+
case AllureStoreDumpFiles.Environments:
|
|
367
|
+
case AllureStoreDumpFiles.ReportVariables:
|
|
368
|
+
case AllureStoreDumpFiles.GlobalAttachments:
|
|
369
|
+
case AllureStoreDumpFiles.GlobalErrors:
|
|
370
|
+
case AllureStoreDumpFiles.IndexAttachmentsByTestResults:
|
|
371
|
+
case AllureStoreDumpFiles.IndexTestResultsByHistoryId:
|
|
372
|
+
case AllureStoreDumpFiles.IndexTestResultsByTestCase:
|
|
373
|
+
case AllureStoreDumpFiles.IndexLatestEnvTestResultsByHistoryId:
|
|
374
|
+
case AllureStoreDumpFiles.IndexAttachmentsByFixture:
|
|
375
|
+
case AllureStoreDumpFiles.IndexFixturesByTestResult:
|
|
376
|
+
case AllureStoreDumpFiles.IndexKnownByHistoryId:
|
|
377
|
+
case AllureStoreDumpFiles.QualityGateResults:
|
|
378
|
+
return acc;
|
|
379
|
+
default:
|
|
380
|
+
if (entry.isDirectory || !attachmentsLinks[entryName] || attachmentsLinks[entryName].missed) {
|
|
381
|
+
return acc;
|
|
382
|
+
}
|
|
383
|
+
return Object.assign(acc, {
|
|
384
|
+
[entryName]: entry,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}, {});
|
|
388
|
+
const dumpState = {
|
|
389
|
+
testResults: JSON.parse(testResultsEntry.toString("utf8")),
|
|
390
|
+
testCases: JSON.parse(testCasesEntry.toString("utf8")),
|
|
391
|
+
fixtures: JSON.parse(fixturesEntry.toString("utf8")),
|
|
392
|
+
attachments: attachmentsLinks,
|
|
393
|
+
checkResults: checkResultsEntry ? JSON.parse(checkResultsEntry.toString("utf8")) : [],
|
|
394
|
+
environments: JSON.parse(environmentsEntry.toString("utf8")),
|
|
395
|
+
reportVariables: JSON.parse(reportVariablesEntry.toString("utf8")),
|
|
396
|
+
globalAttachmentIds: JSON.parse(globalAttachmentsEntry.toString("utf8")),
|
|
397
|
+
globalErrors: JSON.parse(globalErrorsEntry.toString("utf8")),
|
|
398
|
+
indexAttachmentByTestResult: JSON.parse(indexAttachmentsEntry.toString("utf8")),
|
|
399
|
+
indexTestResultByHistoryId: JSON.parse(indexTestResultsByHistoryId.toString("utf8")),
|
|
400
|
+
indexTestResultByTestCase: JSON.parse(indexTestResultsByTestCaseEntry.toString("utf8")),
|
|
401
|
+
indexLatestEnvTestResultByHistoryId: JSON.parse(indexLatestEnvTestResultsByHistoryIdEntry.toString("utf8")),
|
|
402
|
+
indexAttachmentByFixture: JSON.parse(indexAttachmentsByFixtureEntry.toString("utf8")),
|
|
403
|
+
indexFixturesByTestResult: JSON.parse(indexFixturesByTestResultEntry.toString("utf8")),
|
|
404
|
+
indexKnownByHistoryId: JSON.parse(indexKnownByHistoryIdEntry.toString("utf8")),
|
|
405
|
+
qualityGateResults: JSON.parse(qualityGateResultsEntry.toString("utf8")),
|
|
406
|
+
};
|
|
407
|
+
const dumpTempDir = await mkdtemp(join(tmpdir(), basename(dump, ".zip")));
|
|
408
|
+
const resultsAttachments = {};
|
|
409
|
+
__classPrivateFieldGet(this, _AllureReport_dumpTempDirs, "f").push(dumpTempDir);
|
|
410
|
+
try {
|
|
411
|
+
for (const [attachmentId] of Object.entries(attachmentsEntries)) {
|
|
412
|
+
const attachmentContentEntry = await dumpArchive.entryData(attachmentId);
|
|
413
|
+
const attachmentFilePath = resolveDumpAttachmentPath(dumpTempDir, attachmentId);
|
|
414
|
+
await writeFile(attachmentFilePath, attachmentContentEntry);
|
|
415
|
+
resultsAttachments[attachmentId] = new PathResultFile(attachmentFilePath, attachmentId);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
if (err instanceof UnsafeDumpPathError) {
|
|
420
|
+
console.error(`Cannot restore dump from "${dump}": the archive lists attachment paths that would write outside the extract directory (unsafe zip paths such as "../" or absolute names).`);
|
|
421
|
+
console.error(err.message);
|
|
422
|
+
console.error("Only use dump archives produced by this tool; do not load untrusted or third-party --dump zip files.");
|
|
423
|
+
throw err;
|
|
424
|
+
}
|
|
425
|
+
console.error(`Can't restore attachment contents from "${dump}", continuing without them`);
|
|
426
|
+
console.error(errorDetails(err));
|
|
427
|
+
}
|
|
428
|
+
await __classPrivateFieldGet(this, _AllureReport_store, "f").restoreState(dumpState, resultsAttachments);
|
|
429
|
+
console.info(`Successfully restored state from "${dump}"`);
|
|
339
430
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (err instanceof UnsafeDumpPathError) {
|
|
343
|
-
console.error(`Cannot restore dump from "${dump}": the archive lists attachment paths that would write outside the extract directory (unsafe zip paths such as "../" or absolute names).`);
|
|
344
|
-
console.error(err.message);
|
|
345
|
-
console.error("Only use dump archives produced by this tool; do not load untrusted or third-party --dump zip files.");
|
|
431
|
+
catch (err) {
|
|
432
|
+
restoreError = err;
|
|
346
433
|
throw err;
|
|
347
434
|
}
|
|
348
|
-
|
|
349
|
-
|
|
435
|
+
finally {
|
|
436
|
+
try {
|
|
437
|
+
await dumpArchive.close();
|
|
438
|
+
}
|
|
439
|
+
catch (err) {
|
|
440
|
+
if (!restoreError) {
|
|
441
|
+
console.error(`Failed to close dump archive "${dump}"`);
|
|
442
|
+
console.error(errorDetails(err));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
catch (err) {
|
|
448
|
+
console.error(`Failed to restore state from "${dump}", continuing without it`);
|
|
449
|
+
console.error(errorDetails(err));
|
|
350
450
|
}
|
|
351
|
-
await __classPrivateFieldGet(this, _AllureReport_store, "f").restoreState(dumpState, resultsAttachments);
|
|
352
|
-
console.info(`Successfully restored state from "${dump}"`);
|
|
353
451
|
}
|
|
354
452
|
};
|
|
355
453
|
this.done = async () => {
|
|
@@ -363,7 +461,13 @@ export class AllureReport {
|
|
|
363
461
|
const testResults = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestResults();
|
|
364
462
|
const testCases = await __classPrivateFieldGet(this, _AllureReport_store, "f").allTestCases();
|
|
365
463
|
const historyDataPoint = createHistory(this.reportUuid, __classPrivateFieldGet(this, _AllureReport_reportName, "f"), testCases, testResults, this.reportUrl);
|
|
366
|
-
__classPrivateFieldGet(this,
|
|
464
|
+
__classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").close();
|
|
465
|
+
try {
|
|
466
|
+
await __classPrivateFieldGet(this, _AllureReport_realtimeUpdateScheduler, "f").close();
|
|
467
|
+
}
|
|
468
|
+
catch (e) {
|
|
469
|
+
console.error("realtime update failed during shutdown", e);
|
|
470
|
+
}
|
|
367
471
|
__classPrivateFieldSet(this, _AllureReport_executionStage, "done", "f");
|
|
368
472
|
if (__classPrivateFieldGet(this, _AllureReport_dump, "f")) {
|
|
369
473
|
await this.dumpState();
|
|
@@ -586,7 +690,7 @@ export class AllureReport {
|
|
|
586
690
|
if (allureServiceConfig?.legacy) {
|
|
587
691
|
__classPrivateFieldSet(this, _AllureReport_allureServiceClient, new AllureLegacyServiceClient(allureServiceConfig), "f");
|
|
588
692
|
}
|
|
589
|
-
else
|
|
693
|
+
else {
|
|
590
694
|
__classPrivateFieldSet(this, _AllureReport_allureServiceClient, new AllureServiceClient(allureServiceConfig), "f");
|
|
591
695
|
}
|
|
592
696
|
}
|
|
@@ -594,10 +698,8 @@ export class AllureReport {
|
|
|
594
698
|
__classPrivateFieldSet(this, _AllureReport_ci, detect(), "f");
|
|
595
699
|
const reportTitleSuffix = __classPrivateFieldGet(this, _AllureReport_ci, "f")?.pullRequestName ?? __classPrivateFieldGet(this, _AllureReport_ci, "f")?.jobRunName;
|
|
596
700
|
__classPrivateFieldSet(this, _AllureReport_reportName, [name, reportTitleSuffix].filter(Boolean).join(" – "), "f");
|
|
597
|
-
__classPrivateFieldSet(this,
|
|
598
|
-
__classPrivateFieldSet(this,
|
|
599
|
-
__classPrivateFieldSet(this, _AllureReport_realtimeDispatcher, new RealtimeEventsDispatcher(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
|
|
600
|
-
__classPrivateFieldSet(this, _AllureReport_realtimeSubscriber, new RealtimeSubscriber(__classPrivateFieldGet(this, _AllureReport_eventEmitter, "f")), "f");
|
|
701
|
+
__classPrivateFieldSet(this, _AllureReport_realtimeChannel, new RealtimeChannel(), "f");
|
|
702
|
+
__classPrivateFieldSet(this, _AllureReport_realtimeUpdateScheduler, new RealtimeUpdateScheduler(__classPrivateFieldGet(this, _AllureReport_runRealtimeUpdate, "f")), "f");
|
|
601
703
|
__classPrivateFieldSet(this, _AllureReport_realTime, realTime, "f");
|
|
602
704
|
__classPrivateFieldSet(this, _AllureReport_dump, dump, "f");
|
|
603
705
|
__classPrivateFieldSet(this, _AllureReport_hideLabels, hideLabels, "f");
|
|
@@ -621,8 +723,8 @@ export class AllureReport {
|
|
|
621
723
|
}), "f");
|
|
622
724
|
}
|
|
623
725
|
__classPrivateFieldSet(this, _AllureReport_store, new DefaultAllureStore({
|
|
624
|
-
realtimeSubscriber: __classPrivateFieldGet(this,
|
|
625
|
-
realtimeDispatcher: __classPrivateFieldGet(this,
|
|
726
|
+
realtimeSubscriber: __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").subscriber,
|
|
727
|
+
realtimeDispatcher: __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").dispatcher,
|
|
626
728
|
reportVariables: variables,
|
|
627
729
|
environmentsConfig: environments,
|
|
628
730
|
history: __classPrivateFieldGet(this, _AllureReport_history, "f"),
|
|
@@ -643,13 +745,13 @@ export class AllureReport {
|
|
|
643
745
|
return __classPrivateFieldGet(this, _AllureReport_store, "f");
|
|
644
746
|
}
|
|
645
747
|
get realtimeSubscriber() {
|
|
646
|
-
return __classPrivateFieldGet(this,
|
|
748
|
+
return __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").subscriber;
|
|
647
749
|
}
|
|
648
750
|
get realtimeDispatcher() {
|
|
649
|
-
return __classPrivateFieldGet(this,
|
|
751
|
+
return __classPrivateFieldGet(this, _AllureReport_realtimeChannel, "f").dispatcher;
|
|
650
752
|
}
|
|
651
753
|
}
|
|
652
|
-
_AllureReport_reportName = new WeakMap(),
|
|
754
|
+
_AllureReport_reportName = new WeakMap(), _AllureReport_ci = new WeakMap(), _AllureReport_store = new WeakMap(), _AllureReport_readers = new WeakMap(), _AllureReport_plugins = new WeakMap(), _AllureReport_reportFiles = new WeakMap(), _AllureReport_realtimeChannel = new WeakMap(), _AllureReport_realtimeUpdateScheduler = new WeakMap(), _AllureReport_realTime = new WeakMap(), _AllureReport_hideLabels = new WeakMap(), _AllureReport_output = new WeakMap(), _AllureReport_history = new WeakMap(), _AllureReport_allureServiceClient = new WeakMap(), _AllureReport_qualityGate = new WeakMap(), _AllureReport_dump = new WeakMap(), _AllureReport_categories = new WeakMap(), _AllureReport_environments = new WeakMap(), _AllureReport_globalAttachments = new WeakMap(), _AllureReport_dumpTempDirs = new WeakMap(), _AllureReport_state = new WeakMap(), _AllureReport_executionStage = new WeakMap(), _AllureReport_runRealtimeUpdate = new WeakMap(), _AllureReport_eachPlugin = new WeakMap(), _AllureReport_instances = new WeakSet(), _AllureReport_publish_get = function _AllureReport_publish_get() {
|
|
653
755
|
return __classPrivateFieldGet(this, _AllureReport_plugins, "f").some(({ enabled, options }) => enabled && options.publish);
|
|
654
756
|
}, _AllureReport_getPluginState = function _AllureReport_getPluginState(init, id) {
|
|
655
757
|
return init ? new DefaultPluginState({}) : __classPrivateFieldGet(this, _AllureReport_state, "f")?.[id];
|