@allurereport/web-awesome 3.3.0 → 3.4.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.
Files changed (209) hide show
  1. package/dist/multi/173.app-648d4a8e7d5405e104a1.js +1 -0
  2. package/dist/multi/174.app-648d4a8e7d5405e104a1.js +1 -0
  3. package/dist/multi/252.app-648d4a8e7d5405e104a1.js +1 -0
  4. package/dist/multi/282.app-648d4a8e7d5405e104a1.js +1 -0
  5. package/dist/multi/29.app-648d4a8e7d5405e104a1.js +1 -0
  6. package/dist/multi/310.app-648d4a8e7d5405e104a1.js +1 -0
  7. package/dist/multi/416.app-648d4a8e7d5405e104a1.js +1 -0
  8. package/dist/multi/507.app-648d4a8e7d5405e104a1.js +1 -0
  9. package/dist/multi/527.app-648d4a8e7d5405e104a1.js +1 -0
  10. package/dist/multi/600.app-648d4a8e7d5405e104a1.js +1 -0
  11. package/dist/multi/605.app-648d4a8e7d5405e104a1.js +1 -0
  12. package/dist/multi/638.app-648d4a8e7d5405e104a1.js +1 -0
  13. package/dist/multi/672.app-648d4a8e7d5405e104a1.js +1 -0
  14. package/dist/multi/686.app-648d4a8e7d5405e104a1.js +1 -0
  15. package/dist/multi/725.app-648d4a8e7d5405e104a1.js +1 -0
  16. package/dist/multi/741.app-648d4a8e7d5405e104a1.js +1 -0
  17. package/dist/multi/749.app-648d4a8e7d5405e104a1.js +1 -0
  18. package/dist/multi/755.app-648d4a8e7d5405e104a1.js +1 -0
  19. package/dist/multi/{894.app-8be6acc0a596a2197dbf.js → 894.app-648d4a8e7d5405e104a1.js} +1 -1
  20. package/dist/multi/943.app-648d4a8e7d5405e104a1.js +1 -0
  21. package/dist/multi/980.app-648d4a8e7d5405e104a1.js +1 -0
  22. package/dist/multi/app-648d4a8e7d5405e104a1.js +2 -0
  23. package/dist/multi/{app-8be6acc0a596a2197dbf.js.LICENSE.txt → app-648d4a8e7d5405e104a1.js.LICENSE.txt} +1 -1
  24. package/dist/multi/manifest.json +23 -21
  25. package/dist/multi/{styles-0b84e1ef76554ad2db9a.css → styles-b72a0161ddf41447b31c.css} +10 -10
  26. package/dist/single/app-ae966ad3dc27579d6c39.js +2 -0
  27. package/dist/single/{app-8221eb856e47b4ef50d6.js.LICENSE.txt → app-ae966ad3dc27579d6c39.js.LICENSE.txt} +1 -1
  28. package/dist/single/manifest.json +1 -1
  29. package/package.json +18 -36
  30. package/src/components/BaseLayout/index.tsx +2 -0
  31. package/src/components/Categories/CategoriesTree/index.tsx +2 -0
  32. package/src/components/Categories/CategoryHeaderItem/index.tsx +2 -0
  33. package/src/components/Categories/CategoryTreeItem/index.tsx +2 -0
  34. package/src/components/Categories/GroupTreeItem/index.tsx +2 -0
  35. package/src/components/Categories/HistoryTreeItem/index.tsx +2 -0
  36. package/src/components/Categories/LabelTreeItem/index.tsx +2 -0
  37. package/src/components/Categories/MessageTreeItem/index.tsx +2 -0
  38. package/src/components/Categories/SeverityTreeItem/index.tsx +2 -0
  39. package/src/components/Charts/index.tsx +3 -0
  40. package/src/components/EnvironmentPicker/index.tsx +78 -18
  41. package/src/components/EnvironmentPicker/styles.scss +19 -0
  42. package/src/components/Footer/FooterLogo.tsx +1 -0
  43. package/src/components/Footer/FooterVersion.tsx +2 -0
  44. package/src/components/Footer/index.tsx +3 -1
  45. package/src/components/Header/CiInfo/index.tsx +17 -3
  46. package/src/components/Header/index.tsx +3 -0
  47. package/src/components/Header/styles.scss +1 -0
  48. package/src/components/HeaderControls/index.tsx +1 -0
  49. package/src/components/MainReport/index.tsx +3 -0
  50. package/src/components/Metadata/index.tsx +2 -0
  51. package/src/components/MetadataButton/index.tsx +35 -8
  52. package/src/components/MetadataButton/styles.scss +20 -0
  53. package/src/components/Modal/index.tsx +2 -0
  54. package/src/components/NavTabs/index.tsx +2 -1
  55. package/src/components/ReportBody/HeaderActions.tsx +1 -0
  56. package/src/components/ReportBody/SortBy.tsx +2 -0
  57. package/src/components/ReportBody/index.tsx +4 -1
  58. package/src/components/ReportCategories/index.tsx +2 -0
  59. package/src/components/ReportFilters/BaseFilters.tsx +2 -0
  60. package/src/components/ReportFilters/CategoriesFilter.tsx +2 -0
  61. package/src/components/ReportFilters/RetryFlaky.tsx +2 -0
  62. package/src/components/ReportFilters/TagsFilter.tsx +2 -0
  63. package/src/components/ReportFilters/TransitionFilter.tsx +2 -0
  64. package/src/components/ReportFilters/index.tsx +3 -0
  65. package/src/components/ReportGlobalAttachments/index.tsx +3 -0
  66. package/src/components/ReportGlobalErrors/index.tsx +2 -0
  67. package/src/components/ReportHeader/ReportHeaderLabelList.tsx +1 -0
  68. package/src/components/ReportHeader/ReportHeaderLogo.tsx +3 -1
  69. package/src/components/ReportHeader/ReportHeaderPie.tsx +2 -0
  70. package/src/components/ReportHeader/index.tsx +2 -0
  71. package/src/components/ReportMetadata/MetadataItem.tsx +1 -0
  72. package/src/components/ReportMetadata/MetadataSummary.tsx +3 -1
  73. package/src/components/ReportMetadata/MetadataTestType.tsx +2 -0
  74. package/src/components/ReportMetadata/MetadataWithIcon.tsx +2 -0
  75. package/src/components/ReportMetadata/index.tsx +61 -17
  76. package/src/components/ReportQualityGateResults/index.tsx +6 -2
  77. package/src/components/ReportSearch/index.tsx +1 -0
  78. package/src/components/ReportTabs/index.tsx +3 -0
  79. package/src/components/SectionPicker/index.tsx +2 -0
  80. package/src/components/SectionSwitcher/index.tsx +3 -0
  81. package/src/components/SideBySide/index.tsx +1 -0
  82. package/src/components/SplitLayout/index.tsx +2 -0
  83. package/src/components/TestResult/TestStepsEmpty/index.tsx +2 -0
  84. package/src/components/TestResult/TrAttachmentsView/index.tsx +2 -0
  85. package/src/components/TestResult/TrDescription/index.tsx +16 -3
  86. package/src/components/TestResult/TrDropdown/index.tsx +1 -0
  87. package/src/components/TestResult/TrEmpty/index.tsx +3 -1
  88. package/src/components/TestResult/TrEnvironmentItem/index.tsx +3 -0
  89. package/src/components/TestResult/TrEnvironmentsView/index.tsx +8 -2
  90. package/src/components/TestResult/TrError/TrDiff.tsx +3 -1
  91. package/src/components/TestResult/TrError/index.tsx +20 -18
  92. package/src/components/TestResult/TrError/styles.scss +0 -25
  93. package/src/components/TestResult/TrHeader/TrBreadcrumbs.tsx +3 -1
  94. package/src/components/TestResult/TrHeader/index.tsx +2 -0
  95. package/src/components/TestResult/TrHeader/styles.scss +1 -0
  96. package/src/components/TestResult/TrHistory/TrHistoryItem.tsx +3 -1
  97. package/src/components/TestResult/TrHistory/index.tsx +2 -0
  98. package/src/components/TestResult/TrInfo/TrInfoStatuses.tsx +2 -0
  99. package/src/components/TestResult/TrInfo/index.tsx +2 -0
  100. package/src/components/TestResult/TrLinks/index.tsx +63 -11
  101. package/src/components/TestResult/TrMetadata/index.tsx +44 -5
  102. package/src/components/TestResult/TrNavigation/index.tsx +2 -0
  103. package/src/components/TestResult/TrOverview.tsx +20 -17
  104. package/src/components/TestResult/TrParameters/index.tsx +41 -7
  105. package/src/components/TestResult/TrPrevStatuses/index.tsx +2 -0
  106. package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +44 -9
  107. package/src/components/TestResult/TrPwTraces/index.tsx +5 -1
  108. package/src/components/TestResult/TrPwTraces/openPwTraceInNewTab.ts +29 -0
  109. package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +3 -1
  110. package/src/components/TestResult/TrRetriesView/index.tsx +2 -0
  111. package/src/components/TestResult/TrSetup/index.tsx +3 -1
  112. package/src/components/TestResult/TrSeverity/index.tsx +2 -0
  113. package/src/components/TestResult/TrStatus/index.tsx +2 -0
  114. package/src/components/TestResult/TrSteps/TrAttachment.tsx +38 -6
  115. package/src/components/TestResult/TrSteps/TrAttachmentInfo.tsx +50 -2
  116. package/src/components/TestResult/TrSteps/TrBodyItems.tsx +42 -0
  117. package/src/components/TestResult/TrSteps/TrErrorStep.tsx +40 -0
  118. package/src/components/TestResult/TrSteps/TrStep.tsx +31 -65
  119. package/src/components/TestResult/TrSteps/TrStepHeader.tsx +50 -0
  120. package/src/components/TestResult/TrSteps/TrStepInfo.tsx +1 -0
  121. package/src/components/TestResult/TrSteps/index.tsx +12 -32
  122. package/src/components/TestResult/TrSteps/styles.scss +8 -0
  123. package/src/components/TestResult/TrSteps/wrongAttachment.tsx +2 -1
  124. package/src/components/TestResult/TrTabs/index.tsx +1 -0
  125. package/src/components/TestResult/TrTeardown/index.tsx +3 -1
  126. package/src/components/TestResult/bodyItems.ts +151 -0
  127. package/src/components/TestResult/index.tsx +2 -0
  128. package/src/components/Timeline/index.tsx +12 -2
  129. package/src/components/ToggleLayout/index.tsx +1 -0
  130. package/src/components/Tree/index.tsx +6 -2
  131. package/src/components/Tree/styles.scss +11 -0
  132. package/src/index.tsx +9 -3
  133. package/src/locales/ar.json +427 -0
  134. package/src/locales/az.json +43 -46
  135. package/src/locales/de.json +5 -0
  136. package/src/locales/en.json +5 -0
  137. package/src/locales/es.json +5 -0
  138. package/src/locales/fr.json +5 -0
  139. package/src/locales/he.json +5 -0
  140. package/src/locales/hy.json +5 -0
  141. package/src/locales/it.json +5 -0
  142. package/src/locales/ja.json +5 -0
  143. package/src/locales/ka.json +5 -0
  144. package/src/locales/kr.json +5 -0
  145. package/src/locales/nl.json +5 -0
  146. package/src/locales/pl.json +5 -0
  147. package/src/locales/pt.json +5 -0
  148. package/src/locales/ru.json +5 -0
  149. package/src/locales/sv.json +5 -0
  150. package/src/locales/tr.json +5 -0
  151. package/src/locales/uk.json +5 -0
  152. package/src/locales/zh-TW.json +432 -0
  153. package/src/locales/zh.json +5 -0
  154. package/src/stores/categories.ts +1 -0
  155. package/src/stores/chart.ts +2 -1
  156. package/src/stores/env.ts +14 -4
  157. package/src/stores/envInfo.ts +1 -0
  158. package/src/stores/globals.ts +1 -0
  159. package/src/stores/locale.ts +1 -0
  160. package/src/stores/qualityGate.ts +1 -0
  161. package/src/stores/sections.ts +1 -0
  162. package/src/stores/stats.ts +12 -6
  163. package/src/stores/testResult.ts +1 -0
  164. package/src/stores/testResults.ts +1 -0
  165. package/src/stores/timeline.ts +2 -0
  166. package/src/stores/tree.ts +2 -0
  167. package/src/stores/treeFilters/actions.ts +1 -0
  168. package/src/stores/treeFilters/store.ts +1 -0
  169. package/src/stores/treeFilters/utils.ts +1 -0
  170. package/src/stores/variables.ts +1 -0
  171. package/src/utils/time.ts +1 -0
  172. package/src/utils/treeFilters.ts +2 -0
  173. package/test/components/EnvironmentPicker.test.tsx +133 -0
  174. package/test/components/Header/CiInfo.test.tsx +15 -0
  175. package/test/components/Header.test.tsx +1 -0
  176. package/test/components/TestResult/PwTraceButton.test.tsx +104 -0
  177. package/test/components/TestResult/TrErrorStep.test.tsx +127 -0
  178. package/test/components/TestResult/TrOverview.test.tsx +114 -0
  179. package/test/components/TestResult/bodyItems.test.ts +194 -0
  180. package/test/components/TestResult/openPwTraceInNewTab.test.ts +65 -0
  181. package/test/components/Timeline.test.tsx +104 -0
  182. package/test/stores/treeFilters/actions.test.ts +82 -0
  183. package/test/utils/ownerAddress.test.ts +1 -0
  184. package/test/utils/treeFilters.test.ts +1 -0
  185. package/tsconfig.json +1 -2
  186. package/tsconfig.node.json +2 -1
  187. package/types.d.ts +2 -0
  188. package/.eslintrc.cjs +0 -18
  189. package/dist/multi/173.app-8be6acc0a596a2197dbf.js +0 -1
  190. package/dist/multi/174.app-8be6acc0a596a2197dbf.js +0 -1
  191. package/dist/multi/252.app-8be6acc0a596a2197dbf.js +0 -1
  192. package/dist/multi/282.app-8be6acc0a596a2197dbf.js +0 -1
  193. package/dist/multi/29.app-8be6acc0a596a2197dbf.js +0 -1
  194. package/dist/multi/416.app-8be6acc0a596a2197dbf.js +0 -1
  195. package/dist/multi/527.app-8be6acc0a596a2197dbf.js +0 -1
  196. package/dist/multi/600.app-8be6acc0a596a2197dbf.js +0 -1
  197. package/dist/multi/605.app-8be6acc0a596a2197dbf.js +0 -1
  198. package/dist/multi/638.app-8be6acc0a596a2197dbf.js +0 -1
  199. package/dist/multi/672.app-8be6acc0a596a2197dbf.js +0 -1
  200. package/dist/multi/686.app-8be6acc0a596a2197dbf.js +0 -1
  201. package/dist/multi/725.app-8be6acc0a596a2197dbf.js +0 -1
  202. package/dist/multi/741.app-8be6acc0a596a2197dbf.js +0 -1
  203. package/dist/multi/749.app-8be6acc0a596a2197dbf.js +0 -1
  204. package/dist/multi/755.app-8be6acc0a596a2197dbf.js +0 -1
  205. package/dist/multi/943.app-8be6acc0a596a2197dbf.js +0 -1
  206. package/dist/multi/980.app-8be6acc0a596a2197dbf.js +0 -1
  207. package/dist/multi/app-8be6acc0a596a2197dbf.js +0 -2
  208. package/dist/single/app-8221eb856e47b4ef50d6.js +0 -2
  209. package/src/components/TestResult/TrPwTraces/PwTrace.tsx +0 -34
