@allurereport/web-awesome 3.0.0-beta.9 → 3.0.1

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 (290) hide show
  1. package/dist/multi/173.app-bae2a0fe5738d77cd976.js +1 -0
  2. package/dist/multi/174.app-bae2a0fe5738d77cd976.js +1 -0
  3. package/dist/multi/252.app-bae2a0fe5738d77cd976.js +1 -0
  4. package/dist/multi/282.app-bae2a0fe5738d77cd976.js +1 -0
  5. package/dist/multi/29.app-bae2a0fe5738d77cd976.js +1 -0
  6. package/dist/multi/416.app-bae2a0fe5738d77cd976.js +1 -0
  7. package/dist/multi/527.app-bae2a0fe5738d77cd976.js +1 -0
  8. package/dist/multi/600.app-bae2a0fe5738d77cd976.js +1 -0
  9. package/dist/multi/605.app-bae2a0fe5738d77cd976.js +1 -0
  10. package/dist/multi/638.app-bae2a0fe5738d77cd976.js +1 -0
  11. package/dist/multi/672.app-bae2a0fe5738d77cd976.js +1 -0
  12. package/dist/multi/686.app-bae2a0fe5738d77cd976.js +1 -0
  13. package/dist/multi/725.app-bae2a0fe5738d77cd976.js +1 -0
  14. package/dist/multi/741.app-bae2a0fe5738d77cd976.js +1 -0
  15. package/dist/multi/755.app-bae2a0fe5738d77cd976.js +1 -0
  16. package/dist/multi/894.app-bae2a0fe5738d77cd976.js +1 -0
  17. package/dist/multi/91.app-bae2a0fe5738d77cd976.js +1 -0
  18. package/dist/multi/943.app-bae2a0fe5738d77cd976.js +1 -0
  19. package/dist/multi/980.app-bae2a0fe5738d77cd976.js +1 -0
  20. package/dist/multi/app-bae2a0fe5738d77cd976.js +2 -0
  21. package/dist/multi/app-bae2a0fe5738d77cd976.js.LICENSE.txt +10 -0
  22. package/dist/multi/manifest.json +25 -24
  23. package/dist/multi/styles-bbf68b2ba63c38b53c38.css +48 -0
  24. package/dist/single/app-996d3b5869f8fc942b66.js +2 -0
  25. package/dist/single/app-996d3b5869f8fc942b66.js.LICENSE.txt +10 -0
  26. package/dist/single/manifest.json +1 -1
  27. package/package.json +31 -19
  28. package/src/assets/scss/day.scss +2 -0
  29. package/src/assets/scss/index.scss +1 -3
  30. package/src/assets/scss/night.scss +2 -0
  31. package/src/assets/scss/palette.scss +391 -391
  32. package/src/assets/scss/theme.scss +292 -79
  33. package/src/components/BaseLayout/index.tsx +10 -32
  34. package/src/components/BaseLayout/styles.scss +14 -4
  35. package/src/components/Charts/index.tsx +245 -0
  36. package/src/components/Charts/styles.scss +27 -0
  37. package/src/components/EnvironmentPicker/index.tsx +60 -0
  38. package/src/components/EnvironmentPicker/styles.scss +9 -0
  39. package/src/components/Footer/FooterLogo.tsx +1 -2
  40. package/src/components/Footer/FooterVersion.tsx +7 -3
  41. package/src/components/Footer/index.tsx +6 -2
  42. package/src/components/Header/CiInfo/index.tsx +67 -0
  43. package/src/components/Header/CiInfo/styles.scss +7 -0
  44. package/src/components/Header/index.tsx +21 -8
  45. package/src/components/Header/styles.scss +9 -1
  46. package/src/components/HeaderControls/index.tsx +20 -0
  47. package/src/components/MainReport/index.tsx +84 -6
  48. package/src/components/MainReport/styles.scss +20 -0
  49. package/src/components/Metadata/index.tsx +6 -4
  50. package/src/components/MetadataButton/index.tsx +14 -6
  51. package/src/components/MetadataButton/styles.scss +3 -0
  52. package/src/components/Modal/index.tsx +15 -167
  53. package/src/components/NavTabs/index.tsx +70 -0
  54. package/src/components/{TestResult/TestResultTabs → NavTabs}/styles.scss +0 -3
  55. package/src/components/Report/index.tsx +7 -0
  56. package/src/components/ReportBody/Filters.tsx +96 -64
  57. package/src/components/ReportBody/HeaderActions.tsx +2 -2
  58. package/src/components/ReportBody/SortBy.tsx +4 -7
  59. package/src/components/ReportBody/index.tsx +30 -24
  60. package/src/components/ReportBody/styles.scss +9 -3
  61. package/src/components/ReportGlobalAttachments/index.tsx +34 -0
  62. package/src/components/ReportGlobalAttachments/styles.scss +11 -0
  63. package/src/components/ReportGlobalErrors/index.tsx +30 -0
  64. package/src/components/ReportGlobalErrors/styles.scss +12 -0
  65. package/src/components/ReportHeader/ReportHeaderLogo.tsx +6 -2
  66. package/src/components/ReportHeader/ReportHeaderPie.tsx +1 -2
  67. package/src/components/ReportHeader/index.tsx +38 -12
  68. package/src/components/ReportHeader/styles.scss +9 -1
  69. package/src/components/ReportMetadata/MetadataSummary.tsx +57 -65
  70. package/src/components/ReportMetadata/MetadataWithIcon.tsx +11 -13
  71. package/src/components/ReportMetadata/index.tsx +50 -3
  72. package/src/components/ReportMetadata/styles.scss +0 -2
  73. package/src/components/ReportQualityGateResults/index.tsx +42 -0
  74. package/src/components/ReportQualityGateResults/styles.scss +44 -0
  75. package/src/components/ReportTabs/index.tsx +37 -0
  76. package/src/components/SectionPicker/index.tsx +55 -0
  77. package/src/components/SectionPicker/styles.scss +5 -0
  78. package/src/components/SectionSwitcher/index.tsx +16 -0
  79. package/src/components/SectionSwitcher/styles.scss +4 -0
  80. package/src/components/SectionTabs/index.tsx +0 -0
  81. package/src/components/SideBySide/index.tsx +52 -0
  82. package/src/components/SideBySide/styles.scss +64 -0
  83. package/src/components/SplitLayout/index.tsx +71 -0
  84. package/src/components/SplitLayout/styles.scss +84 -0
  85. package/src/components/TestResult/TestStepsEmpty/index.tsx +3 -9
  86. package/src/components/TestResult/TrAttachmentsView/index.tsx +29 -0
  87. package/src/components/TestResult/{TestResultDescription → TrDescription}/index.tsx +5 -5
  88. package/src/components/TestResult/{TestResultDropdown → TrDropdown}/index.tsx +7 -5
  89. package/src/components/TestResult/{TestResultEmpty → TrEmpty}/index.tsx +7 -13
  90. package/src/components/TestResult/TrEnvironmentItem/index.tsx +82 -0
  91. package/src/components/TestResult/TrEnvironmentItem/styles.scss +60 -0
  92. package/src/components/TestResult/TrEnvironmentsView/index.tsx +64 -0
  93. package/src/components/TestResult/TrEnvironmentsView/styles.scss +11 -0
  94. package/src/components/TestResult/TrError/TrDiff.tsx +121 -0
  95. package/src/components/TestResult/TrError/index.tsx +111 -0
  96. package/src/components/TestResult/TrError/styles.scss +223 -0
  97. package/src/components/TestResult/TrHeader/TrBreadcrumbs.tsx +44 -0
  98. package/src/components/TestResult/TrHeader/index.tsx +15 -0
  99. package/src/components/TestResult/{TestResultHeader → TrHeader}/styles.scss +7 -2
  100. package/src/components/TestResult/TrHistory/TrHistoryItem.tsx +94 -0
  101. package/src/components/TestResult/TrHistory/index.tsx +26 -0
  102. package/src/components/TestResult/{TestResultHistory → TrHistory}/styles.scss +2 -1
  103. package/src/components/TestResult/{TestResultInfo/TestResultInfoStatuses.tsx → TrInfo/TrInfoStatuses.tsx} +6 -4
  104. package/src/components/TestResult/TrInfo/index.tsx +99 -0
  105. package/src/components/TestResult/{TestResultInfo → TrInfo}/styles.scss +18 -0
  106. package/src/components/TestResult/{TestResultLinks → TrLinks}/index.tsx +8 -8
  107. package/src/components/TestResult/{TestResultMetadata → TrMetadata}/index.tsx +6 -6
  108. package/src/components/TestResult/{TestResultNavigation → TrNavigation}/index.tsx +7 -9
  109. package/src/components/TestResult/TrOverview.tsx +46 -0
  110. package/src/components/TestResult/{TestResultParameters → TrParameters}/index.tsx +4 -4
  111. package/src/components/TestResult/TrPrevStatuses/index.tsx +63 -0
  112. package/src/components/TestResult/TrPwTraces/PwTrace.tsx +34 -0
  113. package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +32 -0
  114. package/src/components/TestResult/TrPwTraces/index.tsx +32 -0
  115. package/src/components/TestResult/TrPwTraces/styles.scss +20 -0
  116. package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +70 -0
  117. package/src/components/TestResult/TrRetriesView/index.tsx +29 -0
  118. package/src/components/TestResult/{TestResultSetup → TrSetup}/index.tsx +13 -13
  119. package/src/components/TestResult/{TestResultSeverity → TrSeverity}/index.tsx +2 -2
  120. package/src/components/TestResult/{TestResultStatus → TrStatus}/index.tsx +5 -5
  121. package/src/components/TestResult/TrSteps/TrAttachment.tsx +118 -0
  122. package/src/components/TestResult/{TestResultSteps/testResultAttachmentInfo.tsx → TrSteps/TrAttachmentInfo.tsx} +11 -11
  123. package/src/components/TestResult/TrSteps/TrStep.tsx +98 -0
  124. package/src/components/TestResult/TrSteps/TrStepInfo.tsx +90 -0
  125. package/src/components/TestResult/{TestResultSteps → TrSteps}/index.tsx +12 -12
  126. package/src/components/TestResult/{TestResultSteps → TrSteps}/styles.scss +49 -10
  127. package/src/components/TestResult/{TestResultSteps → TrSteps}/wrongAttachment.tsx +1 -1
  128. package/src/components/TestResult/TrTabs/index.tsx +42 -0
  129. package/src/components/TestResult/{TestResultTeardown → TrTeardown}/index.tsx +13 -13
  130. package/src/components/TestResult/index.tsx +54 -38
  131. package/src/components/TestResult/styles.scss +12 -0
  132. package/src/components/Timeline/index.tsx +100 -0
  133. package/src/components/Timeline/styles.scss +45 -0
  134. package/src/components/ToggleLayout/index.tsx +17 -0
  135. package/src/components/Tree/index.tsx +117 -11
  136. package/src/components/Tree/styles.scss +23 -5
  137. package/src/index.html +22 -6
  138. package/src/index.tsx +90 -20
  139. package/src/locales/az.json +378 -0
  140. package/src/locales/de.json +378 -0
  141. package/src/locales/en.json +378 -0
  142. package/src/locales/es.json +378 -0
  143. package/src/locales/fr.json +378 -0
  144. package/src/locales/he.json +378 -0
  145. package/src/locales/hy.json +378 -0
  146. package/src/locales/it.json +378 -0
  147. package/src/locales/ja.json +378 -0
  148. package/src/locales/ka.json +378 -0
  149. package/src/locales/kr.json +378 -0
  150. package/src/locales/nl.json +378 -0
  151. package/src/locales/pl.json +386 -0
  152. package/src/locales/pt.json +378 -0
  153. package/src/locales/ru.json +386 -0
  154. package/src/locales/sv.json +378 -0
  155. package/src/locales/tr.json +378 -0
  156. package/src/locales/ua.json +329 -0
  157. package/src/locales/zh.json +378 -0
  158. package/src/stores/chart.ts +41 -6
  159. package/src/stores/env.ts +88 -0
  160. package/src/stores/envInfo.ts +2 -2
  161. package/src/stores/globals.ts +28 -0
  162. package/src/stores/layout.ts +36 -0
  163. package/src/stores/locale.ts +77 -29
  164. package/src/stores/modal.ts +22 -0
  165. package/src/stores/qualityGate.ts +28 -0
  166. package/src/stores/router.ts +108 -0
  167. package/src/stores/sections.ts +63 -0
  168. package/src/stores/stats.ts +52 -7
  169. package/src/stores/testResults.ts +13 -9
  170. package/src/stores/theme.ts +15 -18
  171. package/src/stores/timeline.ts +39 -0
  172. package/src/stores/tree.ts +65 -110
  173. package/src/stores/treeFilters/actions.ts +67 -0
  174. package/src/stores/treeFilters/constants.ts +7 -0
  175. package/src/stores/treeFilters/index.ts +3 -0
  176. package/src/stores/treeFilters/store.ts +73 -0
  177. package/src/stores/treeFilters/types.ts +12 -0
  178. package/src/stores/variables.ts +40 -0
  179. package/src/styles.scss +66 -0
  180. package/src/utils/persist.ts +23 -0
  181. package/src/utils/time.ts +1 -0
  182. package/src/utils/tree.ts +30 -0
  183. package/src/utils/treeFilters.ts +42 -24
  184. package/test/components/Header/CiInfo.test.tsx +177 -0
  185. package/test/components/Header.test.tsx +122 -0
  186. package/test/stores/treeFilters.test.ts +302 -0
  187. package/test/utils/treeFilters.test.ts +189 -44
  188. package/tsconfig.json +7 -2
  189. package/tsconfig.node.json +8 -0
  190. package/types.d.ts +45 -24
  191. package/vitest.config.ts +15 -2
  192. package/vitest.setup.ts +1 -0
  193. package/webpack.config.js +35 -5
  194. package/dist/multi/141.app-f32e4213.js +0 -1
  195. package/dist/multi/222.app-f32e4213.js +0 -1
  196. package/dist/multi/335.app-f32e4213.js +0 -1
  197. package/dist/multi/34.app-f32e4213.js +0 -1
  198. package/dist/multi/349.app-f32e4213.js +0 -1
  199. package/dist/multi/378.app-f32e4213.js +0 -1
  200. package/dist/multi/406.app-f32e4213.js +0 -1
  201. package/dist/multi/476.app-f32e4213.js +0 -1
  202. package/dist/multi/53.app-f32e4213.js +0 -1
  203. package/dist/multi/584.app-f32e4213.js +0 -1
  204. package/dist/multi/690.app-f32e4213.js +0 -1
  205. package/dist/multi/747.app-f32e4213.js +0 -1
  206. package/dist/multi/767.app-f32e4213.js +0 -1
  207. package/dist/multi/816.app-f32e4213.js +0 -1
  208. package/dist/multi/83.app-f32e4213.js +0 -1
  209. package/dist/multi/873.app-f32e4213.js +0 -1
  210. package/dist/multi/920.app-f32e4213.js +0 -1
  211. package/dist/multi/991.app-f32e4213.js +0 -1
  212. package/dist/multi/app-f32e4213.js +0 -2
  213. package/dist/multi/app-f32e4213.js.LICENSE.txt +0 -16
  214. package/dist/multi/styles-f32e4213.css +0 -284
  215. package/dist/single/app-7fa8e43f.js +0 -2
  216. package/dist/single/app-7fa8e43f.js.LICENSE.txt +0 -16
  217. package/src/assets/scss/code.scss +0 -71
  218. package/src/assets/scss/typography.scss +0 -218
  219. package/src/components/ArrowButton/index.tsx +0 -36
  220. package/src/components/ArrowButton/styles.scss +0 -35
  221. package/src/components/LanguagePicker/index.tsx +0 -40
  222. package/src/components/Modal/styles.scss +0 -126
  223. package/src/components/ReportLogo/index.tsx +0 -16
  224. package/src/components/ReportLogo/styles.scss +0 -20
  225. package/src/components/ReportLogoFull/index.tsx +0 -20
  226. package/src/components/ReportLogoFull/styles.scss +0 -7
  227. package/src/components/Tabs/index.tsx +0 -62
  228. package/src/components/TestResult/TestResultAttachmentsView/index.tsx +0 -27
  229. package/src/components/TestResult/TestResultError/index.tsx +0 -59
  230. package/src/components/TestResult/TestResultError/styles.scss +0 -51
  231. package/src/components/TestResult/TestResultHeader/index.tsx +0 -55
  232. package/src/components/TestResult/TestResultHistory/TestResultHistoryItem.tsx +0 -67
  233. package/src/components/TestResult/TestResultHistory/index.tsx +0 -26
  234. package/src/components/TestResult/TestResultInfo/index.tsx +0 -79
  235. package/src/components/TestResult/TestResultOverview.tsx +0 -43
  236. package/src/components/TestResult/TestResultPrevStatuses/index.tsx +0 -49
  237. package/src/components/TestResult/TestResultRetriesView/TestResultRetriesItem.tsx +0 -52
  238. package/src/components/TestResult/TestResultRetriesView/index.tsx +0 -24
  239. package/src/components/TestResult/TestResultSteps/HtmlAttachmentPreview.tsx +0 -12
  240. package/src/components/TestResult/TestResultSteps/attachment.tsx +0 -68
  241. package/src/components/TestResult/TestResultSteps/attachmentCode.tsx +0 -20
  242. package/src/components/TestResult/TestResultSteps/attachmentImage.tsx +0 -32
  243. package/src/components/TestResult/TestResultSteps/attachmentVideo.tsx +0 -15
  244. package/src/components/TestResult/TestResultSteps/testResultAttachment.tsx +0 -77
  245. package/src/components/TestResult/TestResultSteps/testResultStep.tsx +0 -85
  246. package/src/components/TestResult/TestResultSteps/testResultStepInfo.tsx +0 -30
  247. package/src/components/TestResult/TestResultTabs/index.tsx +0 -59
  248. package/src/components/ThemeButton/ThemeButton.tsx +0 -20
  249. package/src/components/Tree/Tree.tsx +0 -75
  250. package/src/components/Tree/TreeHeader.tsx +0 -82
  251. package/src/components/Tree/TreeItem.tsx +0 -35
  252. package/src/components/Tree/TreeItemIcon.tsx +0 -32
  253. package/src/i18n/constants.ts +0 -124
  254. package/src/i18n/locales/am.json +0 -120
  255. package/src/i18n/locales/az.json +0 -120
  256. package/src/i18n/locales/de.json +0 -120
  257. package/src/i18n/locales/en.json +0 -121
  258. package/src/i18n/locales/es.json +0 -120
  259. package/src/i18n/locales/fr.json +0 -120
  260. package/src/i18n/locales/he.json +0 -120
  261. package/src/i18n/locales/it.json +0 -120
  262. package/src/i18n/locales/ja.json +0 -120
  263. package/src/i18n/locales/ka.json +0 -120
  264. package/src/i18n/locales/kr.json +0 -120
  265. package/src/i18n/locales/nl.json +0 -120
  266. package/src/i18n/locales/pl.json +0 -118
  267. package/src/i18n/locales/pt.json +0 -120
  268. package/src/i18n/locales/ru.json +0 -118
  269. package/src/i18n/locales/sv.json +0 -120
  270. package/src/i18n/locales/tr.json +0 -120
  271. package/src/i18n/locales/zh.json +0 -120
  272. package/src/utils/attachments.ts +0 -156
  273. package/src/utils/capitalize.ts +0 -6
  274. /package/dist/multi/{JetBrainsMono_vf-b9a9c326..woff → JetBrainsMono_vf.woff} +0 -0
  275. /package/dist/multi/{JetBrainsMono_vf-9e9649b6..woff2 → JetBrainsMono_vf.woff2} +0 -0
  276. /package/dist/multi/{pt-root-ui_vf-22fe60ca..woff → pt-root-ui_vf.woff} +0 -0
  277. /package/dist/multi/{pt-root-ui_vf-9d251e8b..woff2 → pt-root-ui_vf.woff2} +0 -0
  278. /package/src/components/{Tabs → ReportTabs}/styles.scss +0 -0
  279. /package/src/components/TestResult/{TestResultAttachmentsView → TrAttachmentsView}/styles.scss +0 -0
  280. /package/src/components/TestResult/{TestResultDescription → TrDescription}/styles.scss +0 -0
  281. /package/src/components/TestResult/{TestResultDropdown → TrDropdown}/styles.scss +0 -0
  282. /package/src/components/TestResult/{TestResultEmpty → TrEmpty}/styles.scss +0 -0
  283. /package/src/components/TestResult/{TestResultLinks → TrLinks}/styles.scss +0 -0
  284. /package/src/components/TestResult/{TestResultMetadata → TrMetadata}/styles.scss +0 -0
  285. /package/src/components/TestResult/{TestResultNavigation → TrNavigation}/styles.scss +0 -0
  286. /package/src/components/TestResult/{TestResultParameters → TrParameters}/styles.scss +0 -0
  287. /package/src/components/TestResult/{TestResultPrevStatuses → TrPrevStatuses}/styles.scss +0 -0
  288. /package/src/components/TestResult/{TestResultRetriesView → TrRetriesView}/styles.scss +0 -0
  289. /package/src/components/TestResult/{TestResultSeverity → TrSeverity}/styles.scss +0 -0
  290. /package/src/components/TestResult/{TestResultStatus → TrStatus}/styles.scss +0 -0
