@allurereport/web-awesome 3.0.0-beta.16 → 3.0.0-beta.18

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.
Files changed (113) hide show
  1. package/dist/multi/173.app-b58a8b2733d390b78773.js +1 -0
  2. package/dist/multi/174.app-b58a8b2733d390b78773.js +1 -0
  3. package/dist/multi/252.app-b58a8b2733d390b78773.js +1 -0
  4. package/dist/multi/282.app-b58a8b2733d390b78773.js +1 -0
  5. package/dist/multi/29.app-b58a8b2733d390b78773.js +1 -0
  6. package/dist/multi/416.app-b58a8b2733d390b78773.js +1 -0
  7. package/dist/multi/527.app-b58a8b2733d390b78773.js +1 -0
  8. package/dist/multi/600.app-b58a8b2733d390b78773.js +1 -0
  9. package/dist/multi/605.app-b58a8b2733d390b78773.js +1 -0
  10. package/dist/multi/638.app-b58a8b2733d390b78773.js +1 -0
  11. package/dist/multi/672.app-b58a8b2733d390b78773.js +1 -0
  12. package/dist/multi/686.app-b58a8b2733d390b78773.js +1 -0
  13. package/dist/multi/725.app-b58a8b2733d390b78773.js +1 -0
  14. package/dist/multi/741.app-b58a8b2733d390b78773.js +1 -0
  15. package/dist/multi/755.app-b58a8b2733d390b78773.js +1 -0
  16. package/dist/multi/894.app-b58a8b2733d390b78773.js +1 -0
  17. package/dist/multi/943.app-b58a8b2733d390b78773.js +1 -0
  18. package/dist/multi/980.app-b58a8b2733d390b78773.js +1 -0
  19. package/dist/multi/app-b58a8b2733d390b78773.js +2 -0
  20. package/dist/multi/app-b58a8b2733d390b78773.js.LICENSE.txt +8 -0
  21. package/dist/multi/manifest.json +20 -20
  22. package/dist/multi/styles-3610e3d9923b6a2a1c67.css +46 -0
  23. package/dist/single/app-51defb8852956a2ff6f1.js +2 -0
  24. package/dist/single/app-51defb8852956a2ff6f1.js.LICENSE.txt +8 -0
  25. package/dist/single/manifest.json +1 -1
  26. package/package.json +17 -10
  27. package/src/components/Charts/index.tsx +12 -3
  28. package/src/components/Header/CiInfo/index.tsx +51 -0
  29. package/src/components/Header/CiInfo/styles.scss +7 -0
  30. package/src/components/Header/index.tsx +6 -1
  31. package/src/components/MainReport/index.tsx +65 -2
  32. package/src/components/MainReport/styles.scss +8 -0
  33. package/src/components/NavTabs/index.tsx +70 -0
  34. package/src/components/ReportBody/Filters.tsx +1 -1
  35. package/src/components/ReportBody/index.tsx +1 -1
  36. package/src/components/ReportBody/styles.scss +2 -2
  37. package/src/components/ReportGlobalAttachments/index.tsx +34 -0
  38. package/src/components/ReportGlobalAttachments/styles.scss +11 -0
  39. package/src/components/ReportGlobalErrors/index.tsx +30 -0
  40. package/src/components/ReportGlobalErrors/styles.scss +12 -0
  41. package/src/components/ReportHeader/index.tsx +28 -10
  42. package/src/components/ReportHeader/styles.scss +7 -1
  43. package/src/components/ReportMetadata/MetadataSummary.tsx +1 -1
  44. package/src/components/ReportMetadata/styles.scss +0 -2
  45. package/src/components/TestResult/TrAttachmentsView/index.tsx +5 -3
  46. package/src/components/TestResult/TrInfo/TrInfoStatuses.tsx +1 -1
  47. package/src/components/TestResult/TrPrevStatuses/index.tsx +1 -2
  48. package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +24 -6
  49. package/src/components/TestResult/TrRetriesView/index.tsx +8 -1
  50. package/src/components/TestResult/TrSeverity/index.tsx +1 -1
  51. package/src/components/TestResult/TrStatus/index.tsx +1 -1
  52. package/src/components/TestResult/TrSteps/TrStepInfo.tsx +4 -4
  53. package/src/components/TestResult/TrSteps/styles.scss +10 -1
  54. package/src/components/TestResult/TrTabs/index.tsx +19 -57
  55. package/src/components/TestResult/index.tsx +0 -1
  56. package/src/components/Tree/index.tsx +1 -3
  57. package/src/index.html +14 -1
  58. package/src/index.tsx +9 -1
  59. package/src/locales/az.json +9 -8
  60. package/src/locales/de.json +9 -8
  61. package/src/locales/en.json +9 -8
  62. package/src/locales/es.json +9 -8
  63. package/src/locales/fr.json +9 -8
  64. package/src/locales/he.json +9 -8
  65. package/src/locales/hy.json +9 -8
  66. package/src/locales/it.json +9 -8
  67. package/src/locales/ja.json +9 -8
  68. package/src/locales/ka.json +9 -8
  69. package/src/locales/kr.json +9 -8
  70. package/src/locales/nl.json +9 -8
  71. package/src/locales/pl.json +9 -8
  72. package/src/locales/pt.json +9 -8
  73. package/src/locales/ru.json +9 -8
  74. package/src/locales/sv.json +9 -8
  75. package/src/locales/tr.json +9 -8
  76. package/src/locales/zh.json +9 -8
  77. package/src/stores/chart.ts +7 -7
  78. package/src/stores/globals.ts +28 -0
  79. package/src/stores/locale.ts +0 -1
  80. package/src/utils/tree.ts +0 -2
  81. package/test/components/Header/CiInfo.test.tsx +151 -0
  82. package/test/components/Header.test.tsx +127 -0
  83. package/tsconfig.json +6 -1
  84. package/tsconfig.node.json +8 -0
  85. package/types.d.ts +2 -1
  86. package/vitest.config.ts +30 -3
  87. package/vitest.setup.ts +1 -0
  88. package/dist/multi/173.app-1e7b32b35927de455ae2.js +0 -1
  89. package/dist/multi/174.app-1e7b32b35927de455ae2.js +0 -1
  90. package/dist/multi/252.app-1e7b32b35927de455ae2.js +0 -1
  91. package/dist/multi/282.app-1e7b32b35927de455ae2.js +0 -1
  92. package/dist/multi/29.app-1e7b32b35927de455ae2.js +0 -1
  93. package/dist/multi/416.app-1e7b32b35927de455ae2.js +0 -1
  94. package/dist/multi/527.app-1e7b32b35927de455ae2.js +0 -1
  95. package/dist/multi/600.app-1e7b32b35927de455ae2.js +0 -1
  96. package/dist/multi/605.app-1e7b32b35927de455ae2.js +0 -1
  97. package/dist/multi/638.app-1e7b32b35927de455ae2.js +0 -1
  98. package/dist/multi/672.app-1e7b32b35927de455ae2.js +0 -1
  99. package/dist/multi/686.app-1e7b32b35927de455ae2.js +0 -1
  100. package/dist/multi/725.app-1e7b32b35927de455ae2.js +0 -1
  101. package/dist/multi/741.app-1e7b32b35927de455ae2.js +0 -1
  102. package/dist/multi/755.app-1e7b32b35927de455ae2.js +0 -1
  103. package/dist/multi/894.app-1e7b32b35927de455ae2.js +0 -1
  104. package/dist/multi/943.app-1e7b32b35927de455ae2.js +0 -1
  105. package/dist/multi/980.app-1e7b32b35927de455ae2.js +0 -1
  106. package/dist/multi/app-1e7b32b35927de455ae2.js +0 -2
  107. package/dist/multi/app-1e7b32b35927de455ae2.js.LICENSE.txt +0 -23
  108. package/dist/multi/styles-99f5e45d3e35c8c13cd6.css +0 -43
  109. package/dist/single/app-b4be944c6ebe4a83f366.js +0 -2
  110. package/dist/single/app-b4be944c6ebe4a83f366.js.LICENSE.txt +0 -23
  111. package/src/utils/capitalize.ts +0 -6
  112. package/src/utils/charts.ts +0 -167
  113. /package/src/components/{TestResult/TrTabs → NavTabs}/styles.scss +0 -0
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Prism: Lightweight, robust, elegant syntax highlighting
3
+ *
4
+ * @license MIT <https://opensource.org/licenses/MIT>
5
+ * @author Lea Verou <https://lea.verou.me>
6
+ * @namespace
7
+ * @public
8
+ */
@@ -1,3 +1,3 @@
1
1
  {
2
- "main.js": "app-b4be944c6ebe4a83f366.js"
2
+ "main.js": "app-51defb8852956a2ff6f1.js"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/web-awesome",
3
- "version": "3.0.0-beta.16",
3
+ "version": "3.0.0-beta.18",
4
4
  "description": "The static files for Allure Awesome Report",
5
5
  "keywords": [
6
6
  "allure",
@@ -31,9 +31,10 @@
31
31
  "IE 11"
32
32
  ],
33
33
  "dependencies": {
34
- "@allurereport/core-api": "3.0.0-beta.16",
35
- "@allurereport/web-commons": "3.0.0-beta.16",
36
- "@allurereport/web-components": "3.0.0-beta.16",
34
+ "@allurereport/core-api": "3.0.0-beta.18",
35
+ "@allurereport/plugin-api": "3.0.0-beta.18",
36
+ "@allurereport/web-commons": "3.0.0-beta.18",
37
+ "@allurereport/web-components": "3.0.0-beta.18",
37
38
  "@preact/signals": "^1.3.0",
38
39
  "clsx": "^2.1.1",
39
40
  "d3-shape": "^3.2.0",
@@ -51,7 +52,11 @@
51
52
  "@eslint/js": "^9.10.0",
52
53
  "@floating-ui/dom": "^1.6.12",
53
54
  "@preact/compat": "^18.3.1",
55
+ "@preact/preset-vite": "^2.10.2",
54
56
  "@stylistic/eslint-plugin": "^2.6.1",
57
+ "@testing-library/jest-dom": "^6.1.5",
58
+ "@testing-library/preact": "^3.2.3",
59
+ "@testing-library/user-event": "^14.5.1",
55
60
  "@types/babel__core": "^7.20.5",
56
61
  "@types/d3-shape": "^3.1.6",
57
62
  "@types/diff": "^7",
@@ -61,9 +66,9 @@
61
66
  "@types/prismjs": "^1.26.5",
62
67
  "@typescript-eslint/eslint-plugin": "^8.0.0",
63
68
  "@typescript-eslint/parser": "^8.0.0",
64
- "@vitest/runner": "^2.1.9",
65
- "@vitest/snapshot": "^2.1.9",
66
- "allure-vitest": "^3.0.9",
69
+ "@vitest/runner": "^3.2.4",
70
+ "@vitest/snapshot": "^3.2.4",
71
+ "allure-vitest": "^3.3.2",
67
72
  "ansi-to-html": "^0.7.2",
68
73
  "autoprefixer": "^10.4.20",
69
74
  "babel-loader": "^9.2.1",
@@ -87,9 +92,10 @@
87
92
  "fork-ts-checker-webpack-plugin": "^9.0.2",
88
93
  "globals": "^15.9.0",
89
94
  "html-webpack-plugin": "^5.6.3",
95
+ "jsdom": "^26.1.0",
90
96
  "mini-css-extract-plugin": "^2.9.1",
91
97
  "npm-run-all2": "^7.0.1",
92
- "postcss": "^8.5.0",
98
+ "postcss": "^8.5.6",
93
99
  "rimraf": "^6.0.1",
94
100
  "sass": "^1.79.1",
95
101
  "sass-loader": "^16.0.1",
@@ -99,10 +105,11 @@
99
105
  "terser-webpack-plugin": "^5.3.14",
100
106
  "typescript": "^5.6.3",
101
107
  "typescript-eslint": "^8.6.0",
102
- "vitest": "^2.1.9",
108
+ "vite": "^7.0.6",
109
+ "vitest": "^3.2.4",
103
110
  "webpack": "^5.99.9",
104
111
  "webpack-cli": "^5.1.4",
105
- "webpack-dev-server": "^5.2.1",
112
+ "webpack-dev-server": "^5.2.2",
106
113
  "webpack-manifest-plugin": "^5.0.0"
107
114
  }
108
115
  }