@@ -3,10 +3,12 @@ import { Loadable } from "@allurereport/web-components";
3
3
  import type { FunctionalComponent } from "preact";
4
4
  import { useEffect } from "preact/hooks";
5
5
  import type { AwesomeTestResult } from "types";
6
+
6
7
  import { TrEnvironmentItem } from "@/components/TestResult/TrEnvironmentItem";
7
8
  import { useI18n } from "@/stores";
8
- import { testEnvGroupsStore } from "@/stores/env";
9
+ import { environmentNameById, testEnvGroupsStore } from "@/stores/env";
9
10
  import { fetchTestResult, testResultStore } from "@/stores/testResults";
11
+
10
12
  import * as styles from "./styles.scss";
11
13
 
12
14
  export const TrEnvironmentSection: FunctionalComponent<{
@@ -50,7 +52,11 @@ export const TrEnvironmentsView: FunctionalComponent<{
50
52
  {envs.map(([env, trId]) => {
51
53
  return (
52
54
  <li key={`${env}-${trId}`}>
53
- <TrEnvironmentSection env={env} testResultId={trId} activeTestResultId={testResult.id} />
55
+ <TrEnvironmentSection
56
+ env={environmentNameById(env)}
57
+ testResultId={trId}
58
+ activeTestResultId={testResult.id}
59
+ />
54
60
  </li>
55
61
  );
56
62
  })}
@@ -2,9 +2,11 @@ import { Button, Code, CodeViewer } from "@allurereport/web-components";
2
2
  import type { Change } from "diff";
3
3
  import { diffChars, diffLines, diffWords } from "diff";
4
4
  import { useState } from "preact/hooks";
5
- import * as styles from "@/components/TestResult/TrError/styles.scss";
5
+
6
6
  import { useI18n } from "@/stores";
7
7
 
8
+ import * as styles from "@/components/TestResult/TrError/styles.scss";
9
+
8
10
  const diffFunctions = {
9
11
  chars: diffChars,
10
12
  words: diffWords,
@@ -4,10 +4,13 @@ import { Button, Code, IconButton, Text, TooltipWrapper, allureIcons } from "@al
4
4
  import clsx from "clsx";
5
5
  import { type FunctionalComponent } from "preact";
6
6
  import { useState } from "preact/hooks";
7
+
8
+ import { hasErrorDiff } from "@/components/TestResult/bodyItems";
7
9
  import { TrDiff } from "@/components/TestResult/TrError/TrDiff";
8
10
  import { useI18n } from "@/stores/locale";
9
11
  import { openModal } from "@/stores/modal";
10
12
  import { copyToClipboard } from "@/utils/copyToClipboard";
13
+
11
14
  import * as styles from "./styles.scss";
12
15
 
13
16
  const TrErrorTrace = ({ trace }: { trace: string }) => {
@@ -34,29 +37,28 @@ const TrErrorTrace = ({ trace }: { trace: string }) => {
34
37
  );
35
38
  };
36
39
 
37
- export const TrError: FunctionalComponent<TestError & { className?: string; status?: TestStatus }> = ({
38
- className,
39
- message = "",
40
- trace,
41
- actual,
42
- expected,
43
- status,
44
- ...rest
45
- }) => {
40
+ export const TrError: FunctionalComponent<
41
+ TestError & { className?: string; status?: TestStatus; showMessage?: boolean }
42
+ > = ({ className, message = "", trace, actual, expected, status, showMessage = true, ...rest }) => {
46
43
  const [isOpen, setIsOpen] = useState(false);
47
44
  const { t } = useI18n("ui");
48
45
  const { t: tooltip } = useI18n("controls");
49
46
  const { t: empty } = useI18n("empty");
47
+ const hasTrace = Boolean(trace?.length);
48
+ const hasDiff = hasErrorDiff({ actual, expected });
50
49
  const openDiff = () =>
51
50
  openModal({
52
51
  title: tooltip("comparison"),
53
52
  data: { actual, expected },
54
53
  component: <TrDiff actual={actual} expected={expected} />,
55
54
  });
56
- const sanitizedMessage = ansiToHTML(message, {
57
- fg: "var(--on-text-primary)",
58
- colors: {},
59
- });
55
+ const sanitizedMessage =
56
+ showMessage && message
57
+ ? ansiToHTML(message, {
58
+ fg: "var(--on-text-primary)",
59
+ colors: {},
60
+ })
61
+ : "";
60
62
 
61
63
  return (
62
64
  <div
@@ -64,7 +66,7 @@ export const TrError: FunctionalComponent<TestError & { className?: string; stat
64
66
  className={clsx(styles["test-result-error"], styles[`tr-status-${status}`], className)}
65
67
  {...rest}
66
68
  >
67
- {message ? (
69
+ {showMessage && message ? (
68
70
  <>
69
71
  <div data-testid="test-result-error-header" className={styles["test-result-error-header"]}>
70
72
  <Text
@@ -93,10 +95,10 @@ export const TrError: FunctionalComponent<TestError & { className?: string; stat
93
95
  </Code>
94
96
  </div>
95
97
  </>
96
- ) : (
98
+ ) : showMessage ? (
97
99
  empty("no-message-provided")
98
- )}
99
- {Boolean(actual && actual !== "undefined" && expected && expected !== "undefined") && (
100
+ ) : null}
101
+ {hasDiff && (
100
102
  <Button
101
103
  style={"flat"}
102
104
  data-testId={"test-result-diff-button"}
@@ -105,7 +107,7 @@ export const TrError: FunctionalComponent<TestError & { className?: string; stat
105
107
  onClick={openDiff}
106
108
  />
107
109
  )}
108
- {isOpen && Boolean(trace?.length) && <TrErrorTrace trace={trace} />}
110
+ {(isOpen || !showMessage) && hasTrace && <TrErrorTrace trace={trace} />}
109
111
  </div>
110
112
  );
111
113
  };
@@ -13,8 +13,6 @@
13
13
  position: absolute;
14
14
  left: 0;
15
15
  top: 0;
16
- //background: var(--on-support-capella);
17
- //background: var(--on-support-capella);
18
16
  }
19
17
  }
20
18
 
@@ -85,29 +83,6 @@
85
83
  color: var(--on-support-skat);
86
84
  }
87
85
 
88
- .tr-bg-failed {
89
- background: var(--bg-support-capella);
90
- }
91
-
92
- .tr-bg-broken {
93
- background: var(--bg-support-atlas);
94
- }
95
-
96
- .tr-bg-skipped {
97
- background: var(--bg-support-rau);
98
- }
99
-
100
- .tr-bg-passed {
101
- background: var(--bg-support-castor);
102
- }
103
-
104
- .tr-bg-failed {
105
- background: var(--bg-support-capella);
106
- }
107
- .tr-bg-unknown {
108
- background: var(--bg-support-skat);
109
- }
110
-
111
86
  .test-result-error-trace {
112
87
  margin-top: 8px;
113
88
  padding-left: 8px;
@@ -1,9 +1,11 @@
1
1
  import { IconButton, SvgIcon, Text, allureIcons } from "@allurereport/web-components";
2
2
  import clsx from "clsx";
3
3
  import type { AwesomeTestResult } from "types";
4
- import * as styles from "@/components/TestResult/TrHeader/styles.scss";
4
+
5
5
  import { navigateToRoot } from "@/stores/router";
6
6
 
7
+ import * as styles from "@/components/TestResult/TrHeader/styles.scss";
8
+
7
9
  interface TrBreadcrumbs {
8
10
  testResult?: AwesomeTestResult;
9
11
  }
@@ -1,8 +1,10 @@
1
1
  import type { FunctionalComponent } from "preact";
2
+
2
3
  import { HeaderControls } from "@/components/HeaderControls";
3
4
  import type { TrProps } from "@/components/TestResult";
4
5
  import { TrBreadcrumbs } from "@/components/TestResult/TrHeader/TrBreadcrumbs";
5
6
  import { isSplitMode } from "@/stores/layout";
7
+
6
8
  import * as styles from "./styles.scss";
7
9
 
8
10
  export const TrHeader: FunctionalComponent<TrProps> = ({ testResult }) => {
@@ -42,6 +42,7 @@
42
42
  margin-left: auto;
43
43
  display: flex;
44
44
  gap: 4px;
45
+ min-width: 0;
45
46
  }
46
47
  .test-result-breadcrumb-arrow {
47
48
  transform: rotate(-90deg);
@@ -4,11 +4,13 @@ import { ArrowButton, IconButton, Text, TooltipWrapper, TreeItemIcon, allureIcon
4
4
  import { type FunctionalComponent } from "preact";
5
5
  import { useMemo, useState } from "preact/hooks";
6
6
  import type { AwesomeReportOptions } from "types";
7
+
7
8
  import { TrError } from "@/components/TestResult/TrError";
8
- import * as styles from "@/components/TestResult/TrHistory/styles.scss";
9
9
  import { useI18n } from "@/stores";
10
10
  import { timestampToDate } from "@/utils/time";
11
11
 
12
+ import * as styles from "@/components/TestResult/TrHistory/styles.scss";
13
+
12
14
  type Props = {
13
15
  historyTr: HistoryTestResult;
14
16
  };
@@ -1,8 +1,10 @@
1
1
  import { EmptyView } from "@allurereport/web-components";
2
2
  import type { FunctionalComponent } from "preact";
3
+
3
4
  import { type AwesomeTestResult } from "@/../types";
4
5
  import { TrHistoryItem } from "@/components/TestResult/TrHistory/TrHistoryItem";
5
6
  import { useI18n } from "@/stores";
7
+
6
8
  import * as styles from "./styles.scss";
7
9
 
8
10
  export type TrHistoryViewProps = {
@@ -1,7 +1,9 @@
1
1
  import { capitalize } from "@allurereport/core-api";
2
2
  import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
3
3
  import { type FunctionalComponent } from "preact";
4
+
4
5
  import { useI18n } from "@/stores";
6
+
5
7
  import * as styles from "./styles.scss";
6
8
 
7
9
  const icons: Record<string, string> = {
@@ -4,6 +4,7 @@ import { Counter, Heading, Loadable, Text, TooltipWrapper } from "@allurereport/
4
4
  import clsx from "clsx";
5
5
  import type { FunctionalComponent } from "preact";
6
6
  import type { AwesomeTestResult } from "types";
7
+
7
8
  import { TrInfoStatuses } from "@/components/TestResult/TrInfo/TrInfoStatuses";
8
9
  import { TrNavigation } from "@/components/TestResult/TrNavigation";
9
10
  import { TrPrevStatuses } from "@/components/TestResult/TrPrevStatuses";
@@ -14,6 +15,7 @@ import { testEnvGroupsStore } from "@/stores/env";
14
15
  import { isSplitMode } from "@/stores/layout";
15
16
  import { useI18n } from "@/stores/locale";
16
17
  import { timestampToDate } from "@/utils/time";
18
+
17
19
  import * as styles from "./styles.scss";
18
20
 
19
21
  export type TrInfoProps = {
@@ -1,11 +1,17 @@
1
- import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
1
+ import { sanitizeExternalUrl } from "@allurereport/core-api";
2
+ import { Button, SvgIcon, Text, allureIcons } from "@allurereport/web-components";
2
3
  import type { FunctionalComponent } from "preact";
3
- import { useState } from "preact/hooks";
4
- import type { AwesomeTestResult } from "types";
4
+
5
5
  import { MetadataButton } from "@/components/MetadataButton";
6
6
  import { useI18n } from "@/stores/locale";
7
+ import { collapsedTrees, toggleTree } from "@/stores/tree";
8
+
9
+ import { AwesomeTestResult } from "../../../../types";
10
+
7
11
  import * as styles from "./styles.scss";
8
12
 
13
+ const VISIBLE_LINKS_LIMIT = 8;
14
+
9
15
  interface TrLinkProps {
10
16
  name: string;
11
17
  url: string;
@@ -23,33 +29,79 @@ const TrLink: FunctionalComponent<{
23
29
  link: TrLinkProps;
24
30
  }> = ({ link }) => {
25
31
  const { url, name, type } = link;
32
+ const safeUrl = sanitizeExternalUrl(url);
33
+ const label = name || url;
26
34
 
27
35
  return (
28
36
  <div className={styles["test-result-link"]} data-testid="test-result-meta-link">
29
37
  <SvgIcon id={linksIconMap[type] ?? allureIcons.lineGeneralLink1} />
30
- <Text tag={"a"} href={url} target={"_blank"} size={"m"} className={styles["test-result-link-text"]}>
31
- {name || url}
32
- </Text>
38
+ {safeUrl ? (
39
+ <Text
40
+ tag={"a"}
41
+ href={safeUrl}
42
+ target={"_blank"}
43
+ rel={"noopener noreferrer"}
44
+ size={"m"}
45
+ className={styles["test-result-link-text"]}
46
+ >
47
+ {label}
48
+ </Text>
49
+ ) : (
50
+ <Text size={"m"} className={styles["test-result-link-text"]}>
51
+ {label}
52
+ </Text>
53
+ )}
33
54
  </div>
34
55
  );
35
56
  };
36
57
 
37
58
  export type TrLinksProps = {
59
+ id?: string;
38
60
  links: AwesomeTestResult["links"];
39
61
  };
40
62
 
41
- export const TrLinks: FunctionalComponent<TrLinksProps> = ({ links }) => {
42
- const [isOpened, setIsOpen] = useState(true);
63
+ export const TrLinks: FunctionalComponent<TrLinksProps> = ({ id, links }) => {
43
64
  const { t } = useI18n("ui");
44
- const linkMap = links.map((link, index) => {
65
+ const linksId = id !== null ? `${id}-links` : null;
66
+ const linksShowAllId = id !== null ? `${id}-links-showAll` : null;
67
+ const isOpened = !collapsedTrees.value.has(linksId);
68
+ const showAll = collapsedTrees.value.has(linksShowAllId);
69
+ const visibleLinks =
70
+ links.length <= VISIBLE_LINKS_LIMIT ? links : showAll ? links : links.slice(0, VISIBLE_LINKS_LIMIT);
71
+ const linkMap = visibleLinks.map((link, index) => {
45
72
  return <TrLink link={link as TrLinkProps} key={index} />;
46
73
  });
47
74
 
48
75
  return (
49
76
  <div className={styles["test-result-links"]} data-testid="test-result-meta-links">
50
77
  <div className={styles["test-result-links-wrapper"]}>
51
- <MetadataButton isOpened={isOpened} setIsOpen={setIsOpen} counter={links.length} title={t("links")} />
52
- {isOpened && <div className={styles["test-result-links-list"]}>{linkMap}</div>}
78
+ <MetadataButton
79
+ isOpened={isOpened}
80
+ setIsOpen={() => {
81
+ if (linksId !== null) {
82
+ toggleTree(linksId);
83
+ }
84
+ }}
85
+ counter={links.length}
86
+ title={t("links")}
87
+ />
88
+ {isOpened && (
89
+ <>
90
+ <div className={styles["test-result-links-list"]}>{linkMap}</div>
91
+ {links.length > VISIBLE_LINKS_LIMIT && (
92
+ <Button
93
+ style="ghost"
94
+ size="s"
95
+ text={showAll ? t("showLess") : t("showMore")}
96
+ onClick={() => {
97
+ if (linksShowAllId !== null) {
98
+ toggleTree(linksShowAllId);
99
+ }
100
+ }}
101
+ />
102
+ )}
103
+ </>
104
+ )}
53
105
  </div>
54
106
  </div>
55
107
  );
@@ -1,26 +1,65 @@
1
+ import { Button } from "@allurereport/web-components";
1
2
  import type { FunctionalComponent } from "preact";
2
- import { useState } from "preact/hooks";
3
3
  import type { AwesomeTestResult } from "types";
4
+
4
5
  import { TrMetadataList } from "@/components/Metadata";
5
6
  import { MetadataButton } from "@/components/MetadataButton";
6
7
  import { useI18n } from "@/stores/locale";
8
+ import { collapsedTrees, toggleTree } from "@/stores/tree";
9
+
7
10
  import * as styles from "./styles.scss";
8
11
 
12
+ const VISIBLE_LABELS_LIMIT = 8;
13
+
9
14
  export type TrMetadataProps = {
15
+ id?: string;
10
16
  testResult?: AwesomeTestResult;
11
17
  };
12
18
 
13
- export const TrMetadata: FunctionalComponent<TrMetadataProps> = ({ testResult }) => {
19
+ export const TrMetadata: FunctionalComponent<TrMetadataProps> = ({ id, testResult }) => {
14
20
  const { t } = useI18n("ui");
15
21
  const { labels, groupedLabels } = testResult ?? {};
16
- const [isOpened, setIsOpened] = useState(true);
22
+ const labelsId = id !== null ? `${id}-labels` : null;
23
+ const labelsShowAllId = id !== null ? `${id}-labels-showAll` : null;
24
+ const isOpened = !collapsedTrees.value.has(labelsId);
25
+ const entries = groupedLabels ? Object.entries(groupedLabels) : [];
26
+ const showAll = collapsedTrees.value.has(labelsShowAllId);
27
+ const visibleEntries = showAll ? entries : entries.slice(0, VISIBLE_LABELS_LIMIT);
28
+ const groupedLabelsVisible = Object.fromEntries(visibleEntries);
29
+
30
+ const handleToggleShowAll = () => {
31
+ if (labelsShowAllId !== null) {
32
+ toggleTree(labelsShowAllId);
33
+ }
34
+ };
17
35
 
18
36
  return (
19
37
  <div className={styles["test-result-metadata"]}>
20
- <MetadataButton isOpened={isOpened} setIsOpen={setIsOpened} counter={labels?.length} title={t("labels")} />
38
+ <MetadataButton
39
+ isOpened={isOpened}
40
+ setIsOpen={() => {
41
+ if (labelsId !== null) {
42
+ toggleTree(labelsId);
43
+ }
44
+ }}
45
+ counter={labels?.length}
46
+ title={t("labels")}
47
+ />
21
48
 
22
49
  <div className={styles["test-result-metadata-wrapper"]}>
23
- {isOpened && <TrMetadataList groupedLabels={groupedLabels} />}
50
+ {isOpened && (
51
+ <>
52
+ <TrMetadataList groupedLabels={groupedLabelsVisible} />
53
+ {entries.length > VISIBLE_LABELS_LIMIT && (
54
+ <Button
55
+ style="ghost"
56
+ size="s"
57
+ text={showAll ? t("showLess") : t("showMore")}
58
+ onClick={handleToggleShowAll}
59
+ />
60
+ )}
61
+ </>
62
+ )}
24
63
  </div>
25
64
  </div>
26
65
  );
@@ -1,11 +1,13 @@
1
1
  import { Code, IconButton, TooltipWrapper, allureIcons } from "@allurereport/web-components";
2
2
  import { computed, useComputed } from "@preact/signals";
3
3
  import type { AwesomeTestResult } from "types";
4
+
4
5
  import { useI18n } from "@/stores";
5
6
  import { navigateToTestResult } from "@/stores/router";
6
7
  import { trCurrentTab } from "@/stores/testResult";
7
8
  import { testResultNavStore } from "@/stores/testResults";
8
9
  import { copyToClipboard } from "@/utils/copyToClipboard";
10
+
9
11
  import * as styles from "./styles.scss";
10
12
 
11
13
  type Props = {
@@ -1,9 +1,9 @@
1
1
  import type { FunctionalComponent } from "preact";
2
2
  import type { AwesomeTestResult } from "types";
3
- import * as styles from "@/components/BaseLayout/styles.scss";
3
+
4
+ import { getBodyItems } from "@/components/TestResult/bodyItems";
4
5
  import TestStepsEmpty from "@/components/TestResult/TestStepsEmpty";
5
6
  import { TrDescription } from "@/components/TestResult/TrDescription";
6
- import { TrError } from "@/components/TestResult/TrError";
7
7
  import { TrLinks } from "@/components/TestResult/TrLinks";
8
8
  import { TrMetadata } from "@/components/TestResult/TrMetadata";
9
9
  import { TrParameters } from "@/components/TestResult/TrParameters";
@@ -11,36 +11,39 @@ import { TrPwTraces } from "@/components/TestResult/TrPwTraces";
11
11
  import { TrSetup } from "@/components/TestResult/TrSetup";
12
12
  import { TrSteps } from "@/components/TestResult/TrSteps";
13
13
  import { TrTeardown } from "@/components/TestResult/TrTeardown";
14
+ import { useI18n } from "@/stores/locale";
15
+ import { currentTrId } from "@/stores/testResult";
16
+
17
+ import * as styles from "@/components/BaseLayout/styles.scss";
14
18
 
15
19
  export type TrOverviewProps = {
16
20
  testResult?: AwesomeTestResult;
17
21
  };
18
22
 
19
23
  export const TrOverview: FunctionalComponent<TrOverviewProps> = ({ testResult }) => {
20
- const { error, parameters, groupedLabels, links, descriptionHtml, setup, steps, teardown, id, status } =
21
- testResult || {};
22
- const isNoSteps = !setup?.length && !steps.length && !teardown.length;
24
+ const { parameters, groupedLabels, links, descriptionHtml, setup, teardown, id } = testResult || {};
25
+ const testResultId = id ?? currentTrId.value;
26
+ const { t } = useI18n("ui");
27
+ const bodyItems = getBodyItems(testResult, t("error"));
28
+ const isNoSteps = !setup?.length && !bodyItems.length && !teardown?.length;
23
29
  const pwTraces = testResult?.attachments?.filter(
24
30
  (attachment) => attachment.link.contentType === "application/vnd.allure.playwright-trace",
25
31
  );
26
32
 
27
33
  return (
28
34
  <>
29
- {Boolean(error?.message) && (
30
- <div className={styles["test-result-errors"]}>
31
- <TrError {...error} status={status} />
32
- </div>
35
+ {Boolean(pwTraces?.length) && <TrPwTraces pwTraces={pwTraces} />}
36
+ {Boolean(parameters?.length) && <TrParameters id={testResultId} parameters={parameters} />}
37
+ {Boolean(groupedLabels && Object.keys(groupedLabels || {})?.length) && (
38
+ <TrMetadata id={testResultId} testResult={testResult} />
33
39
  )}
34
- {Boolean(pwTraces.length) && <TrPwTraces pwTraces={pwTraces} />}
35
- {Boolean(parameters?.length) && <TrParameters parameters={parameters} />}
36
- {Boolean(groupedLabels && Object.keys(groupedLabels || {})?.length) && <TrMetadata testResult={testResult} />}
37
- {Boolean(links?.length) && <TrLinks links={links} />}
38
- {Boolean(descriptionHtml) && <TrDescription descriptionHtml={descriptionHtml} />}
40
+ {Boolean(links?.length) && <TrLinks id={testResultId} links={links} />}
41
+ {Boolean(descriptionHtml) && <TrDescription id={testResultId} descriptionHtml={descriptionHtml} />}
39
42
  <div className={styles["test-results"]}>
40
43
  {isNoSteps && <TestStepsEmpty />}
41
- {Boolean(setup?.length) && <TrSetup id={id} setup={setup} />}
42
- {Boolean(steps?.length) && <TrSteps id={id} steps={steps} />}
43
- {Boolean(teardown?.length) && <TrTeardown id={id} teardown={teardown} />}
44
+ {Boolean(setup?.length) && <TrSetup id={testResultId} setup={setup} />}
45
+ {Boolean(bodyItems.length) && <TrSteps id={testResultId} bodyItems={bodyItems} />}
46
+ {Boolean(teardown?.length) && <TrTeardown id={testResultId} teardown={teardown} />}
44
47
  </div>
45
48
  </>
46
49
  );
@@ -1,30 +1,64 @@
1
+ import { Button } from "@allurereport/web-components";
1
2
  import type { FunctionalComponent } from "preact";
2
- import { useState } from "preact/hooks";
3
3
  import type { AwesomeTestResult } from "types";
4
+
4
5
  import { MetadataList } from "@/components/Metadata";
5
6
  import { MetadataButton } from "@/components/MetadataButton";
6
7
  import { useI18n } from "@/stores/locale";
8
+ import { collapsedTrees, toggleTree } from "@/stores/tree";
9
+
7
10
  import * as styles from "./styles.scss";
8
11
 
12
+ const PARAMETERS_VISIBLE_LIMIT = 8;
13
+
9
14
  export type TrParametersProps = {
15
+ id?: string;
10
16
  parameters: AwesomeTestResult["parameters"];
11
17
  };
12
18
 
13
- export const TrParameters: FunctionalComponent<TrParametersProps> = ({ parameters }) => {
14
- const [isOpened, setIsOpened] = useState(true);
19
+ export const TrParameters: FunctionalComponent<TrParametersProps> = ({ id, parameters }) => {
15
20
  const { t } = useI18n("ui");
21
+ const parametersId = id !== null ? `${id}-parameters` : null;
22
+ const parametersShowAllId = id !== null ? `${id}-parameters-showAll` : null;
23
+ const isOpened = !collapsedTrees.value.has(parametersId);
24
+ const list = parameters ?? [];
25
+ const totalCount = list.length;
26
+ const showAll = collapsedTrees.value.has(parametersShowAllId);
27
+ const visibleList = showAll ? list : list.slice(0, PARAMETERS_VISIBLE_LIMIT);
16
28
 
17
29
  return (
18
30
  <div className={styles["test-result-metadata"]}>
19
31
  <MetadataButton
20
32
  isOpened={isOpened}
21
- setIsOpen={setIsOpened}
33
+ setIsOpen={() => {
34
+ if (parametersId !== null) {
35
+ toggleTree(parametersId);
36
+ }
37
+ }}
22
38
  counter={parameters?.length}
23
39
  title={t("parameters")}
24
40
  />
25
- {/* FIXME: use proper type in the MetadataList component */}
26
- {/* @ts-ignore */}
27
- <div className={styles["test-result-metadata-wrapper"]}>{isOpened && <MetadataList envInfo={parameters} />}</div>
41
+ <div className={styles["test-result-metadata-wrapper"]}>
42
+ {isOpened && (
43
+ <>
44
+ {/* FIXME: use proper type in the MetadataList component */}
45
+ {/* @ts-ignore */}
46
+ <MetadataList envInfo={visibleList} />
47
+ {totalCount > PARAMETERS_VISIBLE_LIMIT && (
48
+ <Button
49
+ style="ghost"
50
+ size="s"
51
+ text={showAll ? t("showLess") : t("showMore")}
52
+ onClick={() => {
53
+ if (parametersShowAllId !== null) {
54
+ toggleTree(parametersShowAllId);
55
+ }
56
+ }}
57
+ />
58
+ )}
59
+ </>
60
+ )}
61
+ </div>
28
62
  </div>
29
63
  );
30
64
  };
@@ -3,8 +3,10 @@ import { getReportOptions } from "@allurereport/web-commons";
3
3
  import { SvgIcon, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
4
4
  import type { FunctionalComponent } from "preact";
5
5
  import type { AwesomeReportOptions, AwesomeTestResult } from "types";
6
+
6
7
  import { useI18n } from "@/stores";
7
8
  import { timestampToDate } from "@/utils/time";
9
+
8
10
  import * as styles from "./styles.scss";
9
11
 
10
12
  const TrPrevStatus: FunctionalComponent<{ item: HistoryTestResult }> = ({ item }) => {