@@ -1,59 +0,0 @@
1
- import type { TestError } from "@allurereport/core-api";
2
- import { Code, IconButton, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
3
- import { type FunctionalComponent } from "preact";
4
- import { useState } from "preact/hooks";
5
- import { useI18n } from "@/stores/locale";
6
- import { copyToClipboard } from "@/utils/copyToClipboard";
7
- import * as styles from "./styles.scss";
8
-
9
- const TestResultErrorTrace = ({ trace }: { trace: string }) => {
10
- return (
11
- <div data-testid="test-result-error-trace" className={styles["test-result-error-trace"]}>
12
- <Code size={"s"} type={"ui"}>
13
- <pre>{trace}</pre>
14
- </Code>
15
- </div>
16
- );
17
- };
18
-
19
- export const TestResultError: FunctionalComponent<TestError> = ({ message, trace }) => {
20
- const [isOpen, setIsOpen] = useState(false);
21
- const { t } = useI18n("ui");
22
- const { t: tooltip } = useI18n("controls");
23
- const { t: empty } = useI18n("empty");
24
-
25
- return (
26
- <div data-testid="test-result-error" className={styles["test-result-error"]}>
27
- {message ? (
28
- <>
29
- <div data-testid="test-result-error-header" className={styles["test-result-error-header"]}>
30
- <Text tag={"p"} size={"m"} bold className={styles["test-result-error-text"]}>
31
- {t("error")}
32
- </Text>
33
- <TooltipWrapper tooltipText={tooltip("clipboard")} tooltipTextAfterClick={tooltip("clipboardSuccess")}>
34
- <IconButton
35
- style={"ghost"}
36
- size={"s"}
37
- icon={allureIcons.lineGeneralCopy3}
38
- onClick={() => {
39
- copyToClipboard(message);
40
- }}
41
- />
42
- </TooltipWrapper>
43
- </div>
44
- <div className={styles["test-result-error-message"]} onClick={() => setIsOpen(!isOpen)}>
45
- <Code data-testid="test-result-error-message" size={"s"}>
46
- <pre>{message}</pre>
47
- </Code>
48
- </div>
49
- </>
50
- ) : (
51
- // TODO add translations
52
- empty("no-message-provided")
53
- )}
54
-
55
- {/* TODO no trace? message is still clickable */}
56
- {isOpen && trace && <TestResultErrorTrace trace={trace} />}
57
- </div>
58
- );
59
- };
@@ -1,51 +0,0 @@
1
- .test-result-error {
2
- padding: 8px 8px 12px 16px;
3
- background-color: var(--bg-alpha-capella);
4
- border-radius: 8px;
5
- position: relative;
6
- overflow: hidden;
7
-
8
- &:before {
9
- content: "";
10
- display: block;
11
- height: 100%;
12
- width: 2px;
13
- position: absolute;
14
- left: 0;
15
- top: 0;
16
- background: var(--on-support-capella);
17
- }
18
- }
19
-
20
- .test-result-error-header {
21
- display: flex;
22
- gap: 4px;
23
- justify-content: space-between;
24
- }
25
-
26
- .test-result-error-text {
27
- margin-bottom: 8px;
28
- padding-left: 8px;
29
- color: var(--on-support-capella);
30
- }
31
-
32
- .test-result-error-trace {
33
- margin-top: 8px;
34
- padding-left: 8px;
35
-
36
- pre {
37
- overflow: scroll;
38
- padding-bottom: 24px;
39
- }
40
- }
41
-
42
- .test-result-error-message {
43
- padding: 8px;
44
- border-radius: 8px;
45
- cursor: pointer;
46
- transition: background-color 300ms;
47
-
48
- &:hover {
49
- background: var(--bg-alpha-capella);
50
- }
51
- }
@@ -1,55 +0,0 @@
1
- import { IconButton, allureIcons } from "@allurereport/web-components";
2
- import { SvgIcon } from "@allurereport/web-components";
3
- import { Text } from "@allurereport/web-components";
4
- import clsx from "clsx";
5
- import type { FunctionalComponent } from "preact";
6
- import type { AllureAwesomeTestResult } from "types";
7
- import { LanguagePicker } from "@/components/LanguagePicker";
8
- import { ThemeButton } from "@/components/ThemeButton/ThemeButton";
9
- import { navigateTo } from "@/index";
10
- import * as styles from "./styles.scss";
11
-
12
- export type TestResultHeaderProps = {
13
- testResult?: AllureAwesomeTestResult;
14
- };
15
-
16
- export const TestResultHeader: FunctionalComponent<TestResultHeaderProps> = ({ testResult }) => {
17
- const { breadcrumbs, name } = testResult || {};
18
-
19
- return (
20
- <div className={styles.above}>
21
- <div className={styles["test-result-breadcrumbs"]}>
22
- <div className={clsx(styles["test-result-breadcrumb"], styles["test-result-home"])}>
23
- <IconButton
24
- icon={allureIcons.lineGeneralHomeLine}
25
- size={"s"}
26
- style={"ghost"}
27
- className={styles["test-result-breadcrumb-link"]}
28
- onClick={() => navigateTo("/")}
29
- />
30
- </div>
31
- {Boolean(breadcrumbs?.length) &&
32
- breadcrumbs?.[0]?.map((item, key) => {
33
- return (
34
- <div className={styles["test-result-breadcrumb"]} key={key}>
35
- <SvgIcon id={allureIcons.lineArrowsChevronDown} className={styles["test-result-breadcrumb-arrow"]} />
36
- <Text size={"s"} bold className={styles["test-result-breadcrumb-title"]}>
37
- {item}
38
- </Text>
39
- </div>
40
- );
41
- })}
42
- <div className={styles["test-result-breadcrumb"]}>
43
- {name && (
44
- <SvgIcon id={allureIcons.lineArrowsChevronDown} className={styles["test-result-breadcrumb-arrow"]} />
45
- )}
46
- <Text size={"s"} bold className={styles["test-result-breadcrumb-title"]}>
47
- {name}
48
- </Text>
49
- </div>
50
- </div>
51
- <LanguagePicker />
52
- <ThemeButton />
53
- </div>
54
- );
55
- };
@@ -1,67 +0,0 @@
1
- import { type HistoryTestResult, formatDuration } from "@allurereport/core-api";
2
- import { IconButton, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
3
- import { type FunctionalComponent } from "preact";
4
- import { useState } from "preact/hooks";
5
- import { ArrowButton } from "@/components/ArrowButton";
6
- import { TestResultError } from "@/components/TestResult/TestResultError";
7
- import * as styles from "@/components/TestResult/TestResultHistory/styles.scss";
8
- import TreeItemIcon from "@/components/Tree/TreeItemIcon";
9
- import { navigateTo, openInNewTab } from "@/index";
10
- import { useI18n } from "@/stores";
11
- import { timestampToDate } from "@/utils/time";
12
-
13
- export const TestResultHistoryItem: FunctionalComponent<{
14
- testResultItem: HistoryTestResult;
15
- }> = ({ testResultItem }: { testResultItem: HistoryTestResult }) => {
16
- const { status, error, stop, duration, id } = testResultItem;
17
- const [isOpened, setIsOpen] = useState(false);
18
- const convertedStop = timestampToDate(stop);
19
- const formattedDuration = formatDuration(duration as number);
20
- const { t } = useI18n("controls");
21
-
22
- const navigateUrl = `/testresult/${id}`;
23
-
24
- return (
25
- <div>
26
- <div className={styles["test-result-history-item-header"]}>
27
- {Boolean(error) && (
28
- <span onClick={() => setIsOpen(!isOpened)}>
29
- <ArrowButton isOpened={isOpened} icon={allureIcons.arrowsChevronDown} />
30
- </span>
31
- )}
32
- <div
33
- className={styles["test-result-history-item-wrap"]}
34
- onClick={(e) => {
35
- e.stopPropagation();
36
- navigateTo(navigateUrl);
37
- }}
38
- >
39
- <TreeItemIcon status={status} className={styles["test-result-history-item-status"]} />
40
- <Text className={styles["test-result-history-item-text"]}>{convertedStop}</Text>
41
- <div className={styles["test-result-history-item-info"]}>
42
- <Text type="ui" size={"s"} className={styles["item-time"]}>
43
- {formattedDuration}
44
- </Text>
45
- <TooltipWrapper tooltipText={t("openInNewTab")}>
46
- <IconButton
47
- icon={allureIcons.lineGeneralLinkExternal}
48
- style={"ghost"}
49
- size={"s"}
50
- className={styles["test-result-history-item-link"]}
51
- onClick={(e) => {
52
- e.stopPropagation();
53
- openInNewTab(navigateUrl);
54
- }}
55
- />
56
- </TooltipWrapper>
57
- </div>
58
- </div>
59
- </div>
60
- {isOpened && error && (
61
- <div>
62
- <TestResultError {...error} />
63
- </div>
64
- )}
65
- </div>
66
- );
67
- };
@@ -1,26 +0,0 @@
1
- import type { FunctionalComponent } from "preact";
2
- import { TestResultHistoryItem } from "@/components/TestResult/TestResultHistory/TestResultHistoryItem";
3
- import { useI18n } from "@/stores";
4
- import { type AllureAwesomeTestResult } from "../../../../types";
5
- import * as styles from "./styles.scss";
6
-
7
- export type TestResultHistoryViewProps = {
8
- testResult?: AllureAwesomeTestResult;
9
- };
10
-
11
- const TestResultHistoryView: FunctionalComponent<TestResultHistoryViewProps> = ({ testResult }) => {
12
- const { history } = testResult ?? {};
13
- const { t } = useI18n("empty");
14
-
15
- return (
16
- <div className={styles["test-result-history"]}>
17
- {history.length ? (
18
- history?.map((item, key) => <TestResultHistoryItem testResultItem={item} key={key} />)
19
- ) : (
20
- <div className={styles["test-result-empty"]}>{t("no-history-results")}</div>
21
- )}
22
- </div>
23
- );
24
- };
25
-
26
- export default TestResultHistoryView;
@@ -1,79 +0,0 @@
1
- import { formatDuration } from "@allurereport/core-api";
2
- import { Counter, Heading, Text, TooltipWrapper } from "@allurereport/web-components";
3
- import type { FunctionalComponent } from "preact";
4
- import type { AllureAwesomeTestResult } from "types";
5
- import { TestResultInfoStatuses } from "@/components/TestResult/TestResultInfo/TestResultInfoStatuses";
6
- import { TestResultNavigation } from "@/components/TestResult/TestResultNavigation";
7
- import { TestResultPrevStatuses } from "@/components/TestResult/TestResultPrevStatuses";
8
- import { TestResultSeverity } from "@/components/TestResult/TestResultSeverity";
9
- import { TestResultStatus } from "@/components/TestResult/TestResultStatus";
10
- import { TestResultTab, TestResultTabsList } from "@/components/TestResult/TestResultTabs";
11
- import { useI18n } from "@/stores/locale";
12
- import { timestampToDate } from "@/utils/time";
13
- import * as styles from "./styles.scss";
14
-
15
- export type TestResultInfoProps = {
16
- testResult?: AllureAwesomeTestResult;
17
- };
18
-
19
- export const TestResultInfo: FunctionalComponent<TestResultInfoProps> = ({ testResult }) => {
20
- const { name, status, muted, flaky, known, duration, labels, history, retries, attachments, stop } = testResult ?? {};
21
- const formattedDuration = formatDuration(duration as number);
22
- const fullDate = stop && timestampToDate(stop);
23
- const severity = labels?.find((label) => label.name === "severity")?.value ?? "normal";
24
- const { t } = useI18n("ui");
25
- const statuses = Object.entries({ flaky, muted, known }).filter(([, value]) => value);
26
-
27
- const Content = () => {
28
- return (
29
- <>
30
- {name && (
31
- <Heading data-testid="test-result-info-title" tag={"h1"} size={"s"} className={styles["test-result-name"]}>
32
- {name}
33
- </Heading>
34
- )}
35
- <div className={styles["test-result-info-data"]}>
36
- {Boolean(status) && <TestResultStatus status={status} />}
37
- {Boolean(history?.length) && <TestResultPrevStatuses history={history} />}
38
- <TestResultSeverity severity={severity} />
39
- {Boolean(statuses.length) && <TestResultInfoStatuses statuses={statuses} />}
40
- <TooltipWrapper tooltipText={fullDate}>
41
- <Text tag={"div"} size={"s"} bold className={styles["test-result-duration"]}>
42
- {formattedDuration}
43
- </Text>
44
- </TooltipWrapper>
45
- </div>
46
- <div className={styles["test-result-tabs"]}>
47
- <TestResultTabsList>
48
- <TestResultTab id="overview">{t("overview")}</TestResultTab>
49
- <TestResultTab id="history" disabled={!history?.length}>
50
- <div className={styles["test-result-tab"]}>
51
- {t("history")}
52
- {Boolean(history?.length) && <Counter size={"s"} count={history?.length} />}
53
- </div>
54
- </TestResultTab>
55
- <TestResultTab id="retries" disabled={!retries?.length}>
56
- <div className={styles["test-result-tab"]}>
57
- {t("retries")}
58
- {Boolean(retries?.length) && <Counter size={"s"} count={retries?.length} />}
59
- </div>
60
- </TestResultTab>
61
- <TestResultTab id="attachments" disabled={!attachments?.length}>
62
- <div className={styles["test-result-tab"]}>
63
- {t("attachments")}
64
- {Boolean(attachments?.length) && <Counter size={"s"} count={attachments?.length} />}
65
- </div>
66
- </TestResultTab>
67
- </TestResultTabsList>
68
- </div>
69
- </>
70
- );
71
- };
72
-
73
- return (
74
- <div className={styles["test-result-info"]}>
75
- <TestResultNavigation testResult={testResult} />
76
- {testResult && <Content />}
77
- </div>
78
- );
79
- };
@@ -1,43 +0,0 @@
1
- import type { FunctionalComponent } from "preact";
2
- import type { AllureAwesomeTestResult } from "types";
3
- import * as styles from "@/components/BaseLayout/styles.scss";
4
- import { TestResultDescription } from "@/components/TestResult/TestResultDescription";
5
- import { TestResultError } from "@/components/TestResult/TestResultError";
6
- import { TestResultLinks } from "@/components/TestResult/TestResultLinks";
7
- import { TestResultMetadata } from "@/components/TestResult/TestResultMetadata";
8
- import { TestResultParameters } from "@/components/TestResult/TestResultParameters";
9
- import { TestResultSetup } from "@/components/TestResult/TestResultSetup";
10
- import { TestResultSteps } from "@/components/TestResult/TestResultSteps";
11
- import { TestResultTeardown } from "@/components/TestResult/TestResultTeardown";
12
- import TestStepsEmpty from "@/components/TestResult/TestStepsEmpty";
13
-
14
- export type TestResultOverviewProps = {
15
- testResult?: AllureAwesomeTestResult;
16
- };
17
-
18
- export const TestResultOverview: FunctionalComponent<TestResultOverviewProps> = ({ testResult }) => {
19
- const { error, parameters, groupedLabels, links, description, setup, steps, teardown, id } = testResult || {};
20
- const isNoSteps = !setup?.length && !steps.length && !teardown.length;
21
-
22
- return (
23
- <>
24
- {Boolean(error?.message) && (
25
- <div className={styles["test-result-errors"]}>
26
- <TestResultError {...error} />
27
- </div>
28
- )}
29
- {Boolean(parameters?.length) && <TestResultParameters parameters={parameters} />}
30
- {Boolean(groupedLabels && Object.keys(groupedLabels || {})?.length) && (
31
- <TestResultMetadata testResult={testResult} />
32
- )}
33
- {Boolean(links?.length) && <TestResultLinks links={links} />}
34
- {Boolean(description) && <TestResultDescription description={description} />}
35
- <div className={styles["test-results"]}>
36
- {isNoSteps && <TestStepsEmpty />}
37
- {Boolean(setup?.length) && <TestResultSetup id={id} setup={setup} />}
38
- {Boolean(steps?.length) && <TestResultSteps id={id} steps={steps} />}
39
- {Boolean(teardown?.length) && <TestResultTeardown id={id} teardown={teardown} />}
40
- </div>
41
- </>
42
- );
43
- };
@@ -1,49 +0,0 @@
1
- import { type HistoryTestResult } from "@allurereport/core-api";
2
- import { SvgIcon, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
3
- import type { FunctionalComponent } from "preact";
4
- import type { AllureAwesomeTestResult } from "types";
5
- import { navigateTo } from "@/index";
6
- import { useI18n } from "@/stores";
7
- import { capitalize } from "@/utils/capitalize";
8
- import { timestampToDate } from "@/utils/time";
9
- import * as styles from "./styles.scss";
10
-
11
- const TestResultPrevStatus: FunctionalComponent<{ item: HistoryTestResult }> = ({ item }) => {
12
- return (
13
- <div className={styles["test-result-prev-status"]} onClick={() => navigateTo(`testresult/${item.id}`)}>
14
- <SvgIcon id={allureIcons.lineShapesDotCircle} className={styles[`status-${item?.status}`]} />
15
- </div>
16
- );
17
- };
18
- const TestResultPrevStatusTooltip: FunctionalComponent<{ item: HistoryTestResult }> = ({ item }) => {
19
- const convertedStop = item.stop && timestampToDate(item.stop);
20
- const { t } = useI18n("statuses");
21
- const status = t(item.status);
22
-
23
- return (
24
- <div className={styles["test-result-prev-status-tooltip"]}>
25
- <Text tag={"div"} size={"m"} bold>
26
- {capitalize(status)}
27
- </Text>
28
- <Text size={"m"}>{convertedStop}</Text>
29
- </div>
30
- );
31
- };
32
-
33
- export type TestResultPrevStatusesProps = {
34
- history: AllureAwesomeTestResult["history"];
35
- };
36
-
37
- export const TestResultPrevStatuses: FunctionalComponent<TestResultPrevStatusesProps> = ({ history }) => {
38
- return (
39
- <div className={styles["test-result-prev-statuses"]}>
40
- {history?.slice(0, 6).map((item, key) => (
41
- <div key={key} className={styles["test-result-prev-status"]}>
42
- <TooltipWrapper key={key} tooltipComponent={<TestResultPrevStatusTooltip item={item} />}>
43
- <TestResultPrevStatus item={item} />
44
- </TooltipWrapper>
45
- </div>
46
- ))}
47
- </div>
48
- );
49
- };
@@ -1,52 +0,0 @@
1
- import { formatDuration } from "@allurereport/core-api";
2
- import { IconButton, Text, allureIcons } from "@allurereport/web-components";
3
- import type { FunctionalComponent } from "preact";
4
- import { useState } from "preact/hooks";
5
- import type { AllureAwesomeTestResult } from "types";
6
- import { ArrowButton } from "@/components/ArrowButton";
7
- import { TestResultError } from "@/components/TestResult/TestResultError";
8
- import * as styles from "@/components/TestResult/TestResultRetriesView/styles.scss";
9
- import TreeItemIcon from "@/components/Tree/TreeItemIcon";
10
- import { navigateTo } from "@/index";
11
- import { timestampToDate } from "@/utils/time";
12
-
13
- export const TestResultRetriesItem: FunctionalComponent<{
14
- testResultItem: AllureAwesomeTestResult;
15
- }> = ({ testResultItem }) => {
16
- const { id, status, error, stop, duration } = testResultItem;
17
- const [isOpened, setIsOpen] = useState(false);
18
- const convertedStop = timestampToDate(stop);
19
- const formattedDuration = typeof duration === "number" ? formatDuration(duration as number) : undefined;
20
- const navigateUrl = `/testresult/${id}`;
21
-
22
- return (
23
- <div>
24
- <div className={styles["test-result-retries-item-header"]} onClick={() => setIsOpen(!isOpened)}>
25
- {Boolean(error) && <ArrowButton isOpened={isOpened} icon={allureIcons.lineArrowsChevronDown} />}
26
- <div className={styles["test-result-retries-item-wrap"]}>
27
- <TreeItemIcon status={status} className={styles["test-result-retries-item-status"]} />
28
- <Text className={styles["test-result-retries-item-text"]}>{convertedStop}</Text>
29
- <div className={styles["test-result-retries-item-info"]}>
30
- {Boolean(formattedDuration) && (
31
- <Text type="ui" size={"s"} className={styles["item-time"]}>
32
- {formattedDuration}
33
- </Text>
34
- )}
35
- <IconButton
36
- icon={allureIcons.lineGeneralLinkExternal}
37
- style={"ghost"}
38
- size={"s"}
39
- className={styles["test-result-retries-item-link"]}
40
- onClick={() => navigateTo(navigateUrl)}
41
- />
42
- </div>
43
- </div>
44
- </div>
45
- {isOpened && error && (
46
- <div className={styles["test-result-retries-item-content"]}>
47
- <TestResultError {...error} />
48
- </div>
49
- )}
50
- </div>
51
- );
52
- };
@@ -1,24 +0,0 @@
1
- import type { FunctionalComponent } from "preact";
2
- import type { AllureAwesomeTestResult } from "types";
3
- import * as styles from "@/components/TestResult/TestResultHistory/styles.scss";
4
- import { TestResultRetriesItem } from "@/components/TestResult/TestResultRetriesView/TestResultRetriesItem";
5
- import { useI18n } from "@/stores";
6
-
7
- export const TestResultRetriesView: FunctionalComponent<{
8
- testResult: AllureAwesomeTestResult;
9
- }> = ({ testResult }) => {
10
- const { retries } = testResult ?? {};
11
- const { t } = useI18n("empty");
12
-
13
- return (
14
- <div className={styles["test-result-history"]}>
15
- {retries.length ? (
16
- retries?.map((item, key) => (
17
- <TestResultRetriesItem testResultItem={item as unknown as AllureAwesomeTestResult} key={key} />
18
- ))
19
- ) : (
20
- <div className={styles["test-result-empty"]}>{t("no-retries-results")}</div>
21
- )}
22
- </div>
23
- );
24
- };
@@ -1,12 +0,0 @@
1
- import type { FunctionalComponent } from "preact";
2
- import * as styles from "./styles.scss";
3
-
4
- // TODO: use proper type here
5
- export type HtmlAttachmentPreviewProps = {
6
- attachment: { text: string };
7
- };
8
-
9
- export const HtmlAttachmentPreview: FunctionalComponent<HtmlAttachmentPreviewProps> = ({ attachment }) => {
10
- // eslint-disable-next-line react/no-danger
11
- return <div className={styles["html-attachment-preview"]} dangerouslySetInnerHTML={{ __html: attachment?.text }} />;
12
- };
@@ -1,68 +0,0 @@
1
- import type { AttachmentTestStepResult } from "@allurereport/core-api";
2
- import { Spinner } from "@allurereport/web-components";
3
- import type { FunctionalComponent } from "preact";
4
- import { useEffect, useState } from "preact/hooks";
5
- import { modalData } from "@/components/Modal";
6
- import { HtmlAttachmentPreview } from "@/components/TestResult/TestResultSteps/HtmlAttachmentPreview";
7
- import { AttachmentCode } from "@/components/TestResult/TestResultSteps/attachmentCode";
8
- import { AttachmentImage } from "@/components/TestResult/TestResultSteps/attachmentImage";
9
- import { AttachmentVideo } from "@/components/TestResult/TestResultSteps/attachmentVideo";
10
- import { EmptyComponent } from "@/components/TestResult/TestResultSteps/wrongAttachment";
11
- import { type Attachments, attachmentType, fetchAttachment } from "@/utils/attachments";
12
- import * as styles from "./styles.scss";
13
-
14
- const componentsByAttachmentType: Record<string, any> = {
15
- image: AttachmentImage,
16
- svg: AttachmentImage,
17
- json: AttachmentCode,
18
- code: AttachmentCode,
19
- uri: AttachmentCode,
20
- css: AttachmentCode,
21
- table: AttachmentCode,
22
- html: AttachmentCode,
23
- text: AttachmentCode,
24
- video: AttachmentVideo,
25
- };
26
- const previewComponentsByAttachmentType: Record<string, any> = {
27
- html: HtmlAttachmentPreview,
28
- };
29
-
30
- export interface AttachmentTestStepResultProps {
31
- item: AttachmentTestStepResult;
32
- previewable?: boolean;
33
- }
34
-
35
- export const Attachment: FunctionalComponent<AttachmentTestStepResultProps> = ({ item, previewable }) => {
36
- const {
37
- link: { contentType, id, ext },
38
- } = item;
39
- const [attachment, setAttachment] = useState<Attachments>(null);
40
- const [loaded, setLoaded] = useState(false);
41
- const attachmentComponent = attachmentType(contentType);
42
- const CurrentComponent = componentsByAttachmentType[attachmentComponent.type];
43
- const CurrentPreviewComponent = previewComponentsByAttachmentType[attachmentComponent.type];
44
-
45
- useEffect(() => {
46
- const fetchData = async () => {
47
- const result: Attachments = await fetchAttachment(id, ext, contentType);
48
- setLoaded(true);
49
- setAttachment(result);
50
- };
51
- fetchData();
52
- }, [contentType, id, ext]);
53
-
54
- if (!loaded) {
55
- return (
56
- <div className={styles["test-result-spinner"]}>
57
- <Spinner />
58
- </div>
59
- );
60
- }
61
-
62
- // temp solution before modal component refactoring
63
- if (CurrentPreviewComponent && previewable && modalData.value.preview) {
64
- return <CurrentPreviewComponent attachment={attachment} item={item} />;
65
- }
66
-
67
- return CurrentComponent ? <CurrentComponent attachment={attachment} item={item} /> : <EmptyComponent />;
68
- };
@@ -1,20 +0,0 @@
1
- import { type AttachmentTestStepResult } from "@allurereport/core-api";
2
- import { type FunctionalComponent } from "preact";
3
- import { useEffect } from "preact/hooks";
4
- import Prism from "prismjs";
5
- import "@/assets/scss/code.scss";
6
-
7
- export const AttachmentCode: FunctionalComponent<{
8
- item: AttachmentTestStepResult;
9
- attachment: { text?: string };
10
- }> = ({ attachment, item }) => {
11
- useEffect(() => {
12
- Prism.highlightAll();
13
- }, [attachment]);
14
-
15
- return (
16
- <pre key={item?.link?.id} className={`language-${item?.link?.ext?.replace(".", "")} line-numbers`}>
17
- <code>{attachment?.text}</code>
18
- </pre>
19
- );
20
- };
@@ -1,32 +0,0 @@
1
- import { type FunctionalComponent } from "preact";
2
- import { useEffect, useState } from "preact/hooks";
3
- import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
4
- import { EmptyComponent } from "@/components/TestResult/TestResultSteps/wrongAttachment";
5
-
6
- export const AttachmentImage: FunctionalComponent<{
7
- attachment: { img: string; originalFileName: string };
8
- }> = ({ attachment }) => {
9
- const [isValidImage, setIsValidImage] = useState(true);
10
-
11
- useEffect(() => {
12
- if (attachment?.img) {
13
- const img = new Image();
14
- img.onload = () => setIsValidImage(true);
15
- img.onerror = () => setIsValidImage(false);
16
- img.src = attachment.img;
17
- }
18
- }, [attachment?.img]);
19
-
20
- if (!attachment?.img || !isValidImage) {
21
- return (
22
- <div className={styles["test-result-attachment-error"]}>
23
- <EmptyComponent />
24
- </div>
25
- );
26
- }
27
- return (
28
- <div className={styles["test-result-attachment-image"]}>
29
- {attachment?.img && <img src={attachment.img} alt={attachment.originalFileName} />}
30
- </div>
31
- );
32
- };
@@ -1,15 +0,0 @@
1
- import { Spinner } from "@allurereport/web-components";
2
- import { type FunctionalComponent } from "preact";
3
-
4
- export const AttachmentVideo: FunctionalComponent<{
5
- attachment: { src: string; contentType?: string };
6
- }> = ({ attachment }) => {
7
- if (!attachment) {
8
- return <Spinner />;
9
- }
10
- return (
11
- <video controls loop muted>
12
- <source src={attachment?.src} type={attachment?.contentType} />
13
- </video>
14
- );
15
- };