@@ -1,6 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- import { ChartType, capitalize } from "@allurereport/web-commons";
2
+ import { ChartType } from "@allurereport/core-api";
3
+ import { type UIChartData, capitalize } from "@allurereport/web-commons";
3
4
  import {
5
+ ComingSoonChartWidget,
4
6
  Grid,
5
7
  GridItem,
6
8
  Loadable,
@@ -12,11 +14,10 @@ import {
12
14
  import { useEffect } from "preact/hooks";
13
15
  import { chartsStore, fetchChartsData } from "@/stores/chart";
14
16
  import { useI18n } from "@/stores/locale";
15
- import type { ChartData } from "@/utils/charts";
16
17
  import * as styles from "./styles.scss";
17
18
 
18
19
  const getChartWidgetByType = (
19
- chartData: ChartData,
20
+ chartData: UIChartData,
20
21
  { t, empty }: Record<string, (key: string, options?: any) => string>,
21
22
  ) => {
22
23
  switch (chartData.type) {
@@ -50,6 +51,14 @@ const getChartWidgetByType = (
50
51
  </Widget>
51
52
  );
52
53
  }
54
+ case ChartType.HeatMap:
55
+ case ChartType.Bar:
56
+ case ChartType.Funnel:
57
+ case ChartType.TreeMap: {
58
+ const title = chartData.title ?? t(`charts.${chartData.type}.title`, { fallback: `${chartData.type} Chart` });
59
+
60
+ return <ComingSoonChartWidget title={title} />;
61
+ }
53
62
  }
54
63
  };
55
64
 
@@ -0,0 +1,51 @@
1
+ import { CiDescriptor, CiType } from "@allurereport/core-api";
2
+ import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
3
+ import type { ClassValue } from "clsx";
4
+ import clsx from "clsx";
5
+ import { useMemo } from "preact/hooks";
6
+ import * as styles from "./styles.scss";
7
+
8
+ interface CiInfoProps {
9
+ ci: CiDescriptor;
10
+ className?: ClassValue;
11
+ }
12
+
13
+ export const CiInfo = ({ ci, className }: CiInfoProps) => {
14
+ const icon = useMemo(() => {
15
+ switch (ci.type) {
16
+ case CiType.Amazon:
17
+ return allureIcons.amazon;
18
+ case CiType.Azure:
19
+ return allureIcons.azure;
20
+ case CiType.Bitbucket:
21
+ return allureIcons.bitbucket;
22
+ case CiType.Circle:
23
+ return allureIcons.circleci;
24
+ case CiType.Drone:
25
+ return allureIcons.drone;
26
+ case CiType.Github:
27
+ return allureIcons.github;
28
+ case CiType.Gitlab:
29
+ return allureIcons.gitlab;
30
+ case CiType.Jenkins:
31
+ return allureIcons.jenkins;
32
+ default:
33
+ return undefined;
34
+ }
35
+ }, [ci]);
36
+ const link = ci.pullRequestUrl ?? ci.jobUrl ?? ci.jobRunUrl;
37
+ const label = ci.pullRequestName ?? ci.jobName ?? ci.jobRunName ?? link;
38
+
39
+ if (!link) {
40
+ return null;
41
+ }
42
+
43
+ return (
44
+ <a className={clsx(styles["ci-info"], className)} href={link}>
45
+ {icon && <SvgIcon id={icon} width={16} height={16} />}
46
+ <Text type={"paragraph"} size={"m"} bold>
47
+ {label}
48
+ </Text>
49
+ </a>
50
+ );
51
+ };
@@ -0,0 +1,7 @@
1
+ .ci-info {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 0 6px;
5
+ color: var(--on-text-secondary);
6
+ text-decoration: none;
7
+ }
@@ -1,3 +1,4 @@
1
+ import { getReportOptions } from "@allurereport/web-commons";
1
2
  import type { ClassValue } from "clsx";
2
3
  import clsx from "clsx";
3
4
  import { HeaderControls } from "@/components/HeaderControls";
@@ -6,6 +7,8 @@ import { TrBreadcrumbs } from "@/components/TestResult/TrHeader/TrBreadcrumbs";
6
7
  import { route } from "@/stores/router";
7
8
  import { availableSections } from "@/stores/sections";
8
9
  import { testResultStore } from "@/stores/testResults";
10
+ import type { AwesomeReportOptions } from "../../../types";
11
+ import { CiInfo } from "./CiInfo";
9
12
  import * as styles from "./styles.scss";
10
13
 
11
14
  interface HeaderProps {
@@ -13,11 +16,13 @@ interface HeaderProps {
13
16
  }
14
17
 
15
18
  export const Header = ({ className }: HeaderProps) => {
16
- const testResultId = route.value.params?.testResultId ?? null;
19
+ const testResultId = route.value.params?.testResultId;
20
+ const { ci } = getReportOptions<AwesomeReportOptions>();
17
21
 
18
22
  return (
19
23
  <div className={clsx(styles.above, className)}>
20
24
  {Boolean(availableSections.value?.length) && <SectionPicker />}
25
+ {!testResultId && ci && <CiInfo ci={ci} />}
21
26
  {testResultId && <TrBreadcrumbs testResult={testResultStore.value?.data?.[testResultId]} />}
22
27
  <HeaderControls className={styles.right} />
23
28
  </div>
@@ -1,17 +1,80 @@
1
+ import { Counter, Loadable } from "@allurereport/web-components";
1
2
  import clsx from "clsx";
3
+ import { NavTab, NavTabs, NavTabsList, useNavTabsContext } from "@/components/NavTabs";
2
4
  import { ReportBody } from "@/components/ReportBody";
5
+ import { ReportGlobalAttachments } from "@/components/ReportGlobalAttachments";
6
+ import { ReportGlobalErrors } from "@/components/ReportGlobalErrors";
3
7
  import { ReportHeader } from "@/components/ReportHeader";
4
8
  import { ReportMetadata } from "@/components/ReportMetadata";
9
+ import { reportStatsStore } from "@/stores";
10
+ import { useI18n } from "@/stores";
11
+ import { globalsStore } from "@/stores/globals";
5
12
  import { isSplitMode } from "@/stores/layout";
6
13
  import * as styles from "./styles.scss";
7
14
 
15
+ enum ReportRootTab {
16
+ Results = "results",
17
+ GlobalAttachments = "globalAttachments",
18
+ GlobalErrors = "globalErrors",
19
+ }
20
+
21
+ const viewsByTab = {
22
+ [ReportRootTab.Results]: () => (
23
+ <>
24
+ <ReportMetadata />
25
+ <ReportBody />
26
+ </>
27
+ ),
28
+ [ReportRootTab.GlobalAttachments]: () => <ReportGlobalAttachments />,
29
+ [ReportRootTab.GlobalErrors]: () => <ReportGlobalErrors />,
30
+ };
31
+
32
+ const MainReportContent = () => {
33
+ const { currentTab } = useNavTabsContext();
34
+ const tab = (currentTab as ReportRootTab) || ReportRootTab.Results;
35
+ const Content = viewsByTab[tab];
36
+
37
+ return <Content />;
38
+ };
39
+
8
40
  const MainReport = () => {
41
+ const { t } = useI18n("tabs");
42
+
9
43
  return (
10
44
  <>
11
45
  <div className={clsx(styles.content, isSplitMode.value ? styles["scroll-inside"] : "")}>
12
46
  <ReportHeader />
13
- <ReportMetadata />
14
- <ReportBody />
47
+ <div className={styles["main-report-tabs"]}>
48
+ <NavTabs initialTab={ReportRootTab.Results}>
49
+ <NavTabsList>
50
+ <Loadable
51
+ source={reportStatsStore}
52
+ renderData={(stats) => (
53
+ <NavTab id={ReportRootTab.Results}>
54
+ {t("results")} <Counter count={stats?.total ?? 0} />
55
+ </NavTab>
56
+ )}
57
+ />
58
+ <Loadable
59
+ source={globalsStore}
60
+ renderData={({ attachments = [], errors = [] }) => (
61
+ <>
62
+ <NavTab id={ReportRootTab.GlobalAttachments}>
63
+ {t("globalAttachments")} <Counter count={attachments.length} />
64
+ </NavTab>
65
+ <NavTab id={ReportRootTab.GlobalErrors}>
66
+ {t("globalErrors")}{" "}
67
+ <Counter status={errors.length > 0 ? "failed" : undefined} count={errors.length} />
68
+ </NavTab>
69
+ </>
70
+ )}
71
+ />
72
+ </NavTabsList>
73
+ <div className={styles["main-report-tabs-content"]}>
74
+ <MainReportContent />
75
+ </div>
76
+ </NavTabs>
77
+ </div>
15
78
  </div>
16
79
  </>
17
80
  );
@@ -10,3 +10,11 @@
10
10
  height: 100%;
11
11
  border-radius: 0;
12
12
  }
13
+
14
+ .main-report-tabs {
15
+ padding: 0 24px;
16
+ }
17
+
18
+ .main-report-tabs-content {
19
+ border-top: 1px solid var(--on-border-primary);
20
+ }
@@ -0,0 +1,70 @@
1
+ import { Text } from "@allurereport/web-components";
2
+ import { type ComponentChildren, createContext } from "preact";
3
+ import { useContext, useState } from "preact/hooks";
4
+ import * as styles from "./styles.scss";
5
+
6
+ type NavTabsContextT = {
7
+ currentTab: string | undefined;
8
+ setCurrentTab: (id: string) => void;
9
+ };
10
+
11
+ const NavTabsContext = createContext<NavTabsContextT | null>(null);
12
+
13
+ export const useNavTabsContext = () => {
14
+ const context = useContext(NavTabsContext);
15
+
16
+ if (!context) {
17
+ throw new Error("NavTabs components must be used within a NavTabs component");
18
+ }
19
+
20
+ return context;
21
+ };
22
+
23
+ export const NavTabsProvider = (props: { initialTab?: string; children: ComponentChildren }) => {
24
+ const { children, initialTab } = props;
25
+ const [currentTab, setCurrentTab] = useState<string | undefined>(initialTab);
26
+
27
+ return <NavTabsContext.Provider value={{ currentTab, setCurrentTab }}>{children}</NavTabsContext.Provider>;
28
+ };
29
+
30
+ export const NavTabs = (props: { children: ComponentChildren; initialTab?: string }) => {
31
+ return <NavTabsProvider {...props} />;
32
+ };
33
+
34
+ export const NavTabsList = (props: { children: ComponentChildren }) => {
35
+ return <div className={styles.tabsList}>{props.children}</div>;
36
+ };
37
+
38
+ export const NavTab = (props: {
39
+ "id": string;
40
+ "children": ComponentChildren;
41
+ "onClick"?: () => void;
42
+ "data-testid"?: string;
43
+ "isCurrentTab"?: boolean;
44
+ }) => {
45
+ const { currentTab, setCurrentTab } = useNavTabsContext();
46
+ const { id, children, onClick, "data-testid": dataTestId, "isCurrentTab": overrideIsCurrentTab } = props;
47
+ const isCurrentTab = overrideIsCurrentTab !== undefined ? overrideIsCurrentTab : currentTab === id;
48
+ const handleTabClick = () => {
49
+ if (onClick) {
50
+ onClick();
51
+ } else if (isCurrentTab) {
52
+ return;
53
+ } else {
54
+ setCurrentTab(id);
55
+ }
56
+ };
57
+
58
+ return (
59
+ <button
60
+ className={styles.tab}
61
+ onClick={handleTabClick}
62
+ data-testid={dataTestId || `nav-tab-${id}`}
63
+ aria-current={isCurrentTab ? true : undefined}
64
+ >
65
+ <Text type="paragraph" size="m">
66
+ {children}
67
+ </Text>
68
+ </button>
69
+ );
70
+ };
@@ -21,7 +21,7 @@ export const Filters = () => {
21
21
 
22
22
  const renderFilterItem = (filter: TreeFilters, value: boolean) => {
23
23
  return (
24
- <TooltipWrapper tooltipText={tooltip(filter)}>
24
+ <TooltipWrapper data-testid="filter-tooltip" tooltipText={tooltip(filter)}>
25
25
  <Menu.Item
26
26
  closeMenuOnClick={false}
27
27
  ariaLabel={t("enable-filter", { filter: t(filter) })}
@@ -1,10 +1,10 @@
1
1
  import { statusesList } from "@allurereport/core-api";
2
+ import { capitalize } from "@allurereport/web-commons";
2
3
  import { Counter, Loadable } from "@allurereport/web-components";
3
4
  import { reportStatsStore, statsByEnvStore } from "@/stores";
4
5
  import { currentEnvironment } from "@/stores/env";
5
6
  import { useI18n } from "@/stores/locale";
6
7
  import { setTreeStatus, treeFiltersStore } from "@/stores/tree";
7
- import { capitalize } from "@/utils/capitalize";
8
8
  import { Tab, Tabs, TabsList, useTabsContext } from "../Tabs";
9
9
  import { TreeList } from "../Tree";
10
10
  import { HeaderActions } from "./HeaderActions";
@@ -1,5 +1,5 @@
1
1
  .header {
2
- padding: 24px 24px 0;
2
+ padding: 24px 0 0;
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  gap: 12px;
@@ -22,7 +22,7 @@
22
22
  }
23
23
 
24
24
  .body {
25
- padding: 16px 24px;
25
+ padding: 16px 0;
26
26
  min-height: 320px;
27
27
  }
28
28
 
@@ -0,0 +1,34 @@
1
+ import type { AttachmentTestStepResult } from "@allurereport/core-api";
2
+ import { Loadable } from "@allurereport/web-components";
3
+ import { TrAttachmentView } from "@/components/TestResult/TrAttachmentsView";
4
+ import { useI18n } from "@/stores";
5
+ import { globalsStore } from "@/stores/globals";
6
+ import { AwesomeTestResult } from "../../../types";
7
+ import * as styles from "./styles.scss";
8
+
9
+ export const ReportGlobalAttachments = () => {
10
+ const { t } = useI18n("empty");
11
+
12
+ return (
13
+ <Loadable
14
+ source={globalsStore}
15
+ renderData={({ attachments }) => {
16
+ if (!attachments.length) {
17
+ return <div className={styles["report-global-attachments-empty"]}>{t("no-attachments-results")}</div>;
18
+ }
19
+
20
+ const attachmentSteps: AttachmentTestStepResult[] = attachments.map((attachment: any) => ({
21
+ link: attachment,
22
+ type: "attachment",
23
+ }));
24
+
25
+ return (
26
+ <TrAttachmentView
27
+ className={styles["report-global-attachments"]}
28
+ testResult={{ attachments: attachmentSteps } as AwesomeTestResult}
29
+ />
30
+ );
31
+ }}
32
+ />
33
+ );
34
+ };
@@ -0,0 +1,11 @@
1
+ .report-global-attachments {
2
+ padding-left: 0;
3
+ padding-right: 0;
4
+ }
5
+
6
+ .report-global-attachments-empty {
7
+ display: flex;
8
+ padding: 48px 0;
9
+ width: 100%;
10
+ justify-content: center;
11
+ }
@@ -0,0 +1,30 @@
1
+ import { Loadable } from "@allurereport/web-components";
2
+ import { TrError } from "@/components/TestResult/TrError";
3
+ import { useI18n } from "@/stores";
4
+ import { globalsStore } from "@/stores/globals";
5
+ import * as styles from "./styles.scss";
6
+
7
+ export const ReportGlobalErrors = () => {
8
+ const { t } = useI18n("empty");
9
+
10
+ return (
11
+ <Loadable
12
+ source={globalsStore}
13
+ renderData={({ errors }) => {
14
+ if (!errors.length) {
15
+ return <div className={styles["report-global-errors-empty"]}>{t("no-global-errors-results")}</div>;
16
+ }
17
+
18
+ return (
19
+ <ul className={styles["report-global-errors"]}>
20
+ {errors.map((error, i) => (
21
+ <li key={i} style={{ marginBottom: "8px" }}>
22
+ <TrError {...error} />
23
+ </li>
24
+ ))}
25
+ </ul>
26
+ );
27
+ }}
28
+ />
29
+ );
30
+ };
@@ -0,0 +1,12 @@
1
+ @import "~@allurereport/web-components/mixins.scss";
2
+
3
+ .report-global-errors {
4
+ padding: 20px 0;
5
+ }
6
+
7
+ .report-global-errors-empty {
8
+ display: flex;
9
+ padding: 48px 0;
10
+ width: 100%;
11
+ justify-content: center;
12
+ }
@@ -1,13 +1,16 @@
1
1
  import { getReportOptions } from "@allurereport/web-commons";
2
- import { Heading, Text } from "@allurereport/web-components";
2
+ import { Heading, Loadable, Text, TooltipWrapper } from "@allurereport/web-components";
3
3
  import type { AwesomeReportOptions } from "types";
4
4
  import { ReportHeaderLogo } from "@/components/ReportHeader/ReportHeaderLogo";
5
5
  import { ReportHeaderPie } from "@/components/ReportHeader/ReportHeaderPie";
6
- import { currentLocaleIso } from "@/stores";
6
+ import { TrStatus } from "@/components/TestResult/TrStatus";
7
+ import { currentLocaleIso, useI18n } from "@/stores";
8
+ import { globalsStore } from "@/stores/globals";
7
9
  import * as styles from "./styles.scss";
8
10
 
9
11
  export const ReportHeader = () => {
10
12
  const { reportName, createdAt } = getReportOptions<AwesomeReportOptions>() ?? {};
13
+ const { t } = useI18n("ui");
11
14
  const formattedCreatedAt = new Date(createdAt as number).toLocaleDateString(currentLocaleIso.value as string, {
12
15
  month: "long",
13
16
  day: "numeric",
@@ -21,14 +24,29 @@ export const ReportHeader = () => {
21
24
  <div className={styles["report-header"]}>
22
25
  <div className={styles["report-wrapper"]}>
23
26
  <ReportHeaderLogo />
24
- <div className={styles["report-wrapper-text"]}>
25
- <Heading size={"s"} tag={"h2"} className={styles["wrapper-header"]} data-testid="report-title">
26
- {reportName}
27
- </Heading>
28
- <Text type="paragraph" size="m" className={styles["report-date"]}>
29
- {formattedCreatedAt}
30
- </Text>
31
- </div>
27
+ <Loadable
28
+ source={globalsStore}
29
+ renderData={({ exitCode }) => {
30
+ const code = exitCode?.actual ?? exitCode.original;
31
+ const status = code === 0 ? "passed" : "failed";
32
+
33
+ return (
34
+ <div className={styles["report-wrapper-text"]}>
35
+ <div className={styles["report-header-title"]}>
36
+ <TrStatus status={status} />
37
+ <Heading size={"s"} tag={"h2"} className={styles["wrapper-header"]} data-testid="report-title">
38
+ {reportName}
39
+ </Heading>
40
+ </div>
41
+ <Text type="paragraph" size="m" className={styles["report-date"]} data-testid="report-data">
42
+ {exitCode.actual !== undefined
43
+ ? t("finishedAtBoth", { formattedCreatedAt, actual: exitCode.actual, original: exitCode.original })
44
+ : t("finishedAtOriginal", { formattedCreatedAt, original: exitCode.original })}
45
+ </Text>
46
+ </div>
47
+ );
48
+ }}
49
+ />
32
50
  </div>
33
51
  <ReportHeaderPie />
34
52
  </div>
@@ -2,7 +2,7 @@
2
2
  display: flex;
3
3
  column-gap: 12px;
4
4
  justify-content: space-between;
5
- padding: 24px;
5
+ padding: 24px 24px 0;
6
6
  align-items: flex-start;
7
7
  background: var(--bg-base-primary);
8
8
  border-radius: 8px;
@@ -49,3 +49,9 @@
49
49
  .report-header-pie-chart {
50
50
  width: 88px;
51
51
  }
52
+
53
+ .report-header-title {
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 0 4px;
57
+ }
@@ -1,4 +1,5 @@
1
1
  import { type Statistic, statusesList } from "@allurereport/core-api";
2
+ import { capitalize } from "@allurereport/web-commons";
2
3
  import { computed } from "@preact/signals";
3
4
  import type { FunctionalComponent } from "preact";
4
5
  import MetadataItem, { type MetadataProps } from "@/components/ReportMetadata/MetadataItem";
@@ -6,7 +7,6 @@ import { MetadataTestType } from "@/components/ReportMetadata/MetadataTestType";
6
7
  import { MetadataWithIcon } from "@/components/ReportMetadata/MetadataWithIcon";
7
8
  import * as styles from "@/components/ReportMetadata/styles.scss";
8
9
  import { useI18n } from "@/stores/locale";
9
- import { capitalize } from "@/utils/capitalize";
10
10
 
11
11
  export interface MetadataSummaryProps {
12
12
  stats: Statistic;
@@ -6,7 +6,6 @@
6
6
  }
7
7
 
8
8
  .report-metadata-wrapper {
9
- padding: 0 24px;
10
9
  align-items: center;
11
10
  }
12
11
 
@@ -27,7 +26,6 @@
27
26
  justify-content: space-between;
28
27
  align-items: baseline;
29
28
  padding: 16px 0;
30
- border-top: 1px solid var(--on-border-primary);
31
29
  border-bottom: 1px solid var(--on-border-primary);
32
30
  width: 100%;
33
31
  }
@@ -1,4 +1,5 @@
1
1
  import type { AttachmentTestStepResult } from "@allurereport/core-api";
2
+ import cx from "clsx";
2
3
  import type { FunctionalComponent } from "preact";
3
4
  import type { AwesomeTestResult } from "types";
4
5
  import { TrAttachment } from "@/components/TestResult/TrSteps/TrAttachment";
@@ -6,15 +7,16 @@ import { useI18n } from "@/stores";
6
7
  import * as styles from "./styles.scss";
7
8
 
8
9
  export type TrAttachmentViewProps = {
10
+ className?: string;
9
11
  testResult?: AwesomeTestResult;
10
12
  };
11
13
 
12
- export const TrAttachmentView: FunctionalComponent<TrAttachmentViewProps> = ({ testResult }) => {
14
+ export const TrAttachmentView: FunctionalComponent<TrAttachmentViewProps> = ({ testResult, className }) => {
13
15
  const { attachments } = testResult ?? {};
14
- const { t } = useI18n("empty");
16
+ const { t } = useI18n("ui");
15
17
 
16
18
  return (
17
- <div className={styles["test-result-attachments-view"]}>
19
+ <div className={cx(styles["test-result-attachments-view"], className)}>
18
20
  {attachments.length ? (
19
21
  attachments?.map((attach, key) => (
20
22
  <TrAttachment item={attach as AttachmentTestStepResult} key={key} stepIndex={key + 1} />
@@ -1,7 +1,7 @@
1
+ import { capitalize } from "@allurereport/web-commons";
1
2
  import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
2
3
  import { type FunctionalComponent } from "preact";
3
4
  import { useI18n } from "@/stores";
4
- import { capitalize } from "@/utils/capitalize";
5
5
  import * as styles from "./styles.scss";
6
6
 
7
7
  const icons: Record<string, string> = {