@allurereport/web-awesome 3.0.0-beta.10 → 3.0.0-beta.12

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 (167) hide show
  1. package/dist/multi/173.app-52d1decd.js +1 -0
  2. package/dist/multi/174.app-52d1decd.js +1 -0
  3. package/dist/multi/252.app-52d1decd.js +1 -0
  4. package/dist/multi/282.app-52d1decd.js +1 -0
  5. package/dist/multi/29.app-52d1decd.js +1 -0
  6. package/dist/multi/416.app-52d1decd.js +1 -0
  7. package/dist/multi/527.app-52d1decd.js +1 -0
  8. package/dist/multi/600.app-52d1decd.js +1 -0
  9. package/dist/multi/605.app-52d1decd.js +1 -0
  10. package/dist/multi/638.app-52d1decd.js +1 -0
  11. package/dist/multi/672.app-52d1decd.js +1 -0
  12. package/dist/multi/686.app-52d1decd.js +1 -0
  13. package/dist/multi/725.app-52d1decd.js +1 -0
  14. package/dist/multi/741.app-52d1decd.js +1 -0
  15. package/dist/multi/755.app-52d1decd.js +1 -0
  16. package/dist/multi/894.app-52d1decd.js +1 -0
  17. package/dist/multi/943.app-52d1decd.js +1 -0
  18. package/dist/multi/980.app-52d1decd.js +1 -0
  19. package/dist/multi/app-52d1decd.js +2 -0
  20. package/dist/multi/{app-d01d0c66.js.LICENSE.txt → app-52d1decd.js.LICENSE.txt} +7 -0
  21. package/dist/multi/manifest.json +20 -20
  22. package/dist/multi/styles-52d1decd.css +41 -0
  23. package/dist/single/app-83b0c4fc.js +2 -0
  24. package/dist/single/{app-6596cb08.js.LICENSE.txt → app-83b0c4fc.js.LICENSE.txt} +7 -0
  25. package/dist/single/manifest.json +1 -1
  26. package/package.json +4 -4
  27. package/src/assets/scss/palette.scss +391 -391
  28. package/src/assets/scss/theme.scss +9 -1
  29. package/src/assets/scss/vars.scss +0 -1
  30. package/src/components/BaseLayout/styles.scss +10 -2
  31. package/src/components/EnvironmentPicker/index.tsx +51 -0
  32. package/src/components/EnvironmentPicker/styles.scss +9 -0
  33. package/src/components/Footer/FooterLogo.tsx +1 -2
  34. package/src/components/Header/index.tsx +4 -10
  35. package/src/components/HeaderControls/index.tsx +20 -0
  36. package/src/components/MainReport/styles.scss +2 -1
  37. package/src/components/Metadata/index.tsx +6 -4
  38. package/src/components/MetadataButton/index.tsx +12 -4
  39. package/src/components/MetadataButton/styles.scss +3 -0
  40. package/src/components/ReportBody/index.tsx +3 -2
  41. package/src/components/ReportHeader/ReportHeaderLogo.tsx +6 -2
  42. package/src/components/ReportHeader/ReportHeaderPie.tsx +1 -2
  43. package/src/components/ReportMetadata/MetadataSummary.tsx +56 -63
  44. package/src/components/ReportMetadata/MetadataWithIcon.tsx +1 -1
  45. package/src/components/ReportMetadata/index.tsx +50 -3
  46. package/src/components/SideBySide/styles.scss +2 -3
  47. package/src/components/SplitLayout/index.tsx +2 -2
  48. package/src/components/SplitLayout/styles.scss +2 -1
  49. package/src/components/TestResult/TestStepsEmpty/index.tsx +2 -2
  50. package/src/components/TestResult/{TestResultAttachmentsView → TrAttachmentsView}/index.tsx +4 -4
  51. package/src/components/TestResult/{TestResultDescription → TrDescription}/index.tsx +2 -2
  52. package/src/components/TestResult/{TestResultDropdown → TrDropdown}/index.tsx +1 -1
  53. package/src/components/TestResult/{TestResultEmpty → TrEmpty}/index.tsx +6 -6
  54. package/src/components/TestResult/TrEnvironmentItem/index.tsx +82 -0
  55. package/src/components/TestResult/TrEnvironmentItem/styles.scss +60 -0
  56. package/src/components/TestResult/TrEnvironmentsView/index.tsx +64 -0
  57. package/src/components/TestResult/TrEnvironmentsView/styles.scss +11 -0
  58. package/src/components/TestResult/TrError/TrDiff.tsx +3 -5
  59. package/src/components/TestResult/TrError/index.tsx +21 -6
  60. package/src/components/TestResult/TrError/styles.scss +92 -2
  61. package/src/components/TestResult/{TestResultHeader/TestResultBreadcrumbs.tsx → TrHeader/TrBreadcrumbs.tsx} +3 -3
  62. package/src/components/TestResult/TrHeader/index.tsx +15 -0
  63. package/src/components/TestResult/{TestResultHistory/TestResultHistoryItem.tsx → TrHistory/TrHistoryItem.tsx} +3 -3
  64. package/src/components/TestResult/{TestResultHistory → TrHistory}/index.tsx +5 -5
  65. package/src/components/TestResult/{TestResultInfo/TestResultInfoStatuses.tsx → TrInfo/TrInfoStatuses.tsx} +1 -1
  66. package/src/components/TestResult/{TestResultInfo → TrInfo}/index.tsx +37 -23
  67. package/src/components/TestResult/{TestResultLinks → TrLinks}/index.tsx +6 -6
  68. package/src/components/TestResult/{TestResultMetadata → TrMetadata}/index.tsx +4 -4
  69. package/src/components/TestResult/{TestResultNavigation → TrNavigation}/index.tsx +3 -2
  70. package/src/components/TestResult/TrOverview.tsx +47 -0
  71. package/src/components/TestResult/{TestResultParameters → TrParameters}/index.tsx +2 -2
  72. package/src/components/TestResult/{TestResultPrevStatuses → TrPrevStatuses}/index.tsx +6 -6
  73. package/src/components/TestResult/TrPwTraces/PwTrace.tsx +34 -0
  74. package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +33 -0
  75. package/src/components/TestResult/TrPwTraces/index.tsx +29 -0
  76. package/src/components/TestResult/TrPwTraces/styles.scss +20 -0
  77. package/src/components/TestResult/{TestResultRetriesView/TestResultRetriesItem.tsx → TrRetriesView/TrRetriesItem.tsx} +3 -3
  78. package/src/components/TestResult/{TestResultRetriesView → TrRetriesView}/index.tsx +4 -6
  79. package/src/components/TestResult/{TestResultSetup → TrSetup}/index.tsx +11 -11
  80. package/src/components/TestResult/{TestResultSeverity → TrSeverity}/index.tsx +1 -1
  81. package/src/components/TestResult/{TestResultStatus → TrStatus}/index.tsx +3 -2
  82. package/src/components/TestResult/{TestResultSteps/testResultAttachment.tsx → TrSteps/TrAttachment.tsx} +10 -7
  83. package/src/components/TestResult/{TestResultSteps/testResultAttachmentInfo.tsx → TrSteps/TrAttachmentInfo.tsx} +8 -8
  84. package/src/components/TestResult/{TestResultSteps/testResultStep.tsx → TrSteps/TrStep.tsx} +25 -14
  85. package/src/components/TestResult/{TestResultSteps/testResultStepInfo.tsx → TrSteps/TrStepInfo.tsx} +2 -2
  86. package/src/components/TestResult/{TestResultSteps → TrSteps}/index.tsx +8 -8
  87. package/src/components/TestResult/{TestResultSteps → TrSteps}/styles.scss +2 -1
  88. package/src/components/TestResult/{TestResultSteps → TrSteps}/wrongAttachment.tsx +1 -1
  89. package/src/components/TestResult/{TestResultTabs → TrTabs}/index.tsx +6 -6
  90. package/src/components/TestResult/{TestResultTeardown → TrTeardown}/index.tsx +11 -11
  91. package/src/components/TestResult/index.tsx +42 -30
  92. package/src/components/TestResult/styles.scss +2 -1
  93. package/src/components/Tree/index.tsx +99 -16
  94. package/src/components/Tree/styles.scss +16 -1
  95. package/src/index.tsx +36 -33
  96. package/src/{i18n/locales → locales}/az.json +14 -4
  97. package/src/{i18n/locales → locales}/de.json +13 -4
  98. package/src/{i18n/locales → locales}/en.json +15 -6
  99. package/src/{i18n/locales → locales}/es.json +13 -4
  100. package/src/{i18n/locales → locales}/fr.json +13 -4
  101. package/src/{i18n/locales → locales}/he.json +13 -4
  102. package/src/{i18n/locales/am.json → locales/hy.json} +13 -4
  103. package/src/{i18n/locales → locales}/it.json +13 -4
  104. package/src/{i18n/locales → locales}/ja.json +13 -4
  105. package/src/{i18n/locales → locales}/ka.json +16 -7
  106. package/src/{i18n/locales → locales}/kr.json +15 -6
  107. package/src/{i18n/locales → locales}/nl.json +13 -4
  108. package/src/{i18n/locales → locales}/pl.json +14 -5
  109. package/src/{i18n/locales → locales}/pt.json +12 -4
  110. package/src/{i18n/locales → locales}/ru.json +14 -5
  111. package/src/{i18n/locales → locales}/sv.json +13 -4
  112. package/src/{i18n/locales → locales}/tr.json +13 -4
  113. package/src/{i18n/locales → locales}/zh.json +13 -4
  114. package/src/stores/chart.ts +3 -3
  115. package/src/stores/env.ts +88 -0
  116. package/src/stores/locale.ts +4 -4
  117. package/src/stores/stats.ts +52 -7
  118. package/src/stores/testResults.ts +6 -6
  119. package/src/stores/tree.ts +48 -17
  120. package/src/stores/variables.ts +38 -0
  121. package/types.d.ts +2 -1
  122. package/dist/multi/141.app-d01d0c66.js +0 -1
  123. package/dist/multi/222.app-d01d0c66.js +0 -1
  124. package/dist/multi/335.app-d01d0c66.js +0 -1
  125. package/dist/multi/34.app-d01d0c66.js +0 -1
  126. package/dist/multi/349.app-d01d0c66.js +0 -1
  127. package/dist/multi/378.app-d01d0c66.js +0 -1
  128. package/dist/multi/406.app-d01d0c66.js +0 -1
  129. package/dist/multi/476.app-d01d0c66.js +0 -1
  130. package/dist/multi/53.app-d01d0c66.js +0 -1
  131. package/dist/multi/584.app-d01d0c66.js +0 -1
  132. package/dist/multi/690.app-d01d0c66.js +0 -1
  133. package/dist/multi/747.app-d01d0c66.js +0 -1
  134. package/dist/multi/767.app-d01d0c66.js +0 -1
  135. package/dist/multi/816.app-d01d0c66.js +0 -1
  136. package/dist/multi/83.app-d01d0c66.js +0 -1
  137. package/dist/multi/873.app-d01d0c66.js +0 -1
  138. package/dist/multi/920.app-d01d0c66.js +0 -1
  139. package/dist/multi/991.app-d01d0c66.js +0 -1
  140. package/dist/multi/app-d01d0c66.js +0 -2
  141. package/dist/multi/styles-d01d0c66.css +0 -39
  142. package/dist/single/app-6596cb08.js +0 -2
  143. package/src/components/LanguagePicker/index.tsx +0 -40
  144. package/src/components/ReportLogo/index.tsx +0 -16
  145. package/src/components/ReportLogo/styles.scss +0 -20
  146. package/src/components/ReportLogoFull/index.tsx +0 -20
  147. package/src/components/ReportLogoFull/styles.scss +0 -7
  148. package/src/components/TestResult/TestResultHeader/index.tsx +0 -21
  149. package/src/components/TestResult/TestResultOverview.tsx +0 -43
  150. package/src/components/ThemeButton/ThemeButton.tsx +0 -20
  151. package/src/i18n/constants.ts +0 -124
  152. /package/src/components/TestResult/{TestResultAttachmentsView → TrAttachmentsView}/styles.scss +0 -0
  153. /package/src/components/TestResult/{TestResultDescription → TrDescription}/styles.scss +0 -0
  154. /package/src/components/TestResult/{TestResultDropdown → TrDropdown}/styles.scss +0 -0
  155. /package/src/components/TestResult/{TestResultEmpty → TrEmpty}/styles.scss +0 -0
  156. /package/src/components/TestResult/{TestResultHeader → TrHeader}/styles.scss +0 -0
  157. /package/src/components/TestResult/{TestResultHistory → TrHistory}/styles.scss +0 -0
  158. /package/src/components/TestResult/{TestResultInfo → TrInfo}/styles.scss +0 -0
  159. /package/src/components/TestResult/{TestResultLinks → TrLinks}/styles.scss +0 -0
  160. /package/src/components/TestResult/{TestResultMetadata → TrMetadata}/styles.scss +0 -0
  161. /package/src/components/TestResult/{TestResultNavigation → TrNavigation}/styles.scss +0 -0
  162. /package/src/components/TestResult/{TestResultParameters → TrParameters}/styles.scss +0 -0
  163. /package/src/components/TestResult/{TestResultPrevStatuses → TrPrevStatuses}/styles.scss +0 -0
  164. /package/src/components/TestResult/{TestResultRetriesView → TrRetriesView}/styles.scss +0 -0
  165. /package/src/components/TestResult/{TestResultSeverity → TrSeverity}/styles.scss +0 -0
  166. /package/src/components/TestResult/{TestResultStatus → TrStatus}/styles.scss +0 -0
  167. /package/src/components/TestResult/{TestResultTabs → TrTabs}/styles.scss +0 -0
