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

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 (98) hide show
  1. package/dist/multi/173.app-1e7b32b35927de455ae2.js +1 -0
  2. package/dist/multi/174.app-1e7b32b35927de455ae2.js +1 -0
  3. package/dist/multi/252.app-1e7b32b35927de455ae2.js +1 -0
  4. package/dist/multi/282.app-1e7b32b35927de455ae2.js +1 -0
  5. package/dist/multi/29.app-1e7b32b35927de455ae2.js +1 -0
  6. package/dist/multi/416.app-1e7b32b35927de455ae2.js +1 -0
  7. package/dist/multi/527.app-1e7b32b35927de455ae2.js +1 -0
  8. package/dist/multi/600.app-1e7b32b35927de455ae2.js +1 -0
  9. package/dist/multi/605.app-1e7b32b35927de455ae2.js +1 -0
  10. package/dist/multi/638.app-1e7b32b35927de455ae2.js +1 -0
  11. package/dist/multi/672.app-1e7b32b35927de455ae2.js +1 -0
  12. package/dist/multi/686.app-1e7b32b35927de455ae2.js +1 -0
  13. package/dist/multi/725.app-1e7b32b35927de455ae2.js +1 -0
  14. package/dist/multi/741.app-1e7b32b35927de455ae2.js +1 -0
  15. package/dist/multi/755.app-1e7b32b35927de455ae2.js +1 -0
  16. package/dist/multi/894.app-1e7b32b35927de455ae2.js +1 -0
  17. package/dist/multi/943.app-1e7b32b35927de455ae2.js +1 -0
  18. package/dist/multi/980.app-1e7b32b35927de455ae2.js +1 -0
  19. package/dist/multi/app-1e7b32b35927de455ae2.js +2 -0
  20. package/dist/multi/manifest.json +24 -24
  21. package/dist/multi/styles-99f5e45d3e35c8c13cd6.css +43 -0
  22. package/dist/single/app-b4be944c6ebe4a83f366.js +2 -0
  23. package/dist/single/manifest.json +1 -1
  24. package/package.json +16 -16
  25. package/src/assets/scss/day.scss +2 -0
  26. package/src/assets/scss/night.scss +2 -0
  27. package/src/assets/scss/theme.scss +4 -0
  28. package/src/components/Charts/index.tsx +2 -2
  29. package/src/components/MetadataButton/index.tsx +1 -1
  30. package/src/components/ReportBody/Filters.tsx +44 -63
  31. package/src/components/ReportMetadata/MetadataSummary.tsx +1 -1
  32. package/src/components/ReportMetadata/MetadataWithIcon.tsx +9 -11
  33. package/src/components/TestResult/TrDescription/index.tsx +1 -1
  34. package/src/components/TestResult/TrError/TrDiff.tsx +0 -1
  35. package/src/components/TestResult/TrHistory/TrHistoryItem.tsx +63 -34
  36. package/src/components/TestResult/TrHistory/styles.scss +2 -1
  37. package/src/components/TestResult/TrInfo/TrInfoStatuses.tsx +4 -2
  38. package/src/components/TestResult/TrOverview.tsx +0 -1
  39. package/src/components/TestResult/TrPrevStatuses/index.tsx +20 -5
  40. package/src/components/TestResult/TrPwTraces/index.tsx +6 -3
  41. package/src/components/TestResult/TrSteps/TrAttachment.tsx +13 -1
  42. package/src/components/TestResult/TrSteps/TrStep.tsx +4 -3
  43. package/src/components/TestResult/TrSteps/TrStepInfo.tsx +61 -1
  44. package/src/components/TestResult/TrSteps/styles.scss +31 -0
  45. package/src/components/Tree/index.tsx +17 -3
  46. package/src/locales/az.json +39 -16
  47. package/src/locales/de.json +39 -15
  48. package/src/locales/en.json +25 -2
  49. package/src/locales/es.json +36 -12
  50. package/src/locales/fr.json +36 -12
  51. package/src/locales/he.json +26 -2
  52. package/src/locales/hy.json +26 -2
  53. package/src/locales/it.json +29 -5
  54. package/src/locales/ja.json +29 -5
  55. package/src/locales/ka.json +36 -12
  56. package/src/locales/kr.json +26 -2
  57. package/src/locales/nl.json +36 -12
  58. package/src/locales/pl.json +46 -20
  59. package/src/locales/pt.json +37 -12
  60. package/src/locales/ru.json +47 -21
  61. package/src/locales/sv.json +36 -12
  62. package/src/locales/tr.json +36 -12
  63. package/src/locales/zh.json +36 -12
  64. package/src/stores/locale.ts +3 -0
  65. package/src/stores/tree.ts +7 -1
  66. package/src/utils/charts.ts +16 -18
  67. package/src/utils/tree.ts +25 -0
  68. package/src/utils/treeFilters.ts +14 -3
  69. package/tsconfig.json +1 -1
  70. package/types.d.ts +3 -1
  71. package/webpack.config.js +5 -5
  72. package/dist/multi/173.app-35b67161.js +0 -1
  73. package/dist/multi/174.app-35b67161.js +0 -1
  74. package/dist/multi/252.app-35b67161.js +0 -1
  75. package/dist/multi/282.app-35b67161.js +0 -1
  76. package/dist/multi/29.app-35b67161.js +0 -1
  77. package/dist/multi/416.app-35b67161.js +0 -1
  78. package/dist/multi/527.app-35b67161.js +0 -1
  79. package/dist/multi/600.app-35b67161.js +0 -1
  80. package/dist/multi/605.app-35b67161.js +0 -1
  81. package/dist/multi/638.app-35b67161.js +0 -1
  82. package/dist/multi/672.app-35b67161.js +0 -1
  83. package/dist/multi/686.app-35b67161.js +0 -1
  84. package/dist/multi/725.app-35b67161.js +0 -1
  85. package/dist/multi/741.app-35b67161.js +0 -1
  86. package/dist/multi/755.app-35b67161.js +0 -1
  87. package/dist/multi/894.app-35b67161.js +0 -1
  88. package/dist/multi/943.app-35b67161.js +0 -1
  89. package/dist/multi/980.app-35b67161.js +0 -1
  90. package/dist/multi/app-35b67161.js +0 -2
  91. package/dist/multi/styles-35b67161.css +0 -43
  92. package/dist/single/app-f5ecfcd9.js +0 -2
  93. /package/dist/multi/{JetBrainsMono_vf-b9a9c326..woff → JetBrainsMono_vf.woff} +0 -0
  94. /package/dist/multi/{JetBrainsMono_vf-9e9649b6..woff2 → JetBrainsMono_vf.woff2} +0 -0
  95. /package/dist/multi/{app-35b67161.js.LICENSE.txt → app-1e7b32b35927de455ae2.js.LICENSE.txt} +0 -0
  96. /package/dist/multi/{pt-root-ui_vf-22fe60ca..woff → pt-root-ui_vf.woff} +0 -0
  97. /package/dist/multi/{pt-root-ui_vf-9d251e8b..woff2 → pt-root-ui_vf.woff2} +0 -0
  98. /package/dist/single/{app-f5ecfcd9.js.LICENSE.txt → app-b4be944c6ebe4a83f366.js.LICENSE.txt} +0 -0
