@allurereport/plugin-awesome 3.20.0 → 3.21.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/categories.js +1 -0
- package/dist/generators.d.ts +3 -1
- package/dist/generators.js +48 -22
- package/dist/plugin.js +20 -9
- package/dist/singleFileAssets.d.ts +1 -0
- package/dist/singleFileAssets.js +81 -0
- package/dist/static/report.tar +0 -0
- package/package.json +12 -9
package/dist/categories.js
CHANGED
|
@@ -198,6 +198,7 @@ export const generateCategories = async (writer, { tests, categories, filename =
|
|
|
198
198
|
duration: tr.duration,
|
|
199
199
|
flaky: tr.flaky,
|
|
200
200
|
retriesCount: tr.retriesCount,
|
|
201
|
+
retriesStatusChange: tr.retriesStatusChange,
|
|
201
202
|
transition: tr.transition,
|
|
202
203
|
tooltips: tr.tooltips,
|
|
203
204
|
});
|
package/dist/generators.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type AttachmentLink, type EnvironmentIdentity, type EnvironmentItem, type HistoryTestResultUrlResolver, type MetricSample, type Statistic, type TestEnvGroup, type TestResult } from "@allurereport/core-api";
|
|
2
|
-
import type { AllureStore, ReportExecutorInfo, ReportRunSummary, ReportTestResult, GlobalAttachmentLink, ExitCode, PluginContext, PluginGlobalError, QualityGateValidationResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
|
|
2
|
+
import type { AllureStore, ReportExecutorInfo, ReportRunSummary, ReportTestResult, GlobalAttachmentLink, ExitCode, PluginContext, PluginGlobalError, QualityGateValidationResult, ReportFiles, ResultFile, TestResultRelatedData } from "@allurereport/plugin-api";
|
|
3
3
|
import type { AwesomeOptions, TemplateManifest } from "./model.js";
|
|
4
4
|
import type { AwesomeDataWriter, ReportFile } from "./writer.js";
|
|
5
5
|
export declare const readTemplateManifest: (_singleFileMode?: boolean) => Promise<TemplateManifest>;
|
|
6
6
|
export declare const generateTestResults: (_writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[], options: {
|
|
7
7
|
pluginId: string;
|
|
8
8
|
hideLabels?: readonly (string | RegExp)[];
|
|
9
|
+
related?: TestResultRelatedData;
|
|
9
10
|
resolveHistoryUrl?: HistoryTestResultUrlResolver;
|
|
10
11
|
}) => Promise<ReportTestResult[]>;
|
|
11
12
|
export declare const generateTestCases: (writer: AwesomeDataWriter, trs: ReportTestResult[]) => Promise<void>;
|
|
@@ -49,6 +50,7 @@ export declare const generateStaticFiles: (payload: AwesomeOptions & {
|
|
|
49
50
|
reportDataFiles: ReportFile[];
|
|
50
51
|
reportUuid: string;
|
|
51
52
|
reportName: string;
|
|
53
|
+
overviewHref?: string;
|
|
52
54
|
executor?: ReportExecutorInfo;
|
|
53
55
|
runSummary?: ReportRunSummary;
|
|
54
56
|
runSummaryByEnv?: Record<string, ReportRunSummary>;
|
package/dist/generators.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { defaultChartsConfig } from "@allurereport/charts-api";
|
|
3
|
-
import { appLoaderFaviconDataUri, appLoaderStyles, compareBy, createAppLoaderMarkup, createBaseUrlScript, createFaviconLinkTag, createFontLinkTag,
|
|
3
|
+
import { appLoaderFaviconDataUri, appLoaderStyles, compareBy, createAppLoaderMarkup, createBaseUrlScript, createFaviconLinkTag, createFontLinkTag, injectReportDataScript, reportDataScriptPlaceholder, stringifyForInlineScript, createScriptTag, createStylesLinkTag, hasRetriesStatusChange, incrementStatistic, joinPosixPath, nullsLast, ordinal, redactParameters, severityLabelName, } from "@allurereport/core-api";
|
|
4
4
|
import { collapseTreeGroups, createTreeByLabels, createTreeByLabelsAndTitlePath, createTreeByTitlePath, preciseTreeLabels, processTree, } from "@allurereport/plugin-api";
|
|
5
5
|
import { copyReportStaticAssets, getReportStaticAsset, readReportStaticAssets, } from "@allurereport/plugin-api/static-assets";
|
|
6
6
|
import { generateCharts, getPieChartValues } from "@allurereport/web-commons";
|
|
7
7
|
import Handlebars from "handlebars";
|
|
8
8
|
import { convertFixtureResult, convertTestResult } from "./converters.js";
|
|
9
|
+
import { createSingleFileScripts } from "./singleFileAssets.js";
|
|
9
10
|
const reportStaticArchive = new URL("../dist/static/report.tar", import.meta.url);
|
|
10
11
|
const template = `<!DOCTYPE html>
|
|
11
12
|
<html dir="ltr" lang="en">
|
|
@@ -78,9 +79,17 @@ const writeConcurrently = async (items, write, concurrency = 64) => {
|
|
|
78
79
|
await Promise.all(items.slice(i, i + concurrency).map(write));
|
|
79
80
|
}
|
|
80
81
|
};
|
|
82
|
+
const mapConcurrently = async (items, map, concurrency = 8) => {
|
|
83
|
+
const results = [];
|
|
84
|
+
for (let i = 0; i < items.length; i += concurrency) {
|
|
85
|
+
results.push(...(await Promise.all(items.slice(i, i + concurrency).map(map))));
|
|
86
|
+
}
|
|
87
|
+
return results;
|
|
88
|
+
};
|
|
81
89
|
export const generateTestResults = async (_writer, store, trs, options) => {
|
|
82
90
|
let convertedTrs = [];
|
|
83
|
-
const related = await store.relatedByTestResultIds(trs.map(({ id }) => id));
|
|
91
|
+
const related = options.related ?? (await store.relatedByTestResultIds(trs.map(({ id }) => id)));
|
|
92
|
+
const resolutionIssuesByTrId = related.resolutionIssuesByTrId;
|
|
84
93
|
for (const tr of trs) {
|
|
85
94
|
const trFixtures = related.fixturesByTrId.get(tr.id) ?? [];
|
|
86
95
|
const convertedTrFixtures = [...trFixtures]
|
|
@@ -89,7 +98,6 @@ export const generateTestResults = async (_writer, store, trs, options) => {
|
|
|
89
98
|
const convertedTr = convertTestResult(tr, {
|
|
90
99
|
hideLabels: options.hideLabels,
|
|
91
100
|
});
|
|
92
|
-
const resolutionIssue = await store.resolutionIssueByTestResultId(tr.id);
|
|
93
101
|
convertedTr.history = (related.historyByTrId.get(tr.id) ?? []).map((item) => ({
|
|
94
102
|
...item,
|
|
95
103
|
url: options.resolveHistoryUrl?.(item.url, options.pluginId, item.id) ?? "",
|
|
@@ -97,6 +105,7 @@ export const generateTestResults = async (_writer, store, trs, options) => {
|
|
|
97
105
|
convertedTr.retries = related.retriesByTrId.get(tr.id) ?? [];
|
|
98
106
|
convertedTr.retriesCount = convertedTr.retries.length;
|
|
99
107
|
convertedTr.retry = convertedTr.retriesCount > 0;
|
|
108
|
+
convertedTr.retriesStatusChange = hasRetriesStatusChange(tr, convertedTr.retries);
|
|
100
109
|
convertedTr.isRetry = tr.isRetry;
|
|
101
110
|
convertedTr.setup = convertedTrFixtures.filter((f) => f.type === "before");
|
|
102
111
|
convertedTr.teardown = convertedTrFixtures.filter((f) => f.type === "after");
|
|
@@ -105,7 +114,9 @@ export const generateTestResults = async (_writer, store, trs, options) => {
|
|
|
105
114
|
type: "attachment",
|
|
106
115
|
}));
|
|
107
116
|
convertedTr.breadcrumbs = createBreadcrumbs(convertedTr);
|
|
108
|
-
convertedTr.resolutionIssue =
|
|
117
|
+
convertedTr.resolutionIssue = resolutionIssuesByTrId
|
|
118
|
+
? resolutionIssuesByTrId.get(tr.id)
|
|
119
|
+
: await store.resolutionIssueByTestResultId(tr.id);
|
|
109
120
|
convertedTrs.push(convertedTr);
|
|
110
121
|
}
|
|
111
122
|
convertedTrs = convertedTrs.sort(nullsLast(compareBy("start", ordinal()))).map((tr, idx) => ({
|
|
@@ -128,7 +139,9 @@ export const generateNav = async (writer, trs, filename = "nav.json") => {
|
|
|
128
139
|
};
|
|
129
140
|
const SEARCHABLE_LABELS = new Set([
|
|
130
141
|
"owner",
|
|
142
|
+
"parentSuite",
|
|
131
143
|
"suite",
|
|
144
|
+
"subSuite",
|
|
132
145
|
"package",
|
|
133
146
|
"testClass",
|
|
134
147
|
"testMethod",
|
|
@@ -166,6 +179,7 @@ const searchDocumentFactory = (test) => {
|
|
|
166
179
|
id: test.id,
|
|
167
180
|
nodeId: test.id,
|
|
168
181
|
name: test.name,
|
|
182
|
+
titlePath: joinSearchValues(test.titlePath ?? []),
|
|
169
183
|
fullName: test.fullName,
|
|
170
184
|
retryHash: test.retryHash,
|
|
171
185
|
labels: joinSearchValues(labels),
|
|
@@ -273,8 +287,9 @@ const buildTreeByTitlePath = (tests) => {
|
|
|
273
287
|
};
|
|
274
288
|
};
|
|
275
289
|
const buildTreeByLabelsAndTitlePathCombined = (tests, labels) => collapseTreeGroups(createTreeByLabelsAndTitlePath(tests, labels, leafFactory, undefined, (group, leaf) => incrementStatistic(group.statistic, leaf.status)));
|
|
276
|
-
const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, resolution, transition, tooltips, retryHash, groupedLabels, categories, }) => {
|
|
290
|
+
const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, retriesStatusChange, resolution, transition, tooltips, retryHash, groupedLabels, categories, parameters, }) => {
|
|
277
291
|
const unresolvedFailure = (status === "failed" || status === "broken") && !resolution;
|
|
292
|
+
const parameterValues = redactParameters(parameters).flatMap(({ value }) => (value ? [value] : []));
|
|
278
293
|
const leaf = {
|
|
279
294
|
nodeId: id,
|
|
280
295
|
id: retryHash ?? id,
|
|
@@ -285,11 +300,15 @@ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesC
|
|
|
285
300
|
start,
|
|
286
301
|
retry,
|
|
287
302
|
retriesCount,
|
|
303
|
+
retriesStatusChange,
|
|
288
304
|
resolution,
|
|
289
305
|
resolutionStatus: resolution ?? (unresolvedFailure ? "none" : undefined),
|
|
290
306
|
transition,
|
|
291
307
|
tooltips,
|
|
292
308
|
};
|
|
309
|
+
if (parameterValues.length) {
|
|
310
|
+
leaf.parameters = parameterValues;
|
|
311
|
+
}
|
|
293
312
|
const severity = groupedLabels[severityLabelName]?.[0];
|
|
294
313
|
if (severity) {
|
|
295
314
|
leaf.severity = severity;
|
|
@@ -319,6 +338,7 @@ const resolutionTestResultFactory = (test, index) => ({
|
|
|
319
338
|
transition: test.transition,
|
|
320
339
|
retry: test.retry,
|
|
321
340
|
retriesCount: test.retriesCount,
|
|
341
|
+
retriesStatusChange: test.retriesStatusChange,
|
|
322
342
|
resolution: test.resolution,
|
|
323
343
|
groupOrder: index + 1,
|
|
324
344
|
tooltips: test.tooltips,
|
|
@@ -379,20 +399,19 @@ export const generateStatistic = async (writer, data) => {
|
|
|
379
399
|
}
|
|
380
400
|
};
|
|
381
401
|
export const generateAttachmentsFiles = async (writer, attachmentLinks, contentFunction) => {
|
|
382
|
-
const
|
|
383
|
-
for (const { id, ext, ...link } of attachmentLinks) {
|
|
402
|
+
const writtenAttachments = await mapConcurrently(attachmentLinks, async ({ id, ext, ...link }) => {
|
|
384
403
|
if (link.missed) {
|
|
385
|
-
|
|
404
|
+
return;
|
|
386
405
|
}
|
|
387
406
|
const content = await contentFunction(id);
|
|
388
407
|
if (!content) {
|
|
389
|
-
|
|
408
|
+
return;
|
|
390
409
|
}
|
|
391
410
|
const src = `${id}${ext}`;
|
|
392
411
|
await writer.writeAttachment(src, content);
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
return
|
|
412
|
+
return [id, src];
|
|
413
|
+
});
|
|
414
|
+
return new Map(writtenAttachments.filter((attachment) => attachment !== undefined));
|
|
396
415
|
};
|
|
397
416
|
export const generateHistoryDataPoints = async (writer, store) => {
|
|
398
417
|
const result = new Map();
|
|
@@ -413,15 +432,22 @@ export const generateGlobals = async (writer, payload) => {
|
|
|
413
432
|
if (globalExitCode) {
|
|
414
433
|
globals.exitCode = globalExitCode;
|
|
415
434
|
}
|
|
416
|
-
|
|
435
|
+
const attachmentWrites = new Map();
|
|
436
|
+
const writtenAttachments = await mapConcurrently(globalAttachments, async (attachment) => {
|
|
417
437
|
const src = `${attachment.id}${attachment.ext}`;
|
|
418
438
|
const content = await contentFunction(attachment.id);
|
|
419
439
|
if (!content) {
|
|
420
|
-
|
|
440
|
+
return;
|
|
421
441
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
442
|
+
let write = attachmentWrites.get(src);
|
|
443
|
+
if (!write) {
|
|
444
|
+
write = writer.writeAttachment(src, content);
|
|
445
|
+
attachmentWrites.set(src, write);
|
|
446
|
+
}
|
|
447
|
+
await write;
|
|
448
|
+
return attachment;
|
|
449
|
+
});
|
|
450
|
+
globals.attachments = writtenAttachments.filter((attachment) => attachment !== undefined);
|
|
425
451
|
Object.entries(globalAttachmentsByEnv).forEach(([environmentId, attachments]) => {
|
|
426
452
|
const attachmentIds = new Set(globals.attachments.map(({ id }) => id));
|
|
427
453
|
const writtenAttachments = attachments.filter(({ id }) => attachmentIds.has(id));
|
|
@@ -459,7 +485,7 @@ export const generateQualityGateResults = async (writer, qualityGateResults = {}
|
|
|
459
485
|
await writer.writeWidget("quality-gate.json", resultsWithTrees);
|
|
460
486
|
};
|
|
461
487
|
export const generateStaticFiles = async (payload) => {
|
|
462
|
-
const { id, reportName = "Allure Report", reportLanguage = "en", logo = "", theme = "auto", groupBy, reportFiles, reportDataFiles, reportUuid, allureVersion, layout = "base", defaultSection = "", ci, executor, runSummary, runSummaryByEnv, stepTreeExpansion, defaultSortBy, } = payload;
|
|
488
|
+
const { id, reportName = "Allure Report", reportLanguage = "en", logo = "", theme = "auto", groupBy, reportFiles, reportDataFiles, reportUuid, allureVersion, layout = "base", defaultSection = "", ci, executor, runSummary, runSummaryByEnv, stepTreeExpansion, defaultSortBy, overviewHref, } = payload;
|
|
463
489
|
const staticAssets = await readReportStaticAssets(reportStaticArchive);
|
|
464
490
|
const { manifest } = staticAssets;
|
|
465
491
|
const headTags = [];
|
|
@@ -487,8 +513,7 @@ export const generateStaticFiles = async (payload) => {
|
|
|
487
513
|
const mainCssContent = getReportStaticAsset(staticAssets, mainCss);
|
|
488
514
|
headTags.push(createStylesLinkTag(`data:text/css;base64,${mainCssContent.toString("base64")}`));
|
|
489
515
|
}
|
|
490
|
-
|
|
491
|
-
bodyTags.push(createScriptTag(`data:text/javascript;base64,${mainJsContent.toString("base64")}`));
|
|
516
|
+
bodyTags.push(createSingleFileScripts(staticAssets.files, mainJs));
|
|
492
517
|
}
|
|
493
518
|
const now = Date.now();
|
|
494
519
|
const reportOptions = {
|
|
@@ -511,12 +536,13 @@ export const generateStaticFiles = async (payload) => {
|
|
|
511
536
|
defaultSection,
|
|
512
537
|
stepTreeExpansion,
|
|
513
538
|
defaultSortBy,
|
|
539
|
+
overviewHref,
|
|
514
540
|
};
|
|
515
541
|
try {
|
|
516
542
|
const html = compiledTemplate({
|
|
517
543
|
headTags: headTags.join("\n"),
|
|
518
544
|
bodyTags: bodyTags.join("\n"),
|
|
519
|
-
reportFilesScript:
|
|
545
|
+
reportFilesScript: reportDataScriptPlaceholder,
|
|
520
546
|
reportOptions: stringifyForInlineScript(reportOptions),
|
|
521
547
|
analyticsEnable: true,
|
|
522
548
|
allureVersion,
|
|
@@ -524,7 +550,7 @@ export const generateStaticFiles = async (payload) => {
|
|
|
524
550
|
reportName,
|
|
525
551
|
singleFile: payload.singleFile,
|
|
526
552
|
});
|
|
527
|
-
await reportFiles.addFile("index.html",
|
|
553
|
+
await reportFiles.addFile("index.html", injectReportDataScript(html, reportDataFiles));
|
|
528
554
|
}
|
|
529
555
|
catch (err) {
|
|
530
556
|
if (err instanceof RangeError) {
|
package/dist/plugin.js
CHANGED
|
@@ -10,16 +10,15 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
12
|
var _AwesomePlugin_writer, _AwesomePlugin_generateAfterStart, _AwesomePlugin_generate;
|
|
13
|
-
import { incrementStatistic, joinPosixPath, } from "@allurereport/core-api";
|
|
13
|
+
import { incrementStatistic, hasRetriesStatusChange, validateEnvironmentId, joinPosixPath, } from "@allurereport/core-api";
|
|
14
14
|
import { createPluginSummary, } from "@allurereport/plugin-api";
|
|
15
15
|
import { preciseTreeLabels } from "@allurereport/plugin-api";
|
|
16
16
|
import { applyCategoriesToTestResults, generateCategories } from "./categories.js";
|
|
17
17
|
import { generateTimeline } from "./generateTimeline.js";
|
|
18
18
|
import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateMetricsWidget, generateNav, generateQualityGateResults, generateResolutionCategories, generateSearchIndex, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateTreeFilters, generateVariables, getRunSummary, } from "./generators.js";
|
|
19
19
|
import { InMemoryReportDataWriter, ReportFileDataWriter } from "./writer.js";
|
|
20
|
-
const statisticByTestResults =
|
|
20
|
+
const statisticByTestResults = (testResults, retriesByTrId) => {
|
|
21
21
|
const statistic = { total: 0 };
|
|
22
|
-
const related = await store.relatedByTestResultIds(testResults.map(({ id }) => id));
|
|
23
22
|
const incrementResolution = (testResult) => {
|
|
24
23
|
if (testResult.resolution === "issue") {
|
|
25
24
|
statistic.resolutions ?? (statistic.resolutions = {});
|
|
@@ -39,9 +38,13 @@ const statisticByTestResults = async (store, testResults) => {
|
|
|
39
38
|
continue;
|
|
40
39
|
}
|
|
41
40
|
incrementStatistic(statistic, testResult.status);
|
|
42
|
-
|
|
41
|
+
const retries = retriesByTrId.get(testResult.id) ?? [];
|
|
42
|
+
if (retries.length > 0) {
|
|
43
43
|
statistic.retries = (statistic.retries ?? 0) + 1;
|
|
44
44
|
}
|
|
45
|
+
if (hasRetriesStatusChange(testResult, retries)) {
|
|
46
|
+
statistic.retriesStatusChange = (statistic.retriesStatusChange ?? 0) + 1;
|
|
47
|
+
}
|
|
45
48
|
if (testResult.flaky) {
|
|
46
49
|
statistic.flaky = (statistic.flaky ?? 0) + 1;
|
|
47
50
|
}
|
|
@@ -69,13 +72,15 @@ export class AwesomePlugin {
|
|
|
69
72
|
const measure = (name, fn) => perf?.measure(name, fn) ?? fn();
|
|
70
73
|
const hideLabels = context.hideLabels;
|
|
71
74
|
const categories = context.categories ?? [];
|
|
72
|
-
const { environmentItems, executor, attachments, allTrs, runSummary, statistics, environments, allTestEnvGroups, globalAttachments, globalAttachmentsByEnv, globalExitCode, globalErrors, globalErrorsByEnv, qualityGateResults, } = await measure("readData", async () => {
|
|
75
|
+
const { environmentItems, executor, attachments, allTrs, related, runSummary, statistics, environments, allTestEnvGroups, globalAttachments, globalAttachmentsByEnv, globalExitCode, globalErrors, globalErrorsByEnv, qualityGateResults, } = await measure("readData", async () => {
|
|
73
76
|
const testResults = await store.allTestResults({ includeRetries: true, filter });
|
|
77
|
+
const relatedData = await store.relatedByTestResultIds(testResults.map(({ id }) => id));
|
|
74
78
|
return {
|
|
75
79
|
environmentItems: await store.metadataByKey("allure_environment"),
|
|
76
80
|
executor: await store.metadataByKey("allure2_executor"),
|
|
77
81
|
attachments: await store.allAttachments(),
|
|
78
82
|
allTrs: testResults,
|
|
83
|
+
related: relatedData,
|
|
79
84
|
runSummary: getRunSummary(testResults),
|
|
80
85
|
statistics: await store.testsStatistic(filter),
|
|
81
86
|
environments: await store.allEnvironmentIdentities(),
|
|
@@ -117,8 +122,8 @@ export class AwesomePlugin {
|
|
|
117
122
|
const trsByEnvId = new Map();
|
|
118
123
|
await measure("stats", async () => {
|
|
119
124
|
const envStatistics = new Map();
|
|
120
|
-
const pieStatistics = await statisticByTestResults(store, allTrs.filter(isActiveStatisticTestResult));
|
|
121
125
|
const pieEnvStatistics = new Map();
|
|
126
|
+
const pieStatistics = statisticByTestResults(allTrs.filter(isActiveStatisticTestResult), related.retriesByTrId);
|
|
122
127
|
for (const tr of allTrs) {
|
|
123
128
|
const environmentId = envIdByTrId.get(tr.id);
|
|
124
129
|
if (!environmentId) {
|
|
@@ -134,8 +139,8 @@ export class AwesomePlugin {
|
|
|
134
139
|
}
|
|
135
140
|
await Promise.all(environments.map(async ({ id }) => {
|
|
136
141
|
const envTrs = trsByEnvId.get(id) ?? [];
|
|
137
|
-
envStatistics.set(id,
|
|
138
|
-
pieEnvStatistics.set(id,
|
|
142
|
+
envStatistics.set(id, statisticByTestResults(envTrs, related.retriesByTrId));
|
|
143
|
+
pieEnvStatistics.set(id, statisticByTestResults(envTrs.filter(isActiveStatisticTestResult), related.retriesByTrId));
|
|
139
144
|
}));
|
|
140
145
|
await generateStatistic(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
|
|
141
146
|
stats: statistics,
|
|
@@ -157,6 +162,7 @@ export class AwesomePlugin {
|
|
|
157
162
|
const convertedTrs = await measure("convert", () => generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs, {
|
|
158
163
|
pluginId: context.id,
|
|
159
164
|
hideLabels,
|
|
165
|
+
related,
|
|
160
166
|
resolveHistoryUrl: context.history?.resolveTestResultUrl,
|
|
161
167
|
}));
|
|
162
168
|
if (perf) {
|
|
@@ -194,7 +200,11 @@ export class AwesomePlugin {
|
|
|
194
200
|
const convertedTrsById = new Map(convertedTrs.map((tr) => [tr.id, tr]));
|
|
195
201
|
await measure("environmentsOutput", async () => {
|
|
196
202
|
for (const reportEnvironment of environments) {
|
|
197
|
-
const
|
|
203
|
+
const environmentIdValidation = validateEnvironmentId(reportEnvironment.id);
|
|
204
|
+
if (!environmentIdValidation.valid) {
|
|
205
|
+
throw new Error(`Invalid environmentId ${JSON.stringify(reportEnvironment.id)}: ${environmentIdValidation.reason}`);
|
|
206
|
+
}
|
|
207
|
+
const envTrs = trsByEnvId.get(reportEnvironment.id) ?? [];
|
|
198
208
|
const envConvertedTrs = envTrs
|
|
199
209
|
.map((tr) => convertedTrsById.get(tr.id))
|
|
200
210
|
.filter((tr) => Boolean(tr));
|
|
@@ -251,6 +261,7 @@ export class AwesomePlugin {
|
|
|
251
261
|
reportFiles: context.reportFiles,
|
|
252
262
|
reportUuid: context.reportUuid,
|
|
253
263
|
reportName: context.reportName,
|
|
264
|
+
overviewHref: context.overviewHref,
|
|
254
265
|
ci: context.ci,
|
|
255
266
|
executor,
|
|
256
267
|
runSummary,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const createSingleFileScripts: (files: ReadonlyMap<string, Buffer>, mainJs: string) => string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { gzipSync } from "node:zlib";
|
|
2
|
+
import { stringifyForInlineScript } from "@allurereport/core-api";
|
|
3
|
+
const embeddedAssetsElementId = "allure-single-file-assets";
|
|
4
|
+
export const createSingleFileScripts = (files, mainJs) => {
|
|
5
|
+
const compressedScripts = Object.fromEntries([...files]
|
|
6
|
+
.filter(([fileName]) => fileName.endsWith(".js"))
|
|
7
|
+
.map(([fileName, content]) => [fileName, gzipSync(content, { level: 9 }).toString("base64")]));
|
|
8
|
+
if (!compressedScripts[mainJs]) {
|
|
9
|
+
throw new Error(`The report static assets do not contain the main script: ${mainJs}`);
|
|
10
|
+
}
|
|
11
|
+
return `
|
|
12
|
+
<script id="${embeddedAssetsElementId}" type="application/json">${stringifyForInlineScript(compressedScripts)}</script>
|
|
13
|
+
<script>
|
|
14
|
+
(function () {
|
|
15
|
+
const assetsElement = document.getElementById(${stringifyForInlineScript(embeddedAssetsElementId)});
|
|
16
|
+
const assets = JSON.parse(assetsElement.textContent || "{}");
|
|
17
|
+
const appendChild = document.head.appendChild;
|
|
18
|
+
|
|
19
|
+
assetsElement.remove();
|
|
20
|
+
|
|
21
|
+
function embeddedAssetName(script) {
|
|
22
|
+
const source = script.getAttribute("src");
|
|
23
|
+
|
|
24
|
+
if (!source) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const path = source.split(/[?#]/, 1)[0];
|
|
29
|
+
|
|
30
|
+
return path.slice(path.lastIndexOf("/") + 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function decompressAsset(encoded) {
|
|
34
|
+
const binary = atob(encoded);
|
|
35
|
+
const compressed = new Uint8Array(binary.length);
|
|
36
|
+
|
|
37
|
+
for (let index = 0; index < binary.length; index++) {
|
|
38
|
+
compressed[index] = binary.charCodeAt(index);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const stream = new Blob([compressed]).stream().pipeThrough(new DecompressionStream("gzip"));
|
|
42
|
+
|
|
43
|
+
return new Response(stream).text();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
document.head.appendChild = function (node) {
|
|
47
|
+
if (node.tagName !== "SCRIPT") {
|
|
48
|
+
return appendChild.call(this, node);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const fileName = embeddedAssetName(node);
|
|
52
|
+
const encoded = fileName && Object.hasOwn(assets, fileName) ? assets[fileName] : undefined;
|
|
53
|
+
|
|
54
|
+
if (!encoded) {
|
|
55
|
+
return appendChild.call(this, node);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void decompressAsset(encoded)
|
|
59
|
+
.then(function (source) {
|
|
60
|
+
node.removeAttribute("src");
|
|
61
|
+
node.text = source;
|
|
62
|
+
delete assets[fileName];
|
|
63
|
+
appendChild.call(document.head, node);
|
|
64
|
+
node.dispatchEvent(new Event("load"));
|
|
65
|
+
})
|
|
66
|
+
.catch(function (error) {
|
|
67
|
+
console.error("Failed to load embedded report asset " + fileName, error);
|
|
68
|
+
node.dispatchEvent(new Event("error"));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return node;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const mainScript = document.createElement("script");
|
|
75
|
+
|
|
76
|
+
mainScript.src = ${stringifyForInlineScript(mainJs)};
|
|
77
|
+
document.head.appendChild(mainScript);
|
|
78
|
+
})();
|
|
79
|
+
</script>
|
|
80
|
+
`;
|
|
81
|
+
};
|
package/dist/static/report.tar
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/plugin-awesome",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.0",
|
|
4
4
|
"description": "Allure Awesome Plugin – brand new HTML report with modern design and new features",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -23,26 +23,29 @@
|
|
|
23
23
|
".": "./dist/index.js"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "run clean && tsc --project ./tsconfig.json && node ../../scripts/pack-report-static.mjs ../web-awesome/dist/multi ./dist/static/report.tar",
|
|
26
|
+
"build": "run clean && tsc --project ./tsconfig.json && node ../../scripts/pack-report-static.mjs ../web-awesome/dist/multi ./dist/static/report.tar --allow-chunks",
|
|
27
27
|
"clean": "rimraf ./dist",
|
|
28
28
|
"test": "rimraf ./out && vitest run",
|
|
29
|
+
"test:unit": "yarn test",
|
|
29
30
|
"lint": "oxlint --import-plugin src test features stories",
|
|
30
31
|
"lint:fix": "oxlint --import-plugin --fix src test features stories"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@allurereport/charts-api": "3.
|
|
34
|
-
"@allurereport/core-api": "3.
|
|
35
|
-
"@allurereport/plugin-api": "3.
|
|
36
|
-
"@allurereport/web-commons": "3.
|
|
34
|
+
"@allurereport/charts-api": "3.21.0",
|
|
35
|
+
"@allurereport/core-api": "3.21.0",
|
|
36
|
+
"@allurereport/plugin-api": "3.21.0",
|
|
37
|
+
"@allurereport/web-commons": "3.21.0",
|
|
37
38
|
"d3-shape": "^3.2.0",
|
|
38
|
-
"handlebars": "
|
|
39
|
-
"markdown-it": "^
|
|
39
|
+
"handlebars": "4.7.10",
|
|
40
|
+
"markdown-it": "^15.0.2"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@allurereport/
|
|
43
|
+
"@allurereport/test-config": "3.21.0",
|
|
44
|
+
"@allurereport/web-awesome": "3.21.0",
|
|
43
45
|
"@types/d3-shape": "^3.1.8",
|
|
44
46
|
"@types/markdown-it": "^14.1.2",
|
|
45
47
|
"@types/node": "^20",
|
|
48
|
+
"@vitest/coverage-istanbul": "^4.1.0",
|
|
46
49
|
"@vitest/runner": "^2",
|
|
47
50
|
"allure-js-commons": "^3",
|
|
48
51
|
"allure-vitest": "^3",
|