@allurereport/web-awesome 3.1.0 → 3.3.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/multi/173.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/174.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/252.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/282.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/29.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/416.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/527.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/600.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/605.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/638.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/672.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/686.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/725.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/741.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/749.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/755.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/894.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/943.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/980.app-8be6acc0a596a2197dbf.js +1 -0
- package/dist/multi/app-8be6acc0a596a2197dbf.js +2 -0
- package/dist/multi/manifest.json +21 -21
- package/dist/multi/{styles-9e390bad7ce54a807a8e.css → styles-0b84e1ef76554ad2db9a.css} +19 -10
- package/dist/single/app-8221eb856e47b4ef50d6.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +8 -10
- package/src/components/BaseLayout/index.tsx +5 -4
- package/src/components/Categories/CategoriesTree/index.tsx +14 -0
- package/src/components/Categories/CategoriesTree/styles.scss +14 -0
- package/src/components/Categories/CategoryHeaderItem/index.tsx +50 -0
- package/src/components/Categories/CategoryHeaderItem/styles.scss +32 -0
- package/src/components/Categories/CategoryTreeItem/index.tsx +309 -0
- package/src/components/Categories/CategoryTreeItem/styles.scss +47 -0
- package/src/components/Categories/GroupTreeItem/index.tsx +76 -0
- package/src/components/Categories/GroupTreeItem/styles.scss +47 -0
- package/src/components/Categories/HistoryTreeItem/index.tsx +71 -0
- package/src/components/Categories/HistoryTreeItem/styles.scss +53 -0
- package/src/components/Categories/LabelTreeItem/index.tsx +150 -0
- package/src/components/Categories/LabelTreeItem/styles.scss +102 -0
- package/src/components/Categories/MessageTreeItem/index.tsx +107 -0
- package/src/components/Categories/MessageTreeItem/styles.scss +178 -0
- package/src/components/Categories/SeverityTreeItem/index.tsx +50 -0
- package/src/components/Categories/SeverityTreeItem/styles.scss +12 -0
- package/src/components/Categories/sticky.ts +12 -0
- package/src/components/Charts/index.tsx +5 -5
- package/src/components/Header/index.tsx +4 -2
- package/src/components/MainReport/index.tsx +148 -47
- package/src/components/Metadata/index.tsx +75 -1
- package/src/components/Metadata/styles.scss +10 -0
- package/src/components/ReportBody/styles.scss +1 -1
- package/src/components/ReportCategories/index.tsx +26 -0
- package/src/components/ReportCategories/styles.scss +55 -0
- package/src/components/ReportFilters/CategoriesFilter.tsx +41 -0
- package/src/components/ReportFilters/index.tsx +12 -1
- package/src/components/ReportQualityGateResults/index.tsx +77 -19
- package/src/components/ReportQualityGateResults/styles.scss +13 -0
- package/src/components/SplitLayout/index.tsx +4 -2
- package/src/components/SplitLayout/styles.scss +1 -0
- package/src/components/TestResult/TrDescription/index.tsx +60 -10
- package/src/components/TestResult/TrDescription/styles.scss +4 -0
- package/src/components/TestResult/TrError/TrDiff.tsx +2 -6
- package/src/components/TestResult/TrError/styles.scss +4 -0
- package/src/components/TestResult/TrInfo/index.tsx +8 -1
- package/src/components/TestResult/TrInfo/styles.scss +4 -0
- package/src/components/TestResult/TrLinks/index.tsx +4 -4
- package/src/components/TestResult/TrOverview.tsx +3 -2
- package/src/components/TestResult/TrSeverity/index.tsx +13 -4
- package/src/components/TestResult/TrSeverity/styles.scss +1 -0
- package/src/components/TestResult/TrTabs/index.tsx +5 -0
- package/src/components/Timeline/index.tsx +2 -5
- package/src/index.tsx +6 -2
- package/src/locales/az.json +108 -79
- package/src/locales/de.json +26 -5
- package/src/locales/en.json +26 -5
- package/src/locales/es.json +26 -5
- package/src/locales/fr.json +26 -5
- package/src/locales/he.json +26 -5
- package/src/locales/hy.json +26 -5
- package/src/locales/it.json +26 -5
- package/src/locales/ja.json +26 -5
- package/src/locales/ka.json +26 -5
- package/src/locales/kr.json +26 -5
- package/src/locales/nl.json +26 -5
- package/src/locales/pl.json +26 -5
- package/src/locales/pt.json +26 -5
- package/src/locales/ru.json +26 -5
- package/src/locales/sv.json +26 -5
- package/src/locales/tr.json +26 -5
- package/src/locales/{ua.json → uk.json} +26 -5
- package/src/locales/zh.json +26 -5
- package/src/stores/categories.ts +44 -0
- package/src/stores/locale.ts +69 -37
- package/src/stores/qualityGate.ts +2 -2
- package/src/stores/router.ts +55 -3
- package/src/stores/testResult.ts +14 -3
- package/src/stores/timeline.ts +5 -2
- package/src/stores/treeFilters/actions.ts +10 -1
- package/src/stores/treeFilters/constants.ts +1 -0
- package/src/stores/treeFilters/model.ts +2 -0
- package/src/stores/treeFilters/store.ts +45 -0
- package/src/stores/treeFilters/utils.ts +10 -0
- package/src/stores/treeSwitcher.ts +9 -0
- package/src/utils/ownerAddress.ts +92 -0
- package/src/utils/time.ts +16 -2
- package/src/utils/treeFilters.ts +16 -9
- package/test/utils/ownerAddress.test.ts +89 -0
- package/test/utils/treeFilters.test.ts +39 -0
- package/types.d.ts +2 -1
- package/dist/multi/173.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/174.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/252.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/282.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/29.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/416.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/527.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/600.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/605.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/638.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/672.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/686.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/725.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/741.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/755.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/894.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/91.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/943.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/980.app-79c65c7bff941abcbc51.js +0 -1
- package/dist/multi/app-79c65c7bff941abcbc51.js +0 -2
- package/dist/single/app-3ca67f29d0f1166c08ca.js +0 -2
- package/src/components/SectionTabs/index.tsx +0 -0
- /package/dist/multi/{app-79c65c7bff941abcbc51.js.LICENSE.txt → app-8be6acc0a596a2197dbf.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-3ca67f29d0f1166c08ca.js.LICENSE.txt → app-8221eb856e47b4ef50d6.js.LICENSE.txt} +0 -0
|
@@ -1,40 +1,98 @@
|
|
|
1
|
+
import { DEFAULT_ENVIRONMENT } from "@allurereport/core-api";
|
|
2
|
+
import type { QualityGateValidationResult } from "@allurereport/plugin-api";
|
|
1
3
|
import { Loadable, SvgIcon, Text, allureIcons } from "@allurereport/web-components";
|
|
4
|
+
import { useState } from "preact/hooks";
|
|
5
|
+
import { MetadataButton } from "@/components/MetadataButton";
|
|
2
6
|
import { TrError } from "@/components/TestResult/TrError";
|
|
3
7
|
import { useI18n } from "@/stores";
|
|
8
|
+
import { currentEnvironment } from "@/stores/env";
|
|
4
9
|
import { qualityGateStore } from "@/stores/qualityGate";
|
|
5
10
|
import * as styles from "./styles.scss";
|
|
6
11
|
|
|
12
|
+
const QualityGateResultsList = ({ results }: { results: QualityGateValidationResult[] }) => (
|
|
13
|
+
<ul className={styles["report-quality-gate-results-list"]} data-testid={"quality-gate-results-section-env-content"}>
|
|
14
|
+
{results.map((result) => (
|
|
15
|
+
<li key={result.rule} data-testid="quality-gate-result">
|
|
16
|
+
<div className={styles["report-quality-gate-result"]}>
|
|
17
|
+
<SvgIcon id={allureIcons.solidXCircle} className={styles["report-quality-gate-result-icon"]} />
|
|
18
|
+
<div className={styles["report-quality-gate-result-content"]}>
|
|
19
|
+
<Text tag="p" size="l" type="ui" bold data-testid="quality-gate-result-rule">
|
|
20
|
+
{result.rule}
|
|
21
|
+
</Text>
|
|
22
|
+
<TrError
|
|
23
|
+
className={styles["report-quality-gate-result-error"]}
|
|
24
|
+
message={result.message}
|
|
25
|
+
data-testid="quality-gate-result-message"
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</li>
|
|
30
|
+
))}
|
|
31
|
+
</ul>
|
|
32
|
+
);
|
|
33
|
+
|
|
7
34
|
export const ReportQualityGateResults = () => {
|
|
8
35
|
const { t } = useI18n("empty");
|
|
36
|
+
const { t: tEnvironments } = useI18n("environments");
|
|
37
|
+
const [collapsedEnvs, setCollapsedEnvs] = useState<string[]>([]);
|
|
9
38
|
|
|
10
39
|
return (
|
|
11
40
|
<Loadable
|
|
12
41
|
source={qualityGateStore}
|
|
13
42
|
renderData={(results) => {
|
|
14
|
-
if (
|
|
43
|
+
if (currentEnvironment.value) {
|
|
44
|
+
const currentEnvResults = results[currentEnvironment.value] ?? [];
|
|
45
|
+
|
|
46
|
+
if (!currentEnvResults.length) {
|
|
47
|
+
return <div className={styles["report-quality-gate-results-empty"]}>{t("no-quality-gate-results")}</div>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return <QualityGateResultsList results={currentEnvResults} />;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const entries = Object.entries(results).filter(([, envResults]) => envResults.length > 0);
|
|
54
|
+
|
|
55
|
+
if (!entries.length) {
|
|
15
56
|
return <div className={styles["report-quality-gate-results-empty"]}>{t("no-quality-gate-results")}</div>;
|
|
16
57
|
}
|
|
17
58
|
|
|
59
|
+
// single default environment
|
|
60
|
+
if (entries.length === 1 && entries[0][0] === DEFAULT_ENVIRONMENT) {
|
|
61
|
+
const currentEnvResults = entries[0][1] ?? [];
|
|
62
|
+
|
|
63
|
+
if (!currentEnvResults.length) {
|
|
64
|
+
return <div className={styles["report-quality-gate-results-empty"]}>{t("no-quality-gate-results")}</div>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return <QualityGateResultsList results={currentEnvResults} />;
|
|
68
|
+
}
|
|
69
|
+
|
|
18
70
|
return (
|
|
19
|
-
<
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
71
|
+
<div className={styles["report-quality-gate-results"]}>
|
|
72
|
+
{entries.map(([env, envResults]) => {
|
|
73
|
+
const isOpened = !collapsedEnvs.includes(env);
|
|
74
|
+
const toggleEnv = () => {
|
|
75
|
+
setCollapsedEnvs((prev) => (isOpened ? prev.concat(env) : prev.filter((e) => e !== env)));
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
key={env}
|
|
81
|
+
className={styles["report-quality-gate-section"]}
|
|
82
|
+
data-testid={"quality-gate-results-section"}
|
|
83
|
+
>
|
|
84
|
+
<MetadataButton
|
|
85
|
+
isOpened={isOpened}
|
|
86
|
+
setIsOpen={toggleEnv}
|
|
87
|
+
title={`${tEnvironments("environment", { count: 1 })}: "${env}"`}
|
|
88
|
+
counter={envResults.length}
|
|
89
|
+
data-testid={"quality-gate-results-section-env-button"}
|
|
90
|
+
/>
|
|
91
|
+
{isOpened && <QualityGateResultsList results={envResults} />}
|
|
34
92
|
</div>
|
|
35
|
-
|
|
36
|
-
)
|
|
37
|
-
</
|
|
93
|
+
);
|
|
94
|
+
})}
|
|
95
|
+
</div>
|
|
38
96
|
);
|
|
39
97
|
}}
|
|
40
98
|
/>
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
@import "~@allurereport/web-components/mixins.scss";
|
|
2
2
|
|
|
3
3
|
.report-quality-gate-results {
|
|
4
|
+
padding: 12px 0 32px 8px;
|
|
5
|
+
min-height: 320px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.report-quality-gate-results-list {
|
|
4
9
|
padding: 20px 0;
|
|
5
10
|
|
|
6
11
|
& > li + li {
|
|
@@ -42,3 +47,11 @@
|
|
|
42
47
|
.report-quality-gate-result-error {
|
|
43
48
|
margin-top: 8px;
|
|
44
49
|
}
|
|
50
|
+
|
|
51
|
+
.report-quality-gate-section {
|
|
52
|
+
&:not(:last-child) {
|
|
53
|
+
padding-bottom: 8px;
|
|
54
|
+
margin-bottom: 14px;
|
|
55
|
+
border-bottom: 1px solid var(--on-border-muted);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -6,7 +6,7 @@ import MainReport from "@/components/MainReport";
|
|
|
6
6
|
import SideBySide from "@/components/SideBySide";
|
|
7
7
|
import TestResult from "@/components/TestResult";
|
|
8
8
|
import { useI18n } from "@/stores";
|
|
9
|
-
import { testResultRoute } from "@/stores/router";
|
|
9
|
+
import { rootTabRoute, testResultRoute } from "@/stores/router";
|
|
10
10
|
import { currentTrId } from "@/stores/testResult";
|
|
11
11
|
import { testResultStore } from "@/stores/testResults";
|
|
12
12
|
import { treeStore } from "@/stores/tree";
|
|
@@ -30,7 +30,9 @@ const Loader = () => {
|
|
|
30
30
|
);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
const isTestResultRoute = computed(
|
|
33
|
+
const isTestResultRoute = computed(
|
|
34
|
+
() => testResultRoute.value.matches || Boolean(rootTabRoute.value.params.testResultId),
|
|
35
|
+
);
|
|
34
36
|
|
|
35
37
|
export const SplitLayout = () => {
|
|
36
38
|
const testResultId = currentTrId.value;
|
|
@@ -1,25 +1,75 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { proseStyles, resolveCssVarDeclarations, sanitizeIframeHtml, themeStore } from "@allurereport/web-commons";
|
|
2
2
|
import type { FunctionalComponent } from "preact";
|
|
3
|
-
import { useState } from "preact/hooks";
|
|
3
|
+
import { useEffect, useMemo, useState } from "preact/hooks";
|
|
4
4
|
import type { AwesomeTestResult } from "types";
|
|
5
5
|
import { MetadataButton } from "@/components/MetadataButton";
|
|
6
6
|
import * as styles from "./styles.scss";
|
|
7
7
|
|
|
8
8
|
export type TrDescriptionProps = {
|
|
9
|
-
|
|
9
|
+
descriptionHtml: AwesomeTestResult["descriptionHtml"];
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const MIN_HEIGHT = 120;
|
|
13
|
+
|
|
14
|
+
export const TrDescription: FunctionalComponent<TrDescriptionProps> = ({ descriptionHtml }) => {
|
|
15
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
16
|
+
const [blobUrl, setBlobUrl] = useState("");
|
|
17
|
+
const [height, setHeight] = useState(MIN_HEIGHT);
|
|
18
|
+
const currentTheme = themeStore.value.current;
|
|
19
|
+
|
|
20
|
+
const sanitized = useMemo(() => (descriptionHtml ? sanitizeIframeHtml(descriptionHtml) : ""), [descriptionHtml]);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!sanitized) {
|
|
24
|
+
setBlobUrl("");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const iframeThemeVars = resolveCssVarDeclarations(proseStyles);
|
|
29
|
+
|
|
30
|
+
const html = `<!DOCTYPE html>
|
|
31
|
+
<html data-theme="${currentTheme}">
|
|
32
|
+
<head>
|
|
33
|
+
<meta charset="utf-8">
|
|
34
|
+
<style>:root {${iframeThemeVars}}</style>
|
|
35
|
+
<style>${proseStyles}</style>
|
|
36
|
+
</head>
|
|
37
|
+
<body>${sanitized}</body>
|
|
38
|
+
</html>`;
|
|
39
|
+
|
|
40
|
+
const blob = new Blob([html], { type: "text/html" });
|
|
41
|
+
const url = URL.createObjectURL(blob);
|
|
42
|
+
setBlobUrl(url);
|
|
43
|
+
|
|
44
|
+
return () => URL.revokeObjectURL(url);
|
|
45
|
+
}, [currentTheme, sanitized]);
|
|
46
|
+
|
|
47
|
+
const handleLoad = (e: Event) => {
|
|
48
|
+
const iframe = e.currentTarget as HTMLIFrameElement;
|
|
49
|
+
const documentElement = iframe.contentDocument?.documentElement;
|
|
50
|
+
const body = iframe.contentDocument?.body;
|
|
51
|
+
const scrollHeight = Math.max(documentElement?.scrollHeight ?? 0, body?.scrollHeight ?? 0);
|
|
52
|
+
setHeight(Math.max(scrollHeight, MIN_HEIGHT));
|
|
53
|
+
};
|
|
14
54
|
|
|
15
55
|
return (
|
|
16
|
-
<div className={styles["test-result-description"]}>
|
|
56
|
+
<div className={styles["test-result-description"]} data-testid="test-result-description">
|
|
17
57
|
<div className={styles["test-result-description-wrapper"]}>
|
|
18
|
-
<MetadataButton title=
|
|
58
|
+
<MetadataButton title="Description" setIsOpen={setIsOpen} isOpened={isOpen} />
|
|
19
59
|
{isOpen && (
|
|
20
|
-
<
|
|
21
|
-
{
|
|
22
|
-
|
|
60
|
+
<div className={styles["test-result-description-text"]}>
|
|
61
|
+
{blobUrl && (
|
|
62
|
+
<iframe
|
|
63
|
+
data-testid="test-result-description-frame"
|
|
64
|
+
src={blobUrl}
|
|
65
|
+
width="100%"
|
|
66
|
+
height={String(height)}
|
|
67
|
+
style={{ border: 0 }}
|
|
68
|
+
sandbox="allow-same-origin"
|
|
69
|
+
onLoad={handleLoad}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
23
73
|
)}
|
|
24
74
|
</div>
|
|
25
75
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button, Code, CodeViewer } from "@allurereport/web-components";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Change } from "diff";
|
|
3
3
|
import { diffChars, diffLines, diffWords } from "diff";
|
|
4
4
|
import { useState } from "preact/hooks";
|
|
5
5
|
import * as styles from "@/components/TestResult/TrError/styles.scss";
|
|
@@ -33,11 +33,7 @@ export const TrDiff = ({ expected, actual }: { expected: string; actual: string
|
|
|
33
33
|
};
|
|
34
34
|
const changeTypeDiff = (type: DiffType = "chars") => {
|
|
35
35
|
const diffFn = diffFunctions[type];
|
|
36
|
-
const result =
|
|
37
|
-
expected,
|
|
38
|
-
actual,
|
|
39
|
-
{},
|
|
40
|
-
);
|
|
36
|
+
const result: Change[] = diffFn(expected, actual, {});
|
|
41
37
|
|
|
42
38
|
setDiffType(type);
|
|
43
39
|
setDiff(result);
|
|
@@ -21,10 +21,12 @@ export type TrInfoProps = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export const TrInfo: FunctionalComponent<TrInfoProps> = ({ testResult }) => {
|
|
24
|
-
const { name, status, muted, flaky, known, duration, labels, history, retries, attachments, stop } =
|
|
24
|
+
const { name, status, muted, flaky, known, duration, labels, history, retries, attachments, stop, categories } =
|
|
25
|
+
testResult ?? {};
|
|
25
26
|
const formattedDuration = formatDuration(duration as number);
|
|
26
27
|
const fullDate = stop && timestampToDate(stop);
|
|
27
28
|
const severity = labels?.find((label) => label.name === "severity")?.value ?? "normal";
|
|
29
|
+
const categoryName = categories?.[0]?.name;
|
|
28
30
|
const { t } = useI18n("ui");
|
|
29
31
|
const statuses = Object.entries({ flaky, muted, known }).filter(([, value]) => value);
|
|
30
32
|
|
|
@@ -41,6 +43,11 @@ export const TrInfo: FunctionalComponent<TrInfoProps> = ({ testResult }) => {
|
|
|
41
43
|
{Boolean(history?.length) && <TrPrevStatuses history={history} />}
|
|
42
44
|
<TrSeverity severity={severity} />
|
|
43
45
|
{Boolean(statuses.length) && <TrInfoStatuses statuses={statuses} />}
|
|
46
|
+
{categoryName && (
|
|
47
|
+
<Text tag={"div"} size={"s"} className={styles["test-result-category"]}>
|
|
48
|
+
{t("category")}: {categoryName}
|
|
49
|
+
</Text>
|
|
50
|
+
)}
|
|
44
51
|
<TooltipWrapper tooltipText={fullDate}>
|
|
45
52
|
<Text tag={"div"} size={"s"} bold className={styles["test-result-duration"]}>
|
|
46
53
|
{formattedDuration}
|
|
@@ -22,13 +22,13 @@ const linksIconMap: Record<string, string> = {
|
|
|
22
22
|
const TrLink: FunctionalComponent<{
|
|
23
23
|
link: TrLinkProps;
|
|
24
24
|
}> = ({ link }) => {
|
|
25
|
-
const { url, type } = link;
|
|
25
|
+
const { url, name, type } = link;
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
|
-
<div className={styles["test-result-link"]}>
|
|
28
|
+
<div className={styles["test-result-link"]} data-testid="test-result-meta-link">
|
|
29
29
|
<SvgIcon id={linksIconMap[type] ?? allureIcons.lineGeneralLink1} />
|
|
30
30
|
<Text tag={"a"} href={url} target={"_blank"} size={"m"} className={styles["test-result-link-text"]}>
|
|
31
|
-
{url}
|
|
31
|
+
{name || url}
|
|
32
32
|
</Text>
|
|
33
33
|
</div>
|
|
34
34
|
);
|
|
@@ -46,7 +46,7 @@ export const TrLinks: FunctionalComponent<TrLinksProps> = ({ links }) => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<div className={styles["test-result-links"]}>
|
|
49
|
+
<div className={styles["test-result-links"]} data-testid="test-result-meta-links">
|
|
50
50
|
<div className={styles["test-result-links-wrapper"]}>
|
|
51
51
|
<MetadataButton isOpened={isOpened} setIsOpen={setIsOpen} counter={links.length} title={t("links")} />
|
|
52
52
|
{isOpened && <div className={styles["test-result-links-list"]}>{linkMap}</div>}
|
|
@@ -17,7 +17,8 @@ export type TrOverviewProps = {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export const TrOverview: FunctionalComponent<TrOverviewProps> = ({ testResult }) => {
|
|
20
|
-
const { error, parameters, groupedLabels, links,
|
|
20
|
+
const { error, parameters, groupedLabels, links, descriptionHtml, setup, steps, teardown, id, status } =
|
|
21
|
+
testResult || {};
|
|
21
22
|
const isNoSteps = !setup?.length && !steps.length && !teardown.length;
|
|
22
23
|
const pwTraces = testResult?.attachments?.filter(
|
|
23
24
|
(attachment) => attachment.link.contentType === "application/vnd.allure.playwright-trace",
|
|
@@ -34,7 +35,7 @@ export const TrOverview: FunctionalComponent<TrOverviewProps> = ({ testResult })
|
|
|
34
35
|
{Boolean(parameters?.length) && <TrParameters parameters={parameters} />}
|
|
35
36
|
{Boolean(groupedLabels && Object.keys(groupedLabels || {})?.length) && <TrMetadata testResult={testResult} />}
|
|
36
37
|
{Boolean(links?.length) && <TrLinks links={links} />}
|
|
37
|
-
{Boolean(
|
|
38
|
+
{Boolean(descriptionHtml) && <TrDescription descriptionHtml={descriptionHtml} />}
|
|
38
39
|
<div className={styles["test-results"]}>
|
|
39
40
|
{isNoSteps && <TestStepsEmpty />}
|
|
40
41
|
{Boolean(setup?.length) && <TrSetup id={id} setup={setup} />}
|
|
@@ -10,17 +10,26 @@ const icons: Record<string, string> = {
|
|
|
10
10
|
normal: allureIcons.lineGeneralEqual,
|
|
11
11
|
minor: allureIcons.lineArrowsChevronDown,
|
|
12
12
|
trivial: allureIcons.lineArrowsChevronDownDouble,
|
|
13
|
+
none: allureIcons.lineGeneralXClose,
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
export const TrSeverity = ({
|
|
16
|
+
export const TrSeverity = ({
|
|
17
|
+
severity = "normal",
|
|
18
|
+
text = "",
|
|
19
|
+
size = "s",
|
|
20
|
+
}: {
|
|
21
|
+
severity?: string;
|
|
22
|
+
text?: string;
|
|
23
|
+
size?: "s" | "m";
|
|
24
|
+
}) => {
|
|
16
25
|
const { t } = useI18n("severity");
|
|
17
26
|
const statusClass = clsx(styles[`severity-${severity}`]);
|
|
18
27
|
|
|
19
28
|
return (
|
|
20
29
|
<div className={styles["test-result-severity"]}>
|
|
21
|
-
<SvgIcon className={statusClass} id={icons[severity]} />
|
|
22
|
-
<Text size={
|
|
23
|
-
{capitalize(t(severity))}
|
|
30
|
+
<SvgIcon className={statusClass} id={icons[severity]} size={size} />
|
|
31
|
+
<Text size={size} bold className={styles["test-result-severity-text"]}>
|
|
32
|
+
{text || capitalize(t(severity))}
|
|
24
33
|
</Text>
|
|
25
34
|
</div>
|
|
26
35
|
);
|
|
@@ -15,6 +15,11 @@ export const TrTab = (props: { id: string; children: ComponentChildren }) => {
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
if (id === "overview") {
|
|
19
|
+
navigateToTestResultTab({ testResultId: currentTrId.value, tab: "" });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
navigateToTestResultTab({ testResultId: currentTrId.value, tab: id });
|
|
19
24
|
};
|
|
20
25
|
|
|
@@ -7,12 +7,9 @@ import type { TimlineTr } from "@/stores/timeline";
|
|
|
7
7
|
import { fetchTimelineData, timelineStore } from "@/stores/timeline";
|
|
8
8
|
import * as styles from "./styles.scss";
|
|
9
9
|
|
|
10
|
-
const getHosts = (tests: TimlineTr[]) => [
|
|
11
|
-
...new Set(tests.map((test) => test.labels.find((label) => label.name === "host")?.value).filter(Boolean)),
|
|
12
|
-
];
|
|
10
|
+
const getHosts = (tests: TimlineTr[]) => [...new Set(tests.map((test) => test.host))];
|
|
13
11
|
|
|
14
|
-
const filterTestsByHost = (tests: TimlineTr[], host: string) =>
|
|
15
|
-
tests.filter((test) => test.labels.find((label) => label.name === "host")?.value === host);
|
|
12
|
+
const filterTestsByHost = (tests: TimlineTr[], host: string) => tests.filter((test) => test.host === host);
|
|
16
13
|
|
|
17
14
|
const currentTimelineData = computed(() => {
|
|
18
15
|
const tests = timelineStore.value.data ?? [];
|
package/src/index.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import { Header } from "@/components/Header";
|
|
|
11
11
|
import { ModalComponent } from "@/components/Modal";
|
|
12
12
|
import { SectionSwitcher } from "@/components/SectionSwitcher";
|
|
13
13
|
import { fetchEnvStats, fetchReportStats, getLocale, waitForI18next } from "@/stores";
|
|
14
|
+
import { fetchCategoriesData } from "@/stores/categories";
|
|
14
15
|
import { fetchPieChartData } from "@/stores/chart";
|
|
15
16
|
import { currentEnvironment, environmentsStore, fetchEnvironments } from "@/stores/env";
|
|
16
17
|
import { fetchEnvInfo } from "@/stores/envInfo";
|
|
@@ -20,7 +21,7 @@ import { fetchTestResult, fetchTestResultNav } from "@/stores/testResults";
|
|
|
20
21
|
import { fetchEnvTreesData } from "@/stores/tree";
|
|
21
22
|
import { isMac } from "@/utils/isMac";
|
|
22
23
|
import { fetchQualityGateResults } from "./stores/qualityGate";
|
|
23
|
-
import { testResultRoute } from "./stores/router";
|
|
24
|
+
import { rootTabRoute, testResultRoute } from "./stores/router";
|
|
24
25
|
import { currentSection } from "./stores/sections";
|
|
25
26
|
import { currentTrId } from "./stores/testResult";
|
|
26
27
|
import { fetchTreeFiltersData } from "./stores/treeFilters/actions";
|
|
@@ -36,7 +37,9 @@ const Loader = () => {
|
|
|
36
37
|
);
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
const isTestResultRoute = computed(
|
|
40
|
+
const isTestResultRoute = computed(
|
|
41
|
+
() => testResultRoute.value.matches || Boolean(rootTabRoute.value.params.testResultId),
|
|
42
|
+
);
|
|
40
43
|
|
|
41
44
|
const App = () => {
|
|
42
45
|
const className = styles[`layout-${currentSection.value !== "default" ? currentSection.value : layoutStore.value}`];
|
|
@@ -51,6 +54,7 @@ const App = () => {
|
|
|
51
54
|
fetchEnvInfo,
|
|
52
55
|
fetchGlobals,
|
|
53
56
|
fetchQualityGateResults,
|
|
57
|
+
fetchCategoriesData,
|
|
54
58
|
];
|
|
55
59
|
|
|
56
60
|
if (globalThis) {
|