@@ -1,3 +1,3 @@
1
1
  {
2
- "main.js": "app-f5ecfcd9.js"
2
+ "main.js": "app-b4be944c6ebe4a83f366.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.15",
3
+ "version": "3.0.0-beta.16",
4
4
  "description": "The static files for Allure Awesome Report",
5
5
  "keywords": [
6
6
  "allure",
@@ -31,23 +31,23 @@
31
31
  "IE 11"
32
32
  ],
33
33
  "dependencies": {
34
- "@allurereport/core-api": "3.0.0-beta.15",
35
- "@allurereport/web-commons": "3.0.0-beta.15",
36
- "@allurereport/web-components": "3.0.0-beta.15",
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",
37
37
  "@preact/signals": "^1.3.0",
38
38
  "clsx": "^2.1.1",
39
39
  "d3-shape": "^3.2.0",
40
40
  "i18next": "^24.0.2",
41
41
  "md5": "^2.3.0",
42
42
  "preact": "^10.24.0",
43
- "prismjs": "^1.29.0",
43
+ "prismjs": "^1.30.0",
44
44
  "reset.css": "^2.0.2"
45
45
  },
46
46
  "devDependencies": {
47
- "@babel/core": "^7.25.2",
48
- "@babel/plugin-transform-react-jsx": "^7.25.2",
49
- "@babel/preset-env": "^7.25.4",
50
- "@babel/preset-typescript": "^7.24.7",
47
+ "@babel/core": "^7.27.4",
48
+ "@babel/plugin-transform-react-jsx": "^7.27.1",
49
+ "@babel/preset-env": "^7.27.2",
50
+ "@babel/preset-typescript": "^7.27.1",
51
51
  "@eslint/js": "^9.10.0",
52
52
  "@floating-ui/dom": "^1.6.12",
53
53
  "@preact/compat": "^18.3.1",
@@ -58,11 +58,11 @@
58
58
  "@types/eslint": "^8.56.11",
59
59
  "@types/md5": "^2.3.5",
60
60
  "@types/node": "^20.17.9",
61
- "@types/prismjs": "^1",
61
+ "@types/prismjs": "^1.26.5",
62
62
  "@typescript-eslint/eslint-plugin": "^8.0.0",
63
63
  "@typescript-eslint/parser": "^8.0.0",
64
- "@vitest/runner": "^2.1.8",
65
- "@vitest/snapshot": "^2.1.8",
64
+ "@vitest/runner": "^2.1.9",
65
+ "@vitest/snapshot": "^2.1.9",
66
66
  "allure-vitest": "^3.0.9",
67
67
  "ansi-to-html": "^0.7.2",
68
68
  "autoprefixer": "^10.4.20",
@@ -89,7 +89,7 @@
89
89
  "html-webpack-plugin": "^5.6.3",
90
90
  "mini-css-extract-plugin": "^2.9.1",
91
91
  "npm-run-all2": "^7.0.1",
92
- "postcss": "^8.4.49",
92
+ "postcss": "^8.5.0",
93
93
  "rimraf": "^6.0.1",
94
94
  "sass": "^1.79.1",
95
95
  "sass-loader": "^16.0.1",
@@ -99,10 +99,10 @@
99
99
  "terser-webpack-plugin": "^5.3.14",
100
100
  "typescript": "^5.6.3",
101
101
  "typescript-eslint": "^8.6.0",
102
- "vitest": "^2.1.8",
103
- "webpack": "^5.94.0",
102
+ "vitest": "^2.1.9",
103
+ "webpack": "^5.99.9",
104
104
  "webpack-cli": "^5.1.4",
105
- "webpack-dev-server": "^5.1.0",
105
+ "webpack-dev-server": "^5.2.1",
106
106
  "webpack-manifest-plugin": "^5.0.0"
107
107
  }
108
108
  }
