@allurereport/web-awesome 3.8.2 → 3.10.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/README.md +112 -0
- package/allurerc-dev.mjs +10 -0
- package/dist/multi/121.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/173.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/174.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/252.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/282.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/29.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/310.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/416.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/507.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/527.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/600.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/605.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/638.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/672.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/686.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/725.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/741.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/749.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/755.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/779.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/894.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/943.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/980.app-b18cce138691927e8759.js +1 -0
- package/dist/multi/app-b18cce138691927e8759.js +2 -0
- package/dist/multi/manifest.json +26 -23
- package/dist/multi/styles-212da6c68fa0beb4c6c5.css +1 -0
- package/dist/multi/styles-5c882b14b6f3112e40c4.css +1 -0
- package/dist/multi/styles-a4f65de86208f79dd2be.css +58 -0
- package/dist/single/app-733f473da7b51f98876d.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +19 -14
- package/src/assets/scss/_common.scss +2 -2
- package/src/assets/scss/index.scss +8 -6
- package/src/components/BaseLayout/index.tsx +14 -2
- package/src/components/BaseLayout/styles.scss +5 -5
- package/src/components/Categories/CategoryHeaderItem/styles.scss +2 -2
- package/src/components/Categories/CategoryTreeItem/styles.scss +2 -2
- package/src/components/Categories/GroupTreeItem/styles.scss +4 -5
- package/src/components/Categories/HistoryTreeItem/styles.scss +2 -2
- package/src/components/Categories/LabelTreeItem/styles.scss +2 -2
- package/src/components/Categories/MessageTreeItem/index.tsx +1 -1
- package/src/components/Categories/MessageTreeItem/styles.scss +18 -18
- package/src/components/Categories/sticky.ts +1 -1
- package/src/components/Footer/FooterVersion.tsx +5 -10
- package/src/components/Footer/index.tsx +7 -1
- package/src/components/Footer/styles.scss +8 -2
- package/src/components/Header/CiInfo/index.tsx +17 -13
- package/src/components/Header/CiInfo/styles.scss +1 -1
- package/src/components/Header/styles.scss +2 -2
- package/src/components/HeaderControls/index.tsx +1 -3
- package/src/components/HotkeysProvider/index.tsx +556 -0
- package/src/components/KeyboardShortcuts/index.tsx +73 -0
- package/src/components/KeyboardShortcuts/shortcutsConfig.ts +91 -0
- package/src/components/KeyboardShortcuts/styles.scss +69 -0
- package/src/components/MainReport/index.tsx +89 -72
- package/src/components/MainReport/styles.scss +20 -5
- package/src/components/Metadata/index.tsx +27 -6
- package/src/components/Metadata/styles.scss +21 -9
- package/src/components/MetadataButton/index.tsx +2 -0
- package/src/components/MetadataButton/styles.scss +1 -1
- package/src/components/NavTabs/styles.scss +8 -8
- package/src/components/ReportBody/styles.scss +3 -4
- package/src/components/ReportCategories/styles.scss +1 -1
- package/src/components/ReportFilters/styles.scss +1 -1
- package/src/components/ReportGlobalAttachments/styles.scss +1 -1
- package/src/components/ReportGlobalErrors/styles.scss +1 -1
- package/src/components/ReportHeader/index.tsx +25 -13
- package/src/components/ReportHeader/styles.scss +2 -2
- package/src/components/ReportMetadata/index.tsx +44 -15
- package/src/components/ReportMetadata/styles.scss +6 -6
- package/src/components/ReportQualityGateResults/styles.scss +2 -2
- package/src/components/ReportSearch/index.tsx +1 -5
- package/src/components/ReportTabs/styles.scss +9 -9
- package/src/components/SectionSwitcher/index.tsx +87 -10
- package/src/components/SideBySide/index.tsx +20 -2
- package/src/components/SideBySide/styles.scss +9 -1
- package/src/components/SplitLayout/index.tsx +11 -2
- package/src/components/SplitLayout/styles.scss +23 -4
- package/src/components/TestResult/TestStepsEmpty/styles.scss +1 -1
- package/src/components/TestResult/TrDescription/styles.scss +1 -1
- package/src/components/TestResult/TrDropdown/index.tsx +2 -2
- package/src/components/TestResult/TrDropdown/styles.scss +1 -1
- package/src/components/TestResult/TrEmpty/styles.scss +1 -1
- package/src/components/TestResult/TrEnvironmentItem/styles.scss +4 -4
- package/src/components/TestResult/TrError/index.tsx +32 -7
- package/src/components/TestResult/TrError/styles.scss +23 -23
- package/src/components/TestResult/TrHeader/styles.scss +2 -2
- package/src/components/TestResult/TrHistory/styles.scss +6 -6
- package/src/components/TestResult/TrInfo/styles.scss +8 -8
- package/src/components/TestResult/TrLinks/index.tsx +2 -2
- package/src/components/TestResult/TrLinks/styles.scss +2 -2
- package/src/components/TestResult/TrMetadata/index.tsx +1 -1
- package/src/components/TestResult/TrMetadata/styles.scss +1 -1
- package/src/components/TestResult/TrNavigation/index.tsx +1 -1
- package/src/components/TestResult/TrNavigation/styles.scss +2 -2
- package/src/components/TestResult/TrOverview.tsx +2 -0
- package/src/components/TestResult/TrParameters/index.tsx +1 -1
- package/src/components/TestResult/TrParameters/styles.scss +1 -1
- package/src/components/TestResult/TrPrevStatuses/styles.scss +8 -8
- package/src/components/TestResult/TrPwTraces/styles.scss +1 -1
- package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +27 -1
- package/src/components/TestResult/TrRetriesView/styles.scss +20 -10
- package/src/components/TestResult/TrSetup/index.tsx +10 -4
- package/src/components/TestResult/TrSeverity/styles.scss +7 -7
- package/src/components/TestResult/TrStatus/styles.scss +2 -35
- package/src/components/TestResult/TrSteps/TrAttachment.tsx +79 -43
- package/src/components/TestResult/TrSteps/TrAttachmentInfo.tsx +44 -17
- package/src/components/TestResult/TrSteps/TrBodyItems.tsx +5 -2
- package/src/components/TestResult/TrSteps/TrErrorStep.tsx +3 -0
- package/src/components/TestResult/TrSteps/TrStep.tsx +15 -6
- package/src/components/TestResult/TrSteps/TrStepHeader.tsx +8 -5
- package/src/components/TestResult/TrSteps/index.tsx +7 -5
- package/src/components/TestResult/TrSteps/stepTreeExpansion.ts +27 -9
- package/src/components/TestResult/TrSteps/styles.scss +80 -20
- package/src/components/TestResult/TrTeardown/index.tsx +10 -4
- package/src/components/TestResult/bodyItems.ts +1 -1
- package/src/components/TestResult/index.tsx +8 -2
- package/src/components/TestResult/styles.scss +10 -1
- package/src/components/TestResult/trOverviewFocus.scss +4 -0
- package/src/components/Timeline/styles.scss +6 -6
- package/src/components/Tree/index.tsx +79 -5
- package/src/components/Tree/styles.scss +55 -35
- package/src/hooks/useTestResultOverviewFocusScroll.ts +23 -0
- package/src/index.html +30 -33
- package/src/index.tsx +12 -6
- package/src/locales/ar.json +62 -1
- package/src/locales/az.json +62 -1
- package/src/locales/de.json +62 -1
- package/src/locales/en.json +62 -1
- package/src/locales/es.json +62 -1
- package/src/locales/fr.json +62 -1
- package/src/locales/he.json +62 -1
- package/src/locales/hy.json +62 -1
- package/src/locales/it.json +62 -1
- package/src/locales/ja.json +62 -1
- package/src/locales/ka.json +62 -1
- package/src/locales/kr.json +62 -1
- package/src/locales/nl.json +62 -1
- package/src/locales/pl.json +62 -1
- package/src/locales/pt.json +62 -1
- package/src/locales/ru.json +62 -1
- package/src/locales/sv.json +62 -1
- package/src/locales/tr.json +62 -1
- package/src/locales/uk.json +62 -1
- package/src/locales/zh-TW.json +62 -1
- package/src/locales/zh.json +62 -1
- package/src/stores/keyboard.ts +371 -0
- package/src/stores/keyboardActions.ts +769 -0
- package/src/stores/locale.ts +5 -2
- package/src/stores/reportEnvSections.ts +6 -0
- package/src/stores/reportRootTabs.ts +95 -0
- package/src/stores/search.ts +147 -0
- package/src/stores/testResultOverviewNav.ts +119 -0
- package/src/stores/testResultTabs.ts +62 -0
- package/src/stores/timeline.ts +1 -1
- package/src/stores/tree.ts +42 -4
- package/src/stores/treeFilters/store.ts +3 -36
- package/src/stores/treeSort.ts +7 -1
- package/src/styles/_pane-active.scss +8 -0
- package/src/styles.scss +1 -1
- package/src/utils/atSeparator.ts +4 -0
- package/src/utils/flattenTestResultOverview.ts +182 -0
- package/src/utils/time.ts +2 -1
- package/src/utils/trOverviewFocus.ts +18 -0
- package/src/utils/treeFilters.ts +15 -4
- package/test/components/EnvironmentPicker.test.tsx +21 -3
- package/test/components/Footer.test.tsx +26 -0
- package/test/components/Header/CiInfo.test.tsx +56 -0
- package/test/components/Header.test.tsx +8 -0
- package/test/components/HeaderControls.test.tsx +28 -0
- package/test/components/ReportGlobals.test.tsx +9 -1
- package/test/components/ReportHeader.test.tsx +77 -0
- package/test/components/ReportMetadata.test.tsx +131 -0
- package/test/components/TestResult/PwTraceButton.test.tsx +8 -0
- package/test/components/TestResult/TrErrorStep.test.tsx +8 -0
- package/test/components/TestResult/TrOverview.test.tsx +30 -10
- package/test/components/TestResult/TrRetriesItem.test.tsx +163 -0
- package/test/components/TestResult/TrSteps.test.tsx +108 -0
- package/test/components/TestResult/bodyItems.test.ts +9 -1
- package/test/components/TestResult/openPwTraceInNewTab.test.ts +8 -0
- package/test/components/TestResult/stepTreeExpansion.test.ts +10 -2
- package/test/components/Timeline.test.tsx +15 -7
- package/test/stores/keyboard/keyboardActions.test.ts +615 -0
- package/test/stores/search.test.ts +143 -0
- package/test/stores/treeFilters/actions.test.ts +8 -0
- package/test/stores/treeSort.test.ts +58 -0
- package/test/utils/flattenTestResultOverview.test.ts +57 -0
- package/test/utils/ownerAddress.test.ts +9 -1
- package/test/utils/time.test.ts +52 -0
- package/test/utils/treeFilters.test.ts +113 -1
- package/types.d.ts +39 -0
- package/webpack.config.js +12 -7
- package/CONTRIBUTING.md +0 -34
- package/dist/multi/173.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/174.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/252.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/282.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/29.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/310.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/416.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/507.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/527.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/600.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/605.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/638.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/672.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/686.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/725.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/741.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/749.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/755.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/894.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/943.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/980.app-f008fb8342025f2b1ace.js +0 -1
- package/dist/multi/app-f008fb8342025f2b1ace.js +0 -2
- package/dist/multi/styles-9f7a23a0c8b79fa76981.css +0 -58
- package/dist/single/app-07332238da9897064301.js +0 -2
- package/src/assets/scss/day.scss +0 -53
- package/src/assets/scss/fonts.scss +0 -3
- package/src/assets/scss/night.scss +0 -63
- package/src/assets/scss/palette.scss +0 -393
- package/src/assets/scss/theme.scss +0 -330
- package/src/assets/scss/vars.scss +0 -11
- /package/dist/multi/{app-f008fb8342025f2b1ace.js.LICENSE.txt → app-b18cce138691927e8759.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-07332238da9897064301.js.LICENSE.txt → app-733f473da7b51f98876d.js.LICENSE.txt} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatDuration } from "@allurereport/core-api";
|
|
1
2
|
import { getReportOptions } from "@allurereport/web-commons";
|
|
2
3
|
import { Heading, Loadable, Text, TooltipWrapper } from "@allurereport/web-components";
|
|
3
4
|
import type { AwesomeReportOptions } from "types";
|
|
@@ -5,22 +6,28 @@ import type { AwesomeReportOptions } from "types";
|
|
|
5
6
|
import { ReportHeaderLogo } from "@/components/ReportHeader/ReportHeaderLogo";
|
|
6
7
|
import { ReportHeaderPie } from "@/components/ReportHeader/ReportHeaderPie";
|
|
7
8
|
import { TrStatus } from "@/components/TestResult/TrStatus";
|
|
8
|
-
import {
|
|
9
|
+
import { useI18n } from "@/stores";
|
|
9
10
|
import { globalsStore } from "@/stores/globals";
|
|
11
|
+
import { timestampToDate } from "@/utils/time";
|
|
10
12
|
|
|
11
13
|
import * as styles from "./styles.scss";
|
|
12
14
|
|
|
15
|
+
const reportDateOptions: Intl.DateTimeFormatOptions = {
|
|
16
|
+
month: "long",
|
|
17
|
+
day: "numeric",
|
|
18
|
+
year: "numeric",
|
|
19
|
+
hour: "numeric",
|
|
20
|
+
minute: "numeric",
|
|
21
|
+
second: "numeric",
|
|
22
|
+
};
|
|
23
|
+
|
|
13
24
|
export const ReportHeader = () => {
|
|
14
|
-
const { reportName, createdAt } = getReportOptions<AwesomeReportOptions>() ?? {};
|
|
25
|
+
const { reportName, createdAt, runSummary } = getReportOptions<AwesomeReportOptions>() ?? {};
|
|
15
26
|
const { t } = useI18n("ui");
|
|
16
|
-
const formattedCreatedAt =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
hour: "numeric",
|
|
21
|
-
minute: "numeric",
|
|
22
|
-
second: "numeric",
|
|
23
|
-
});
|
|
27
|
+
const formattedCreatedAt = timestampToDate(createdAt as number, reportDateOptions);
|
|
28
|
+
const formattedReportTime = runSummary
|
|
29
|
+
? `${timestampToDate(runSummary.start, reportDateOptions)} (${formatDuration(runSummary.duration)})`
|
|
30
|
+
: formattedCreatedAt;
|
|
24
31
|
|
|
25
32
|
return (
|
|
26
33
|
<div className={styles["report-header"]}>
|
|
@@ -41,14 +48,19 @@ export const ReportHeader = () => {
|
|
|
41
48
|
</div>
|
|
42
49
|
<Text type="paragraph" size="m" className={styles["report-date"]} data-testid="report-data">
|
|
43
50
|
{code === undefined
|
|
44
|
-
?
|
|
51
|
+
? formattedReportTime
|
|
45
52
|
: exitCode.actual !== undefined
|
|
46
53
|
? t("finishedAtBoth", {
|
|
47
|
-
|
|
54
|
+
// Keep the existing i18n parameter name; the value can now be either a timestamp or run interval.
|
|
55
|
+
formattedCreatedAt: formattedReportTime,
|
|
48
56
|
actual: exitCode.actual,
|
|
49
57
|
original: exitCode.original,
|
|
50
58
|
})
|
|
51
|
-
: t("finishedAtOriginal", {
|
|
59
|
+
: t("finishedAtOriginal", {
|
|
60
|
+
// Keep the existing i18n parameter name; the value can now be either a timestamp or run interval.
|
|
61
|
+
formattedCreatedAt: formattedReportTime,
|
|
62
|
+
original: exitCode.original,
|
|
63
|
+
})}
|
|
52
64
|
</Text>
|
|
53
65
|
</div>
|
|
54
66
|
);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
justify-content: space-between;
|
|
5
5
|
padding: 24px 24px 0;
|
|
6
6
|
align-items: flex-start;
|
|
7
|
-
background: var(--bg-
|
|
7
|
+
background: var(--color-bg-primary);
|
|
8
8
|
border-radius: 8px;
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.report-date {
|
|
23
|
-
color: var(--
|
|
23
|
+
color: var(--color-text-secondary);
|
|
24
24
|
display: block;
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { EnvironmentItem } from "@allurereport/core-api";
|
|
2
|
+
import { getReportOptions } from "@allurereport/web-commons";
|
|
2
3
|
import { Button, Loadable } from "@allurereport/web-components";
|
|
3
4
|
import type { FunctionalComponent } from "preact";
|
|
4
5
|
import { useEffect } from "preact/hooks";
|
|
6
|
+
import type { AwesomeExecutorInfo, AwesomeReportOptions } from "types";
|
|
5
7
|
|
|
6
8
|
import { MetadataList } from "@/components/Metadata";
|
|
7
9
|
import { MetadataButton } from "@/components/MetadataButton";
|
|
@@ -9,6 +11,7 @@ import { MetadataSummary } from "@/components/ReportMetadata/MetadataSummary";
|
|
|
9
11
|
import { reportStatsStore, statsByEnvStore, useI18n } from "@/stores";
|
|
10
12
|
import { currentEnvironment } from "@/stores/env";
|
|
11
13
|
import { envInfoStore } from "@/stores/envInfo";
|
|
14
|
+
import { getReportEnvSectionId } from "@/stores/reportEnvSections";
|
|
12
15
|
import { collapsedTrees, toggleTree } from "@/stores/tree";
|
|
13
16
|
import { fetchVariables, variables } from "@/stores/variables";
|
|
14
17
|
|
|
@@ -18,6 +21,7 @@ const REPORT_VISIBLE_LIMIT = 8;
|
|
|
18
21
|
|
|
19
22
|
export interface MetadataItem extends EnvironmentItem {
|
|
20
23
|
value?: string;
|
|
24
|
+
url?: string;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
// TODO: check, where do we use the component and refactor it up to our needs
|
|
@@ -34,12 +38,11 @@ export type MetadataVariablesProps = {
|
|
|
34
38
|
};
|
|
35
39
|
|
|
36
40
|
const Metadata: FunctionalComponent<MetadataProps> = ({ envInfo = [] }) => {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const showAllId = `report-${envKey}-metadata-showAll`;
|
|
41
|
+
const sectionId = getReportEnvSectionId("metadata");
|
|
42
|
+
const showAllId = `${sectionId}-showAll`;
|
|
40
43
|
const isOpened = !collapsedTrees.value.has(sectionId);
|
|
41
44
|
const showAll = collapsedTrees.value.has(showAllId);
|
|
42
|
-
const list = envInfo.map((env) => ({ ...env, value: env.values.join(", ") }));
|
|
45
|
+
const list = envInfo.map((env) => ({ ...env, value: env.value ?? env.values.join(", ") }));
|
|
43
46
|
const totalCount = list.length;
|
|
44
47
|
const visibleList = totalCount <= REPORT_VISIBLE_LIMIT ? list : showAll ? list : list.slice(0, REPORT_VISIBLE_LIMIT);
|
|
45
48
|
const { t } = useI18n("ui");
|
|
@@ -71,9 +74,8 @@ const Metadata: FunctionalComponent<MetadataProps> = ({ envInfo = [] }) => {
|
|
|
71
74
|
|
|
72
75
|
const MetadataVariables: FunctionalComponent<MetadataVariablesProps> = (props) => {
|
|
73
76
|
const { t } = useI18n("ui");
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const showAllId = `report-${envKey}-variables-showAll`;
|
|
77
|
+
const sectionId = getReportEnvSectionId("variables");
|
|
78
|
+
const showAllId = `${sectionId}-showAll`;
|
|
77
79
|
const isOpened = !collapsedTrees.value.has(sectionId);
|
|
78
80
|
const showAll = collapsedTrees.value.has(showAllId);
|
|
79
81
|
const fullList = Object.entries(props.variables).map(([key, value]) => ({
|
|
@@ -110,27 +112,54 @@ const MetadataVariables: FunctionalComponent<MetadataVariablesProps> = (props) =
|
|
|
110
112
|
);
|
|
111
113
|
};
|
|
112
114
|
|
|
115
|
+
const getExecutorLabel = (executor?: AwesomeExecutorInfo) => {
|
|
116
|
+
if (!executor) return undefined;
|
|
117
|
+
if (executor.name && executor.buildName) return `${executor.name} · ${executor.buildName}`;
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
executor.buildName ||
|
|
121
|
+
executor.reportName ||
|
|
122
|
+
executor.name ||
|
|
123
|
+
executor.buildUrl ||
|
|
124
|
+
executor.reportUrl ||
|
|
125
|
+
executor.url
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const getExecutorMetadata = (executor?: AwesomeExecutorInfo): MetadataItem[] => {
|
|
130
|
+
const label = getExecutorLabel(executor);
|
|
131
|
+
|
|
132
|
+
return label
|
|
133
|
+
? [{ name: "executor", values: [], value: label, url: executor?.buildUrl || executor?.reportUrl || executor?.url }]
|
|
134
|
+
: [];
|
|
135
|
+
};
|
|
136
|
+
|
|
113
137
|
export const ReportMetadata = () => {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
138
|
+
const envId = currentEnvironment.value;
|
|
139
|
+
const { executor } = getReportOptions<AwesomeReportOptions>();
|
|
140
|
+
const executorMetadata = getExecutorMetadata(executor);
|
|
141
|
+
const stats = envId ? statsByEnvStore.value.data[envId] : reportStatsStore.value.data;
|
|
117
142
|
|
|
118
143
|
useEffect(() => {
|
|
119
|
-
fetchVariables(
|
|
120
|
-
}, [
|
|
144
|
+
fetchVariables(envId);
|
|
145
|
+
}, [envId]);
|
|
121
146
|
|
|
122
147
|
return (
|
|
123
148
|
<div className={styles["report-metadata-wrapper"]}>
|
|
124
149
|
{stats && <MetadataSummary stats={stats} />}
|
|
125
150
|
<Loadable
|
|
126
151
|
source={variables}
|
|
127
|
-
transformData={(data) => data?.[
|
|
152
|
+
transformData={(data) => data?.[envId ?? "default"] ?? {}}
|
|
128
153
|
renderData={(data) => !!Object.keys(data).length && <MetadataVariables variables={data} />}
|
|
129
154
|
/>
|
|
130
155
|
<Loadable
|
|
131
156
|
source={envInfoStore}
|
|
132
|
-
renderError={() =>
|
|
133
|
-
renderData={(data) =>
|
|
157
|
+
renderError={() => Boolean(executorMetadata.length) && <Metadata envInfo={executorMetadata} />}
|
|
158
|
+
renderData={(data) => {
|
|
159
|
+
const metadata = [...executorMetadata, ...(data ?? [])];
|
|
160
|
+
|
|
161
|
+
return Boolean(metadata.length) && <Metadata envInfo={metadata} />;
|
|
162
|
+
}}
|
|
134
163
|
/>
|
|
135
164
|
</div>
|
|
136
165
|
);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
.report-metadata-separator {
|
|
13
|
-
border-left: 1px solid var(--
|
|
13
|
+
border-left: 1px solid var(--color-border-default);
|
|
14
14
|
height: 24px;
|
|
15
15
|
margin: 11px 0;
|
|
16
16
|
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
justify-content: space-between;
|
|
27
27
|
align-items: baseline;
|
|
28
28
|
padding: 16px 0;
|
|
29
|
-
border-bottom: 1px solid var(--
|
|
29
|
+
border-bottom: 1px solid var(--color-border-default);
|
|
30
30
|
width: 100%;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.metadata-item-title {
|
|
40
|
-
color: var(--
|
|
40
|
+
color: var(--color-text-secondary);
|
|
41
41
|
margin-bottom: 6px;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
.report-metadata {
|
|
49
|
-
border-bottom: 1px solid var(--
|
|
49
|
+
border-bottom: 1px solid var(--color-border-default);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.report-metadata-keyvalue {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
width: 4px;
|
|
81
81
|
height: 12px;
|
|
82
82
|
border-radius: 2px;
|
|
83
|
-
background: var(--
|
|
83
|
+
background: var(--color-text-secondary);
|
|
84
84
|
margin-right: 8px;
|
|
85
85
|
align-self: center;
|
|
86
86
|
@include status-bg-and-text();
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
|
|
94
94
|
.metadata-icon {
|
|
95
95
|
margin-right: 8px;
|
|
96
|
-
color: var(--
|
|
96
|
+
color: var(--color-icon-secondary);
|
|
97
97
|
}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
.report-quality-gate-result-icon {
|
|
34
34
|
flex: 0 0 auto;
|
|
35
35
|
margin-top: 3px;
|
|
36
|
-
color: var(--
|
|
36
|
+
color: var(--color-status-failed-chart);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.report-quality-gate-result-content {
|
|
@@ -52,6 +52,6 @@
|
|
|
52
52
|
&:not(:last-child) {
|
|
53
53
|
padding-bottom: 8px;
|
|
54
54
|
margin-bottom: 14px;
|
|
55
|
-
border-bottom: 1px solid var(--
|
|
55
|
+
border-bottom: 1px solid var(--color-border-subtle);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -12,7 +12,7 @@ const handleQuerySearch = (value: string) => {
|
|
|
12
12
|
setTreeQueryFilter(value);
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
export const ReportSearch = () => {
|
|
16
16
|
const { t } = useI18n("search");
|
|
17
17
|
|
|
18
18
|
return (
|
|
@@ -24,7 +24,3 @@ const QuerySearch = () => {
|
|
|
24
24
|
/>
|
|
25
25
|
);
|
|
26
26
|
};
|
|
27
|
-
|
|
28
|
-
export const ReportSearch = () => {
|
|
29
|
-
return <QuerySearch />;
|
|
30
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.tabsList {
|
|
2
|
-
background-color: var(--bg-
|
|
2
|
+
background-color: var(--color-bg-secondary);
|
|
3
3
|
padding: 2px;
|
|
4
4
|
border-radius: 8px;
|
|
5
5
|
display: flex;
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.tab {
|
|
12
|
-
background-color: var(--
|
|
13
|
-
color: var(--
|
|
12
|
+
background-color: var(--color-control-bg-ghost);
|
|
13
|
+
color: var(--color-text-primary);
|
|
14
14
|
border-radius: 6px;
|
|
15
15
|
border: 1px solid transparent;
|
|
16
16
|
padding: 2px 8px;
|
|
@@ -28,17 +28,17 @@
|
|
|
28
28
|
border-color var(--color-change-transition-duration);
|
|
29
29
|
|
|
30
30
|
&[aria-current] {
|
|
31
|
-
background-color: var(--bg-
|
|
32
|
-
border-color: var(--
|
|
31
|
+
background-color: var(--color-bg-raised);
|
|
32
|
+
border-color: var(--color-border-default);
|
|
33
33
|
cursor: default;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
&:hover:not([aria-current]) {
|
|
37
|
-
background-color: var(--
|
|
37
|
+
background-color: var(--color-control-bg-ghost-hover);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
&:active:not([aria-current]) {
|
|
41
|
-
background-color: var(--
|
|
41
|
+
background-color: var(--color-control-bg-ghost-active);
|
|
42
42
|
transform: scale(0.94);
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
&:focus-visible {
|
|
50
|
-
outline: 1px solid var(--
|
|
50
|
+
outline: 1px solid var(--color-focus-ring);
|
|
51
51
|
|
|
52
52
|
&:not([aria-current]) {
|
|
53
|
-
background-color: var(--
|
|
53
|
+
background-color: var(--color-control-bg-ghost-hover);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -1,19 +1,96 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PageLoader } from "@allurereport/web-components";
|
|
2
|
+
import type { ComponentType } from "preact";
|
|
3
|
+
import { useEffect, useState } from "preact/hooks";
|
|
2
4
|
|
|
3
|
-
import { Charts } from "@/components/Charts";
|
|
4
5
|
import { Report } from "@/components/Report";
|
|
5
6
|
import { currentSection } from "@/stores/sections";
|
|
6
7
|
|
|
7
|
-
import { Timeline } from "../Timeline";
|
|
8
|
-
|
|
9
8
|
import * as styles from "./styles.scss";
|
|
10
9
|
|
|
10
|
+
type SectionName = "report" | "charts" | "timeline";
|
|
11
|
+
|
|
12
|
+
const sectionLoaders: Record<Exclude<SectionName, "report">, () => Promise<ComponentType>> = {
|
|
13
|
+
charts: () => import("@/components/Charts").then((module) => module.Charts),
|
|
14
|
+
timeline: () => import("@/components/Timeline").then((module) => module.Timeline),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const sectionCache = new Map<string, ComponentType>();
|
|
18
|
+
|
|
19
|
+
type LoadedSection = {
|
|
20
|
+
section: SectionName;
|
|
21
|
+
Component: ComponentType;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const LazySection = ({ section }: { section: SectionName }) => {
|
|
25
|
+
const cached = sectionCache.get(section);
|
|
26
|
+
const [loaded, setLoaded] = useState<LoadedSection | null>(cached ? { section, Component: cached } : null);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (section === "report") {
|
|
30
|
+
setLoaded({ section, Component: Report });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const loader = sectionLoaders[section];
|
|
35
|
+
let mounted = true;
|
|
36
|
+
|
|
37
|
+
if (!loader) {
|
|
38
|
+
setLoaded(null);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const cachedComponent = sectionCache.get(section);
|
|
43
|
+
if (cachedComponent) {
|
|
44
|
+
if (mounted) {
|
|
45
|
+
setLoaded({ section, Component: cachedComponent });
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setLoaded(null);
|
|
51
|
+
|
|
52
|
+
loader()
|
|
53
|
+
.then((LoadedComponent) => {
|
|
54
|
+
if (mounted) {
|
|
55
|
+
sectionCache.set(section, LoadedComponent);
|
|
56
|
+
setLoaded({ section, Component: LoadedComponent });
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
.catch((err) => {
|
|
60
|
+
console.error(`Failed to load section "${section}":`, err);
|
|
61
|
+
if (mounted) {
|
|
62
|
+
setLoaded({ section, Component: Report });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return () => {
|
|
67
|
+
mounted = false;
|
|
68
|
+
};
|
|
69
|
+
}, [section]);
|
|
70
|
+
|
|
71
|
+
if (section === "report" || !sectionLoaders[section]) {
|
|
72
|
+
return <Report />;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!loaded || loaded.section !== section) {
|
|
76
|
+
return <PageLoader />;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const { Component } = loaded;
|
|
80
|
+
|
|
81
|
+
return <Component />;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const VALID_SECTIONS: SectionName[] = ["report", "charts", "timeline"];
|
|
85
|
+
|
|
11
86
|
export const SectionSwitcher = () => {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
timeline: <Timeline />,
|
|
16
|
-
};
|
|
87
|
+
const section = VALID_SECTIONS.includes(currentSection.value as SectionName)
|
|
88
|
+
? (currentSection.value as SectionName)
|
|
89
|
+
: "report";
|
|
17
90
|
|
|
18
|
-
return
|
|
91
|
+
return (
|
|
92
|
+
<div className={styles.layout}>
|
|
93
|
+
<LazySection section={section} />
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
19
96
|
};
|
|
@@ -2,6 +2,8 @@ import type { JSX } from "preact";
|
|
|
2
2
|
import { useEffect, useMemo, useRef } from "preact/hooks";
|
|
3
3
|
import Split from "split.js";
|
|
4
4
|
|
|
5
|
+
import { activePane, focusTestResultPane, focusTreePane } from "@/stores/keyboard";
|
|
6
|
+
|
|
5
7
|
import * as styles from "./styles.scss";
|
|
6
8
|
|
|
7
9
|
const SideBySide = ({ left, right }: { left: JSX.Element; right: JSX.Element }) => {
|
|
@@ -42,10 +44,26 @@ const SideBySide = ({ left, right }: { left: JSX.Element; right: JSX.Element })
|
|
|
42
44
|
};
|
|
43
45
|
}, []);
|
|
44
46
|
|
|
47
|
+
const pane = activePane.value;
|
|
48
|
+
|
|
45
49
|
return (
|
|
46
50
|
<div class={styles.side} ref={containerRef}>
|
|
47
|
-
<div
|
|
48
|
-
|
|
51
|
+
<div
|
|
52
|
+
class={styles["side-left"]}
|
|
53
|
+
data-pane="tree"
|
|
54
|
+
data-pane-active={pane === "tree" ? "true" : undefined}
|
|
55
|
+
onMouseDown={() => focusTreePane()}
|
|
56
|
+
>
|
|
57
|
+
{leftContent}
|
|
58
|
+
</div>
|
|
59
|
+
<div
|
|
60
|
+
class={styles["side-right"]}
|
|
61
|
+
data-pane="testResult"
|
|
62
|
+
data-pane-active={pane === "testResult" ? "true" : undefined}
|
|
63
|
+
onMouseDown={() => focusTestResultPane()}
|
|
64
|
+
>
|
|
65
|
+
{rightContent}
|
|
66
|
+
</div>
|
|
49
67
|
</div>
|
|
50
68
|
);
|
|
51
69
|
};
|
|
@@ -15,10 +15,18 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.side-left {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
18
20
|
margin-right: auto;
|
|
19
21
|
border-radius: 12px 0 0 12px;
|
|
20
22
|
box-shadow: var(--shadow-small);
|
|
21
23
|
overflow: hidden;
|
|
24
|
+
min-height: 0;
|
|
25
|
+
|
|
26
|
+
> * {
|
|
27
|
+
flex: 1 1 auto;
|
|
28
|
+
min-height: 0;
|
|
29
|
+
}
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
.side-right {
|
|
@@ -56,7 +64,7 @@
|
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
.gutter {
|
|
59
|
-
background: var(--bg-
|
|
67
|
+
background: var(--color-bg-secondary) no-repeat 50%;
|
|
60
68
|
height: 100%;
|
|
61
69
|
}
|
|
62
70
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Loadable, PageLoader, Text } from "@allurereport/web-components";
|
|
2
2
|
import { computed } from "@preact/signals";
|
|
3
|
+
import clsx from "clsx";
|
|
3
4
|
import type { JSX } from "preact";
|
|
4
5
|
import { useEffect, useRef, useState } from "preact/hooks";
|
|
5
6
|
|
|
@@ -7,6 +8,8 @@ import MainReport from "@/components/MainReport";
|
|
|
7
8
|
import SideBySide from "@/components/SideBySide";
|
|
8
9
|
import TestResult from "@/components/TestResult";
|
|
9
10
|
import { useI18n } from "@/stores";
|
|
11
|
+
import { activePane } from "@/stores/keyboard";
|
|
12
|
+
import { isSplitMode } from "@/stores/layout";
|
|
10
13
|
import { rootTabRoute, testResultRoute } from "@/stores/router";
|
|
11
14
|
import { currentTrId } from "@/stores/testResult";
|
|
12
15
|
import { testResultStore } from "@/stores/testResults";
|
|
@@ -18,7 +21,7 @@ const MainReportWrapper = () => {
|
|
|
18
21
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
19
22
|
|
|
20
23
|
return (
|
|
21
|
-
<div className={styles.wrapper} ref={containerRef}>
|
|
24
|
+
<div className={styles.wrapper} ref={containerRef} data-tree-scroll-container>
|
|
22
25
|
<MainReport />
|
|
23
26
|
</div>
|
|
24
27
|
);
|
|
@@ -59,7 +62,13 @@ export const SplitLayout = () => {
|
|
|
59
62
|
}}
|
|
60
63
|
/>
|
|
61
64
|
) : (
|
|
62
|
-
<div
|
|
65
|
+
<div
|
|
66
|
+
className={clsx(
|
|
67
|
+
styles.empty,
|
|
68
|
+
isSplitMode.value && styles["empty-split-pane"],
|
|
69
|
+
isSplitMode.value && activePane.value === "testResult" && styles["pane-active"],
|
|
70
|
+
)}
|
|
71
|
+
>
|
|
63
72
|
<Text>{t("noSelectedTR")}</Text>
|
|
64
73
|
</div>
|
|
65
74
|
);
|
|
@@ -1,22 +1,29 @@
|
|
|
1
|
+
@use "../../styles/pane-active" as paneActive;
|
|
2
|
+
|
|
1
3
|
.layout {
|
|
2
4
|
margin: auto;
|
|
3
5
|
padding: 12px 32px;
|
|
4
|
-
background: var(--bg-
|
|
5
|
-
color: var(--
|
|
6
|
+
background: var(--color-bg-canvas);
|
|
7
|
+
color: var(--color-text-primary);
|
|
6
8
|
font-size: 14px;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
.wrapper {
|
|
12
|
+
display: flex;
|
|
10
13
|
width: 100%;
|
|
11
14
|
flex-direction: column;
|
|
12
15
|
margin: auto;
|
|
13
16
|
position: relative;
|
|
14
17
|
height: 100%;
|
|
18
|
+
min-height: 0;
|
|
19
|
+
overflow-y: auto;
|
|
20
|
+
overflow-x: hidden;
|
|
21
|
+
scrollbar-width: thin;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
.content {
|
|
18
25
|
box-shadow: var(--shadow-small);
|
|
19
|
-
background: var(--bg-
|
|
26
|
+
background: var(--color-bg-primary);
|
|
20
27
|
border-radius: 12px;
|
|
21
28
|
width: 100%;
|
|
22
29
|
overflow: hidden;
|
|
@@ -39,7 +46,7 @@
|
|
|
39
46
|
.title {
|
|
40
47
|
font-size: 14px;
|
|
41
48
|
line-height: 1.25;
|
|
42
|
-
color: var(--
|
|
49
|
+
color: var(--color-text-primary);
|
|
43
50
|
margin-bottom: 8px;
|
|
44
51
|
}
|
|
45
52
|
|
|
@@ -79,6 +86,18 @@
|
|
|
79
86
|
height: 100%;
|
|
80
87
|
}
|
|
81
88
|
|
|
89
|
+
.empty-split-pane {
|
|
90
|
+
position: relative;
|
|
91
|
+
background: var(--color-bg-raised);
|
|
92
|
+
border-radius: 12px;
|
|
93
|
+
overflow: auto;
|
|
94
|
+
@include paneActive.split-pane-indicator;
|
|
95
|
+
|
|
96
|
+
&.pane-active {
|
|
97
|
+
@include paneActive.split-pane-indicator-active;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
82
101
|
.header {
|
|
83
102
|
padding: 8px;
|
|
84
103
|
margin-bottom: 0;
|
|
@@ -13,9 +13,9 @@ export const TrDropdown: FunctionalComponent<{
|
|
|
13
13
|
counter: number;
|
|
14
14
|
actions?: preact.ComponentChildren;
|
|
15
15
|
className?: ClassValue;
|
|
16
|
-
}> = ({ isOpened, setIsOpen, title, icon, counter, actions, className }) => {
|
|
16
|
+
}> = ({ isOpened, setIsOpen, title, icon, counter, actions, className, ...rest }) => {
|
|
17
17
|
return (
|
|
18
|
-
<div className={clsx(styles["test-result-dropdown"], className)} onClick={() => setIsOpen(!isOpened)}>
|
|
18
|
+
<div className={clsx(styles["test-result-dropdown"], className)} onClick={() => setIsOpen(!isOpened)} {...rest}>
|
|
19
19
|
<ArrowButton isOpened={isOpened} icon={allureIcons.arrowsChevronDown} />
|
|
20
20
|
<div className={styles["test-result-dropdown-wrap"]}>
|
|
21
21
|
<SvgIcon id={icon} />
|