@@ -1,16 +1,17 @@
1
- import type { DefaultTestStepResult } from "@allurereport/core-api";
1
+ import type { DefaultTestStepResult, TestStepResult } from "@allurereport/core-api";
2
2
  import { Code, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
3
3
  import type { FunctionComponent } from "preact";
4
4
  import { useState } from "preact/hooks";
5
5
  import { ArrowButton } from "@/components/ArrowButton";
6
6
  import { MetadataList } from "@/components/Metadata";
7
7
  import { type MetadataItem } from "@/components/ReportMetadata";
8
- import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
9
- import { TestResultAttachment } from "@/components/TestResult/TestResultSteps/testResultAttachment";
10
- import { TestResultStepInfo } from "@/components/TestResult/TestResultSteps/testResultStepInfo";
8
+ import { TrError } from "@/components/TestResult/TrError";
9
+ import { TrAttachment } from "@/components/TestResult/TrSteps/TrAttachment";
10
+ import { TrStepInfo } from "@/components/TestResult/TrSteps/TrStepInfo";
11
+ import * as styles from "@/components/TestResult/TrSteps/styles.scss";
11
12
  import { collapsedTrees, toggleTree } from "@/stores/tree";
12
13
 
13
- export const TestResultStepParameters = (props: { parameters: DefaultTestStepResult["parameters"] }) => {
14
+ export const TrStepParameters = (props: { parameters: DefaultTestStepResult["parameters"] }) => {
14
15
  const { parameters } = props;
15
16
 
16
17
  return (
@@ -19,21 +20,22 @@ export const TestResultStepParameters = (props: { parameters: DefaultTestStepRes
19
20
  </div>
20
21
  );
21
22
  };
22
- export const TestResultStepsContent = (props: { item: DefaultTestStepResult }) => {
23
+ export const TrStepsContent = (props: { item: DefaultTestStepResult }) => {
23
24
  const { item } = props;
24
25
 
25
26
  return (
26
27
  <div className={styles["test-result-step-content"]}>
27
- {Boolean(item?.parameters?.length) && <TestResultStepParameters parameters={item.parameters} />}
28
+ {Boolean(item?.parameters?.length) && <TrStepParameters parameters={item.parameters} />}
29
+ {Boolean(item?.message && item?.trace) && <TrError {...item} />}
28
30
  {Boolean(item?.steps?.length) && (
29
31
  <>
30
32
  {item.steps?.map((subItem, key) => {
31
33
  if (subItem.type === "step") {
32
- return <TestResultStep stepIndex={key + 1} key={key} item={subItem} />;
34
+ return <TrStep stepIndex={key + 1} key={key} item={subItem} />;
33
35
  }
34
36
 
35
37
  if (subItem.type === "attachment") {
36
- return <TestResultAttachment stepIndex={key + 1} key={key} item={subItem} />;
38
+ return <TrAttachment stepIndex={key + 1} key={key} item={subItem} />;
37
39
  }
38
40
 
39
41
  return null;
@@ -44,14 +46,23 @@ export const TestResultStepsContent = (props: { item: DefaultTestStepResult }) =
44
46
  );
45
47
  };
46
48
 
47
- export const TestResultStep: FunctionComponent<{
49
+ const hasFailedStep = (step: TestStepResult): boolean => {
50
+ if (step.type !== "step") {
51
+ return false;
52
+ }
53
+
54
+ return step.status !== "passed" || step.steps.some(hasFailedStep);
55
+ };
56
+
57
+ export const TrStep: FunctionComponent<{
48
58
  item: DefaultTestStepResult;
49
59
  stepIndex?: number;
50
60
  className?: string;
51
61
  }> = ({ item, stepIndex }) => {
52
- const isEarlyOpened = collapsedTrees.value.has(item.stepId);
62
+ const haveFailedSteps = hasFailedStep(item);
63
+ const isEarlyOpened = collapsedTrees.value.has(item.stepId) ? false : Boolean(haveFailedSteps);
53
64
  const [isOpened, setIsOpen] = useState(isEarlyOpened || false);
54
- const hasContent = Boolean(item?.steps?.length || item?.parameters?.length);
65
+ const hasContent = Boolean(item?.steps?.length || item?.parameters?.length || item?.message || item?.trace);
55
66
 
56
67
  const handleClick = () => {
57
68
  setIsOpen(!isOpened);
@@ -76,9 +87,9 @@ export const TestResultStep: FunctionComponent<{
76
87
  {stepIndex}
77
88
  </Code>
78
89
  <Text className={styles["test-result-header-text"]}>{item.name}</Text>
79
- <TestResultStepInfo item={item} />
90
+ <TrStepInfo item={item} />
80
91
  </div>
81
- {hasContent && isOpened && <TestResultStepsContent item={item} />}
92
+ {hasContent && isOpened && <TrStepsContent item={item} />}
82
93
  </div>
83
94
  );
84
95
  };
@@ -1,8 +1,8 @@
1
1
  import { type DefaultTestStepResult, formatDuration } from "@allurereport/core-api";
2
2
  import { SvgIcon, Text, allureIcons } from "@allurereport/web-components";
3
- import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
3
+ import * as styles from "@/components/TestResult/TrSteps/styles.scss";
4
4
 
5
- export const TestResultStepInfo = (props: { item: DefaultTestStepResult }) => {
5
+ export const TrStepInfo = (props: { item: DefaultTestStepResult }) => {
6
6
  const { item } = props;
7
7
  const formattedDuration = formatDuration(item?.duration as number);
8
8
  const stepLength = item.steps?.length;
@@ -2,19 +2,19 @@ import { allureIcons } from "@allurereport/web-components";
2
2
  import type { FunctionalComponent } from "preact";
3
3
  import { useState } from "preact/hooks";
4
4
  import type { AwesomeTestResult, AwesomeTestStepResult } from "types";
5
- import { TestResultDropdown } from "@/components/TestResult/TestResultDropdown";
6
- import { TestResultAttachment } from "@/components/TestResult/TestResultSteps/testResultAttachment";
7
- import { TestResultStep } from "@/components/TestResult/TestResultSteps/testResultStep";
5
+ import { TrDropdown } from "@/components/TestResult/TrDropdown";
6
+ import { TrAttachment } from "@/components/TestResult/TrSteps/TrAttachment";
7
+ import { TrStep } from "@/components/TestResult/TrSteps/TrStep";
8
8
  import { useI18n } from "@/stores/locale";
9
9
  import { collapsedTrees, toggleTree } from "@/stores/tree";
10
10
  import * as styles from "./styles.scss";
11
11
 
12
12
  const typeMap = {
13
- step: TestResultStep,
14
- attachment: TestResultAttachment,
13
+ step: TrStep,
14
+ attachment: TrAttachment,
15
15
  } as const;
16
16
 
17
- export type TestResultStepsProps = {
17
+ export type TrStepsProps = {
18
18
  steps: AwesomeTestResult["steps"];
19
19
  id?: string;
20
20
  };
@@ -24,7 +24,7 @@ type StepComponentProps = FunctionalComponent<{
24
24
  stepIndex?: number;
25
25
  }>;
26
26
 
27
- export const TestResultSteps: FunctionalComponent<TestResultStepsProps> = ({ steps, id }) => {
27
+ export const TrSteps: FunctionalComponent<TrStepsProps> = ({ steps, id }) => {
28
28
  const stepsId = `${id}-steps`;
29
29
  const isEarlyCollapsed = Boolean(!collapsedTrees.value.has(stepsId));
30
30
  const [isOpened, setIsOpen] = useState<boolean>(isEarlyCollapsed);
@@ -37,7 +37,7 @@ export const TestResultSteps: FunctionalComponent<TestResultStepsProps> = ({ ste
37
37
  const { t } = useI18n("execution");
38
38
  return (
39
39
  <div className={styles["test-result-steps"]}>
40
- <TestResultDropdown
40
+ <TrDropdown
41
41
  icon={allureIcons.lineHelpersPlayCircle}
42
42
  isOpened={isOpened}
43
43
  setIsOpen={handleClick}
@@ -56,6 +56,7 @@
56
56
  .test-result-header-text {
57
57
  padding-left: 4px;
58
58
  word-break: break-word;
59
+ margin-right: auto;
59
60
  }
60
61
 
61
62
  .test-result-step-button {
@@ -82,7 +83,6 @@
82
83
  }
83
84
 
84
85
  .item-info {
85
- margin-left: auto;
86
86
  display: flex;
87
87
  gap: 8px;
88
88
  color: var(--on-text-secondary);
@@ -151,6 +151,7 @@
151
151
  .test-result-attachment-text {
152
152
  padding-left: 4px;
153
153
  word-break: break-word;
154
+ margin-right: auto;
154
155
  }
155
156
 
156
157
  .test-result-attachment-image {
@@ -1,4 +1,4 @@
1
- import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
1
+ import * as styles from "@/components/TestResult/TrSteps/styles.scss";
2
2
  import { useI18n } from "@/stores";
3
3
 
4
4
  export const EmptyComponent = () => {
@@ -4,18 +4,18 @@ import { useContext, useEffect, useState } from "preact/hooks";
4
4
  import { activeTab, navigateTo, route } from "@/stores/router";
5
5
  import * as styles from "./styles.scss";
6
6
 
7
- type TestResultTabsContextT = {
7
+ type TrTabsContextT = {
8
8
  currentTab: string | undefined;
9
9
  setCurrentTab: (id: string) => void;
10
10
  };
11
11
 
12
- const TestResultTabsContext = createContext<TestResultTabsContextT | null>(null);
12
+ const TestResultTabsContext = createContext<TrTabsContextT | null>(null);
13
13
 
14
14
  export const useTestResultTabsContext = () => {
15
15
  const context = useContext(TestResultTabsContext);
16
16
 
17
17
  if (!context) {
18
- throw new Error("TestResultTabs components must be used within a TestResultTabs component");
18
+ throw new Error("TestResultTabs components must be used within a TrTabs component");
19
19
  }
20
20
 
21
21
  return context;
@@ -30,15 +30,15 @@ export const TestResultTabsProvider = (props: { initialTab?: string; children: C
30
30
  );
31
31
  };
32
32
 
33
- export const TestResultTabs = (props: { children: ComponentChildren; initialTab?: string }) => {
33
+ export const TrTabs = (props: { children: ComponentChildren; initialTab?: string }) => {
34
34
  return <TestResultTabsProvider {...props} />;
35
35
  };
36
36
 
37
- export const TestResultTabsList = (props: { children: ComponentChildren }) => {
37
+ export const TrTabsList = (props: { children: ComponentChildren }) => {
38
38
  return <div className={styles.tabsList}>{props.children}</div>;
39
39
  };
40
40
 
41
- export const TestResultTab = (props: { id: string; children: ComponentChildren; disabled?: boolean }) => {
41
+ export const TrTab = (props: { id: string; children: ComponentChildren; disabled?: boolean }) => {
42
42
  const { currentTab, setCurrentTab } = useTestResultTabsContext();
43
43
  const { id, children } = props;
44
44
  const isActiveFromUrl = activeTab.value === id;
@@ -2,26 +2,26 @@ import { allureIcons } from "@allurereport/web-components";
2
2
  import type { FunctionalComponent } from "preact";
3
3
  import { useState } from "preact/hooks";
4
4
  import type { AwesomeTestResult } from "types";
5
- import { TestResultDropdown } from "@/components/TestResult/TestResultDropdown";
6
- import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
7
- import { TestResultAttachment } from "@/components/TestResult/TestResultSteps/testResultAttachment";
8
- import { TestResultStep } from "@/components/TestResult/TestResultSteps/testResultStep";
5
+ import { TrDropdown } from "@/components/TestResult/TrDropdown";
6
+ import { TrAttachment } from "@/components/TestResult/TrSteps/TrAttachment";
7
+ import { TrStep } from "@/components/TestResult/TrSteps/TrStep";
8
+ import * as styles from "@/components/TestResult/TrSteps/styles.scss";
9
9
  import { useI18n } from "@/stores/locale";
10
10
  import { collapsedTrees, toggleTree } from "@/stores/tree";
11
11
 
12
12
  const typeMap = {
13
- before: TestResultStep,
14
- after: TestResultStep,
15
- step: TestResultStep,
16
- attachment: TestResultAttachment,
13
+ before: TrStep,
14
+ after: TrStep,
15
+ step: TrStep,
16
+ attachment: TrAttachment,
17
17
  };
18
18
 
19
- export type TestResultTeardownProps = {
19
+ export type TrTeardownProps = {
20
20
  teardown: AwesomeTestResult["teardown"];
21
21
  id: string;
22
22
  };
23
23
 
24
- export const TestResultTeardown: FunctionalComponent<TestResultTeardownProps> = ({ teardown, id }) => {
24
+ export const TrTeardown: FunctionalComponent<TrTeardownProps> = ({ teardown, id }) => {
25
25
  const teardownId = `${id}-teardown`;
26
26
  const isEarlyCollapsed = !collapsedTrees.value.has(teardownId);
27
27
  const [isOpened, setIsOpen] = useState<boolean>(isEarlyCollapsed);
@@ -35,7 +35,7 @@ export const TestResultTeardown: FunctionalComponent<TestResultTeardownProps> =
35
35
 
36
36
  return (
37
37
  <div className={styles["test-result-steps"]}>
38
- <TestResultDropdown
38
+ <TrDropdown
39
39
  icon={allureIcons.lineHelpersFlag}
40
40
  isOpened={isOpened}
41
41
  setIsOpen={handleClick}
@@ -1,59 +1,71 @@
1
1
  import clsx from "clsx";
2
2
  import type { FunctionComponent, FunctionalComponent } from "preact";
3
+ import { useEffect } from "preact/hooks";
3
4
  import type { AwesomeTestResult } from "types";
4
- import { TestResultAttachmentView } from "@/components/TestResult/TestResultAttachmentsView";
5
- import TestResultEmpty from "@/components/TestResult/TestResultEmpty";
6
- import { TestResultHeader } from "@/components/TestResult/TestResultHeader";
7
- import TestResultHistoryView from "@/components/TestResult/TestResultHistory";
8
- import { TestResultInfo } from "@/components/TestResult/TestResultInfo";
9
- import { TestResultOverview } from "@/components/TestResult/TestResultOverview";
10
- import { TestResultRetriesView } from "@/components/TestResult/TestResultRetriesView";
11
- import { TestResultTabs, useTestResultTabsContext } from "@/components/TestResult/TestResultTabs";
5
+ import { TrAttachmentView } from "@/components/TestResult/TrAttachmentsView";
6
+ import TrEmpty from "@/components/TestResult/TrEmpty";
7
+ import { TrEnvironmentsView } from "@/components/TestResult/TrEnvironmentsView";
8
+ import { TrHeader } from "@/components/TestResult/TrHeader";
9
+ import TrHistoryView from "@/components/TestResult/TrHistory";
10
+ import { TrInfo } from "@/components/TestResult/TrInfo";
11
+ import { TrOverview } from "@/components/TestResult/TrOverview";
12
+ import { TrRetriesView } from "@/components/TestResult/TrRetriesView";
13
+ import { TrTabs, useTestResultTabsContext } from "@/components/TestResult/TrTabs";
14
+ import { fetchTestEnvGroup } from "@/stores/env";
12
15
  import { isSplitMode } from "@/stores/layout";
13
16
  import * as styles from "./styles.scss";
14
17
 
15
- export type TestResultViewProps = {
18
+ export type TrViewProps = {
16
19
  testResult?: AwesomeTestResult;
17
20
  };
18
21
 
19
- const TestResultView: FunctionalComponent<TestResultViewProps> = ({ testResult }) => {
22
+ export type TrContentProps = {
23
+ testResult?: AwesomeTestResult;
24
+ };
25
+
26
+ export type TrProps = {
27
+ testResult?: AwesomeTestResult;
28
+ };
29
+
30
+ const TrView: FunctionalComponent<TrViewProps> = ({ testResult }) => {
20
31
  const { currentTab } = useTestResultTabsContext();
21
32
  const viewMap: Record<string, any> = {
22
- overview: TestResultOverview,
23
- history: TestResultHistoryView,
24
- attachments: TestResultAttachmentView,
25
- retries: TestResultRetriesView,
33
+ overview: TrOverview,
34
+ history: TrHistoryView,
35
+ attachments: TrAttachmentView,
36
+ retries: TrRetriesView,
37
+ environments: TrEnvironmentsView,
26
38
  };
27
39
  const ViewComponent = viewMap[currentTab];
28
40
 
29
41
  return <ViewComponent testResult={testResult} />;
30
42
  };
31
43
 
32
- export type TestResultContentProps = {
33
- testResult?: AwesomeTestResult;
34
- };
35
-
36
- const TestResultContent: FunctionalComponent<TestResultContentProps> = ({ testResult }) => {
44
+ const TrContent: FunctionalComponent<TrContentProps> = ({ testResult }) => {
37
45
  return (
38
- <TestResultTabs initialTab="overview">
39
- <TestResultInfo testResult={testResult} />
40
- <TestResultView testResult={testResult} />
41
- </TestResultTabs>
46
+ <TrTabs initialTab="overview">
47
+ <TrInfo testResult={testResult} />
48
+ <TrView testResult={testResult} />
49
+ </TrTabs>
42
50
  );
43
51
  };
44
52
 
45
- export type TestResultProps = {
46
- testResult?: AwesomeTestResult;
47
- };
48
-
49
- const TestResult: FunctionComponent<TestResultProps> = ({ testResult }) => {
53
+ const TestResult: FunctionComponent<TrProps> = ({ testResult }) => {
50
54
  const splitModeClass = isSplitMode.value ? styles["scroll-inside"] : "";
51
55
 
56
+ useEffect(() => {
57
+ const testCaseId = testResult?.testCase?.id;
58
+
59
+ if (testCaseId) {
60
+ fetchTestEnvGroup(testCaseId);
61
+ }
62
+ }, [testResult]);
63
+
52
64
  return (
53
65
  <>
54
- {!isSplitMode.value && <TestResultHeader testResult={testResult} />}
66
+ {!isSplitMode.value && <TrHeader testResult={testResult} />}
55
67
  <div className={clsx(styles.content, splitModeClass)}>
56
- {testResult ? <TestResultContent testResult={testResult} /> : <TestResultEmpty />}
68
+ {testResult ? <TrContent testResult={testResult} /> : <TrEmpty />}
57
69
  </div>
58
70
  </>
59
71
  );
@@ -7,5 +7,6 @@
7
7
 
8
8
  .scroll-inside {
9
9
  overflow: auto;
10
- height: calc(100vh - var(--footer-header-sizes));
10
+ height: 100%;
11
+ border-radius: 0;
11
12
  }
@@ -1,9 +1,11 @@
1
- import { Button, Loadable, PageLoader, Text, Tree } from "@allurereport/web-components";
1
+ import { Button, Loadable, PageLoader, Text, Tree, TreeStatusBar } from "@allurereport/web-components";
2
2
  import type { AwesomeStatus } from "types";
3
+ import { MetadataButton } from "@/components/MetadataButton";
3
4
  import { useTabsContext } from "@/components/Tabs";
4
- import { statsStore } from "@/stores";
5
+ import { reportStatsStore, statsByEnvStore } from "@/stores";
6
+ import { collapsedEnvironments, currentEnvironment, environmentsStore } from "@/stores/env";
5
7
  import { useI18n } from "@/stores/locale";
6
- import { navigateTo } from "@/stores/router";
8
+ import { navigateTo, route } from "@/stores/router";
7
9
  import {
8
10
  clearTreeFilters,
9
11
  collapsedTrees,
@@ -11,20 +13,22 @@ import {
11
13
  noTests,
12
14
  noTestsFound,
13
15
  toggleTree,
14
- treeFiltersStore,
15
16
  treeStore,
16
17
  } from "@/stores/tree";
17
18
  import * as styles from "./styles.scss";
18
19
 
19
20
  export const TreeList = () => {
20
21
  const { t } = useI18n("empty");
22
+ const { t: tEnvironments } = useI18n("environments");
21
23
  const { currentTab } = useTabsContext();
24
+ const { id: routeId } = route.value;
22
25
 
23
26
  return (
24
27
  <Loadable
25
28
  source={treeStore}
26
29
  renderLoader={() => <PageLoader />}
27
30
  renderData={() => {
31
+ // TODO: use function instead of computed
28
32
  if (noTests.value) {
29
33
  return (
30
34
  <div className={styles["tree-list"]}>
@@ -55,19 +59,98 @@ export const TreeList = () => {
55
59
  );
56
60
  }
57
61
 
62
+ // render single tree for single environment
63
+ if (environmentsStore.value.data.length === 1) {
64
+ return (
65
+ <div className={styles["tree-list"]}>
66
+ <Tree
67
+ reportStatistic={reportStatsStore.value.data}
68
+ statistic={statsByEnvStore.value.data[currentEnvironment.value]}
69
+ collapsedTrees={collapsedTrees.value}
70
+ toggleTree={toggleTree}
71
+ navigateTo={navigateTo}
72
+ tree={filteredTree.value.default}
73
+ statusFilter={currentTab as AwesomeStatus}
74
+ routeId={routeId}
75
+ root
76
+ />
77
+ </div>
78
+ );
79
+ }
80
+
81
+ const currentTree = currentEnvironment.value ? filteredTree.value[currentEnvironment.value] : undefined;
82
+
83
+ if (currentTree) {
84
+ return (
85
+ <div className={styles["tree-list"]}>
86
+ <Tree
87
+ reportStatistic={reportStatsStore.value.data}
88
+ statistic={statsByEnvStore.value.data[currentEnvironment.value]}
89
+ collapsedTrees={collapsedTrees.value}
90
+ toggleTree={toggleTree}
91
+ navigateTo={navigateTo}
92
+ tree={currentTree}
93
+ statusFilter={currentTab as AwesomeStatus}
94
+ routeId={routeId}
95
+ root
96
+ />
97
+ </div>
98
+ );
99
+ }
100
+
101
+ // render tree section for every environment
58
102
  return (
59
- <div className={styles["tree-list"]}>
60
- <Tree
61
- collapsedTrees={collapsedTrees.value}
62
- toggleTree={toggleTree}
63
- treeFiltersStore={treeFiltersStore}
64
- navigateTo={navigateTo}
65
- statsStore={statsStore}
66
- tree={filteredTree.value}
67
- statusFilter={currentTab as AwesomeStatus}
68
- root
69
- />
70
- </div>
103
+ <>
104
+ {Object.entries(filteredTree.value).map(([key, value]) => {
105
+ const { total } = value.statistic;
106
+
107
+ if (total === 0) {
108
+ return null;
109
+ }
110
+
111
+ const isOpened = !collapsedEnvironments.value.includes(key);
112
+ const toggleEnv = () => {
113
+ collapsedEnvironments.value = isOpened
114
+ ? collapsedEnvironments.value.concat(key)
115
+ : collapsedEnvironments.value.filter((env) => env !== key);
116
+ };
117
+ const stats = statsByEnvStore.value.data[key];
118
+
119
+ return (
120
+ <div key={key} className={styles["tree-section"]} data-testid={"tree-section"}>
121
+ <div className={styles["tree-env-button"]}>
122
+ <MetadataButton
123
+ isOpened={isOpened}
124
+ setIsOpen={toggleEnv}
125
+ title={`${tEnvironments("environment", { count: 1 })}: "${key}"`}
126
+ counter={total}
127
+ data-testid={"tree-section-env-button"}
128
+ />
129
+ <TreeStatusBar
130
+ statistic={stats}
131
+ reportStatistic={reportStatsStore.value.data}
132
+ statusFilter={currentTab}
133
+ />
134
+ </div>
135
+ {isOpened && (
136
+ <div className={styles["tree-list"]} data-testid={"tree-section-env-content"}>
137
+ <Tree
138
+ statistic={statsByEnvStore.value.data[key]}
139
+ reportStatistic={reportStatsStore.value.data}
140
+ collapsedTrees={collapsedTrees.value}
141
+ toggleTree={toggleTree}
142
+ statusFilter={currentTab}
143
+ navigateTo={navigateTo}
144
+ tree={value}
145
+ routeId={routeId}
146
+ root
147
+ />
148
+ </div>
149
+ )}
150
+ </div>
151
+ );
152
+ })}
153
+ </>
71
154
  );
72
155
  }}
73
156
  />
@@ -7,7 +7,7 @@
7
7
  }
8
8
 
9
9
  .tree-list {
10
- min-height: 128px;
10
+ min-height: 320px;
11
11
  }
12
12
 
13
13
  .tree-header {
@@ -187,3 +187,18 @@
187
187
  .tree-item-marked {
188
188
  background: var(--bg-base-secondary);
189
189
  }
190
+
191
+ .tree-section {
192
+ &:not(:last-child) {
193
+ padding-bottom: 8px;
194
+ margin-bottom: 14px;
195
+ border-bottom: 1px solid var(--on-border-muted);
196
+ }
197
+ }
198
+
199
+ .tree-env-button {
200
+ display: flex;
201
+ align-items: center;
202
+ justify-content: space-between;
203
+ padding: 0 8px 0 6px;
204
+ }
package/src/index.tsx CHANGED
@@ -3,18 +3,19 @@ import { Spinner, SvgIcon, allureIcons } from "@allurereport/web-components";
3
3
  import "@allurereport/web-components/index.css";
4
4
  import clsx from "clsx";
5
5
  import { render } from "preact";
6
- import { useEffect } from "preact/hooks";
6
+ import { useEffect, useState } from "preact/hooks";
7
7
  import "@/assets/scss/index.scss";
8
8
  import { BaseLayout } from "@/components/BaseLayout";
9
9
  import { ModalComponent } from "@/components/Modal";
10
10
  import { SplitLayout } from "@/components/SplitLayout";
11
- import { fetchStats, getLocale, getTheme, waitForI18next } from "@/stores";
11
+ import { fetchEnvStats, fetchReportStats, getLocale, getTheme, waitForI18next } from "@/stores";
12
12
  import { fetchPieChartData } from "@/stores/chart";
13
+ import { currentEnvironment, environmentsStore, fetchEnvironments } from "@/stores/env";
13
14
  import { fetchEnvInfo } from "@/stores/envInfo";
14
15
  import { getLayout, isLayoutLoading, isSplitMode } from "@/stores/layout";
15
16
  import { handleHashChange, route } from "@/stores/router";
16
17
  import { fetchTestResult, fetchTestResultNav } from "@/stores/testResults";
17
- import { fetchTreeData } from "@/stores/tree";
18
+ import { fetchEnvTreesData } from "@/stores/tree";
18
19
  import { isMac } from "@/utils/isMac";
19
20
  import * as styles from "./styles.scss";
20
21
 
@@ -26,28 +27,40 @@ const Loader = () => {
26
27
  </div>
27
28
  );
28
29
  };
30
+
29
31
  const App = () => {
32
+ const [prefetched, setPrefetched] = useState(false);
30
33
  const { id: testResultId } = route.value;
34
+ const prefetchData = async () => {
35
+ const fns = [ensureReportDataReady, fetchReportStats, fetchPieChartData, fetchEnvironments, fetchEnvInfo];
31
36
 
32
- useEffect(() => {
33
37
  if (globalThis) {
34
- getLocale();
35
- getLayout();
36
- getTheme();
38
+ fns.unshift(getLocale, getLayout as () => Promise<void>, getTheme as () => Promise<void>);
39
+ }
40
+
41
+ await waitForI18next;
42
+ await Promise.all(fns.map((fn) => fn(currentEnvironment.value)));
43
+
44
+ if (currentEnvironment.value) {
45
+ await fetchEnvTreesData([currentEnvironment.value]);
46
+ } else {
47
+ await fetchEnvTreesData(environmentsStore.value.data);
48
+ await fetchEnvStats(environmentsStore.value.data);
37
49
  }
38
- ensureReportDataReady();
39
- fetchStats();
40
- fetchEnvInfo();
41
- fetchPieChartData();
42
- fetchTreeData();
43
- }, []);
50
+
51
+ setPrefetched(true);
52
+ };
53
+
54
+ useEffect(() => {
55
+ prefetchData();
56
+ }, [currentEnvironment.value]);
44
57
 
45
58
  useEffect(() => {
46
59
  if (testResultId) {
47
60
  fetchTestResult(testResultId);
48
- fetchTestResultNav();
61
+ fetchTestResultNav(currentEnvironment.value);
49
62
  }
50
- }, [testResultId]);
63
+ }, [testResultId, currentEnvironment]);
51
64
 
52
65
  useEffect(() => {
53
66
  handleHashChange();
@@ -60,9 +73,13 @@ const App = () => {
60
73
 
61
74
  return (
62
75
  <div className={styles.main}>
63
- <Loader />
64
- {isSplitMode.value ? <SplitLayout /> : <BaseLayout />}
65
- <ModalComponent />
76
+ {!prefetched && <Loader />}
77
+ {prefetched && (
78
+ <>
79
+ {isSplitMode.value ? <SplitLayout /> : <BaseLayout />}
80
+ <ModalComponent />
81
+ </>
82
+ )}
66
83
  </div>
67
84
  );
68
85
  };
@@ -79,18 +96,4 @@ document.addEventListener("DOMContentLoaded", () => {
79
96
  }
80
97
  });
81
98
 
82
- (async () => {
83
- await waitForI18next;
84
- if (globalThis) {
85
- await getLocale();
86
- getLayout();
87
- getTheme();
88
- }
89
- await ensureReportDataReady();
90
- await fetchStats();
91
- await fetchEnvInfo();
92
- await fetchPieChartData();
93
- await fetchTreeData();
94
-
95
- render(<App />, rootElement);
96
- })();
99
+ render(<App />, rootElement);