@@ -26,6 +26,7 @@
26
26
  --bg-support-castor-medium-day: var(--castor-day-darken-2);
27
27
  --bg-support-rau-day: var(--rau-day-darken-1);
28
28
  --bg-support-skat-day: var(--skat-day-darken-1);
29
+ --bg-support-sirius-day: var(--sirius-day-darken-1);
29
30
  --constant-bg-base-modal-day: var(--gray-neutral-800);
30
31
  --constant-on-border-heavy-day: var(--gray-neutral-alpha-night-300);
31
32
  --constant-on-icon-primary-day: var(--gray-neutral-alpha-night-50);
@@ -48,4 +49,5 @@
48
49
  --on-text-hint-day: var(--gray-neutral-alpha-day-450);
49
50
  --on-text-primary-day: var(--gray-neutral-alpha-day-800);
50
51
  --on-text-secondary-day: var(--gray-neutral-alpha-day-600);
52
+ --on-text-universal-primary-day: var(--gray-neutral-75);
51
53
  }
@@ -29,6 +29,7 @@
29
29
  --bg-support-castor-night: var(--castor-night-darken-5);
30
30
  --bg-support-rau-night: var(--rau-night-darken-5);
31
31
  --bg-support-skat-night: var(--skat-night-darken-5);
32
+ --bg-support-sirius-night: var(--sirius-night-darken-5);
32
33
  --constant-bg-base-modal-night: var(--gray-neutral-750);
33
34
  --constant-bg-base-primary-night: var(--gray-neutral-950);
34
35
  --constant-on-border-heavy-night: var(--gray-neutral-alpha-night-300);
@@ -58,4 +59,5 @@
58
59
  --on-text-hint-night: var(--gray-neutral-alpha-night-450);
59
60
  --on-text-primary-night: var(--gray-neutral-alpha-night-100);
60
61
  --on-text-secondary-night: var(--gray-neutral-alpha-night-300);
62
+ --on-text-universal-primary-night: var(--gray-neutral-75);
61
63
  }
@@ -25,6 +25,7 @@
25
25
  --bg-support-castor: var(--bg-support-castor-day);
26
26
  --bg-support-rau: var(--bg-support-rau-day);
27
27
  --bg-support-skat: var(--bg-support-skat-day);
28
+ --bg-support-sirius: var(--bg-support-sirius-day);
28
29
  --constant-bg-base-modal: var(--constant-bg-base-modal-day);
29
30
  --constant-on-border-heavy: var(--constant-on-border-heavy-day);
30
31
  --constant-on-icon-primary: var(--constant-on-icon-primary-day);
@@ -47,6 +48,7 @@
47
48
  --on-text-hint: var(--on-text-hint-day);
48
49
  --on-text-primary: var(--on-text-primary-day);
49
50
  --on-text-secondary: var(--on-text-secondary-day);
51
+ --on-text-universal-primary: var(--on-text-universal-primary-day);
50
52
  --scrollbar-color: var(--gray-300);
51
53
  --bg-alpha-atlas: var(--atlas-day-darken-1-8);
52
54
  --bg-alpha-rau: var(--rau-day-darken-1-8);
@@ -88,6 +90,7 @@
88
90
  --bg-support-castor: var(--bg-support-castor-night);
89
91
  --bg-support-rau: var(--bg-support-rau-night);
90
92
  --bg-support-skat: var(--bg-support-skat-night);
93
+ --bg-support-sirius: var(--bg-support-sirius-night);
91
94
  --constant-bg-base-modal: var(--constant-bg-base-modal-night);
92
95
  --constant-bg-base-primary: var(--constant-bg-base-primary-night);
