@allurereport/web-awesome 3.0.0-beta.13 → 3.0.0-beta.15
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/multi/{173.app-01ff983b.js → 173.app-35b67161.js} +1 -1
- package/dist/multi/{174.app-01ff983b.js → 174.app-35b67161.js} +1 -1
- package/dist/multi/{252.app-01ff983b.js → 252.app-35b67161.js} +1 -1
- package/dist/multi/{282.app-01ff983b.js → 282.app-35b67161.js} +1 -1
- package/dist/multi/{29.app-01ff983b.js → 29.app-35b67161.js} +1 -1
- package/dist/multi/{416.app-01ff983b.js → 416.app-35b67161.js} +1 -1
- package/dist/multi/{527.app-01ff983b.js → 527.app-35b67161.js} +1 -1
- package/dist/multi/{600.app-01ff983b.js → 600.app-35b67161.js} +1 -1
- package/dist/multi/{605.app-01ff983b.js → 605.app-35b67161.js} +1 -1
- package/dist/multi/{638.app-01ff983b.js → 638.app-35b67161.js} +1 -1
- package/dist/multi/{672.app-01ff983b.js → 672.app-35b67161.js} +1 -1
- package/dist/multi/{686.app-01ff983b.js → 686.app-35b67161.js} +1 -1
- package/dist/multi/{725.app-01ff983b.js → 725.app-35b67161.js} +1 -1
- package/dist/multi/{741.app-01ff983b.js → 741.app-35b67161.js} +1 -1
- package/dist/multi/{755.app-01ff983b.js → 755.app-35b67161.js} +1 -1
- package/dist/multi/{894.app-01ff983b.js → 894.app-35b67161.js} +1 -1
- package/dist/multi/{943.app-01ff983b.js → 943.app-35b67161.js} +1 -1
- package/dist/multi/{980.app-01ff983b.js → 980.app-35b67161.js} +1 -1
- package/dist/multi/app-35b67161.js +2 -0
- package/dist/multi/manifest.json +20 -20
- package/dist/multi/{styles-01ff983b.css → styles-35b67161.css} +12 -10
- package/dist/single/app-f5ecfcd9.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +5 -4
- package/src/components/BaseLayout/index.tsx +1 -4
- package/src/components/BaseLayout/styles.scss +5 -3
- package/src/components/Charts/index.tsx +89 -0
- package/src/components/Charts/styles.scss +29 -0
- package/src/components/Footer/index.tsx +6 -2
- package/src/components/Header/index.tsx +5 -2
- package/src/components/Header/styles.scss +1 -0
- package/src/components/MainReport/index.tsx +0 -2
- package/src/components/MetadataButton/index.tsx +2 -2
- package/src/components/Report/index.tsx +7 -0
- package/src/components/ReportBody/index.tsx +24 -13
- package/src/components/ReportBody/styles.scss +1 -0
- package/src/components/ReportHeader/index.tsx +3 -0
- package/src/components/SectionPicker/index.tsx +54 -0
- package/src/components/SectionPicker/styles.scss +5 -0
- package/src/components/SectionSwitcher/index.tsx +14 -0
- package/src/components/SectionSwitcher/styles.scss +4 -0
- package/src/components/SectionTabs/index.tsx +0 -0
- package/src/components/SideBySide/styles.scss +1 -1
- package/src/components/SplitLayout/index.tsx +1 -3
- package/src/components/SplitLayout/styles.scss +1 -3
- package/src/components/TestResult/TrDropdown/index.tsx +1 -2
- package/src/components/TestResult/TrEnvironmentItem/index.tsx +1 -2
- package/src/components/TestResult/TrHistory/TrHistoryItem.tsx +1 -2
- package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +0 -1
- package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +5 -4
- package/src/components/TestResult/TrSteps/TrAttachment.tsx +31 -5
- package/src/components/TestResult/TrSteps/TrStep.tsx +1 -2
- package/src/components/TestResult/TrSteps/styles.scss +4 -2
- package/src/components/TestResult/TrTabs/index.tsx +8 -4
- package/src/components/TestResult/index.tsx +0 -1
- package/src/components/Tree/index.tsx +6 -6
- package/src/components/Tree/styles.scss +0 -4
- package/src/index.tsx +25 -12
- package/src/locales/az.json +16 -0
- package/src/locales/de.json +16 -0
- package/src/locales/en.json +16 -0
- package/src/locales/es.json +16 -0
- package/src/locales/fr.json +16 -0
- package/src/locales/he.json +16 -0
- package/src/locales/hy.json +16 -0
- package/src/locales/it.json +16 -0
- package/src/locales/ja.json +16 -0
- package/src/locales/ka.json +16 -0
- package/src/locales/kr.json +16 -0
- package/src/locales/nl.json +16 -0
- package/src/locales/pl.json +16 -0
- package/src/locales/pt.json +16 -0
- package/src/locales/ru.json +16 -0
- package/src/locales/sv.json +16 -0
- package/src/locales/tr.json +16 -0
- package/src/locales/zh.json +16 -0
- package/src/stores/chart.ts +35 -1
- package/src/stores/env.ts +1 -1
- package/src/stores/envInfo.ts +2 -2
- package/src/stores/locale.ts +2 -0
- package/src/stores/router.ts +76 -16
- package/src/stores/sections.ts +63 -0
- package/src/stores/stats.ts +2 -2
- package/src/stores/testResults.ts +6 -2
- package/src/stores/tree.ts +10 -7
- package/src/stores/variables.ts +3 -1
- package/src/styles.scss +21 -0
- package/src/utils/charts.ts +169 -0
- package/types.d.ts +4 -1
- package/webpack.config.js +14 -0
- package/dist/multi/app-01ff983b.js +0 -2
- package/dist/single/app-607f21f7.js +0 -2
- package/src/components/ArrowButton/index.tsx +0 -36
- package/src/components/ArrowButton/styles.scss +0 -35
- /package/dist/multi/{app-01ff983b.js.LICENSE.txt → app-35b67161.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-607f21f7.js.LICENSE.txt → app-f5ecfcd9.js.LICENSE.txt} +0 -0
package/src/locales/tr.json
CHANGED
|
@@ -138,5 +138,21 @@
|
|
|
138
138
|
},
|
|
139
139
|
"errors": {
|
|
140
140
|
"missedAttachment": "Ek bulunamadı"
|
|
141
|
+
},
|
|
142
|
+
"sections": {
|
|
143
|
+
"report": "Report",
|
|
144
|
+
"charts": "Grafikler"
|
|
145
|
+
},
|
|
146
|
+
"charts": {
|
|
147
|
+
"trend": {
|
|
148
|
+
"title": "Trend Grafiği: {{type}}",
|
|
149
|
+
"type": {
|
|
150
|
+
"status": "Durum",
|
|
151
|
+
"severity": "Önem Derecesi"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"pie": {
|
|
155
|
+
"title": "Test Başarı Oranı"
|
|
156
|
+
}
|
|
141
157
|
}
|
|
142
158
|
}
|
package/src/locales/zh.json
CHANGED
|
@@ -138,5 +138,21 @@
|
|
|
138
138
|
},
|
|
139
139
|
"errors": {
|
|
140
140
|
"missedAttachment": "未找到附件"
|
|
141
|
+
},
|
|
142
|
+
"sections": {
|
|
143
|
+
"report": "Report",
|
|
144
|
+
"charts": "图形"
|
|
145
|
+
},
|
|
146
|
+
"charts": {
|
|
147
|
+
"trend": {
|
|
148
|
+
"title": "趋势图表: {{type}}",
|
|
149
|
+
"type": {
|
|
150
|
+
"status": "状态",
|
|
151
|
+
"severity": "严重程度"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"pie": {
|
|
155
|
+
"title": "测试成功率"
|
|
156
|
+
}
|
|
141
157
|
}
|
|
142
158
|
}
|
package/src/stores/chart.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
2
|
import { signal } from "@preact/signals";
|
|
3
3
|
import type { StoreSignalState } from "@/stores/types";
|
|
4
|
+
import type { ChartsData, ChartsResponse } from "@/utils/charts";
|
|
5
|
+
import { createCharts } from "@/utils/charts";
|
|
4
6
|
|
|
5
7
|
export const pieChartStore = signal<StoreSignalState<any>>({
|
|
6
8
|
loading: true,
|
|
@@ -16,7 +18,9 @@ export const fetchPieChartData = async (env: string) => {
|
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
try {
|
|
19
|
-
const res = await fetchReportJsonData(env ? `widgets/${env}/pie_chart.json` : "widgets/pie_chart.json"
|
|
21
|
+
const res = await fetchReportJsonData(env ? `widgets/${env}/pie_chart.json` : "widgets/pie_chart.json", {
|
|
22
|
+
bustCache: true,
|
|
23
|
+
});
|
|
20
24
|
|
|
21
25
|
pieChartStore.value = {
|
|
22
26
|
data: res,
|
|
@@ -30,3 +34,33 @@ export const fetchPieChartData = async (env: string) => {
|
|
|
30
34
|
};
|
|
31
35
|
}
|
|
32
36
|
};
|
|
37
|
+
|
|
38
|
+
export const chartsStore = signal<StoreSignalState<ChartsData>>({
|
|
39
|
+
loading: true,
|
|
40
|
+
error: undefined,
|
|
41
|
+
data: undefined,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const fetchChartsData = async () => {
|
|
45
|
+
chartsStore.value = {
|
|
46
|
+
...chartsStore.value,
|
|
47
|
+
loading: true,
|
|
48
|
+
error: undefined,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetchReportJsonData<ChartsResponse>("widgets/charts.json", { bustCache: true });
|
|
53
|
+
|
|
54
|
+
chartsStore.value = {
|
|
55
|
+
data: createCharts(res),
|
|
56
|
+
error: undefined,
|
|
57
|
+
loading: false,
|
|
58
|
+
};
|
|
59
|
+
} catch (err) {
|
|
60
|
+
chartsStore.value = {
|
|
61
|
+
data: undefined,
|
|
62
|
+
error: err.message,
|
|
63
|
+
loading: false,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
package/src/stores/env.ts
CHANGED
|
@@ -32,7 +32,7 @@ export const fetchEnvironments = async () => {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
try {
|
|
35
|
-
const res = await fetchReportJsonData<string[]>("widgets/environments.json");
|
|
35
|
+
const res = await fetchReportJsonData<string[]>("widgets/environments.json", { bustCache: true });
|
|
36
36
|
|
|
37
37
|
environmentsStore.value = {
|
|
38
38
|
data: res,
|
package/src/stores/envInfo.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EnvironmentItem } from "@allurereport/core-api";
|
|
2
2
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
3
3
|
import { signal } from "@preact/signals";
|
|
4
|
-
import { StoreSignalState } from "@/stores/types";
|
|
4
|
+
import type { StoreSignalState } from "@/stores/types";
|
|
5
5
|
|
|
6
6
|
export const envInfoStore = signal<StoreSignalState<EnvironmentItem[]>>({
|
|
7
7
|
loading: false,
|
|
@@ -17,7 +17,7 @@ export const fetchEnvInfo = async () => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
|
-
const res = await fetchReportJsonData<EnvironmentItem[]>("widgets/allure_environment.json");
|
|
20
|
+
const res = await fetchReportJsonData<EnvironmentItem[]>("widgets/allure_environment.json", { bustCache: true });
|
|
21
21
|
|
|
22
22
|
envInfoStore.value = {
|
|
23
23
|
data: res,
|
package/src/stores/locale.ts
CHANGED
package/src/stores/router.ts
CHANGED
|
@@ -1,42 +1,101 @@
|
|
|
1
1
|
import { computed, signal } from "@preact/signals";
|
|
2
2
|
|
|
3
|
-
type NavigateToString = string;
|
|
4
3
|
type NavigateToObject = {
|
|
5
|
-
|
|
4
|
+
category?: string;
|
|
6
5
|
params?: {
|
|
7
|
-
|
|
6
|
+
testResultId?: string | null;
|
|
7
|
+
subTab?: string | null;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
params: params ? { tabName: params } : {},
|
|
11
|
+
type Route = {
|
|
12
|
+
category?: string;
|
|
13
|
+
params?: {
|
|
14
|
+
testResultId?: string | null;
|
|
15
|
+
subTab?: string | null;
|
|
17
16
|
};
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
export const
|
|
19
|
+
export const parseHash = (): Route => {
|
|
20
|
+
const hash = globalThis.location.hash.replace(/^#/, "").trim();
|
|
21
|
+
const parts = hash.split("/").filter(Boolean);
|
|
22
|
+
const [first, second] = parts;
|
|
23
|
+
|
|
24
|
+
if (parts.length === 0) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (parts.length === 1) {
|
|
29
|
+
if (/^[a-f0-9]{32,}$/.test(first)) {
|
|
30
|
+
return { params: { testResultId: first } };
|
|
31
|
+
}
|
|
32
|
+
return { category: first || "", params: { testResultId: second } };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (parts.length === 2) {
|
|
36
|
+
if (/^[a-f0-9]{32,}$/.test(first)) {
|
|
37
|
+
return {
|
|
38
|
+
params: {
|
|
39
|
+
testResultId: first,
|
|
40
|
+
subTab: second,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
category: first,
|
|
47
|
+
params: {
|
|
48
|
+
testResultId: second,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (parts.length === 3) {
|
|
54
|
+
const [category, testResultId, subTab] = parts;
|
|
55
|
+
return { category, params: { testResultId, subTab } };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const route = signal<Route>(parseHash());
|
|
21
62
|
|
|
22
63
|
export const handleHashChange = () => {
|
|
23
64
|
const newRoute = parseHash();
|
|
24
65
|
|
|
25
|
-
if (
|
|
26
|
-
route.value
|
|
66
|
+
if (
|
|
67
|
+
newRoute.category !== route.value?.category ||
|
|
68
|
+
newRoute.params?.testResultId !== route.value.params?.testResultId ||
|
|
69
|
+
newRoute.params?.subTab !== route.value.params?.subTab
|
|
70
|
+
) {
|
|
71
|
+
route.value = { ...newRoute };
|
|
27
72
|
}
|
|
28
73
|
};
|
|
29
74
|
|
|
30
|
-
export const navigateTo = (path:
|
|
75
|
+
export const navigateTo = (path: NavigateToObject | string) => {
|
|
31
76
|
let newHash = "";
|
|
32
77
|
|
|
33
78
|
if (typeof path === "string") {
|
|
34
79
|
newHash = path.startsWith("#") ? path.slice(1) : path;
|
|
35
80
|
} else {
|
|
36
|
-
const {
|
|
81
|
+
const { category, params = {} } = path;
|
|
82
|
+
const parts: string[] = [];
|
|
37
83
|
|
|
38
|
-
|
|
84
|
+
if (category) {
|
|
85
|
+
parts.push(category);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (params.testResultId) {
|
|
89
|
+
parts.push(params.testResultId);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (params.subTab) {
|
|
93
|
+
parts.push(params.subTab);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
newHash = parts.join("/");
|
|
39
97
|
}
|
|
98
|
+
|
|
40
99
|
history.pushState(null, "", `#${newHash}`);
|
|
41
100
|
handleHashChange();
|
|
42
101
|
};
|
|
@@ -45,4 +104,5 @@ export const openInNewTab = (path: string) => {
|
|
|
45
104
|
window.open(`#${path}`, "_blank");
|
|
46
105
|
};
|
|
47
106
|
|
|
48
|
-
export const activeTab = computed(() => route.value.
|
|
107
|
+
export const activeTab = computed(() => route.value.category || "");
|
|
108
|
+
export const activeSubTab = computed(() => route.value.params?.subTab || "overview");
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { getReportOptions } from "@allurereport/web-commons";
|
|
2
|
+
import { effect, signal } from "@preact/signals";
|
|
3
|
+
import { navigateTo, parseHash, route } from "@/stores/router";
|
|
4
|
+
import type { AwesomeReportOptions } from "../../types.js";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_SECTION = "default";
|
|
7
|
+
type Section = string;
|
|
8
|
+
|
|
9
|
+
export const currentSection = signal<Section>("");
|
|
10
|
+
export const availableSections = signal<Section[]>([]);
|
|
11
|
+
|
|
12
|
+
const updateSectionState = (section: Section): void => {
|
|
13
|
+
currentSection.value = section;
|
|
14
|
+
document.documentElement.setAttribute("data-section", section);
|
|
15
|
+
globalThis.localStorage.setItem("chosenSection", section);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const setSection = (chosenSection: Section): void => {
|
|
19
|
+
const isDefaultSection = chosenSection === DEFAULT_SECTION;
|
|
20
|
+
const isValidSection = availableSections.value?.includes(chosenSection);
|
|
21
|
+
const isSectionChanged = currentSection.value !== chosenSection;
|
|
22
|
+
|
|
23
|
+
updateSectionState(chosenSection);
|
|
24
|
+
|
|
25
|
+
if (isDefaultSection) {
|
|
26
|
+
navigateTo({ category: "" });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (isSectionChanged && isValidSection) {
|
|
31
|
+
navigateTo({ category: chosenSection });
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const getSection = () => {
|
|
36
|
+
const { category } = parseHash();
|
|
37
|
+
availableSections.value = getReportOptions<AwesomeReportOptions>()?.sections ?? [];
|
|
38
|
+
const defaultSectionFromReportOptions = getReportOptions<AwesomeReportOptions>()?.defaultSection ?? "";
|
|
39
|
+
const sectionFromUrl = parseHash().category;
|
|
40
|
+
const sectionFromLS =
|
|
41
|
+
globalThis.localStorage.getItem("chosenSection") === ""
|
|
42
|
+
? ""
|
|
43
|
+
: globalThis.localStorage.getItem("chosenSection") || defaultSectionFromReportOptions;
|
|
44
|
+
currentSection.value = sectionFromUrl || sectionFromLS;
|
|
45
|
+
|
|
46
|
+
if (category) {
|
|
47
|
+
setSection(category);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (sectionFromLS) {
|
|
52
|
+
setSection(sectionFromLS);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setSection("");
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
effect(() => {
|
|
60
|
+
const category = route.value.category;
|
|
61
|
+
|
|
62
|
+
setSection(category || "");
|
|
63
|
+
});
|
package/src/stores/stats.ts
CHANGED
|
@@ -26,7 +26,7 @@ export const fetchReportStats = async () => {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
const res = await fetchReportJsonData<Statistic>("widgets/statistic.json");
|
|
29
|
+
const res = await fetchReportJsonData<Statistic>("widgets/statistic.json", { bustCache: true });
|
|
30
30
|
|
|
31
31
|
reportStatsStore.value = {
|
|
32
32
|
data: res,
|
|
@@ -58,7 +58,7 @@ export const fetchEnvStats = async (envs: string[]) => {
|
|
|
58
58
|
|
|
59
59
|
try {
|
|
60
60
|
const data = await Promise.all(
|
|
61
|
-
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/statistic.json
|
|
61
|
+
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/statistic.json`, { bustCache: true })),
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
statsByEnvStore.value = {
|
|
@@ -21,7 +21,9 @@ export const testResultNavStore = signal<StoreSignalState<TrNavStoreState>>({
|
|
|
21
21
|
|
|
22
22
|
export const fetchTestResultNav = async (env?: string) => {
|
|
23
23
|
try {
|
|
24
|
-
const data = await fetchReportJsonData<string[]>(env ? `widgets/${env}/nav.json` : "widgets/nav.json"
|
|
24
|
+
const data = await fetchReportJsonData<string[]>(env ? `widgets/${env}/nav.json` : "widgets/nav.json", {
|
|
25
|
+
bustCache: true,
|
|
26
|
+
});
|
|
25
27
|
|
|
26
28
|
testResultNavStore.value = {
|
|
27
29
|
data,
|
|
@@ -49,7 +51,9 @@ export const fetchTestResult = async (testResultId: string) => {
|
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
try {
|
|
52
|
-
const data = await fetchReportJsonData<AwesomeTestResult>(`data/test-results/${testResultId}.json
|
|
54
|
+
const data = await fetchReportJsonData<AwesomeTestResult>(`data/test-results/${testResultId}.json`, {
|
|
55
|
+
bustCache: true,
|
|
56
|
+
});
|
|
53
57
|
|
|
54
58
|
testResultStore.value = {
|
|
55
59
|
data: { ...testResultStore.value.data, [testResultId]: data },
|
package/src/stores/tree.ts
CHANGED
|
@@ -164,16 +164,19 @@ export const fetchEnvTreesData = async (envs: string[]) => {
|
|
|
164
164
|
|
|
165
165
|
try {
|
|
166
166
|
const data = await Promise.all(
|
|
167
|
-
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/tree.json
|
|
167
|
+
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/tree.json`, { bustCache: true })),
|
|
168
168
|
);
|
|
169
169
|
|
|
170
|
+
const previous = treeStore.value.data;
|
|
170
171
|
treeStore.value = {
|
|
171
|
-
data:
|
|
172
|
-
(acc, env, index) =>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
data: envsToFetch.reduce(
|
|
173
|
+
(acc, env, index) => {
|
|
174
|
+
return {
|
|
175
|
+
...acc,
|
|
176
|
+
[env]: data[index],
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
{ ...previous },
|
|
177
180
|
),
|
|
178
181
|
loading: false,
|
|
179
182
|
error: undefined,
|
package/src/stores/variables.ts
CHANGED
|
@@ -18,7 +18,9 @@ export const fetchVariables = async (env: string = "default") => {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
|
-
const res = await fetchReportJsonData<string[]>(env ? `widgets/${env}/variables.json` : "widgets/variables.json"
|
|
21
|
+
const res = await fetchReportJsonData<string[]>(env ? `widgets/${env}/variables.json` : "widgets/variables.json", {
|
|
22
|
+
bustCache: true,
|
|
23
|
+
});
|
|
22
24
|
|
|
23
25
|
variables.value = {
|
|
24
26
|
data: {
|
package/src/styles.scss
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
position: relative;
|
|
3
3
|
max-width: 1920px;
|
|
4
4
|
margin: 0 auto;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
height: 100vh;
|
|
5
8
|
|
|
6
9
|
&:hover {
|
|
7
10
|
.split {
|
|
@@ -10,6 +13,16 @@
|
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
|
|
16
|
+
.layout {
|
|
17
|
+
flex: 1 1 auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.content {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
height: 100%;
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
.split {
|
|
14
27
|
opacity: 0;
|
|
15
28
|
position: absolute;
|
|
@@ -43,3 +56,11 @@
|
|
|
43
56
|
opacity: 1;
|
|
44
57
|
}
|
|
45
58
|
}
|
|
59
|
+
|
|
60
|
+
.layout-base {
|
|
61
|
+
max-width: 920px;
|
|
62
|
+
margin: auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.layout-split {
|
|
66
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { type SeverityLevel, type TestStatus, severityLevels, statusesList } from "@allurereport/core-api";
|
|
2
|
+
|
|
3
|
+
export enum ChartType {
|
|
4
|
+
Trend = "trend",
|
|
5
|
+
Pie = "pie",
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export enum ChartDataType {
|
|
9
|
+
Status = "status",
|
|
10
|
+
Severity = "severity",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ChartId = string;
|
|
14
|
+
|
|
15
|
+
export interface Point {
|
|
16
|
+
x: Date | string | number;
|
|
17
|
+
y: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface Slice {
|
|
21
|
+
min: number;
|
|
22
|
+
max: number;
|
|
23
|
+
metadata: { executionId: string };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ResponseTrendChartData {
|
|
27
|
+
type: ChartType.Trend;
|
|
28
|
+
dataType: ChartDataType;
|
|
29
|
+
title?: string;
|
|
30
|
+
min: number;
|
|
31
|
+
max: number;
|
|
32
|
+
points: Record<string, Point>;
|
|
33
|
+
slices: Record<string, Slice>;
|
|
34
|
+
series: Record<TestStatus | SeverityLevel, string[]>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface TrendChartItem {
|
|
38
|
+
id: string;
|
|
39
|
+
data: Point[];
|
|
40
|
+
color: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface TrendChartData {
|
|
44
|
+
type: ChartType.Trend;
|
|
45
|
+
dataType: ChartDataType;
|
|
46
|
+
min: number;
|
|
47
|
+
max: number;
|
|
48
|
+
items: TrendChartItem[];
|
|
49
|
+
slices: Slice[];
|
|
50
|
+
title?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface PieSlice {
|
|
54
|
+
status: TestStatus;
|
|
55
|
+
count: number;
|
|
56
|
+
d: string | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ResponsePieChartData {
|
|
60
|
+
type: ChartType.Pie;
|
|
61
|
+
title?: string;
|
|
62
|
+
percentage: number;
|
|
63
|
+
slices: PieSlice[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type PieChartData = ResponsePieChartData;
|
|
67
|
+
export type ChartData = TrendChartData | PieChartData;
|
|
68
|
+
export type ChartsResponse = Partial<Record<ChartId, ResponseTrendChartData | ResponsePieChartData>>;
|
|
69
|
+
export type ChartsData = Record<ChartId, ChartData>;
|
|
70
|
+
|
|
71
|
+
const statusColors: Record<TestStatus, string> = {
|
|
72
|
+
failed: "var(--bg-support-capella)",
|
|
73
|
+
broken: "var(--bg-support-atlas)",
|
|
74
|
+
passed: "var(--bg-support-castor)",
|
|
75
|
+
skipped: "var(--bg-support-rau)",
|
|
76
|
+
unknown: "var(--bg-support-skat)",
|
|
77
|
+
};
|
|
78
|
+
const severityColors: Record<SeverityLevel, string> = {
|
|
79
|
+
blocker: "var(--bg-support-capella)",
|
|
80
|
+
critical: "var(--bg-support-atlas)",
|
|
81
|
+
normal: "var(--bg-support-castor)",
|
|
82
|
+
minor: "var(--bg-support-rau)",
|
|
83
|
+
trivial: "var(--bg-support-skat)",
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Helper function to create chart data for different chart types
|
|
88
|
+
*
|
|
89
|
+
* @param getChart - Function to get the chart data
|
|
90
|
+
* @param getGroups - Function to get the groups
|
|
91
|
+
* @param getColor - Function to get the color
|
|
92
|
+
* @returns TrendChartData or undefined if the chart data is not available
|
|
93
|
+
*/
|
|
94
|
+
export const createTrendChartData = <T extends TestStatus | SeverityLevel>(
|
|
95
|
+
getChart: () => ResponseTrendChartData | undefined,
|
|
96
|
+
getGroups: () => readonly T[],
|
|
97
|
+
getColor: (group: T) => string,
|
|
98
|
+
): TrendChartData | undefined => {
|
|
99
|
+
const chart = getChart();
|
|
100
|
+
if (!chart) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const items = getGroups().reduce((acc, group) => {
|
|
105
|
+
const pointsByGroupBy =
|
|
106
|
+
chart.series[group]?.map((pointId) => ({
|
|
107
|
+
x: chart.points[pointId].x,
|
|
108
|
+
y: chart.points[pointId].y,
|
|
109
|
+
})) ?? [];
|
|
110
|
+
|
|
111
|
+
if (pointsByGroupBy.length) {
|
|
112
|
+
acc.push({
|
|
113
|
+
id: group.charAt(0).toUpperCase() + group.slice(1),
|
|
114
|
+
data: pointsByGroupBy,
|
|
115
|
+
color: getColor(group),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return acc;
|
|
120
|
+
}, [] as TrendChartItem[]);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
type: chart.type,
|
|
124
|
+
dataType: chart.dataType,
|
|
125
|
+
title: chart.title,
|
|
126
|
+
items,
|
|
127
|
+
slices: Object.values(chart.slices),
|
|
128
|
+
min: chart.min,
|
|
129
|
+
max: chart.max,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const createStatusTrendChartData = (chartId: ChartId, res: ChartsResponse): TrendChartData | undefined =>
|
|
134
|
+
createTrendChartData(
|
|
135
|
+
() => res[chartId] as ResponseTrendChartData | undefined,
|
|
136
|
+
() => statusesList,
|
|
137
|
+
(status) => statusColors[status],
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
export const createSeverityTrendChartData = (chartId: ChartId, res: ChartsResponse): TrendChartData | undefined =>
|
|
141
|
+
createTrendChartData(
|
|
142
|
+
() => res[chartId] as ResponseTrendChartData | undefined,
|
|
143
|
+
() => severityLevels,
|
|
144
|
+
(severity) => severityColors[severity],
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
export const createaTrendChartData = (
|
|
148
|
+
chartId: string,
|
|
149
|
+
chartData: ResponseTrendChartData,
|
|
150
|
+
res: ChartsResponse,
|
|
151
|
+
): TrendChartData | undefined => {
|
|
152
|
+
if (chartData.dataType === ChartDataType.Status) {
|
|
153
|
+
return createStatusTrendChartData(chartId, res);
|
|
154
|
+
} else if (chartData.dataType === ChartDataType.Severity) {
|
|
155
|
+
return createSeverityTrendChartData(chartId, res);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const createCharts = (res: ChartsResponse): ChartsData => {
|
|
160
|
+
return Object.entries(res).reduce((acc, [chartId, chart]) => {
|
|
161
|
+
if (chart.type === ChartType.Trend) {
|
|
162
|
+
acc[chartId] = createaTrendChartData(chartId, chart, res);
|
|
163
|
+
} else if (chart.type === ChartType.Pie) {
|
|
164
|
+
acc[chartId] = chart;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return acc;
|
|
168
|
+
}, {} as ChartsData);
|
|
169
|
+
};
|
package/types.d.ts
CHANGED
|
@@ -22,6 +22,9 @@ export type AwesomeReportOptions = {
|
|
|
22
22
|
createdAt: number;
|
|
23
23
|
reportUuid: string;
|
|
24
24
|
layout?: Layout;
|
|
25
|
+
defaultSection?: string;
|
|
26
|
+
sections?: string[];
|
|
27
|
+
cacheKey: string;
|
|
25
28
|
};
|
|
26
29
|
|
|
27
30
|
export type AwesomeFixtureResult = Omit<
|
|
@@ -97,4 +100,4 @@ export type AwesomeRecursiveTree = DefaultTreeGroup & {
|
|
|
97
100
|
// TODO: add worst status
|
|
98
101
|
export type AwesomeTestResultGroup = Pick<AwesomeTestResult, "name" | "fullName" | "groupOrder"> & {
|
|
99
102
|
testResults: AwesomeTestResult[];
|
|
100
|
-
}
|
|
103
|
+
};
|
package/webpack.config.js
CHANGED
|
@@ -7,6 +7,7 @@ import SpriteLoaderPlugin from "svg-sprite-loader/plugin.js";
|
|
|
7
7
|
import webpack from "webpack";
|
|
8
8
|
import { WebpackManifestPlugin } from "webpack-manifest-plugin";
|
|
9
9
|
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin";
|
|
10
|
+
import TerserPlugin from "terser-webpack-plugin";
|
|
10
11
|
|
|
11
12
|
const { SINGLE_FILE_MODE } = env;
|
|
12
13
|
const baseDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -21,6 +22,19 @@ export default (env, argv) => {
|
|
|
21
22
|
assetModuleFilename: devMode ? `[name].[ext]` : `[name]-[hash:8].[ext]`,
|
|
22
23
|
},
|
|
23
24
|
devtool: devMode ? "inline-source-map" : false,
|
|
25
|
+
optimization: {
|
|
26
|
+
minimize: !devMode,
|
|
27
|
+
minimizer: [
|
|
28
|
+
new TerserPlugin({
|
|
29
|
+
terserOptions: {
|
|
30
|
+
compress: {
|
|
31
|
+
drop_console: false,
|
|
32
|
+
drop_debugger: false,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
},
|
|
24
38
|
module: {
|
|
25
39
|
rules: [
|
|
26
40
|
{
|