@allurereport/web-awesome 3.0.0-beta.3 → 3.0.0-beta.5
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/.eslintrc.cjs +1 -1
- package/CONTRIBUTING.md +34 -0
- package/dist/multi/{141.app-b6362ca0.js → 141.app-71d7f77e.js} +1 -1
- package/dist/multi/222.app-71d7f77e.js +1 -0
- package/dist/multi/335.app-71d7f77e.js +1 -0
- package/dist/multi/{34.app-b6362ca0.js → 34.app-71d7f77e.js} +1 -1
- package/dist/multi/349.app-71d7f77e.js +1 -0
- package/dist/multi/378.app-71d7f77e.js +1 -0
- package/dist/multi/{406.app-b6362ca0.js → 406.app-71d7f77e.js} +1 -1
- package/dist/multi/476.app-71d7f77e.js +1 -0
- package/dist/multi/{53.app-b6362ca0.js → 53.app-71d7f77e.js} +1 -1
- package/dist/multi/{584.app-b6362ca0.js → 584.app-71d7f77e.js} +1 -1
- package/dist/multi/690.app-71d7f77e.js +1 -0
- package/dist/multi/{747.app-b6362ca0.js → 747.app-71d7f77e.js} +1 -1
- package/dist/multi/{767.app-b6362ca0.js → 767.app-71d7f77e.js} +1 -1
- package/dist/multi/{816.app-b6362ca0.js → 816.app-71d7f77e.js} +1 -1
- package/dist/multi/83.app-71d7f77e.js +1 -0
- package/dist/multi/{873.app-b6362ca0.js → 873.app-71d7f77e.js} +1 -1
- package/dist/multi/{920.app-b6362ca0.js → 920.app-71d7f77e.js} +1 -1
- package/dist/multi/{991.app-b6362ca0.js → 991.app-71d7f77e.js} +1 -1
- package/dist/multi/app-71d7f77e.js +2 -0
- package/dist/multi/manifest.json +20 -20
- package/dist/multi/{styles-b6362ca0.css → styles-71d7f77e.css} +6 -6
- package/dist/single/app-7aa8b012.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +11 -4
- package/src/assets/scss/_common.scss +9 -0
- package/src/components/app/ArrowButton/index.tsx +3 -2
- package/src/components/app/BaseLayout/index.tsx +5 -5
- package/src/components/app/ReportBody/Filters.tsx +12 -10
- package/src/components/app/ReportBody/HeaderActions.tsx +3 -3
- package/src/components/app/ReportBody/SortBy.tsx +10 -10
- package/src/components/app/ReportBody/context.tsx +0 -1
- package/src/components/app/ReportHeader/index.tsx +1 -1
- package/src/components/app/Tabs/index.tsx +2 -3
- package/src/components/app/TestResult/TestResultDescription/index.tsx +3 -3
- package/src/components/app/TestResult/TestResultNavigation/index.tsx +34 -37
- package/src/components/app/TestResult/TestResultNavigation/styles.scss +1 -1
- package/src/components/app/TestResult/TestResultSteps/attachment.tsx +4 -6
- package/src/components/app/Tree/Tree.tsx +54 -101
- package/src/components/app/Tree/TreeHeader.tsx +13 -12
- package/src/components/app/Tree/TreeItem.tsx +3 -1
- package/src/components/app/Tree/index.tsx +31 -7
- package/src/components/app/Tree/styles.scss +9 -3
- package/src/components/commons/Menu/index.tsx +44 -19
- package/src/components/commons/SearchBox/index.tsx +8 -5
- package/src/components/commons/SuccessRatePieChart/styles.scss +0 -1
- package/src/components/commons/Toggle/index.tsx +3 -2
- package/src/components/commons/Tooltip/index.tsx +3 -3
- package/src/i18n/constants.ts +21 -2
- package/src/i18n/locales/am.json +3 -1
- package/src/i18n/locales/az.json +3 -1
- package/src/i18n/locales/de.json +3 -1
- package/src/i18n/locales/en.json +4 -2
- package/src/i18n/locales/es.json +3 -0
- package/src/i18n/locales/fr.json +3 -1
- package/src/i18n/locales/he.json +3 -1
- package/src/i18n/locales/it.json +3 -1
- package/src/i18n/locales/ja.json +3 -1
- package/src/i18n/locales/ka.json +3 -1
- package/src/i18n/locales/kr.json +3 -1
- package/src/i18n/locales/nl.json +3 -1
- package/src/i18n/locales/pl.json +3 -1
- package/src/i18n/locales/pt.json +3 -1
- package/src/i18n/locales/ru.json +3 -1
- package/src/i18n/locales/sv.json +3 -1
- package/src/i18n/locales/tr.json +3 -1
- package/src/i18n/locales/zh.json +4 -2
- package/src/index.html +1 -0
- package/src/stores/chart.ts +2 -2
- package/src/stores/testResults.ts +26 -4
- package/src/stores/tree.ts +98 -4
- package/src/types/globals.d.ts +6 -1
- package/src/utils/capitalize.ts +5 -3
- package/src/utils/treeFilters.ts +73 -120
- package/test/utils/treeFilters.test.ts +424 -0
- package/types.d.ts +25 -4
- package/vitest.config.ts +12 -0
- package/dist/multi/222.app-b6362ca0.js +0 -1
- package/dist/multi/335.app-b6362ca0.js +0 -1
- package/dist/multi/349.app-b6362ca0.js +0 -1
- package/dist/multi/378.app-b6362ca0.js +0 -1
- package/dist/multi/476.app-b6362ca0.js +0 -1
- package/dist/multi/690.app-b6362ca0.js +0 -1
- package/dist/multi/83.app-b6362ca0.js +0 -1
- package/dist/multi/app-b6362ca0.js +0 -2
- package/dist/single/app-57ae0a60.js +0 -2
- /package/dist/multi/{app-b6362ca0.js.LICENSE.txt → app-71d7f77e.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-57ae0a60.js.LICENSE.txt → app-7aa8b012.js.LICENSE.txt} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/web-awesome",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
4
|
"description": "The static files for Allure Awesome Report",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"build:prod:multi": "webpack --mode production",
|
|
23
23
|
"build:dev:single": "SINGLE_FILE_MODE=1 webpack --mode development",
|
|
24
24
|
"build:dev:multi": "webpack --mode development",
|
|
25
|
-
"lint": "eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
|
|
25
|
+
"lint": "eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
26
|
+
"test": "vitest run"
|
|
26
27
|
},
|
|
27
28
|
"browserslist": [
|
|
28
29
|
"last 1 version",
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
"IE 11"
|
|
31
32
|
],
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@allurereport/core-api": "3.0.0-beta.
|
|
34
|
-
"@allurereport/web-commons": "3.0.0-beta.
|
|
34
|
+
"@allurereport/core-api": "3.0.0-beta.5",
|
|
35
|
+
"@allurereport/web-commons": "3.0.0-beta.5",
|
|
35
36
|
"@preact/signals": "^1.3.0",
|
|
36
37
|
"clsx": "^2.1.1",
|
|
37
38
|
"d3-shape": "^3.2.0",
|
|
@@ -57,6 +58,10 @@
|
|
|
57
58
|
"@types/prismjs": "^1",
|
|
58
59
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
59
60
|
"@typescript-eslint/parser": "^8.0.0",
|
|
61
|
+
"@vitest/runner": "^2.1.8",
|
|
62
|
+
"@vitest/snapshot": "^2.1.8",
|
|
63
|
+
"allure-vitest": "^3.0.7",
|
|
64
|
+
"autoprefixer": "^10.4.20",
|
|
60
65
|
"babel-loader": "^9.2.1",
|
|
61
66
|
"babel-plugin-prismjs": "^2.1.0",
|
|
62
67
|
"css-loader": "^7.1.2",
|
|
@@ -78,6 +83,7 @@
|
|
|
78
83
|
"html-webpack-plugin": "^5.6.3",
|
|
79
84
|
"mini-css-extract-plugin": "^2.9.1",
|
|
80
85
|
"npm-run-all2": "^7.0.1",
|
|
86
|
+
"postcss": "^8.4.49",
|
|
81
87
|
"rimraf": "^6.0.1",
|
|
82
88
|
"sass": "^1.79.1",
|
|
83
89
|
"sass-loader": "^16.0.1",
|
|
@@ -85,6 +91,7 @@
|
|
|
85
91
|
"svg-sprite-loader": "^6.0.11",
|
|
86
92
|
"typescript": "^5.6.3",
|
|
87
93
|
"typescript-eslint": "^8.6.0",
|
|
94
|
+
"vitest": "^2.1.8",
|
|
88
95
|
"webpack": "^5.94.0",
|
|
89
96
|
"webpack-cli": "^5.1.4",
|
|
90
97
|
"webpack-dev-server": "^5.1.0",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*::after {
|
|
4
4
|
box-sizing: border-box;
|
|
5
5
|
}
|
|
6
|
+
|
|
6
7
|
html,
|
|
7
8
|
body,
|
|
8
9
|
div,
|
|
@@ -91,6 +92,7 @@ video {
|
|
|
91
92
|
font: inherit;
|
|
92
93
|
vertical-align: baseline;
|
|
93
94
|
}
|
|
95
|
+
|
|
94
96
|
/* HTML5 display-role reset for older browsers */
|
|
95
97
|
article,
|
|
96
98
|
aside,
|
|
@@ -105,17 +107,21 @@ nav,
|
|
|
105
107
|
section {
|
|
106
108
|
display: block;
|
|
107
109
|
}
|
|
110
|
+
|
|
108
111
|
body {
|
|
109
112
|
line-height: 1;
|
|
110
113
|
}
|
|
114
|
+
|
|
111
115
|
ol,
|
|
112
116
|
ul {
|
|
113
117
|
list-style: none;
|
|
114
118
|
}
|
|
119
|
+
|
|
115
120
|
blockquote,
|
|
116
121
|
q {
|
|
117
122
|
quotes: none;
|
|
118
123
|
}
|
|
124
|
+
|
|
119
125
|
blockquote:before,
|
|
120
126
|
blockquote:after,
|
|
121
127
|
q:before,
|
|
@@ -123,12 +129,15 @@ q:after {
|
|
|
123
129
|
content: "";
|
|
124
130
|
content: none;
|
|
125
131
|
}
|
|
132
|
+
|
|
126
133
|
table {
|
|
127
134
|
border-collapse: collapse;
|
|
128
135
|
border-spacing: 0;
|
|
129
136
|
}
|
|
137
|
+
|
|
130
138
|
body {
|
|
131
139
|
color: var(--on-text-primary);
|
|
132
140
|
background: var(--bg-base-secondary);
|
|
133
141
|
font-family: var(--font-family);
|
|
142
|
+
-webkit-text-size-adjust: 100%;
|
|
134
143
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { clsx } from "clsx";
|
|
2
|
-
import { FunctionalComponent } from "preact";
|
|
2
|
+
import type { FunctionalComponent } from "preact";
|
|
3
3
|
import lineChevronDown from "@/assets/svg/line-arrows-chevron-down.svg";
|
|
4
4
|
import { SvgIcon } from "@/components/commons/SvgIcon";
|
|
5
5
|
import * as styles from "./styles.scss";
|
|
@@ -18,9 +18,10 @@ export const ArrowButton: FunctionalComponent<ArrowButtonProps> = ({
|
|
|
18
18
|
iconSize = "xs",
|
|
19
19
|
className,
|
|
20
20
|
icon,
|
|
21
|
+
...rest
|
|
21
22
|
}) => {
|
|
22
23
|
return (
|
|
23
|
-
<button className={clsx(styles["arrow-button"], styles[`arrow-button-${buttonSize}`])}>
|
|
24
|
+
<button className={clsx(styles["arrow-button"], styles[`arrow-button-${buttonSize}`])} {...rest}>
|
|
24
25
|
<SvgIcon
|
|
25
26
|
id={icon || lineChevronDown.id}
|
|
26
27
|
size={iconSize}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensureReportDataReady } from "@allurereport/web-commons";
|
|
1
|
+
import { ensureReportDataReady, getReportOptions } from "@allurereport/web-commons";
|
|
2
2
|
import { useEffect } from "preact/compat";
|
|
3
3
|
import { Footer } from "@/components/app/Footer";
|
|
4
4
|
import MainReport from "@/components/app/MainReport";
|
|
@@ -6,11 +6,10 @@ import Modal from "@/components/app/Modal";
|
|
|
6
6
|
import TestResult from "@/components/app/TestResult";
|
|
7
7
|
import { Loadable } from "@/components/commons/Loadable";
|
|
8
8
|
import { PageLoader } from "@/components/commons/PageLoader";
|
|
9
|
-
import { fetchStats, getTheme } from "@/stores";
|
|
10
|
-
import { getLocale } from "@/stores";
|
|
9
|
+
import { fetchStats, getLocale, getTheme } from "@/stores";
|
|
11
10
|
import { fetchPieChartData } from "@/stores/chart";
|
|
12
11
|
import { fetchEnvInfo } from "@/stores/envInfo";
|
|
13
|
-
import { fetchTestResult, testResultStore } from "@/stores/testResults";
|
|
12
|
+
import { fetchTestResult, fetchTestResultNav, testResultStore } from "@/stores/testResults";
|
|
14
13
|
import { fetchTreeData, treeStore } from "@/stores/tree";
|
|
15
14
|
import * as styles from "./styles.scss";
|
|
16
15
|
|
|
@@ -23,12 +22,13 @@ export const BaseLayout = ({ testResultId }) => {
|
|
|
23
22
|
useEffect(() => {
|
|
24
23
|
if (testResultId) {
|
|
25
24
|
fetchTestResult(testResultId);
|
|
25
|
+
fetchTestResultNav();
|
|
26
26
|
} else {
|
|
27
27
|
Promise.all([
|
|
28
28
|
ensureReportDataReady(),
|
|
29
29
|
fetchStats(),
|
|
30
30
|
fetchPieChartData(),
|
|
31
|
-
fetchTreeData(
|
|
31
|
+
fetchTreeData(),
|
|
32
32
|
fetchEnvInfo(),
|
|
33
33
|
]);
|
|
34
34
|
}
|
|
@@ -2,18 +2,16 @@ import notificationBoxIcon from "@/assets/svg/line-alerts-notification-box.svg";
|
|
|
2
2
|
import refreshIcon from "@/assets/svg/line-arrows-refresh-ccw-1.svg";
|
|
3
3
|
import settingsIcon from "@/assets/svg/line-general-settings-1.svg";
|
|
4
4
|
import zapIcon from "@/assets/svg/line-general-zap.svg";
|
|
5
|
-
import { useReportContentContext } from "@/components/app/ReportBody/context";
|
|
6
5
|
import { Button } from "@/components/commons/Button";
|
|
7
6
|
import { Menu } from "@/components/commons/Menu";
|
|
8
7
|
import { Toggle } from "@/components/commons/Toggle";
|
|
9
8
|
import { useI18n } from "@/stores/locale";
|
|
9
|
+
import { setTreeFilter, treeFiltersStore } from "@/stores/tree";
|
|
10
10
|
import * as styles from "./styles.scss";
|
|
11
11
|
|
|
12
12
|
export const Filters = () => {
|
|
13
13
|
const { t } = useI18n("filters");
|
|
14
|
-
const {
|
|
15
|
-
|
|
16
|
-
const { flaky, retry, new: isNew } = filter;
|
|
14
|
+
const { flaky, retry, new: isNew } = treeFiltersStore.value.filter;
|
|
17
15
|
const hasFilter = flaky || retry || isNew;
|
|
18
16
|
|
|
19
17
|
return (
|
|
@@ -26,6 +24,7 @@ export const Filters = () => {
|
|
|
26
24
|
size="m"
|
|
27
25
|
style="outline"
|
|
28
26
|
isActive={isOpened}
|
|
27
|
+
data-testid="filters-button"
|
|
29
28
|
onClick={onClick}
|
|
30
29
|
/>
|
|
31
30
|
</div>
|
|
@@ -36,7 +35,7 @@ export const Filters = () => {
|
|
|
36
35
|
closeMenuOnClick={false}
|
|
37
36
|
ariaLabel={t("enable-filter", { filter: t("flaky") })}
|
|
38
37
|
onClick={() => {
|
|
39
|
-
|
|
38
|
+
setTreeFilter("flaky", !flaky);
|
|
40
39
|
}}
|
|
41
40
|
leadingIcon={zapIcon.id}
|
|
42
41
|
rightSlot={
|
|
@@ -45,7 +44,8 @@ export const Filters = () => {
|
|
|
45
44
|
focusable={false}
|
|
46
45
|
value={flaky}
|
|
47
46
|
label={t("enable-filter", { filter: t("flaky") })}
|
|
48
|
-
|
|
47
|
+
data-testid="flaky-filter"
|
|
48
|
+
onChange={(value) => setTreeFilter("flaky", value)}
|
|
49
49
|
/>
|
|
50
50
|
</div>
|
|
51
51
|
}
|
|
@@ -55,7 +55,7 @@ export const Filters = () => {
|
|
|
55
55
|
<Menu.Item
|
|
56
56
|
closeMenuOnClick={false}
|
|
57
57
|
ariaLabel={t("enable-filter", { filter: t("retry") })}
|
|
58
|
-
onClick={() =>
|
|
58
|
+
onClick={() => setTreeFilter("retry", !retry)}
|
|
59
59
|
leadingIcon={refreshIcon.id}
|
|
60
60
|
rightSlot={
|
|
61
61
|
<div className={styles.filterToggle}>
|
|
@@ -63,7 +63,8 @@ export const Filters = () => {
|
|
|
63
63
|
focusable={false}
|
|
64
64
|
value={retry}
|
|
65
65
|
label={t("enable-filter", { filter: t("retry") })}
|
|
66
|
-
|
|
66
|
+
data-testid="retry-filter"
|
|
67
|
+
onChange={(value) => setTreeFilter("retry", value)}
|
|
67
68
|
/>
|
|
68
69
|
</div>
|
|
69
70
|
}
|
|
@@ -73,7 +74,7 @@ export const Filters = () => {
|
|
|
73
74
|
<Menu.Item
|
|
74
75
|
closeMenuOnClick={false}
|
|
75
76
|
ariaLabel={t("enable-filter", { filter: t("new") })}
|
|
76
|
-
onClick={() =>
|
|
77
|
+
onClick={() => setTreeFilter("new", !isNew)}
|
|
77
78
|
leadingIcon={notificationBoxIcon.id}
|
|
78
79
|
rightSlot={
|
|
79
80
|
<div className={styles.filterToggle}>
|
|
@@ -81,7 +82,8 @@ export const Filters = () => {
|
|
|
81
82
|
focusable={false}
|
|
82
83
|
value={isNew}
|
|
83
84
|
label={t("enable-filter", { filter: t("new") })}
|
|
84
|
-
|
|
85
|
+
data-testid="new-filter"
|
|
86
|
+
onChange={(value) => setTreeFilter("new", value)}
|
|
85
87
|
/>
|
|
86
88
|
</div>
|
|
87
89
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useI18n } from "@/stores/locale";
|
|
2
|
+
import { setTreeQuery, treeFiltersStore } from "@/stores/tree";
|
|
2
3
|
import { SearchBox } from "../../commons/SearchBox";
|
|
3
4
|
import { Filters } from "./Filters";
|
|
4
|
-
import { useReportContentContext } from "./context";
|
|
5
5
|
import * as styles from "./styles.scss";
|
|
6
6
|
|
|
7
7
|
const Search = () => {
|
|
8
|
-
const {
|
|
8
|
+
const { query } = treeFiltersStore.value;
|
|
9
9
|
const { t } = useI18n("search");
|
|
10
10
|
|
|
11
|
-
return <SearchBox placeholder={t("search-placeholder")} value={query} onChange={
|
|
11
|
+
return <SearchBox placeholder={t("search-placeholder")} value={query} onChange={setTreeQuery} />;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export const HeaderActions = () => {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import clsx from "clsx";
|
|
2
|
-
import { ComponentChildren } from "preact";
|
|
2
|
+
import type { ComponentChildren } from "preact";
|
|
3
3
|
import lineChevronDownIcon from "@/assets/svg/line-arrows-chevron-down.svg";
|
|
4
4
|
import sortAscIcon from "@/assets/svg/line-arrows-sort-line-asc.svg";
|
|
5
5
|
import sortDescIcon from "@/assets/svg/line-arrows-sort-line-desc.svg";
|
|
6
6
|
import switchVerticalIcon from "@/assets/svg/line-arrows-switch-vertical-1.svg";
|
|
7
7
|
import { useI18n } from "@/stores/locale";
|
|
8
|
+
import { setTreeDirection, setTreeSortBy, treeFiltersStore } from "@/stores/tree";
|
|
8
9
|
import { DropdownButton } from "../../commons/Button";
|
|
9
10
|
import { Link } from "../../commons/Link";
|
|
10
11
|
import { Menu } from "../../commons/Menu";
|
|
11
12
|
import { SvgIcon } from "../../commons/SvgIcon";
|
|
12
13
|
import { Text } from "../../commons/Typography";
|
|
13
|
-
import { useReportContentContext } from "./context";
|
|
14
14
|
import * as styles from "./styles.scss";
|
|
15
15
|
|
|
16
16
|
const BtnWrapper = ({ children }: { children: ComponentChildren }) => {
|
|
@@ -21,7 +21,7 @@ export const SortBy = () => {
|
|
|
21
21
|
const { t: sortByLocale } = useI18n("sort-by");
|
|
22
22
|
const { t: sortByValuesLocale } = useI18n("sort-by.values");
|
|
23
23
|
const { t: sortByDirectionsLocale } = useI18n("sort-by.directions");
|
|
24
|
-
const {
|
|
24
|
+
const { sortBy, direction } = treeFiltersStore.value;
|
|
25
25
|
|
|
26
26
|
const displayedSortByValue = sortByValuesLocale(sortBy);
|
|
27
27
|
const displayedDirection = sortByDirectionsLocale(`${sortBy}-${direction}-short`);
|
|
@@ -72,16 +72,16 @@ export const SortBy = () => {
|
|
|
72
72
|
)}
|
|
73
73
|
>
|
|
74
74
|
<Menu.Section>
|
|
75
|
-
<Menu.ItemWithCheckmark onClick={() =>
|
|
75
|
+
<Menu.ItemWithCheckmark onClick={() => setTreeSortBy("order")} isChecked={sortBy === "order"}>
|
|
76
76
|
{sortByValuesLocale("order")}
|
|
77
77
|
</Menu.ItemWithCheckmark>
|
|
78
|
-
<Menu.ItemWithCheckmark onClick={() =>
|
|
78
|
+
<Menu.ItemWithCheckmark onClick={() => setTreeSortBy("duration")} isChecked={sortBy === "duration"}>
|
|
79
79
|
{sortByValuesLocale("duration")}
|
|
80
80
|
</Menu.ItemWithCheckmark>
|
|
81
|
-
<Menu.ItemWithCheckmark onClick={() =>
|
|
81
|
+
<Menu.ItemWithCheckmark onClick={() => setTreeSortBy("status")} isChecked={sortBy === "status"}>
|
|
82
82
|
{sortByValuesLocale("status")}
|
|
83
83
|
</Menu.ItemWithCheckmark>
|
|
84
|
-
<Menu.ItemWithCheckmark onClick={() =>
|
|
84
|
+
<Menu.ItemWithCheckmark onClick={() => setTreeSortBy("alphabet")} isChecked={sortBy === "alphabet"}>
|
|
85
85
|
{sortByValuesLocale("alphabet")}
|
|
86
86
|
</Menu.ItemWithCheckmark>
|
|
87
87
|
</Menu.Section>
|
|
@@ -92,7 +92,7 @@ export const SortBy = () => {
|
|
|
92
92
|
<Menu.Item
|
|
93
93
|
closeMenuOnClick={false}
|
|
94
94
|
onClick={onClick}
|
|
95
|
-
leadingIcon={direction
|
|
95
|
+
leadingIcon={direction === "asc" ? sortAscIcon.id : sortDescIcon.id}
|
|
96
96
|
rightSlot={
|
|
97
97
|
<BtnWrapper>
|
|
98
98
|
<DropdownButton
|
|
@@ -111,14 +111,14 @@ export const SortBy = () => {
|
|
|
111
111
|
>
|
|
112
112
|
<Menu.Section>
|
|
113
113
|
<Menu.ItemWithCheckmark
|
|
114
|
-
onClick={() =>
|
|
114
|
+
onClick={() => setTreeDirection("asc")}
|
|
115
115
|
leadingIcon={sortAscIcon.id}
|
|
116
116
|
isChecked={direction === "asc"}
|
|
117
117
|
>
|
|
118
118
|
{sortByDirectionsLocale(`${sortBy}-asc`)}
|
|
119
119
|
</Menu.ItemWithCheckmark>
|
|
120
120
|
<Menu.ItemWithCheckmark
|
|
121
|
-
onClick={() =>
|
|
121
|
+
onClick={() => setTreeDirection("desc")}
|
|
122
122
|
leadingIcon={sortDescIcon.id}
|
|
123
123
|
isChecked={direction === "desc"}
|
|
124
124
|
>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type ComponentChildren, createContext } from "preact";
|
|
2
2
|
import { useCallback, useContext, useReducer } from "preact/hooks";
|
|
3
|
-
import { capitalize } from "@/utils/capitalize";
|
|
4
3
|
|
|
5
4
|
export type SortBy = "order" | "duration" | "status" | "alphabet";
|
|
6
5
|
export type Direction = "asc" | "desc";
|
|
@@ -19,7 +19,7 @@ export const ReportHeader = () => {
|
|
|
19
19
|
<div className={styles["report-wrapper"]}>
|
|
20
20
|
<ReportHeaderLogo />
|
|
21
21
|
<div className={styles["report-wrapper-text"]}>
|
|
22
|
-
<Heading size={"s"} tag={"h2"} className={styles["wrapper-header"]}>
|
|
22
|
+
<Heading size={"s"} tag={"h2"} className={styles["wrapper-header"]} data-testid="report-title">
|
|
23
23
|
{reportName}
|
|
24
24
|
</Heading>
|
|
25
25
|
<Text type="paragraph" size="m" className={styles["report-date"]}>
|
|
@@ -10,7 +10,7 @@ type TabsContextT = {
|
|
|
10
10
|
|
|
11
11
|
const TabsContext = createContext<TabsContextT | null>(null);
|
|
12
12
|
|
|
13
|
-
export
|
|
13
|
+
export const useTabsContext = () => {
|
|
14
14
|
const context = useContext(TabsContext);
|
|
15
15
|
|
|
16
16
|
if (!context) {
|
|
@@ -18,7 +18,7 @@ export function useTabsContext() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
return context;
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
|
|
23
23
|
export const TabsProvider = (props: { initialTab?: string; children: ComponentChildren }) => {
|
|
24
24
|
const { children, initialTab } = props;
|
|
@@ -39,7 +39,6 @@ export const Tab = (props: { id: string; children: ComponentChildren }) => {
|
|
|
39
39
|
const { id, children, ...rest } = props;
|
|
40
40
|
const { currentTab, setCurrentTab } = useTabsContext();
|
|
41
41
|
const isCurrentTab = currentTab === id;
|
|
42
|
-
|
|
43
42
|
const handleTabClick = () => {
|
|
44
43
|
if (isCurrentTab) {
|
|
45
44
|
return;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { FunctionalComponent } from "preact";
|
|
1
2
|
import { useState } from "preact/hooks";
|
|
2
3
|
import { MetadataButton } from "@/components/app/MetadataButton";
|
|
3
4
|
import { Text } from "@/components/commons/Typography";
|
|
4
|
-
import * as styles from "./styles.scss";
|
|
5
|
-
import { FunctionalComponent } from "preact";
|
|
6
5
|
import { AllureAwesomeTestResult } from "../../../../../types";
|
|
6
|
+
import * as styles from "./styles.scss";
|
|
7
7
|
|
|
8
8
|
export type TestResultDescriptionProps = {
|
|
9
9
|
description: AllureAwesomeTestResult["description"];
|
|
10
|
-
}
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
export const TestResultDescription: FunctionalComponent<TestResultDescriptionProps> = ({ description }) => {
|
|
13
13
|
const [isOpen, setIsOpen] = useState<boolean>(true);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FunctionalComponent } from "preact";
|
|
2
|
-
import { AllureAwesomeTestResult } from "types";
|
|
1
|
+
import type { FunctionalComponent } from "preact";
|
|
2
|
+
import type { AllureAwesomeTestResult } from "types";
|
|
3
3
|
import LineArrowsChevronDown from "@/assets/svg/line-arrows-chevron-down.svg";
|
|
4
4
|
import LineGeneralCopy3 from "@/assets/svg/line-general-copy-3.svg";
|
|
5
5
|
import { IconButton } from "@/components/commons/Button";
|
|
@@ -8,7 +8,7 @@ import { TooltipWrapper } from "@/components/commons/Tooltip";
|
|
|
8
8
|
import { Code } from "@/components/commons/Typography";
|
|
9
9
|
import { navigateTo } from "@/index";
|
|
10
10
|
import { useI18n } from "@/stores";
|
|
11
|
-
import {
|
|
11
|
+
import { testResultNavStore } from "@/stores/testResults";
|
|
12
12
|
import { copyToClipboard } from "@/utils/copyToClipboard";
|
|
13
13
|
import * as styles from "./styles.scss";
|
|
14
14
|
|
|
@@ -20,47 +20,44 @@ export const TestResultNavigation: FunctionalComponent<TestResultNavigationProps
|
|
|
20
20
|
const { fullName, id: testResultId } = testResult ?? {};
|
|
21
21
|
const id = testResultId || "";
|
|
22
22
|
const { t: tooltip } = useI18n("controls");
|
|
23
|
+
const FullName = () => {
|
|
24
|
+
return (
|
|
25
|
+
<div data-testid="test-result-fullname" className={styles["test-result-fullName"]}>
|
|
26
|
+
<TooltipWrapper tooltipText={tooltip("clipboard")} tooltipTextAfterClick={tooltip("clipboardSuccess")}>
|
|
27
|
+
<IconButton
|
|
28
|
+
data-testid="test-result-fullname-copy"
|
|
29
|
+
style={"ghost"}
|
|
30
|
+
size={"s"}
|
|
31
|
+
icon={LineGeneralCopy3.id}
|
|
32
|
+
onClick={() => copyToClipboard(fullName)}
|
|
33
|
+
/>
|
|
34
|
+
</TooltipWrapper>
|
|
35
|
+
<Code tag={"div"} size={"s"} className={styles["test-result-fullName-text"]}>
|
|
36
|
+
{fullName && fullName}
|
|
37
|
+
</Code>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
23
41
|
|
|
24
42
|
return (
|
|
25
43
|
<Loadable
|
|
26
|
-
source={
|
|
27
|
-
renderData={(
|
|
28
|
-
const
|
|
29
|
-
const currentIndex = id && leaves?.findIndex((leave) => leave === id) + 1;
|
|
30
|
-
const allTestResults = leaves?.length;
|
|
31
|
-
|
|
32
|
-
const FullName = () => {
|
|
33
|
-
return (
|
|
34
|
-
<div data-testid="test-result-fullname" className={styles["test-result-fullName"]}>
|
|
35
|
-
<TooltipWrapper tooltipText={tooltip("clipboard")} tooltipTextAfterClick={tooltip("clipboardSuccess")}>
|
|
36
|
-
<IconButton
|
|
37
|
-
data-testid="test-result-fullname-copy"
|
|
38
|
-
style={"ghost"}
|
|
39
|
-
size={"s"}
|
|
40
|
-
icon={LineGeneralCopy3.id}
|
|
41
|
-
onClick={() => copyToClipboard(fullName)}
|
|
42
|
-
/>
|
|
43
|
-
</TooltipWrapper>
|
|
44
|
-
<Code tag={"div"} size={"s"} className={styles["test-result-fullName-text"]}>
|
|
45
|
-
{fullName && fullName}
|
|
46
|
-
</Code>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
};
|
|
44
|
+
source={testResultNavStore}
|
|
45
|
+
renderData={(data) => {
|
|
46
|
+
const currentIndex = data.indexOf(id) + 1;
|
|
50
47
|
|
|
51
48
|
return (
|
|
52
49
|
<div className={styles["test-result-nav"]}>
|
|
53
50
|
{fullName && <FullName />}
|
|
54
|
-
{
|
|
51
|
+
{data && (
|
|
55
52
|
<div className={styles["test-result-navigator"]}>
|
|
56
|
-
<TooltipWrapper tooltipText={tooltip("
|
|
53
|
+
<TooltipWrapper tooltipText={tooltip("prevTR")} isTriggerActive={currentIndex > 1}>
|
|
57
54
|
<IconButton
|
|
58
55
|
icon={LineArrowsChevronDown.id}
|
|
59
56
|
style={"ghost"}
|
|
60
|
-
isDisabled={currentIndex ===
|
|
61
|
-
data-testid="test-result-nav-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
isDisabled={currentIndex === data.length}
|
|
58
|
+
data-testid="test-result-nav-prev"
|
|
59
|
+
className={styles["test-result-nav-prev"]}
|
|
60
|
+
onClick={() => navigateTo(data[currentIndex])}
|
|
64
61
|
/>
|
|
65
62
|
</TooltipWrapper>
|
|
66
63
|
<Code
|
|
@@ -68,15 +65,15 @@ export const TestResultNavigation: FunctionalComponent<TestResultNavigationProps
|
|
|
68
65
|
size={"s"}
|
|
69
66
|
className={styles["test-result-navigator-numbers"]}
|
|
70
67
|
>
|
|
71
|
-
{currentIndex}/{
|
|
68
|
+
{currentIndex}/{data.length}
|
|
72
69
|
</Code>
|
|
73
|
-
<TooltipWrapper tooltipText={tooltip("
|
|
70
|
+
<TooltipWrapper tooltipText={tooltip("nextTR")}>
|
|
74
71
|
<IconButton
|
|
75
72
|
icon={LineArrowsChevronDown.id}
|
|
76
73
|
style={"ghost"}
|
|
77
74
|
isDisabled={currentIndex <= 1}
|
|
78
|
-
data-testid="test-result-nav-
|
|
79
|
-
onClick={() => navigateTo(
|
|
75
|
+
data-testid="test-result-nav-next"
|
|
76
|
+
onClick={() => navigateTo(data[currentIndex - 2])}
|
|
80
77
|
/>
|
|
81
78
|
</TooltipWrapper>
|
|
82
79
|
</div>
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import type { AttachmentTestStepResult } from "@allurereport/core-api";
|
|
2
2
|
import type { FunctionalComponent } from "preact";
|
|
3
3
|
import { useEffect, useState } from "preact/hooks";
|
|
4
|
+
import { modalData } from "@/components/app/Modal";
|
|
5
|
+
import { HtmlAttachmentPreview } from "@/components/app/TestResult/TestResultSteps/HtmlAttachmentPreview";
|
|
4
6
|
import { AttachmentCode } from "@/components/app/TestResult/TestResultSteps/attachmentCode";
|
|
5
7
|
import { AttachmentImage } from "@/components/app/TestResult/TestResultSteps/attachmentImage";
|
|
6
8
|
import { AttachmentVideo } from "@/components/app/TestResult/TestResultSteps/attachmentVideo";
|
|
7
9
|
import { EmptyComponent } from "@/components/app/TestResult/TestResultSteps/wrongAttachment";
|
|
8
10
|
import { Spinner } from "@/components/commons/Spinner";
|
|
9
11
|
import { type Attachments, attachmentType, fetchAttachment } from "@/utils/attachments";
|
|
10
|
-
import {
|
|
11
|
-
HtmlAttachmentPreview
|
|
12
|
-
} from "@/components/app/TestResult/TestResultSteps/HtmlAttachmentPreview";
|
|
13
|
-
import { modalData } from "@/components/app/Modal";
|
|
14
12
|
import * as styles from "./styles.scss";
|
|
15
13
|
|
|
16
14
|
const componentsByAttachmentType = {
|
|
@@ -63,8 +61,8 @@ export const Attachment: FunctionalComponent<AttachmentTestStepResultProps> = ({
|
|
|
63
61
|
|
|
64
62
|
// temp solution before modal component refactoring
|
|
65
63
|
if (CurrentPreviewComponent && previewable && modalData.value.preview) {
|
|
66
|
-
return <CurrentPreviewComponent attachment={attachment} item={item}
|
|
64
|
+
return <CurrentPreviewComponent attachment={attachment} item={item} />;
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
return CurrentComponent ? <CurrentComponent attachment={attachment} item={item} /> : <EmptyComponent
|
|
67
|
+
return CurrentComponent ? <CurrentComponent attachment={attachment} item={item} /> : <EmptyComponent />;
|
|
70
68
|
};
|