93
96
  --constant-on-border-heavy: var(--constant-on-border-heavy-night);
@@ -117,6 +120,7 @@
117
120
  --on-text-hint: var(--on-text-hint-night);
118
121
  --on-text-primary: var(--on-text-primary-night);
119
122
  --on-text-secondary: var(--on-text-secondary-night);
123
+ --on-text-universal-primary: var(--on-text-universal-primary-night);
120
124
 
121
125
  --scrollbar-color: var(--gray-400);
122
126
  --bg-alpha-atlas: var(--atlas-night-darken-5-12);
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- import { capitalize } from "@allurereport/web-commons";
2
+ import { ChartType, capitalize } from "@allurereport/web-commons";
3
3
  import {
4
4
  Grid,
5
5
  GridItem,
@@ -13,7 +13,6 @@ import { useEffect } from "preact/hooks";
13
13
  import { chartsStore, fetchChartsData } from "@/stores/chart";
14
14
  import { useI18n } from "@/stores/locale";
15
15
  import type { ChartData } from "@/utils/charts";
16
- import { ChartType } from "@/utils/charts";
17
16
  import * as styles from "./styles.scss";
18
17
 
19
18
  const getChartWidgetByType = (
@@ -29,6 +28,7 @@ const getChartWidgetByType = (
29
28
  return (
30
29
  <TrendChartWidget
31
30
  title={title}
31
+ mode={chartData.mode}
32
32
  items={chartData.items}
33
33
  slices={chartData.slices}
34
34
  min={chartData.min}
@@ -27,7 +27,7 @@ export const MetadataButton: FunctionalComponent<MetadataButtonProps> = ({
27
27
  <Text size={"m"} bold>
28
28
  {title}
29
29
  </Text>
30
- {counter !== null && <Counter count={counter} size="s" />}
30
+ {!!counter && <Counter count={counter} size="s" />}
31
31
  <ArrowButton
32
32
  isOpened={isOpened}
33
33
  iconSize={"s"}
@@ -1,12 +1,51 @@
1
- import { Button, Menu, Toggle, allureIcons } from "@allurereport/web-components";
1
+ import { Button, Menu, Toggle, TooltipWrapper, allureIcons } from "@allurereport/web-components";
2
2
  import { useI18n } from "@/stores/locale";
3
- import { setTreeFilter, treeFiltersStore } from "@/stores/tree";
3
+ import { type TreeFilters, setTreeFilter, treeFiltersStore } from "@/stores/tree";
4
4
  import * as styles from "./styles.scss";
5
5
 
6
+ const filterIcons: Record<TreeFilters, string> = {
7
+ flaky: allureIcons.lineIconBomb2,
8
+ retry: allureIcons.lineArrowsRefreshCcw1,
9
+ new: allureIcons.lineAlertsNew,
10
+ fixed: allureIcons.lineAlertsFixed,
11
+ regressed: allureIcons.lineAlertsRegressed,
12
+ malfunctioned: allureIcons.lineAlertsMalfunctioned,
13
+ };
14
+
15
+ const MENU_KEYS = ["flaky", "retry", "new", "fixed", "regressed", "malfunctioned"] as TreeFilters[];
16
+
6
17
  export const Filters = () => {
7
18
  const { t } = useI18n("filters");
8
- const { flaky, retry, new: isNew } = treeFiltersStore.value.filter;
9
- const hasFilter = flaky || retry || isNew;
19
+ const { t: tooltip } = useI18n("filters.description");
20
+ const hasFilter = MENU_KEYS.some((key) => treeFiltersStore.value.filter[key]);
21
+
22
+ const renderFilterItem = (filter: TreeFilters, value: boolean) => {
23
+ return (
24
+ <TooltipWrapper tooltipText={tooltip(filter)}>
25
+ <Menu.Item
26
+ closeMenuOnClick={false}
27
+ ariaLabel={t("enable-filter", { filter: t(filter) })}
28
+ onClick={() => {
29
+ setTreeFilter(filter, !value);
30
+ }}
31
+ leadingIcon={filterIcons[filter]}
32
+ rightSlot={
33
+ <div className={styles.filterToggle}>
34
+ <Toggle
35
+ focusable={false}
36
+ value={value}
37
+ label={t("enable-filter", { filter: t(filter) })}
38
+ data-testid={`${filter}-filter`}
39
+ onChange={(changeValue) => setTreeFilter(filter, changeValue)}
40
+ />
41
+ </div>
42
+ }
43
+ >
44
+ {t(filter)}
45
+ </Menu.Item>
46
+ </TooltipWrapper>
47
+ );
48
+ };
10
49
 
11
50
  return (
12
51
  <Menu
@@ -25,65 +64,7 @@ export const Filters = () => {
25
64
  )}
26
65
  >
27
66
  <Menu.Section data-testid="filters-menu">
28
- <Menu.Item
29
- closeMenuOnClick={false}
30
- ariaLabel={t("enable-filter", { filter: t("flaky") })}
31
- onClick={() => {
32
- setTreeFilter("flaky", !flaky);
33
- }}
34
- leadingIcon={allureIcons.lineIconBomb2}
35
- rightSlot={
36
- <div className={styles.filterToggle}>
37
- <Toggle
38
- focusable={false}
39
- value={flaky}
40
- label={t("enable-filter", { filter: t("flaky") })}
41
- data-testid="flaky-filter"
42
- onChange={(value) => setTreeFilter("flaky", value)}
43
- />
44
- </div>
45
- }
46
- >
47
- {t("flaky")}
48
- </Menu.Item>
49
- <Menu.Item
50
- closeMenuOnClick={false}
51
- ariaLabel={t("enable-filter", { filter: t("retry") })}
52
- onClick={() => setTreeFilter("retry", !retry)}
53
- leadingIcon={allureIcons.lineArrowsRefreshCcw1}
54
- rightSlot={
55
- <div className={styles.filterToggle}>
56
- <Toggle
57
- focusable={false}
58
- value={retry}
59
- label={t("enable-filter", { filter: t("retry") })}
60
- data-testid="retry-filter"
61
- onChange={(value) => setTreeFilter("retry", value)}
62
- />
63
- </div>
64
- }
65
- >
66
- {t("retry")}
67
- </Menu.Item>
68
- <Menu.Item
69
- closeMenuOnClick={false}
70
- ariaLabel={t("enable-filter", { filter: t("new") })}
71
- onClick={() => setTreeFilter("new", !isNew)}
72
- leadingIcon={allureIcons.lineAlertsNotificationBox}
73
- rightSlot={
74
- <div className={styles.filterToggle}>
75
- <Toggle
76
- focusable={false}
77
- value={isNew}
78
- label={t("enable-filter", { filter: t("new") })}
79
- data-testid="new-filter"
80
- onChange={(value) => setTreeFilter("new", value)}
81
- />
82
- </div>
83
- }
84
- >
85
- {t("new")}
86
- </Menu.Item>
67
+ {MENU_KEYS.map((key: TreeFilters) => renderFilterItem(key, treeFiltersStore.value.filter[key]))}
87
68
  </Menu.Section>
88
69
  </Menu>
89
70
  );
@@ -12,7 +12,7 @@ export interface MetadataSummaryProps {
12
12
  stats: Statistic;
13
13
  }
14
14
 
15
- const metadataTestsTypes = ["flaky", "retries"] as const as (keyof Statistic)[];
15
+ const metadataTestsTypes = ["flaky", "new", "retries"] as const as (keyof Statistic)[];
16
16
 
17
17
  export const MetadataSummary: FunctionalComponent<MetadataSummaryProps> = ({ stats }) => {
18
18
  const { t } = useI18n("statuses");
@@ -6,16 +6,14 @@ import * as styles from "./styles.scss";
6
6
  const icons: Record<string, string> = {
7
7
  flaky: allureIcons.lineIconBomb2,
8
8
  retries: allureIcons.lineArrowsRefreshCcw1,
9
- new: allureIcons.lineAlertsNotificationBox,
9
+ new: allureIcons.lineAlertsNew,
10
10
  };
11
11
 
12
- export const MetadataWithIcon: FunctionComponent<MetadataProps> = ({ type, count }) => {
13
- return (
14
- <div data-testid="metadata-value" className={styles["metadata-with-icon"]}>
15
- {type !== "all" && <SvgIcon className={styles["metadata-icon"]} id={icons[type]} size={"s"} />}
16
- <Text size={"m"} bold>
17
- {count}
18
- </Text>
19
- </div>
20
- );
21
- };
12
+ export const MetadataWithIcon: FunctionComponent<MetadataProps> = ({ type, count }) => (
13
+ <div data-testid="metadata-value" className={styles["metadata-with-icon"]}>
14
+ {type !== "all" && <SvgIcon className={styles["metadata-icon"]} id={icons[type]} size={"s"} />}
15
+ <Text size={"m"} bold>
16
+ {count}
17
+ </Text>
18
+ </div>
19
+ );
@@ -18,7 +18,7 @@ export const TrDescription: FunctionalComponent<TrDescriptionProps> = ({ descrip
18
18
  <MetadataButton title={"Description"} setIsOpen={setIsOpen} isOpened={isOpen} />
19
19
  {isOpen && (
20
20
  <Text tag={"p"} className={styles["test-result-description-text"]}>
21
- {description || "Description mock"}
21
+ {description}
22
22
  </Text>
23
23
  )}
24
24
  </div>
@@ -2,7 +2,6 @@ import { Button, Code, CodeViewer } from "@allurereport/web-components";
2
2
  import type { BaseOptions, Change } from "diff";
3
3
  import { diffChars, diffLines, diffWords } from "diff";
4
4
  import { useState } from "preact/hooks";
5
- import { ac } from "vitest/dist/chunks/reporters.D7Jzd9GS";
6
5
  import * as styles from "@/components/TestResult/TrError/styles.scss";
7
6
  import { useI18n } from "@/stores";
8
7
 
@@ -1,59 +1,88 @@
1
1
  import { type HistoryTestResult, formatDuration } from "@allurereport/core-api";
2
+ import { getReportOptions } from "@allurereport/web-commons";
2
3
  import { ArrowButton, IconButton, Text, TooltipWrapper, TreeItemIcon, allureIcons } from "@allurereport/web-components";
3
4
  import { type FunctionalComponent } from "preact";
4
- import { useState } from "preact/hooks";
5
+ import { useMemo, useState } from "preact/hooks";
6
+ import type { AwesomeReportOptions } from "types";
5
7
  import { TrError } from "@/components/TestResult/TrError";
6
8
  import * as styles from "@/components/TestResult/TrHistory/styles.scss";
7
9
  import { useI18n } from "@/stores";
8
- import { navigateTo, openInNewTab } from "@/stores/router";
9
10
  import { timestampToDate } from "@/utils/time";
10
11
 
11
12
  export const TrHistoryItem: FunctionalComponent<{
12
13
  testResultItem: HistoryTestResult;
13
14
  }> = ({ testResultItem }: { testResultItem: HistoryTestResult }) => {
14
- const { status, error, stop, duration, id } = testResultItem;
15
+ const reportOptions = getReportOptions<AwesomeReportOptions & { id: string }>();
16
+ const { status, error, stop, duration, id, url } = testResultItem;
15
17
  const [isOpened, setIsOpen] = useState(false);
16
- const convertedStop = timestampToDate(stop);
17
- const formattedDuration = formatDuration(duration as number);
18
+ const convertedStop = stop ? timestampToDate(stop) : undefined;
19
+ const formattedDuration = duration ? formatDuration(duration) : undefined;
18
20
  const { t } = useI18n("controls");
21
+ const navigateUrl = useMemo(() => {
22
+ if (!url) {
23
+ return undefined;
24
+ }
19
25
 
20
- const navigateUrl = id;
26
+ const { origin, pathname } = new URL(url);
27
+ const navUrl = new URL([pathname, reportOptions.id].join("/"), origin);
21
28
 
22
- return (
23
- <div>
24
- <div className={styles["test-result-history-item-header"]}>
25
- {Boolean(error) && (
26
- <span onClick={() => setIsOpen(!isOpened)}>
27
- <ArrowButton isOpened={isOpened} icon={allureIcons.arrowsChevronDown} />
28
- </span>
29
- )}
30
- <div
31
- className={styles["test-result-history-item-wrap"]}
29
+ navUrl.hash = id;
30
+
31
+ return navUrl.toString();
32
+ }, [reportOptions, id, url]);
33
+ const renderExternalLink = () => {
34
+ if (!navigateUrl) {
35
+ return null;
36
+ }
37
+
38
+ return (
39
+ <TooltipWrapper tooltipText={t("openInNewTab")}>
40
+ <IconButton
41
+ href={navigateUrl.toString()}
42
+ target={"_blank"}
43
+ icon={allureIcons.lineGeneralLinkExternal}
44
+ style={"ghost"}
45
+ size={"s"}
46
+ className={styles["test-result-history-item-link"]}
32
47
  onClick={(e) => {
33
48
  e.stopPropagation();
34
- navigateTo(navigateUrl);
35
49
  }}
36
- >
37
- <TreeItemIcon status={status} className={styles["test-result-history-item-status"]} />
38
- <Text className={styles["test-result-history-item-text"]}>{convertedStop}</Text>
39
- <div className={styles["test-result-history-item-info"]}>
50
+ />
51
+ </TooltipWrapper>
52
+ );
53
+ };
54
+ const renderItemContent = () => {
55
+ return (
56
+ <>
57
+ <TreeItemIcon status={status} className={styles["test-result-history-item-status"]} />
58
+ {convertedStop && <Text className={styles["test-result-history-item-text"]}>{convertedStop}</Text>}
59
+ <div className={styles["test-result-history-item-info"]}>
60
+ {formattedDuration && (
40
61
  <Text type="ui" size={"s"} className={styles["item-time"]}>
41
62
  {formattedDuration}
42
63
  </Text>
43
- <TooltipWrapper tooltipText={t("openInNewTab")}>
44
- <IconButton
45
- icon={allureIcons.lineGeneralLinkExternal}
46
- style={"ghost"}
47
- size={"s"}
48
- className={styles["test-result-history-item-link"]}
49
- onClick={(e) => {
50
- e.stopPropagation();
51
- openInNewTab(navigateUrl);
52
- }}
53
- />
54
- </TooltipWrapper>
55
- </div>
64
+ )}
65
+ {renderExternalLink()}
56
66
  </div>
67
+ </>
68
+ );
69
+ };
70
+
71
+ return (
72
+ <div data-testid={"test-result-history-item"}>
73
+ <div className={styles["test-result-history-item-header"]}>
74
+ {Boolean(error) && (
75
+ <span onClick={() => setIsOpen(!isOpened)}>
76
+ <ArrowButton isOpened={isOpened} icon={allureIcons.arrowsChevronDown} />
77
+ </span>
78
+ )}
79
+ {navigateUrl ? (
80
+ <a href={navigateUrl} className={styles["test-result-history-item-wrap"]}>
81
+ {renderItemContent()}
82
+ </a>
83
+ ) : (
84
+ <div className={styles["test-result-history-item-wrap"]}>{renderItemContent()}</div>
85
+ )}
57
86
  </div>
58
87
  {isOpened && error && (
59
88
  <div>
@@ -8,7 +8,6 @@
8
8
  width: 100%;
9
9
  gap: 4px;
10
10
  align-items: center;
11
- cursor: pointer;
12
11
  }
13
12
 
14
13
  .test-result-history-item-wrap {
@@ -20,6 +19,8 @@
20
19
  padding: 4px 4px 4px 4px;
21
20
  width: 100%;
22
21
  align-items: flex-start;
22
+ text-decoration: none;
23
+ color: var(--on-text-primary);
23
24
 
24
25
  &:hover {
25
26
  background: var(--bg-control-flat-medium);
@@ -1,4 +1,4 @@
1
- import { SvgIcon, allureIcons } from "@allurereport/web-components";
1
+ import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
2
2
  import { type FunctionalComponent } from "preact";
3
3
  import { useI18n } from "@/stores";
4
4
  import { capitalize } from "@/utils/capitalize";
@@ -21,7 +21,9 @@ export const TrInfoStatuses: FunctionalComponent<{ statuses: [string, boolean][]
21
21
  return (
22
22
  <div key={key} className={styles["test-result-info-status"]}>
23
23
  <SvgIcon className={styles["metadata-icon"]} id={icons[status]} size={"s"} />
24
- {capitalize(title)}
24
+ <Text type={"ui"} size={"s"}>
25
+ {capitalize(title)}
26
+ </Text>
25
27
  </div>
26
28
  );
27
29
  })}
@@ -1,4 +1,3 @@
1
- import type { TestStatus } from "@allurereport/core-api";
2
1
  import type { FunctionalComponent } from "preact";
3
2
  import type { AwesomeTestResult } from "types";
4
3
  import * as styles from "@/components/BaseLayout/styles.scss";
@@ -1,18 +1,33 @@
1
1
  import { type HistoryTestResult } from "@allurereport/core-api";
2
+ import { getReportOptions } from "@allurereport/web-commons";
2
3
  import { SvgIcon, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
3
4
  import type { FunctionalComponent } from "preact";
4
- import type { AwesomeTestResult } from "types";
5
+ import type { AwesomeReportOptions, AwesomeTestResult } from "types";
5
6
  import { useI18n } from "@/stores";
6
- import { navigateTo } from "@/stores/router";
7
7
  import { capitalize } from "@/utils/capitalize";
8
8
  import { timestampToDate } from "@/utils/time";
9
9
  import * as styles from "./styles.scss";
10
10
 
11
11
  const TrPrevStatus: FunctionalComponent<{ item: HistoryTestResult }> = ({ item }) => {
12
+ const reportOptions = getReportOptions<AwesomeReportOptions & { id: string }>();
13
+
14
+ if (!item.url) {
15
+ return (
16
+ <div className={styles["test-result-prev-status"]}>
17
+ <SvgIcon id={allureIcons.lineShapesDotCircle} className={styles[`status-${item?.status}`]} />
18
+ </div>
19
+ );
20
+ }
21
+
22
+ const { origin, pathname } = new URL(item.url);
23
+ const navigateUrl = new URL([pathname, reportOptions.id].join("/"), origin);
24
+
25
+ navigateUrl.hash = item.id;
26
+
12
27
  return (
13
- <div className={styles["test-result-prev-status"]} onClick={() => navigateTo(`${item.id}`)}>
28
+ <a className={styles["test-result-prev-status"]} href={navigateUrl.toString()}>
14
29
  <SvgIcon id={allureIcons.lineShapesDotCircle} className={styles[`status-${item?.status}`]} />
15
- </div>
30
+ </a>
16
31
  );
17
32
  };
18
33
  const TrPrevStatusTooltip: FunctionalComponent<{ item: HistoryTestResult }> = ({ item }) => {
@@ -38,7 +53,7 @@ export const TrPrevStatuses: FunctionalComponent<TrPrevStatusesProps> = ({ histo
38
53
  return (
39
54
  <div className={styles["test-result-prev-statuses"]}>
40
55
  {history?.slice(0, 6).map((item, key) => (
41
- <div key={key} className={styles["test-result-prev-status"]}>
56
+ <div key={key} data-testid={"test-result-prev-status"} className={styles["test-result-prev-status"]}>
42
57
  <TooltipWrapper key={key} tooltipComponent={<TrPrevStatusTooltip item={item} />}>
43
58
  <TrPrevStatus item={item} />
44
59
  </TooltipWrapper>
@@ -4,7 +4,6 @@ import { useState } from "preact/hooks";
4
4
  import type { AwesomeTestResult } from "types";
5
5
  import { MetadataButton } from "@/components/MetadataButton";
6
6
  import { TrAttachment } from "@/components/TestResult/TrSteps/TrAttachment";
7
- import { useI18n } from "@/stores/locale";
8
7
  import * as styles from "./styles.scss";
9
8
 
10
9
  export type TrMetadataProps = {
@@ -13,12 +12,16 @@ export type TrMetadataProps = {
13
12
  };
14
13
 
15
14
  export const TrPwTraces: FunctionalComponent<TrMetadataProps> = ({ pwTraces }) => {
16
- const { t } = useI18n("ui");
17
15
  const [isOpened, setIsOpened] = useState(true);
18
16
 
19
17
  return (
20
18
  <div className={styles["tr-metadata"]}>
21
- <MetadataButton isOpened={isOpened} setIsOpen={setIsOpened} counter={pwTraces?.length} title={t("pwTrace")} />
19
+ <MetadataButton
20
+ isOpened={isOpened}
21
+ setIsOpen={setIsOpened}
22
+ counter={pwTraces?.length}
23
+ title={"Playwright Trace"}
24
+ />
22
25
  {isOpened && (
23
26
  <div className={styles["tr-metadata-wrapper"]}>
24
27
  {pwTraces?.map((pw, index) => <TrAttachment stepIndex={index + 1} item={pw} key={pw.link.id} />)}
@@ -6,6 +6,7 @@ import type { FunctionComponent } from "preact";
6
6
  import { useState } from "preact/hooks";
7
7
  import { TrAttachmentInfo } from "@/components/TestResult/TrSteps/TrAttachmentInfo";
8
8
  import * as styles from "@/components/TestResult/TrSteps/styles.scss";
9
+ import { openModal } from "@/stores/modal";
9
10
 
10
11
  const { lineImagesImage, lineFilesFileAttachment2, playwrightLogo } = allureIcons;
11
12
 
@@ -60,6 +61,17 @@ export const TrAttachment: FunctionComponent<{
60
61
  const componentType = attachmentType(link.contentType);
61
62
  const isValidComponentType = !["archive", null].includes(componentType.type as string);
62
63
 
64
+ const expandAttachment = (event: Event) => {
65
+ event.stopPropagation();
66
+ if (componentType.type !== "image") {
67
+ return;
68
+ }
69
+ openModal({
70
+ data: item,
71
+ component: <Attachment item={item} previewable={true} />,
72
+ });
73
+ };
74
+
63
75
  return (
64
76
  <div data-testid={"test-result-attachment"} className={styles["test-result-step"]}>
65
77
  <div
@@ -96,7 +108,7 @@ export const TrAttachment: FunctionComponent<{
96
108
  </div>
97
109
  {isOpened && isValidComponentType && (
98
110
  <div className={styles["test-result-attachment-content-wrapper"]}>
99
- <div className={styles["test-result-attachment-content"]}>
111
+ <div className={styles["test-result-attachment-content"]} role={"button"} onClick={expandAttachment}>
100
112
  <Attachment item={item} />
101
113
  </div>
102
114
  </div>
@@ -1,5 +1,5 @@
1
- import type { DefaultTestStepResult, TestStepResult } from "@allurereport/core-api";
2
- import { ArrowButton, Code, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
1
+ import type { DefaultTestStepResult, TestStatus, TestStepResult } from "@allurereport/core-api";
2
+ import { ArrowButton, Code, SvgIcon, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
3
3
  import type { FunctionComponent } from "preact";
4
4
  import { useState } from "preact/hooks";
5
5
  import { MetadataList } from "@/components/Metadata";
@@ -19,13 +19,14 @@ export const TrStepParameters = (props: { parameters: DefaultTestStepResult["par
19
19
  </div>
20
20
  );
21
21
  };
22
+
22
23
  export const TrStepsContent = (props: { item: DefaultTestStepResult }) => {
23
24
  const { item } = props;
24
25
 
25
26
  return (
26
27
  <div data-testid={"test-result-step-content"} className={styles["test-result-step-content"]}>
27
28
  {Boolean(item?.parameters?.length) && <TrStepParameters parameters={item.parameters} />}
28
- {Boolean(item?.message && item?.trace) && <TrError {...item} />}
29
+ {Boolean(item?.message && item?.trace && !item?.hasSimilarErrorInSubSteps) && <TrError {...item} />}
29
30
  {Boolean(item?.steps?.length) && (
30
31
  <>
31
32
  {item.steps?.map((subItem, key) => {