@allurereport/plugin-awesome 3.19.1 → 3.20.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/generators.d.ts +2 -1
- package/dist/generators.js +38 -17
- package/dist/plugin.js +21 -9
- package/dist/static/report.tar +0 -0
- package/package.json +6 -6
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>;
|
package/dist/generators.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { defaultChartsConfig } from "@allurereport/charts-api";
|
|
3
|
-
import { appLoaderFaviconDataUri, appLoaderStyles, compareBy, createAppLoaderMarkup, createBaseUrlScript, createFaviconLinkTag, createFontLinkTag, createReportDataScript, stringifyForInlineScript, createScriptTag, createStylesLinkTag, incrementStatistic, joinPosixPath, nullsLast, ordinal, severityLabelName, } from "@allurereport/core-api";
|
|
3
|
+
import { appLoaderFaviconDataUri, appLoaderStyles, compareBy, createAppLoaderMarkup, createBaseUrlScript, createFaviconLinkTag, createFontLinkTag, createReportDataScript, stringifyForInlineScript, createScriptTag, createStylesLinkTag, 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";
|
|
@@ -78,9 +78,17 @@ const writeConcurrently = async (items, write, concurrency = 64) => {
|
|
|
78
78
|
await Promise.all(items.slice(i, i + concurrency).map(write));
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
|
+
const mapConcurrently = async (items, map, concurrency = 8) => {
|
|
82
|
+
const results = [];
|
|
83
|
+
for (let i = 0; i < items.length; i += concurrency) {
|
|
84
|
+
results.push(...(await Promise.all(items.slice(i, i + concurrency).map(map))));
|
|
85
|
+
}
|
|
86
|
+
return results;
|
|
87
|
+
};
|
|
81
88
|
export const generateTestResults = async (_writer, store, trs, options) => {
|
|
82
89
|
let convertedTrs = [];
|
|
83
|
-
const related = await store.relatedByTestResultIds(trs.map(({ id }) => id));
|
|
90
|
+
const related = options.related ?? (await store.relatedByTestResultIds(trs.map(({ id }) => id)));
|
|
91
|
+
const resolutionIssuesByTrId = related.resolutionIssuesByTrId;
|
|
84
92
|
for (const tr of trs) {
|
|
85
93
|
const trFixtures = related.fixturesByTrId.get(tr.id) ?? [];
|
|
86
94
|
const convertedTrFixtures = [...trFixtures]
|
|
@@ -89,7 +97,6 @@ export const generateTestResults = async (_writer, store, trs, options) => {
|
|
|
89
97
|
const convertedTr = convertTestResult(tr, {
|
|
90
98
|
hideLabels: options.hideLabels,
|
|
91
99
|
});
|
|
92
|
-
const resolutionIssue = await store.resolutionIssueByTestResultId(tr.id);
|
|
93
100
|
convertedTr.history = (related.historyByTrId.get(tr.id) ?? []).map((item) => ({
|
|
94
101
|
...item,
|
|
95
102
|
url: options.resolveHistoryUrl?.(item.url, options.pluginId, item.id) ?? "",
|
|
@@ -105,7 +112,9 @@ export const generateTestResults = async (_writer, store, trs, options) => {
|
|
|
105
112
|
type: "attachment",
|
|
106
113
|
}));
|
|
107
114
|
convertedTr.breadcrumbs = createBreadcrumbs(convertedTr);
|
|
108
|
-
convertedTr.resolutionIssue =
|
|
115
|
+
convertedTr.resolutionIssue = resolutionIssuesByTrId
|
|
116
|
+
? resolutionIssuesByTrId.get(tr.id)
|
|
117
|
+
: await store.resolutionIssueByTestResultId(tr.id);
|
|
109
118
|
convertedTrs.push(convertedTr);
|
|
110
119
|
}
|
|
111
120
|
convertedTrs = convertedTrs.sort(nullsLast(compareBy("start", ordinal()))).map((tr, idx) => ({
|
|
@@ -273,7 +282,9 @@ const buildTreeByTitlePath = (tests) => {
|
|
|
273
282
|
};
|
|
274
283
|
};
|
|
275
284
|
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, }) => {
|
|
285
|
+
const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, resolution, transition, tooltips, retryHash, groupedLabels, categories, parameters, }) => {
|
|
286
|
+
const unresolvedFailure = (status === "failed" || status === "broken") && !resolution;
|
|
287
|
+
const parameterValues = redactParameters(parameters).flatMap(({ value }) => (value ? [value] : []));
|
|
277
288
|
const leaf = {
|
|
278
289
|
nodeId: id,
|
|
279
290
|
id: retryHash ?? id,
|
|
@@ -285,9 +296,13 @@ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesC
|
|
|
285
296
|
retry,
|
|
286
297
|
retriesCount,
|
|
287
298
|
resolution,
|
|
299
|
+
resolutionStatus: resolution ?? (unresolvedFailure ? "none" : undefined),
|
|
288
300
|
transition,
|
|
289
301
|
tooltips,
|
|
290
302
|
};
|
|
303
|
+
if (parameterValues.length) {
|
|
304
|
+
leaf.parameters = parameterValues;
|
|
305
|
+
}
|
|
291
306
|
const severity = groupedLabels[severityLabelName]?.[0];
|
|
292
307
|
if (severity) {
|
|
293
308
|
leaf.severity = severity;
|
|
@@ -377,20 +392,19 @@ export const generateStatistic = async (writer, data) => {
|
|
|
377
392
|
}
|
|
378
393
|
};
|
|
379
394
|
export const generateAttachmentsFiles = async (writer, attachmentLinks, contentFunction) => {
|
|
380
|
-
const
|
|
381
|
-
for (const { id, ext, ...link } of attachmentLinks) {
|
|
395
|
+
const writtenAttachments = await mapConcurrently(attachmentLinks, async ({ id, ext, ...link }) => {
|
|
382
396
|
if (link.missed) {
|
|
383
|
-
|
|
397
|
+
return;
|
|
384
398
|
}
|
|
385
399
|
const content = await contentFunction(id);
|
|
386
400
|
if (!content) {
|
|
387
|
-
|
|
401
|
+
return;
|
|
388
402
|
}
|
|
389
403
|
const src = `${id}${ext}`;
|
|
390
404
|
await writer.writeAttachment(src, content);
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
return
|
|
405
|
+
return [id, src];
|
|
406
|
+
});
|
|
407
|
+
return new Map(writtenAttachments.filter((attachment) => attachment !== undefined));
|
|
394
408
|
};
|
|
395
409
|
export const generateHistoryDataPoints = async (writer, store) => {
|
|
396
410
|
const result = new Map();
|
|
@@ -411,15 +425,22 @@ export const generateGlobals = async (writer, payload) => {
|
|
|
411
425
|
if (globalExitCode) {
|
|
412
426
|
globals.exitCode = globalExitCode;
|
|
413
427
|
}
|
|
414
|
-
|
|
428
|
+
const attachmentWrites = new Map();
|
|
429
|
+
const writtenAttachments = await mapConcurrently(globalAttachments, async (attachment) => {
|
|
415
430
|
const src = `${attachment.id}${attachment.ext}`;
|
|
416
431
|
const content = await contentFunction(attachment.id);
|
|
417
432
|
if (!content) {
|
|
418
|
-
|
|
433
|
+
return;
|
|
419
434
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
435
|
+
let write = attachmentWrites.get(src);
|
|
436
|
+
if (!write) {
|
|
437
|
+
write = writer.writeAttachment(src, content);
|
|
438
|
+
attachmentWrites.set(src, write);
|
|
439
|
+
}
|
|
440
|
+
await write;
|
|
441
|
+
return attachment;
|
|
442
|
+
});
|
|
443
|
+
globals.attachments = writtenAttachments.filter((attachment) => attachment !== undefined);
|
|
423
444
|
Object.entries(globalAttachmentsByEnv).forEach(([environmentId, attachments]) => {
|
|
424
445
|
const attachmentIds = new Set(globals.attachments.map(({ id }) => id));
|
|
425
446
|
const writtenAttachments = attachments.filter(({ id }) => attachmentIds.has(id));
|
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, 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, trIdsWithRetries) => {
|
|
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,7 +38,7 @@ const statisticByTestResults = async (store, testResults) => {
|
|
|
39
38
|
continue;
|
|
40
39
|
}
|
|
41
40
|
incrementStatistic(statistic, testResult.status);
|
|
42
|
-
if (
|
|
41
|
+
if (trIdsWithRetries.has(testResult.id)) {
|
|
43
42
|
statistic.retries = (statistic.retries ?? 0) + 1;
|
|
44
43
|
}
|
|
45
44
|
if (testResult.flaky) {
|
|
@@ -69,13 +68,15 @@ export class AwesomePlugin {
|
|
|
69
68
|
const measure = (name, fn) => perf?.measure(name, fn) ?? fn();
|
|
70
69
|
const hideLabels = context.hideLabels;
|
|
71
70
|
const categories = context.categories ?? [];
|
|
72
|
-
const { environmentItems, executor, attachments, allTrs, runSummary, statistics, environments, allTestEnvGroups, globalAttachments, globalAttachmentsByEnv, globalExitCode, globalErrors, globalErrorsByEnv, qualityGateResults, } = await measure("readData", async () => {
|
|
71
|
+
const { environmentItems, executor, attachments, allTrs, related, runSummary, statistics, environments, allTestEnvGroups, globalAttachments, globalAttachmentsByEnv, globalExitCode, globalErrors, globalErrorsByEnv, qualityGateResults, } = await measure("readData", async () => {
|
|
73
72
|
const testResults = await store.allTestResults({ includeRetries: true, filter });
|
|
73
|
+
const relatedData = await store.relatedByTestResultIds(testResults.map(({ id }) => id));
|
|
74
74
|
return {
|
|
75
75
|
environmentItems: await store.metadataByKey("allure_environment"),
|
|
76
76
|
executor: await store.metadataByKey("allure2_executor"),
|
|
77
77
|
attachments: await store.allAttachments(),
|
|
78
78
|
allTrs: testResults,
|
|
79
|
+
related: relatedData,
|
|
79
80
|
runSummary: getRunSummary(testResults),
|
|
80
81
|
statistics: await store.testsStatistic(filter),
|
|
81
82
|
environments: await store.allEnvironmentIdentities(),
|
|
@@ -116,9 +117,15 @@ export class AwesomePlugin {
|
|
|
116
117
|
});
|
|
117
118
|
const trsByEnvId = new Map();
|
|
118
119
|
await measure("stats", async () => {
|
|
120
|
+
const trIdsWithRetries = new Set();
|
|
119
121
|
const envStatistics = new Map();
|
|
120
|
-
const pieStatistics = await statisticByTestResults(store, allTrs.filter(isActiveStatisticTestResult));
|
|
121
122
|
const pieEnvStatistics = new Map();
|
|
123
|
+
related.retriesByTrId.forEach((retries, trId) => {
|
|
124
|
+
if (retries.length > 0) {
|
|
125
|
+
trIdsWithRetries.add(trId);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const pieStatistics = statisticByTestResults(allTrs.filter(isActiveStatisticTestResult), trIdsWithRetries);
|
|
122
129
|
for (const tr of allTrs) {
|
|
123
130
|
const environmentId = envIdByTrId.get(tr.id);
|
|
124
131
|
if (!environmentId) {
|
|
@@ -134,8 +141,8 @@ export class AwesomePlugin {
|
|
|
134
141
|
}
|
|
135
142
|
await Promise.all(environments.map(async ({ id }) => {
|
|
136
143
|
const envTrs = trsByEnvId.get(id) ?? [];
|
|
137
|
-
envStatistics.set(id,
|
|
138
|
-
pieEnvStatistics.set(id,
|
|
144
|
+
envStatistics.set(id, statisticByTestResults(envTrs, trIdsWithRetries));
|
|
145
|
+
pieEnvStatistics.set(id, statisticByTestResults(envTrs.filter(isActiveStatisticTestResult), trIdsWithRetries));
|
|
139
146
|
}));
|
|
140
147
|
await generateStatistic(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
|
|
141
148
|
stats: statistics,
|
|
@@ -157,6 +164,7 @@ export class AwesomePlugin {
|
|
|
157
164
|
const convertedTrs = await measure("convert", () => generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs, {
|
|
158
165
|
pluginId: context.id,
|
|
159
166
|
hideLabels,
|
|
167
|
+
related,
|
|
160
168
|
resolveHistoryUrl: context.history?.resolveTestResultUrl,
|
|
161
169
|
}));
|
|
162
170
|
if (perf) {
|
|
@@ -194,7 +202,11 @@ export class AwesomePlugin {
|
|
|
194
202
|
const convertedTrsById = new Map(convertedTrs.map((tr) => [tr.id, tr]));
|
|
195
203
|
await measure("environmentsOutput", async () => {
|
|
196
204
|
for (const reportEnvironment of environments) {
|
|
197
|
-
const
|
|
205
|
+
const environmentIdValidation = validateEnvironmentId(reportEnvironment.id);
|
|
206
|
+
if (!environmentIdValidation.valid) {
|
|
207
|
+
throw new Error(`Invalid environmentId ${JSON.stringify(reportEnvironment.id)}: ${environmentIdValidation.reason}`);
|
|
208
|
+
}
|
|
209
|
+
const envTrs = trsByEnvId.get(reportEnvironment.id) ?? [];
|
|
198
210
|
const envConvertedTrs = envTrs
|
|
199
211
|
.map((tr) => convertedTrsById.get(tr.id))
|
|
200
212
|
.filter((tr) => Boolean(tr));
|
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.20.1",
|
|
4
4
|
"description": "Allure Awesome Plugin – brand new HTML report with modern design and new features",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -30,16 +30,16 @@
|
|
|
30
30
|
"lint:fix": "oxlint --import-plugin --fix src test features stories"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@allurereport/charts-api": "3.
|
|
34
|
-
"@allurereport/core-api": "3.
|
|
35
|
-
"@allurereport/plugin-api": "3.
|
|
36
|
-
"@allurereport/web-commons": "3.
|
|
33
|
+
"@allurereport/charts-api": "3.20.1",
|
|
34
|
+
"@allurereport/core-api": "3.20.1",
|
|
35
|
+
"@allurereport/plugin-api": "3.20.1",
|
|
36
|
+
"@allurereport/web-commons": "3.20.1",
|
|
37
37
|
"d3-shape": "^3.2.0",
|
|
38
38
|
"handlebars": "^4.7.9",
|
|
39
39
|
"markdown-it": "^14.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@allurereport/web-awesome": "3.
|
|
42
|
+
"@allurereport/web-awesome": "3.20.1",
|
|
43
43
|
"@types/d3-shape": "^3.1.8",
|
|
44
44
|
"@types/markdown-it": "^14.1.2",
|
|
45
45
|
"@types/node": "^20",
|