@allurereport/web-awesome 3.7.0 → 3.8.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 (33) hide show
  1. package/dist/multi/app-740cc9d690fe65dc28b0.js +2 -0
  2. package/dist/multi/manifest.json +22 -22
  3. package/dist/single/{app-c06dada6aab4e69b7f74.js → app-71a9c3c616953bdbd06a.js} +2 -2
  4. package/dist/single/manifest.json +1 -1
  5. package/package.json +6 -6
  6. package/src/components/TestResult/TrDescription/index.tsx +12 -7
  7. package/src/components/TestResult/TrSteps/index.tsx +8 -8
  8. package/src/utils/treeFilters.ts +16 -6
  9. package/test/utils/treeFilters.test.ts +84 -5
  10. package/dist/multi/app-2db623c010c07fd8a909.js +0 -2
  11. /package/dist/multi/{173.app-2db623c010c07fd8a909.js → 173.app-740cc9d690fe65dc28b0.js} +0 -0
  12. /package/dist/multi/{174.app-2db623c010c07fd8a909.js → 174.app-740cc9d690fe65dc28b0.js} +0 -0
  13. /package/dist/multi/{252.app-2db623c010c07fd8a909.js → 252.app-740cc9d690fe65dc28b0.js} +0 -0
  14. /package/dist/multi/{282.app-2db623c010c07fd8a909.js → 282.app-740cc9d690fe65dc28b0.js} +0 -0
  15. /package/dist/multi/{29.app-2db623c010c07fd8a909.js → 29.app-740cc9d690fe65dc28b0.js} +0 -0
  16. /package/dist/multi/{310.app-2db623c010c07fd8a909.js → 310.app-740cc9d690fe65dc28b0.js} +0 -0
  17. /package/dist/multi/{416.app-2db623c010c07fd8a909.js → 416.app-740cc9d690fe65dc28b0.js} +0 -0
  18. /package/dist/multi/{507.app-2db623c010c07fd8a909.js → 507.app-740cc9d690fe65dc28b0.js} +0 -0
  19. /package/dist/multi/{527.app-2db623c010c07fd8a909.js → 527.app-740cc9d690fe65dc28b0.js} +0 -0
  20. /package/dist/multi/{600.app-2db623c010c07fd8a909.js → 600.app-740cc9d690fe65dc28b0.js} +0 -0
  21. /package/dist/multi/{605.app-2db623c010c07fd8a909.js → 605.app-740cc9d690fe65dc28b0.js} +0 -0
  22. /package/dist/multi/{638.app-2db623c010c07fd8a909.js → 638.app-740cc9d690fe65dc28b0.js} +0 -0
  23. /package/dist/multi/{672.app-2db623c010c07fd8a909.js → 672.app-740cc9d690fe65dc28b0.js} +0 -0
  24. /package/dist/multi/{686.app-2db623c010c07fd8a909.js → 686.app-740cc9d690fe65dc28b0.js} +0 -0
  25. /package/dist/multi/{725.app-2db623c010c07fd8a909.js → 725.app-740cc9d690fe65dc28b0.js} +0 -0
  26. /package/dist/multi/{741.app-2db623c010c07fd8a909.js → 741.app-740cc9d690fe65dc28b0.js} +0 -0
  27. /package/dist/multi/{749.app-2db623c010c07fd8a909.js → 749.app-740cc9d690fe65dc28b0.js} +0 -0
  28. /package/dist/multi/{755.app-2db623c010c07fd8a909.js → 755.app-740cc9d690fe65dc28b0.js} +0 -0
  29. /package/dist/multi/{894.app-2db623c010c07fd8a909.js → 894.app-740cc9d690fe65dc28b0.js} +0 -0
  30. /package/dist/multi/{943.app-2db623c010c07fd8a909.js → 943.app-740cc9d690fe65dc28b0.js} +0 -0
  31. /package/dist/multi/{980.app-2db623c010c07fd8a909.js → 980.app-740cc9d690fe65dc28b0.js} +0 -0
  32. /package/dist/multi/{app-2db623c010c07fd8a909.js.LICENSE.txt → app-740cc9d690fe65dc28b0.js.LICENSE.txt} +0 -0
  33. /package/dist/single/{app-c06dada6aab4e69b7f74.js.LICENSE.txt → app-71a9c3c616953bdbd06a.js.LICENSE.txt} +0 -0
