@allurereport/plugin-awesome 3.1.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/categories.d.ts +13 -0
- package/dist/categories.js +213 -0
- package/dist/converters.d.ts +1 -1
- package/dist/converters.js +6 -1
- package/dist/generateTimeline.d.ts +2 -2
- package/dist/generateTimeline.js +6 -9
- package/dist/generators.d.ts +4 -4
- package/dist/generators.js +23 -20
- package/dist/model.d.ts +1 -1
- package/dist/plugin.js +31 -23
- package/package.json +9 -7
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CategoryDefinition } from "@allurereport/core-api";
|
|
2
|
+
import type { AwesomeTestResult } from "@allurereport/web-awesome";
|
|
3
|
+
import type { AwesomeDataWriter } from "./writer.js";
|
|
4
|
+
export declare const applyCategoriesToTestResults: (tests: AwesomeTestResult[], categories: CategoryDefinition[]) => void;
|
|
5
|
+
export declare const generateCategories: (writer: AwesomeDataWriter, { tests, categories, filename, environmentCount, selectedEnvironmentCount, environments, defaultEnvironment, }: {
|
|
6
|
+
tests: AwesomeTestResult[];
|
|
7
|
+
categories: CategoryDefinition[];
|
|
8
|
+
filename?: string;
|
|
9
|
+
environmentCount?: number;
|
|
10
|
+
selectedEnvironmentCount?: number;
|
|
11
|
+
environments?: string[];
|
|
12
|
+
defaultEnvironment?: string;
|
|
13
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { EMPTY_VALUE, buildEnvironmentSortOrder, compareChildNodes, extractErrorMatchingData, findLastByLabelName, incrementStatistic, matchCategory, } from "@allurereport/core-api";
|
|
2
|
+
import { md5 } from "@allurereport/plugin-api";
|
|
3
|
+
const emptyStat = () => ({
|
|
4
|
+
total: 0,
|
|
5
|
+
});
|
|
6
|
+
const msgKey = (m) => (m && m.trim().length ? m : EMPTY_VALUE);
|
|
7
|
+
const envKey = (m) => (m && m.trim().length ? m : EMPTY_VALUE);
|
|
8
|
+
const formatEmptyValue = (key) => {
|
|
9
|
+
if (key === "message") {
|
|
10
|
+
return "No message";
|
|
11
|
+
}
|
|
12
|
+
if (key === "transition") {
|
|
13
|
+
return "No transition";
|
|
14
|
+
}
|
|
15
|
+
if (key === "environment") {
|
|
16
|
+
return "No environment";
|
|
17
|
+
}
|
|
18
|
+
return `No ${key}`;
|
|
19
|
+
};
|
|
20
|
+
const hasEnvironmentSelector = (category) => category.groupBy.some((selector) => selector === "environment");
|
|
21
|
+
const computeGroupEnvironments = (category, environmentCount, isSingleEnvironmentSelected) => {
|
|
22
|
+
if (isSingleEnvironmentSelected) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (category.groupEnvironments !== undefined) {
|
|
26
|
+
return category.groupEnvironments;
|
|
27
|
+
}
|
|
28
|
+
if (environmentCount > 1 && !hasEnvironmentSelector(category)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
};
|
|
33
|
+
const displayGroupValue = (key, value) => (value === EMPTY_VALUE ? formatEmptyValue(key) : value);
|
|
34
|
+
const formatGroupName = (key, value) => `${key}: ${displayGroupValue(key, value)}`;
|
|
35
|
+
export const applyCategoriesToTestResults = (tests, categories) => {
|
|
36
|
+
for (const tr of tests) {
|
|
37
|
+
const matchingData = extractErrorMatchingData(tr);
|
|
38
|
+
const matched = matchCategory(categories, matchingData);
|
|
39
|
+
if (!matched) {
|
|
40
|
+
tr.categories = [];
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
tr.categories = [{ name: matched.name }];
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const extractGroupValue = (selector, testResult) => {
|
|
47
|
+
if (selector === "flaky") {
|
|
48
|
+
const flakyValue = testResult.flaky ? "true" : "false";
|
|
49
|
+
return { key: "flaky", value: flakyValue, name: formatGroupName("flaky", flakyValue) };
|
|
50
|
+
}
|
|
51
|
+
if (selector === "transition") {
|
|
52
|
+
const transitionValue = testResult.transition ?? EMPTY_VALUE;
|
|
53
|
+
return { key: "transition", value: transitionValue, name: formatGroupName("transition", transitionValue) };
|
|
54
|
+
}
|
|
55
|
+
if (selector === "status") {
|
|
56
|
+
const statusValue = testResult.status ?? "unknown";
|
|
57
|
+
return { key: "status", value: statusValue, name: formatGroupName("status", statusValue) };
|
|
58
|
+
}
|
|
59
|
+
if (selector === "environment") {
|
|
60
|
+
const environmentValue = envKey(testResult.environment);
|
|
61
|
+
return { key: "environment", value: environmentValue, name: formatGroupName("environment", environmentValue) };
|
|
62
|
+
}
|
|
63
|
+
if (selector === "owner") {
|
|
64
|
+
const ownerValue = findLastByLabelName(testResult.labels, "owner") ?? EMPTY_VALUE;
|
|
65
|
+
return { key: "owner", value: ownerValue, name: formatGroupName("owner", ownerValue) };
|
|
66
|
+
}
|
|
67
|
+
if (selector === "severity") {
|
|
68
|
+
const fallbackValue = selector === "severity" ? "normal" : EMPTY_VALUE;
|
|
69
|
+
const builtInValue = findLastByLabelName(testResult.labels, selector) ?? fallbackValue;
|
|
70
|
+
return {
|
|
71
|
+
key: selector,
|
|
72
|
+
value: builtInValue,
|
|
73
|
+
name: formatGroupName(selector, builtInValue),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (selector === "layer") {
|
|
77
|
+
const layerValue = findLastByLabelName(testResult.labels, "layer") ?? EMPTY_VALUE;
|
|
78
|
+
return { key: "layer", value: layerValue, name: formatGroupName("layer", layerValue) };
|
|
79
|
+
}
|
|
80
|
+
const labelName = selector.label;
|
|
81
|
+
const labelValue = findLastByLabelName(testResult.labels, labelName) ?? EMPTY_VALUE;
|
|
82
|
+
return { key: labelName, value: labelValue, name: formatGroupName(labelName, labelValue) };
|
|
83
|
+
};
|
|
84
|
+
const buildGroupLevels = (category, testResult, matchingData, environmentCount, isSingleEnvironmentSelected) => {
|
|
85
|
+
const levels = [];
|
|
86
|
+
for (const selector of category.groupBy) {
|
|
87
|
+
const groupValue = extractGroupValue(selector, testResult);
|
|
88
|
+
levels.push({ type: "group", key: groupValue.key, value: groupValue.value, name: groupValue.name });
|
|
89
|
+
}
|
|
90
|
+
if (category.groupByMessage) {
|
|
91
|
+
const messageValue = msgKey(matchingData.message);
|
|
92
|
+
levels.push({
|
|
93
|
+
type: "message",
|
|
94
|
+
key: "message",
|
|
95
|
+
value: messageValue,
|
|
96
|
+
name: displayGroupValue("message", messageValue),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const groupEnvironments = computeGroupEnvironments(category, environmentCount, isSingleEnvironmentSelected);
|
|
100
|
+
if (groupEnvironments) {
|
|
101
|
+
const testKeyValue = testResult.historyId ?? testResult.id;
|
|
102
|
+
const testDisplayName = testResult.name ?? testKeyValue;
|
|
103
|
+
levels.push({
|
|
104
|
+
type: "history",
|
|
105
|
+
key: "historyId",
|
|
106
|
+
value: testKeyValue,
|
|
107
|
+
name: testDisplayName,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return levels;
|
|
111
|
+
};
|
|
112
|
+
export const generateCategories = async (writer, { tests, categories, filename = "categories.json", environmentCount = 0, selectedEnvironmentCount, environments = [], defaultEnvironment = "default", }) => {
|
|
113
|
+
const visible = tests.filter((t) => !t.hidden);
|
|
114
|
+
const environmentOrderMap = buildEnvironmentSortOrder(environments, defaultEnvironment);
|
|
115
|
+
const nodes = {};
|
|
116
|
+
const roots = [];
|
|
117
|
+
const childrenMap = new Map();
|
|
118
|
+
const categoryOrder = categories.filter((cat) => !cat.hide).map((cat) => cat.name);
|
|
119
|
+
const categoryIds = new Map();
|
|
120
|
+
const categoryTouched = new Set();
|
|
121
|
+
const duplicateChecker = (node) => {
|
|
122
|
+
var _a;
|
|
123
|
+
nodes[_a = node.id] ?? (nodes[_a] = node);
|
|
124
|
+
return nodes[node.id];
|
|
125
|
+
};
|
|
126
|
+
const attachChild = (parentId, childId) => {
|
|
127
|
+
const set = childrenMap.get(parentId) ?? new Set();
|
|
128
|
+
set.add(childId);
|
|
129
|
+
childrenMap.set(parentId, set);
|
|
130
|
+
};
|
|
131
|
+
const bumpStat = (nodeId, status) => {
|
|
132
|
+
const node = nodes[nodeId];
|
|
133
|
+
node.statistic ?? (node.statistic = emptyStat());
|
|
134
|
+
incrementStatistic(node.statistic, status);
|
|
135
|
+
};
|
|
136
|
+
const ensureCategoryNode = (category) => {
|
|
137
|
+
const catId = categoryIds.get(category.name) ?? `cat:${md5(category.name)}`;
|
|
138
|
+
if (!categoryIds.has(category.name)) {
|
|
139
|
+
categoryIds.set(category.name, catId);
|
|
140
|
+
}
|
|
141
|
+
duplicateChecker({
|
|
142
|
+
id: catId,
|
|
143
|
+
type: "category",
|
|
144
|
+
name: category.name,
|
|
145
|
+
statistic: emptyStat(),
|
|
146
|
+
childrenIds: [],
|
|
147
|
+
expand: category.expand,
|
|
148
|
+
});
|
|
149
|
+
return catId;
|
|
150
|
+
};
|
|
151
|
+
for (const tr of visible) {
|
|
152
|
+
const matchingData = extractErrorMatchingData(tr);
|
|
153
|
+
const matchedCategory = matchCategory(categories, matchingData);
|
|
154
|
+
if (!matchedCategory || matchedCategory.hide) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const catId = ensureCategoryNode(matchedCategory);
|
|
158
|
+
categoryTouched.add(matchedCategory.name);
|
|
159
|
+
bumpStat(catId, tr.status);
|
|
160
|
+
const environmentValue = envKey(tr.environment);
|
|
161
|
+
const isSingleEnvironmentSelected = selectedEnvironmentCount === 1;
|
|
162
|
+
const groupEnvironments = computeGroupEnvironments(matchedCategory, environmentCount, isSingleEnvironmentSelected);
|
|
163
|
+
const levels = buildGroupLevels(matchedCategory, tr, matchingData, environmentCount, isSingleEnvironmentSelected);
|
|
164
|
+
const leafName = groupEnvironments ? formatGroupName("environment", environmentValue) : tr.name;
|
|
165
|
+
let parentId = catId;
|
|
166
|
+
for (const level of levels) {
|
|
167
|
+
const levelId = `${level.type}:${md5(`${parentId}\n${level.key}\n${level.value}`)}`;
|
|
168
|
+
const historyId = level.type === "history" ? level.value : undefined;
|
|
169
|
+
duplicateChecker({
|
|
170
|
+
id: levelId,
|
|
171
|
+
type: level.type,
|
|
172
|
+
name: level.name,
|
|
173
|
+
key: level.key,
|
|
174
|
+
value: level.value,
|
|
175
|
+
historyId,
|
|
176
|
+
statistic: emptyStat(),
|
|
177
|
+
childrenIds: [],
|
|
178
|
+
});
|
|
179
|
+
bumpStat(levelId, tr.status);
|
|
180
|
+
attachChild(parentId, levelId);
|
|
181
|
+
parentId = levelId;
|
|
182
|
+
}
|
|
183
|
+
duplicateChecker({
|
|
184
|
+
id: tr.id,
|
|
185
|
+
type: "tr",
|
|
186
|
+
name: leafName,
|
|
187
|
+
key: groupEnvironments ? "environment" : undefined,
|
|
188
|
+
value: groupEnvironments ? environmentValue : undefined,
|
|
189
|
+
status: tr.status,
|
|
190
|
+
duration: tr.duration,
|
|
191
|
+
flaky: tr.flaky,
|
|
192
|
+
retriesCount: tr.retriesCount,
|
|
193
|
+
transition: tr.transition,
|
|
194
|
+
tooltips: tr.tooltips,
|
|
195
|
+
});
|
|
196
|
+
attachChild(parentId, tr.id);
|
|
197
|
+
}
|
|
198
|
+
for (const [parentNodeId, childNodeIds] of childrenMap.entries()) {
|
|
199
|
+
const sortedChildIds = Array.from(childNodeIds).sort((leftChildId, rightChildId) => compareChildNodes(leftChildId, rightChildId, nodes, environmentOrderMap));
|
|
200
|
+
nodes[parentNodeId].childrenIds = sortedChildIds;
|
|
201
|
+
}
|
|
202
|
+
for (const catName of categoryOrder) {
|
|
203
|
+
if (!categoryTouched.has(catName)) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const id = categoryIds.get(catName);
|
|
207
|
+
if (id) {
|
|
208
|
+
roots.push(id);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const store = { roots, nodes };
|
|
212
|
+
await writer.writeWidget(filename, store);
|
|
213
|
+
};
|
package/dist/converters.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type TestFixtureResult, type TestResult, type TestStepResult } from "@allurereport/core-api";
|
|
2
2
|
import type { AwesomeFixtureResult, AwesomeTestResult, AwesomeTestStepResult } from "@allurereport/web-awesome";
|
|
3
3
|
export declare const convertTestResult: (tr: TestResult) => AwesomeTestResult;
|
|
4
4
|
export declare const convertTestStepResult: (tsr: TestStepResult) => AwesomeTestStepResult;
|
package/dist/converters.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { createDictionary, } from "@allurereport/core-api";
|
|
2
|
+
import MarkdownIt from "markdown-it";
|
|
3
|
+
const md = new MarkdownIt();
|
|
4
|
+
const markdownToHtml = (value) => (value ? md.render(value) : undefined);
|
|
1
5
|
const mapLabelsByName = (labels) => {
|
|
2
6
|
return labels.reduce((acc, { name, value }) => {
|
|
3
7
|
acc[name] = acc[name] || [];
|
|
@@ -5,7 +9,7 @@ const mapLabelsByName = (labels) => {
|
|
|
5
9
|
acc[name].push(value);
|
|
6
10
|
}
|
|
7
11
|
return acc;
|
|
8
|
-
},
|
|
12
|
+
}, createDictionary());
|
|
9
13
|
};
|
|
10
14
|
export const convertTestResult = (tr) => {
|
|
11
15
|
return {
|
|
@@ -28,6 +32,7 @@ export const convertTestResult = (tr) => {
|
|
|
28
32
|
steps: tr.steps,
|
|
29
33
|
error: tr.error,
|
|
30
34
|
testCase: tr.testCase,
|
|
35
|
+
descriptionHtml: tr.descriptionHtml ?? markdownToHtml(tr.description),
|
|
31
36
|
environment: tr.environment,
|
|
32
37
|
setup: [],
|
|
33
38
|
teardown: [],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AwesomeTestResult } from "@allurereport/web-awesome";
|
|
2
2
|
import type { AwesomeOptions } from "./model.js";
|
|
3
3
|
type Writer = {
|
|
4
4
|
writeWidget(fileName: string, data: any): Promise<void>;
|
|
5
5
|
};
|
|
6
|
-
export declare const generateTimeline: (writer: Writer,
|
|
6
|
+
export declare const generateTimeline: (writer: Writer, trs: AwesomeTestResult[], options: AwesomeOptions) => Promise<void>;
|
|
7
7
|
export {};
|
package/dist/generateTimeline.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { hasLabels } from "@allurereport/web-commons";
|
|
2
1
|
const DEFAULT_MIN_DURATION = 1;
|
|
3
|
-
const HOST_LABEL = "host";
|
|
4
|
-
const THREAD_LABEL = "thread";
|
|
5
2
|
const DEFAULT_TIMELINE_OPTIONS = {
|
|
6
3
|
minDuration: DEFAULT_MIN_DURATION,
|
|
7
4
|
};
|
|
8
|
-
export const generateTimeline = async (writer,
|
|
5
|
+
export const generateTimeline = async (writer, trs, options) => {
|
|
9
6
|
const { timeline = DEFAULT_TIMELINE_OPTIONS } = options;
|
|
10
7
|
const { minDuration = DEFAULT_MIN_DURATION } = timeline;
|
|
11
|
-
const testResults = await store.allTestResults({ includeHidden: true });
|
|
12
8
|
const result = [];
|
|
13
|
-
for (const test of
|
|
9
|
+
for (const test of trs) {
|
|
14
10
|
const hasStart = Number.isInteger(test.start);
|
|
15
11
|
const hasStop = Number.isInteger(test.stop);
|
|
16
12
|
if (!hasStart || !hasStop) {
|
|
@@ -20,7 +16,8 @@ export const generateTimeline = async (writer, store, options) => {
|
|
|
20
16
|
if (duration < minDuration) {
|
|
21
17
|
continue;
|
|
22
18
|
}
|
|
23
|
-
|
|
19
|
+
const { host, thread } = test.groupedLabels;
|
|
20
|
+
if (!host?.length || !thread?.length) {
|
|
24
21
|
continue;
|
|
25
22
|
}
|
|
26
23
|
result.push({
|
|
@@ -29,10 +26,10 @@ export const generateTimeline = async (writer, store, options) => {
|
|
|
29
26
|
name: test.name,
|
|
30
27
|
status: test.status,
|
|
31
28
|
hidden: test.hidden,
|
|
32
|
-
|
|
29
|
+
host: host[0],
|
|
30
|
+
thread: thread[0],
|
|
33
31
|
environment: test.environment,
|
|
34
32
|
start: test.start,
|
|
35
|
-
stop: test.stop,
|
|
36
33
|
duration,
|
|
37
34
|
});
|
|
38
35
|
}
|
package/dist/generators.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type AttachmentLink, type EnvironmentItem, type Statistic, type TestEnvGroup, type TestError, type TestResult } from "@allurereport/core-api";
|
|
2
|
-
import type { AllureStore, ExitCode, PluginContext, QualityGateValidationResult, ReportFiles, ResultFile
|
|
2
|
+
import type { AllureStore, ExitCode, PluginContext, QualityGateValidationResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
|
|
3
3
|
import type { AwesomeTestResult } from "@allurereport/web-awesome";
|
|
4
4
|
import type { AwesomeOptions, TemplateManifest } from "./model.js";
|
|
5
5
|
import type { AwesomeDataWriter, ReportFile } from "./writer.js";
|
|
6
6
|
export declare const readTemplateManifest: (singleFileMode?: boolean) => Promise<TemplateManifest>;
|
|
7
|
-
export declare const generateTestResults: (writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[]
|
|
7
|
+
export declare const generateTestResults: (writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[]) => Promise<AwesomeTestResult[]>;
|
|
8
8
|
export declare const generateTestCases: (writer: AwesomeDataWriter, trs: AwesomeTestResult[]) => Promise<void>;
|
|
9
9
|
export declare const generateTestEnvGroups: (writer: AwesomeDataWriter, groups: TestEnvGroup[]) => Promise<void>;
|
|
10
10
|
export declare const generateNav: (writer: AwesomeDataWriter, trs: AwesomeTestResult[], filename?: string) => Promise<void>;
|
|
@@ -27,7 +27,7 @@ export declare const generateGlobals: (writer: AwesomeDataWriter, payload: {
|
|
|
27
27
|
globalErrors?: TestError[];
|
|
28
28
|
contentFunction: (id: string) => Promise<ResultFile | undefined>;
|
|
29
29
|
}) => Promise<void>;
|
|
30
|
-
export declare const generateQualityGateResults: (writer: AwesomeDataWriter, qualityGateResults?: QualityGateValidationResult[]) => Promise<void>;
|
|
30
|
+
export declare const generateQualityGateResults: (writer: AwesomeDataWriter, qualityGateResults?: Record<string, QualityGateValidationResult[]>) => Promise<void>;
|
|
31
31
|
export declare const generateStaticFiles: (payload: AwesomeOptions & {
|
|
32
32
|
id: string;
|
|
33
33
|
allureVersion: string;
|
|
@@ -37,4 +37,4 @@ export declare const generateStaticFiles: (payload: AwesomeOptions & {
|
|
|
37
37
|
reportName: string;
|
|
38
38
|
}) => Promise<void>;
|
|
39
39
|
export declare const generateAllCharts: (writer: AwesomeDataWriter, store: AllureStore, options: AwesomeOptions, context: PluginContext) => Promise<void>;
|
|
40
|
-
export declare const generateTreeFilters: (writer: AwesomeDataWriter,
|
|
40
|
+
export declare const generateTreeFilters: (writer: AwesomeDataWriter, testResults: AwesomeTestResult[]) => Promise<void>;
|
package/dist/generators.js
CHANGED
|
@@ -58,9 +58,9 @@ const createBreadcrumbs = (convertedTr) => {
|
|
|
58
58
|
acc[label.name].push(label.value || "");
|
|
59
59
|
return acc;
|
|
60
60
|
}, {});
|
|
61
|
-
const parentSuites = labelsByType.parentSuite
|
|
62
|
-
const suites = labelsByType.suite
|
|
63
|
-
const subSuites = labelsByType.subSuite
|
|
61
|
+
const parentSuites = labelsByType.parentSuite ?? [""];
|
|
62
|
+
const suites = labelsByType.suite ?? [""];
|
|
63
|
+
const subSuites = labelsByType.subSuite ?? [""];
|
|
64
64
|
return parentSuites.reduce((acc, parentSuite) => {
|
|
65
65
|
suites.forEach((suite) => {
|
|
66
66
|
subSuites.forEach((subSuite) => {
|
|
@@ -73,10 +73,9 @@ const createBreadcrumbs = (convertedTr) => {
|
|
|
73
73
|
return acc;
|
|
74
74
|
}, []);
|
|
75
75
|
};
|
|
76
|
-
export const generateTestResults = async (writer, store, trs
|
|
77
|
-
const allTr = trs.filter((tr) => (filter ? filter(tr) : true));
|
|
76
|
+
export const generateTestResults = async (writer, store, trs) => {
|
|
78
77
|
let convertedTrs = [];
|
|
79
|
-
for (const tr of
|
|
78
|
+
for (const tr of trs) {
|
|
80
79
|
const trFixtures = await store.fixturesByTrId(tr.id);
|
|
81
80
|
const convertedTrFixtures = trFixtures.map(convertFixtureResult);
|
|
82
81
|
const convertedTr = convertTestResult(tr);
|
|
@@ -190,7 +189,7 @@ const buildTreeByTitlePath = (tests) => {
|
|
|
190
189
|
};
|
|
191
190
|
};
|
|
192
191
|
const buildTreeByLabelsAndTitlePathCombined = (tests, labels) => createTreeByLabelsAndTitlePath(tests, labels, leafFactory, undefined, (group, leaf) => incrementStatistic(group.statistic, leaf.status));
|
|
193
|
-
const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, transition, tooltips, historyId, groupedLabels, }) => {
|
|
192
|
+
const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, transition, tooltips, historyId, groupedLabels, categories, }) => {
|
|
194
193
|
const leaf = {
|
|
195
194
|
nodeId: id,
|
|
196
195
|
id: historyId ?? id,
|
|
@@ -207,6 +206,9 @@ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesC
|
|
|
207
206
|
if (groupedLabels.tag && groupedLabels.tag.length > 0) {
|
|
208
207
|
leaf.tags = groupedLabels.tag;
|
|
209
208
|
}
|
|
209
|
+
if (categories?.length) {
|
|
210
|
+
leaf.categories = categories.map((category) => category.name).filter(Boolean);
|
|
211
|
+
}
|
|
210
212
|
return leaf;
|
|
211
213
|
};
|
|
212
214
|
export const generateEnvironmentJson = async (writer, env) => {
|
|
@@ -283,7 +285,7 @@ export const generateGlobals = async (writer, payload) => {
|
|
|
283
285
|
}
|
|
284
286
|
await writer.writeWidget("globals.json", globals);
|
|
285
287
|
};
|
|
286
|
-
export const generateQualityGateResults = async (writer, qualityGateResults =
|
|
288
|
+
export const generateQualityGateResults = async (writer, qualityGateResults = {}) => {
|
|
287
289
|
await writer.writeWidget("quality-gate.json", qualityGateResults);
|
|
288
290
|
};
|
|
289
291
|
export const generateStaticFiles = async (payload) => {
|
|
@@ -359,28 +361,29 @@ export const generateStaticFiles = async (payload) => {
|
|
|
359
361
|
}
|
|
360
362
|
};
|
|
361
363
|
export const generateAllCharts = async (writer, store, options, context) => {
|
|
362
|
-
const { charts = defaultChartsConfig } = options;
|
|
363
|
-
const generatedChartsData = await generateCharts(charts, store, context.reportName, randomUUID);
|
|
364
|
+
const { charts = defaultChartsConfig, filter } = options;
|
|
365
|
+
const generatedChartsData = await generateCharts(charts, store, context.reportName, randomUUID, filter);
|
|
364
366
|
if (Object.keys(generatedChartsData.general).length > 0) {
|
|
365
367
|
await writer.writeWidget("charts.json", generatedChartsData);
|
|
366
368
|
}
|
|
367
369
|
};
|
|
368
|
-
export const generateTreeFilters = async (writer,
|
|
370
|
+
export const generateTreeFilters = async (writer, testResults) => {
|
|
369
371
|
const trTags = new Set();
|
|
370
|
-
const
|
|
371
|
-
for (const tr of
|
|
372
|
-
|
|
373
|
-
|
|
372
|
+
const trCategories = new Set();
|
|
373
|
+
for (const tr of testResults) {
|
|
374
|
+
for (const tag of tr.groupedLabels.tag ?? []) {
|
|
375
|
+
trTags.add(tag);
|
|
374
376
|
}
|
|
375
|
-
tr.
|
|
376
|
-
if (
|
|
377
|
-
|
|
377
|
+
tr.categories?.forEach((category) => {
|
|
378
|
+
if (category.name) {
|
|
379
|
+
trCategories.add(category.name);
|
|
378
380
|
}
|
|
379
381
|
});
|
|
380
382
|
}
|
|
381
|
-
if (trTags.size === 0) {
|
|
383
|
+
if (trTags.size === 0 && trCategories.size === 0) {
|
|
382
384
|
return Promise.resolve();
|
|
383
385
|
}
|
|
384
386
|
const tags = Array.from(trTags).sort((a, b) => a.localeCompare(b));
|
|
385
|
-
|
|
387
|
+
const categories = Array.from(trCategories).sort((a, b) => a.localeCompare(b));
|
|
388
|
+
await writer.writeWidget("tree-filters.json", { tags, categories });
|
|
386
389
|
};
|
package/dist/model.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type AwesomeOptions = {
|
|
|
5
5
|
singleFile?: boolean;
|
|
6
6
|
logo?: string;
|
|
7
7
|
theme?: "light" | "dark" | "auto";
|
|
8
|
-
reportLanguage?:
|
|
8
|
+
reportLanguage?: string;
|
|
9
9
|
groupBy?: string[];
|
|
10
10
|
layout?: "base" | "split";
|
|
11
11
|
environments?: Record<string, EnvironmentsConfig>;
|
package/dist/plugin.js
CHANGED
|
@@ -10,10 +10,10 @@ 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_generate;
|
|
13
|
-
import {
|
|
14
|
-
import { convertToSummaryTestResult, } from "@allurereport/plugin-api";
|
|
13
|
+
import { createPluginSummary, } from "@allurereport/plugin-api";
|
|
15
14
|
import { preciseTreeLabels } from "@allurereport/plugin-api";
|
|
16
15
|
import { join } from "node:path";
|
|
16
|
+
import { applyCategoriesToTestResults, generateCategories } from "./categories.js";
|
|
17
17
|
import { filterEnv } from "./environments.js";
|
|
18
18
|
import { generateTimeline } from "./generateTimeline.js";
|
|
19
19
|
import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateNav, generateQualityGateResults, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateTreeFilters, generateVariables, } from "./generators.js";
|
|
@@ -24,10 +24,11 @@ export class AwesomePlugin {
|
|
|
24
24
|
_AwesomePlugin_writer.set(this, void 0);
|
|
25
25
|
_AwesomePlugin_generate.set(this, async (context, store) => {
|
|
26
26
|
const { singleFile, groupBy = [], filter, appendTitlePath } = this.options ?? {};
|
|
27
|
+
const categories = context.categories ?? [];
|
|
27
28
|
const environmentItems = await store.metadataByKey("allure_environment");
|
|
28
29
|
const reportEnvironments = await store.allEnvironments();
|
|
29
30
|
const attachments = await store.allAttachments();
|
|
30
|
-
const allTrs = await store.allTestResults({ includeHidden: true });
|
|
31
|
+
const allTrs = await store.allTestResults({ includeHidden: true, filter });
|
|
31
32
|
const statistics = await store.testsStatistic(filter);
|
|
32
33
|
const environments = await store.allEnvironments();
|
|
33
34
|
const envStatistics = new Map();
|
|
@@ -35,7 +36,7 @@ export class AwesomePlugin {
|
|
|
35
36
|
const globalAttachments = await store.allGlobalAttachments();
|
|
36
37
|
const globalExitCode = await store.globalExitCode();
|
|
37
38
|
const globalErrors = await store.allGlobalErrors();
|
|
38
|
-
const qualityGateResults = await store.
|
|
39
|
+
const qualityGateResults = await store.qualityGateResultsByEnv();
|
|
39
40
|
for (const env of environments) {
|
|
40
41
|
envStatistics.set(env, await store.testsStatistic(filterEnv(env, filter)));
|
|
41
42
|
}
|
|
@@ -45,9 +46,18 @@ export class AwesomePlugin {
|
|
|
45
46
|
envs: environments,
|
|
46
47
|
});
|
|
47
48
|
await generateAllCharts(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, this.options, context);
|
|
48
|
-
await
|
|
49
|
-
|
|
49
|
+
const convertedTrs = await generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs);
|
|
50
|
+
applyCategoriesToTestResults(convertedTrs, categories);
|
|
51
|
+
await generateCategories(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
|
|
52
|
+
tests: convertedTrs,
|
|
53
|
+
categories,
|
|
54
|
+
environmentCount: environments.length,
|
|
55
|
+
environments,
|
|
56
|
+
defaultEnvironment: "default",
|
|
57
|
+
selectedEnvironmentCount: environments.length,
|
|
58
|
+
});
|
|
50
59
|
const hasGroupBy = groupBy.length > 0;
|
|
60
|
+
await generateTimeline(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs, this.options);
|
|
51
61
|
const treeLabels = hasGroupBy
|
|
52
62
|
? preciseTreeLabels(groupBy, convertedTrs, ({ labels }) => labels.map(({ name }) => name))
|
|
53
63
|
: [];
|
|
@@ -62,8 +72,16 @@ export class AwesomePlugin {
|
|
|
62
72
|
appendTitlePath,
|
|
63
73
|
});
|
|
64
74
|
await generateNav(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), envConvertedTrs, join(reportEnvironment, "nav.json"));
|
|
75
|
+
await generateCategories(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
|
|
76
|
+
tests: envConvertedTrs,
|
|
77
|
+
categories,
|
|
78
|
+
environmentCount: 1,
|
|
79
|
+
defaultEnvironment: "default",
|
|
80
|
+
selectedEnvironmentCount: 1,
|
|
81
|
+
filename: join(reportEnvironment, "categories.json"),
|
|
82
|
+
});
|
|
65
83
|
}
|
|
66
|
-
await generateTreeFilters(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"),
|
|
84
|
+
await generateTreeFilters(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs);
|
|
67
85
|
await generateEnvirontmentsList(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store);
|
|
68
86
|
await generateVariables(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store);
|
|
69
87
|
if (environmentItems?.length) {
|
|
@@ -114,29 +132,19 @@ export class AwesomePlugin {
|
|
|
114
132
|
};
|
|
115
133
|
}
|
|
116
134
|
async info(context, store) {
|
|
117
|
-
|
|
118
|
-
const newTrs = await store.allNewTestResults();
|
|
119
|
-
const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
|
|
120
|
-
const flakyTrs = allTrs.filter((tr) => !!tr?.flaky);
|
|
121
|
-
const duration = allTrs.reduce((acc, { duration: trDuration = 0 }) => acc + trDuration, 0);
|
|
122
|
-
const worstStatus = getWorstStatus(allTrs.map(({ status }) => status));
|
|
123
|
-
const createdAt = allTrs.reduce((acc, { stop }) => Math.max(acc, stop || 0), 0);
|
|
124
|
-
return {
|
|
135
|
+
return createPluginSummary({
|
|
125
136
|
name: this.options.reportName || context.reportName,
|
|
126
|
-
stats: await store.testsStatistic(this.options.filter),
|
|
127
|
-
status: worstStatus ?? "passed",
|
|
128
|
-
duration,
|
|
129
|
-
createdAt,
|
|
130
137
|
plugin: "Awesome",
|
|
131
|
-
newTests: newTrs.map(convertToSummaryTestResult),
|
|
132
|
-
flakyTests: flakyTrs.map(convertToSummaryTestResult),
|
|
133
|
-
retryTests: retryTrs.map(convertToSummaryTestResult),
|
|
134
138
|
meta: {
|
|
135
139
|
reportId: context.reportUuid,
|
|
136
140
|
singleFile: this.options.singleFile ?? false,
|
|
137
141
|
withTestResultsLinks: true,
|
|
138
142
|
},
|
|
139
|
-
|
|
143
|
+
filter: this.options.filter,
|
|
144
|
+
ci: context.ci,
|
|
145
|
+
history: context.history,
|
|
146
|
+
store,
|
|
147
|
+
});
|
|
140
148
|
}
|
|
141
149
|
}
|
|
142
150
|
_AwesomePlugin_writer = new WeakMap(), _AwesomePlugin_generate = new WeakMap();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/plugin-awesome",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "Allure Awesome Plugin – brand new HTML report with modern design and new features",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -30,18 +30,20 @@
|
|
|
30
30
|
"test": "rimraf ./out && vitest run"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@allurereport/charts-api": "3.1
|
|
34
|
-
"@allurereport/core-api": "3.1
|
|
35
|
-
"@allurereport/plugin-api": "3.1
|
|
36
|
-
"@allurereport/web-awesome": "3.1
|
|
37
|
-
"@allurereport/web-commons": "3.1
|
|
33
|
+
"@allurereport/charts-api": "3.3.1",
|
|
34
|
+
"@allurereport/core-api": "3.3.1",
|
|
35
|
+
"@allurereport/plugin-api": "3.3.1",
|
|
36
|
+
"@allurereport/web-awesome": "3.3.1",
|
|
37
|
+
"@allurereport/web-commons": "3.3.1",
|
|
38
38
|
"d3-shape": "^3.2.0",
|
|
39
|
-
"handlebars": "^4.7.8"
|
|
39
|
+
"handlebars": "^4.7.8",
|
|
40
|
+
"markdown-it": "^14.1.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@stylistic/eslint-plugin": "^2.6.1",
|
|
43
44
|
"@types/d3-shape": "^3.1.6",
|
|
44
45
|
"@types/eslint": "^8.56.11",
|
|
46
|
+
"@types/markdown-it": "^14.1.2",
|
|
45
47
|
"@types/node": "^20.17.9",
|
|
46
48
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
47
49
|
"@typescript-eslint/parser": "^8.0.0",
|