@@ -1,3 +1,3 @@
1
1
  {
2
- "main.js": "app-c06dada6aab4e69b7f74.js"
2
+ "main.js": "app-71a9c3c616953bdbd06a.js"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/web-awesome",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "The static files for Allure Awesome Report",
5
5
  "keywords": [
6
6
  "allure",
@@ -27,11 +27,11 @@
27
27
  "lint:fix": "oxlint --import-plugin --fix src test features stories"
28
28
  },
29
29
  "dependencies": {
30
- "@allurereport/charts-api": "3.7.0",
31
- "@allurereport/core-api": "3.7.0",
32
- "@allurereport/plugin-api": "3.7.0",
33
- "@allurereport/web-commons": "3.7.0",
34
- "@allurereport/web-components": "3.7.0",
30
+ "@allurereport/charts-api": "3.8.0",
31
+ "@allurereport/core-api": "3.8.0",
32
+ "@allurereport/plugin-api": "3.8.0",
33
+ "@allurereport/web-commons": "3.8.0",
34
+ "@allurereport/web-components": "3.8.0",
35
35
  "@preact/signals": "^2.6.1",
36
36
  "clsx": "^2.1.1",
37
37
  "d3-shape": "^3.2.0",
@@ -13,13 +13,20 @@ export type TrDescriptionProps = {
13
13
  descriptionHtml: AwesomeTestResult["descriptionHtml"];
14
14
  };
15
15
 
16
- const MIN_HEIGHT = 120;
16
+ const getIframeContentHeight = (iframe: HTMLIFrameElement) => {
17
+ const documentElement = iframe.contentDocument?.documentElement;
18
+ const body = iframe.contentDocument?.body;
19
+ const bodyRectHeight = body?.getBoundingClientRect().height ?? 0;
20
+ const scrollHeight = Math.max(body?.scrollHeight ?? 0, documentElement?.scrollHeight ?? 0);
21
+
22
+ return Math.ceil(Math.max(bodyRectHeight, scrollHeight));
23
+ };
17
24
 
18
25
  export const TrDescription: FunctionalComponent<TrDescriptionProps> = ({ id, descriptionHtml }) => {
19
- const descriptionId = id !== null ? `${id}-description` : null;
26
+ const descriptionId = typeof id === "string" ? `${id}-description` : null;
20
27
  const isOpen = !collapsedTrees.value.has(descriptionId);
21
28
  const [blobUrl, setBlobUrl] = useState("");
22
- const [height, setHeight] = useState(MIN_HEIGHT);
29
+ const [height, setHeight] = useState(0);
23
30
  const currentTheme = themeStore.value.current;
24
31
 
25
32
  const sanitized = useMemo(() => (descriptionHtml ? sanitizeIframeHtml(descriptionHtml) : ""), [descriptionHtml]);
@@ -51,10 +58,7 @@ export const TrDescription: FunctionalComponent<TrDescriptionProps> = ({ id, des
51
58
 
52
59
  const handleLoad = (e: Event) => {
53
60
  const iframe = e.currentTarget as HTMLIFrameElement;
54
- const documentElement = iframe.contentDocument?.documentElement;
55
- const body = iframe.contentDocument?.body;
56
- const scrollHeight = Math.max(documentElement?.scrollHeight ?? 0, body?.scrollHeight ?? 0);
57
- setHeight(Math.max(scrollHeight, MIN_HEIGHT));
61
+ setHeight(getIframeContentHeight(iframe));
58
62
  };
59
63
 
60
64
  return (
@@ -74,6 +78,7 @@ export const TrDescription: FunctionalComponent<TrDescriptionProps> = ({ id, des
74
78
  {blobUrl && (
75
79
  <iframe
76
80
  data-testid="test-result-description-frame"
81
+ title="Description"
77
82
  src={blobUrl}
78
83
  width="100%"
79
84
  height={String(height)}
@@ -9,9 +9,7 @@ import {
9
9
  getNextSubtreeToggleState,
10
10
  getSubtreeToggleIcon,
11
11
  getStepTreeExpansionPolicy,
12
- hasFailedStepContext,
13
12
  isSubtreeFirstLevelOnlyOpened,
14
- isOpenByDefaultForPolicy,
15
13
  type SubtreeNode,
16
14
  type SubtreeToggleState,
17
15
  } from "@/components/TestResult/TrSteps/stepTreeExpansion";
@@ -36,21 +34,23 @@ export type TrStepsProps = {
36
34
  export const TrSteps: FunctionalComponent<TrStepsProps> = ({ bodyItems, id }) => {
37
35
  const stepsId = typeof id === "string" ? `${id}-steps` : null;
38
36
  const policy = getStepTreeExpansionPolicy();
39
- const openedByDefault = isOpenByDefaultForPolicy(policy, hasFailedStepContext(bodyItems));
40
- const isOpened = stepsId !== null ? isTreeOpened(stepsId, openedByDefault) : openedByDefault;
37
+ const isRootOpenedByDefault = policy !== "collapsed";
38
+ const isOpened = stepsId !== null ? isTreeOpened(stepsId, isRootOpenedByDefault) : isRootOpenedByDefault;
41
39
  const expandableTreeNodes = collectExpandableStepNodes(bodyItems, policy);
42
40
  const hasChildren = stepsId !== null && bodyItems.length > 0;
43
41
  const subtreeNodes: SubtreeNode[] = hasChildren
44
42
  ? [
45
- { id: stepsId, openedByDefault, isRoot: true },
43
+ { id: stepsId, openedByDefault: isRootOpenedByDefault, isRoot: true },
46
44
  ...expandableTreeNodes.map((node) => ({ ...node, isRoot: false })),
47
45
  ]
48
46
  : [];
49
47
  const [lastSubtreeToggle, setLastSubtreeToggle] = useState<SubtreeToggleState | null>(null);
50
- const isRootSubtreeOpened = stepsId !== null ? isTreeOpened(stepsId, openedByDefault) : false;
48
+ const isRootSubtreeOpened = stepsId !== null ? isTreeOpened(stepsId, isRootOpenedByDefault) : false;
51
49
  const isSubtreeCollapsedAll = !isRootSubtreeOpened;
52
50
  const isSubtreeFirstLevelOnly =
53
- stepsId !== null ? isSubtreeFirstLevelOnlyOpened(stepsId, openedByDefault, subtreeNodes, isTreeOpened) : false;
51
+ stepsId !== null
52
+ ? isSubtreeFirstLevelOnlyOpened(stepsId, isRootOpenedByDefault, subtreeNodes, isTreeOpened)
53
+ : false;
54
54
  const isSubtreeExpandedAll = hasChildren && subtreeNodes.every((node) => isTreeOpened(node.id, node.openedByDefault));
55
55
  const hasOnlyLeafResults = hasChildren && subtreeNodes.every((node) => node.isRoot);
56
56
  const subtreeToggleIcon =
@@ -89,7 +89,7 @@ export const TrSteps: FunctionalComponent<TrStepsProps> = ({ bodyItems, id }) =>
89
89
  return;
90
90
  }
91
91
  setLastSubtreeToggle(null);
92
- toggleTree(stepsId, openedByDefault);
92
+ toggleTree(stepsId, isRootOpenedByDefault);
93
93
  };
94
94
 
95
95
  const { t } = useI18n("execution");
@@ -58,18 +58,28 @@ const groupComparatorByTreeSortBy = (sortBy: SortBy = "status,asc"): Comparator<
58
58
  }
59
59
  };
60
60
 
61
+ const withDirection = <T extends { name: string }>(cmp: Comparator<T>, sortBy: SortBy): Comparator<T> => {
62
+ const sortParams = sortBy.split(",");
63
+ const isStatusSort = sortParams.includes("status");
64
+ const isDescending = sortParams.includes("desc");
65
+ const nameComparator = compareBy<T>("name", alphabetically());
66
+
67
+ return andThen([
68
+ isDescending && !isStatusSort ? reverse(cmp) : cmp,
69
+ isDescending && isStatusSort ? reverse(nameComparator) : nameComparator,
70
+ ]);
71
+ };
72
+
61
73
  export const leafComparator = (sortBy: SortBy = "status,asc"): Comparator<TreeLeaf<AwesomeTreeLeaf>> => {
62
74
  const cmp = leafComparatorByTreeSortBy(sortBy);
63
- const directional = sortBy.split(",")[1] === "asc" ? cmp : reverse(cmp);
64
- // apply fallback sorting by name
65
- return andThen([directional, compareBy("name", alphabetically())]);
75
+
76
+ return withDirection(cmp, sortBy);
66
77
  };
67
78
 
68
79
  export const groupComparator = (sortBy: SortBy = "status,asc"): Comparator<DefaultTreeGroup> => {
69
80
  const cmp = groupComparatorByTreeSortBy(sortBy);
70
- const directional = sortBy.split(",")[1] === "asc" ? cmp : reverse(cmp);
71
- // apply fallback sorting by name
72
- return andThen([directional, compareBy("name", alphabetically())]);
81
+
82
+ return withDirection(cmp, sortBy);
73
83
  };
74
84
 
75
85
  export const filterLeaves = (
@@ -138,7 +138,7 @@ describe("utils > treeFilters", () => {
138
138
  });
139
139
 
140
140
  it("sorts leaves by status in descending order", () => {
141
- const leaves = ["a1", "b2", "c3", "d4", "e5"];
141
+ const leaves = ["a1", "b2", "c3", "d4", "e5", "f6", "z9"];
142
142
  const leavesById = {
143
143
  a1: {
144
144
  name: "a1",
@@ -160,15 +160,25 @@ describe("utils > treeFilters", () => {
160
160
  name: "e5",
161
161
  status: "skipped",
162
162
  } as AwesomeTestResult,
163
+ f6: {
164
+ name: "f6",
165
+ status: "failed",
166
+ } as AwesomeTestResult,
167
+ z9: {
168
+ name: "z9",
169
+ status: "passed",
170
+ } as AwesomeTestResult,
163
171
  };
164
172
  const result = filterLeaves(leaves, leavesById as any, alwaysTruePredicate, "status,desc");
165
173
 
166
174
  expect(result).toEqual([
167
- expect.objectContaining({ name: "d4" }),
168
- expect.objectContaining({ name: "e5" }),
169
- expect.objectContaining({ name: "a1" }),
170
- expect.objectContaining({ name: "c3" }),
175
+ expect.objectContaining({ name: "f6" }),
171
176
  expect.objectContaining({ name: "b2" }),
177
+ expect.objectContaining({ name: "c3" }),
178
+ expect.objectContaining({ name: "z9" }),
179
+ expect.objectContaining({ name: "a1" }),
180
+ expect.objectContaining({ name: "e5" }),
181
+ expect.objectContaining({ name: "d4" }),
172
182
  ]);
173
183
  });
174
184
 
@@ -326,5 +336,74 @@ describe("utils > treeFilters", () => {
326
336
  }),
327
337
  );
328
338
  });
339
+
340
+ it("keeps problem-heavy groups first when sorting by status in descending order", () => {
341
+ const group = {
342
+ leaves: [],
343
+ groups: ["passedHeavy", "failedAlpha", "brokenGroup", "failedZulu"],
344
+ };
345
+ const leavesById = {
346
+ failedAlphaTest: {
347
+ name: "failedAlphaTest",
348
+ status: "failed",
349
+ } as AwesomeTestResult,
350
+ failedZuluTest: {
351
+ name: "failedZuluTest",
352
+ status: "failed",
353
+ } as AwesomeTestResult,
354
+ brokenTest1: {
355
+ name: "brokenTest1",
356
+ status: "broken",
357
+ } as AwesomeTestResult,
358
+ brokenTest2: {
359
+ name: "brokenTest2",
360
+ status: "broken",
361
+ } as AwesomeTestResult,
362
+ passedTest1: {
363
+ name: "passedTest1",
364
+ status: "passed",
365
+ } as AwesomeTestResult,
366
+ passedTest2: {
367
+ name: "passedTest2",
368
+ status: "passed",
369
+ } as AwesomeTestResult,
370
+ };
371
+ const groupsById = {
372
+ passedHeavy: {
373
+ name: "passedHeavy",
374
+ leaves: ["passedTest1", "passedTest2"],
375
+ groups: [] as string[],
376
+ },
377
+ brokenGroup: {
378
+ name: "brokenGroup",
379
+ leaves: ["brokenTest1", "brokenTest2"],
380
+ groups: [] as string[],
381
+ },
382
+ failedAlpha: {
383
+ name: "failedAlpha",
384
+ leaves: ["failedAlphaTest"],
385
+ groups: [] as string[],
386
+ },
387
+ failedZulu: {
388
+ name: "failedZulu",
389
+ leaves: ["failedZuluTest"],
390
+ groups: [] as string[],
391
+ },
392
+ };
393
+ const result = createRecursiveTree({
394
+ group: group as any,
395
+ leavesById: leavesById as any,
396
+ groupsById: groupsById as any,
397
+ filterPredicate: alwaysTruePredicate,
398
+ sortBy: "status,desc",
399
+ });
400
+
401
+ expect(result.trees).toEqual([
402
+ expect.objectContaining({ name: "failedZulu" }),
403
+ expect.objectContaining({ name: "failedAlpha" }),
404
+ expect.objectContaining({ name: "brokenGroup" }),
405
+ expect.objectContaining({ name: "passedHeavy" }),
406
+ ]);
407
+ });
329
408
  });
330
409
  });