Skip to content

Commit

Permalink
split improvements and bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
todti committed Feb 18, 2025
1 parent 9ab6fa6 commit 98b0977
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { type HistoryTestResult, formatDuration } from "@allurereport/core-api";
import { IconButton, Text, TooltipWrapper, allureIcons } from "@allurereport/web-components";
import { IconButton, Text, TooltipWrapper, TreeItemIcon, allureIcons } from "@allurereport/web-components";
import { type FunctionalComponent } from "preact";
import { useState } from "preact/hooks";
import { ArrowButton } from "@/components/ArrowButton";
import { TestResultError } from "@/components/TestResult/TestResultError";
import * as styles from "@/components/TestResult/TestResultHistory/styles.scss";
import TreeItemIcon from "@/components/Tree/TreeItemIcon";
import { useI18n } from "@/stores";
import { navigateTo, openInNewTab } from "@/stores/router";
import { timestampToDate } from "@/utils/time";
Expand All @@ -19,7 +18,7 @@ export const TestResultHistoryItem: FunctionalComponent<{
const formattedDuration = formatDuration(duration as number);
const { t } = useI18n("controls");

const navigateUrl = `/testresult/${id}`;
const navigateUrl = `/${id}`;

return (
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { formatDuration } from "@allurereport/core-api";
import { IconButton, Text, allureIcons } from "@allurereport/web-components";
import { IconButton, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
import type { FunctionalComponent } from "preact";
import { useState } from "preact/hooks";
import type { AllureAwesomeTestResult } from "types";
import { ArrowButton } from "@/components/ArrowButton";
import { TestResultError } from "@/components/TestResult/TestResultError";
import * as styles from "@/components/TestResult/TestResultRetriesView/styles.scss";
import TreeItemIcon from "@/components/Tree/TreeItemIcon";
import { navigateTo } from "@/stores/router";
import { timestampToDate } from "@/utils/time";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { TestStatus } from "@allurereport/core-api";
import { Text } from "@allurereport/web-components";
import { Text, TreeItemIcon } from "@allurereport/web-components";
import clsx from "clsx";
import TreeItemIcon from "@/components/Tree/TreeItemIcon";
import { useI18n } from "@/stores";
import { capitalize } from "@/utils/capitalize";
import * as styles from "./styles.scss";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefaultTestStepResult } from "@allurereport/core-api";
import { Code, Text, allureIcons } from "@allurereport/web-components";
import { Code, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
import type { FunctionComponent } from "preact";
import { useState } from "preact/hooks";
import { ArrowButton } from "@/components/ArrowButton";
Expand All @@ -8,7 +8,6 @@ import { type MetadataItem } from "@/components/ReportMetadata";
import * as styles from "@/components/TestResult/TestResultSteps/styles.scss";
import { TestResultAttachment } from "@/components/TestResult/TestResultSteps/testResultAttachment";
import { TestResultStepInfo } from "@/components/TestResult/TestResultSteps/testResultStepInfo";
import TreeItemIcon from "@/components/Tree/TreeItemIcon";
import { collapsedTrees, toggleTree } from "@/stores/tree";

export const TestResultStepParameters = (props: { parameters: DefaultTestStepResult["parameters"] }) => {
Expand Down
27 changes: 23 additions & 4 deletions packages/web-awesome/src/components/Tree/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Button, Loadable, PageLoader, Text } from "@allurereport/web-components";
import { Button, Loadable, PageLoader, Text, Tree } from "@allurereport/web-components";
import type { AllureAwesomeStatus } from "types";
import { useTabsContext } from "@/components/Tabs";
import Tree from "@/components/Tree/Tree";
import { statsStore } from "@/stores";
import { useI18n } from "@/stores/locale";
import { clearTreeFilters, filteredTree, noTests, noTestsFound, treeStore } from "@/stores/tree";
import { navigateTo } from "@/stores/router";
import {
clearTreeFilters,
collapsedTrees,
filteredTree,
noTests,
noTestsFound,
toggleTree,
treeFiltersStore,
treeStore,
} from "@/stores/tree";
import * as styles from "./styles.scss";

export const TreeList = () => {
Expand Down Expand Up @@ -47,7 +57,16 @@ export const TreeList = () => {

return (
<div className={styles["tree-list"]}>
<Tree tree={filteredTree.value} statusFilter={currentTab as AllureAwesomeStatus} root />
<Tree
collapsedTrees={collapsedTrees.value}
toggleTree={toggleTree}
treeFiltersStore={treeFiltersStore}
navigateTo={navigateTo}
statsStore={statsStore}
tree={filteredTree.value}
statusFilter={currentTab as AllureAwesomeStatus}
root
/>
</div>
);
}}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-classic/src/components/Tree/TreeHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const TreeHeader: FunctionComponent<TreeHeaderProps> = ({
return (
<Loadable
source={statsStore}
renderData={(stats) => {
renderData={(stats: Statistic) => {
const width = Math.floor(progress(statistic.total, stats.total) * (maxWidthTab - minWidthTab) + minWidthTab);

const treeHeaderBar = statistic
Expand Down
96 changes: 96 additions & 0 deletions packages/web-components/global.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,97 @@
// import "@testing-library/jest-dom";
import type {
AttachmentTestStepResult,
DefaultTreeGroup,
HistoryTestResult,
TestFixtureResult,
TestResult,
TestStatus,
TestStepResult,
TreeData,
WithChildren,
} from "@allurereport/core-api";

export type Allure2ReportOptions = {
reportName?: string;
reportLanguage?: string;
createdAt: number;
};

export type AllureAwesomeReportOptions = {
reportName?: string;
logo?: string;
theme?: "light" | "dark";
groupBy?: string[];
reportLanguage?: "en" | "ru";
createdAt: number;
reportUuid: string;
};

export type AllureAwesomeFixtureResult = Omit<
TestFixtureResult,
"testResultIds" | "start" | "stop" | "sourceMetadata" | "steps"
> & {
steps: AllureAwesomeTestStepResult[];
};

export type AllureAwesomeStatus = TestStatus | "total";

export type AllureAwesomeTestStepResult = TestStepResult;

type AllureAwesomeBreadcrumbItem = string[] | string[][];

export type AllureAwesomeTestResult = Omit<
TestResult,
| "runSelector"
| "sourceMetadata"
| "expectedResult"
| "expectedResultHtml"
| "precondition"
| "preconditionHtml"
| "steps"
> & {
setup: AllureAwesomeFixtureResult[];
teardown: AllureAwesomeFixtureResult[];
steps: AllureAwesomeTestStepResult[];
history: HistoryTestResult[];
retries?: TestResult[];
groupedLabels: Record<string, string[]>;
attachments?: AttachmentTestStepResult[];
breadcrumbs: AllureAwesomeBreadcrumbItem[];
order?: number;
groupOrder?: number;
retry: boolean;
time?: Record<string, string[]>;
extra?: { severity: string };
};

export type AllureAwesomeTreeLeaf = Pick<
AllureAwesomeTestResult,
"duration" | "name" | "start" | "status" | "groupOrder" | "flaky" | "retry"
> & {
nodeId: string;
};

export type AllureAwesomeTreeGroup = WithChildren & DefaultTreeGroup & { nodeId: string };

export type AllureAwesomeTree = TreeData<AllureAwesomeTreeLeaf, AllureAwesomeTreeGroup>;

/**
* Tree which contains tree leaves instead of their IDs and recursive trees structure instead of groups
*/
export type AllureAwesomeRecursiveTree = DefaultTreeGroup & {
nodeId: string;
leaves: AllureAwesomeTreeLeaf[];
trees: AllureAwesomeRecursiveTree[];
};

export type TreeSortBy = "order" | "duration" | "status" | "alphabet";
export type TreeDirection = "asc" | "desc";
export type TreeFilters = "flaky" | "retry" | "new";
export type TreeFiltersState = {
query: string;
status: AllureAwesomeStatus;
filter: Record<TreeFilters, boolean>;
sortBy: TreeSortBy;
direction: TreeDirection;
};
36 changes: 36 additions & 0 deletions packages/web-components/src/components/ArrowButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { clsx } from "clsx";
import type { FunctionalComponent } from "preact";
import { SvgIcon, allureIcons } from "@/components/SvgIcon";
import styles from "./styles.scss";

export interface ArrowButtonProps {
isOpened?: boolean;
iconSize?: "m" | "xs" | "s";
buttonSize?: "m" | "xs" | "s";
className?: string;
icon?: string;
}

export const ArrowButton: FunctionalComponent<ArrowButtonProps> = ({
isOpened,
buttonSize = "m",
iconSize = "xs",
className,
icon = allureIcons.lineArrowsChevronDown,
...rest
}) => {
return (
<button className={clsx(styles["arrow-button"], styles[`arrow-button-${buttonSize}`])} {...rest}>
<SvgIcon
id={icon}
size={iconSize}
className={clsx(
styles["arrow-button-icon"],
isOpened && styles["arrow-button-icon--opened"],
styles[`icon-size-${iconSize}`],
className,
)}
/>
</button>
);
};
35 changes: 35 additions & 0 deletions packages/web-components/src/components/ArrowButton/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.arrow-button {
background: transparent;
border: none;
padding: 8px 4px;
border-radius: 4px;
cursor: pointer;
color: var(--on-icon-secondary);

&:hover {
background: var(--bg-control-flat-medium);
color: var(--on-icon-primary);
}
}

.arrow-button-s {
padding: 0 4px;
}

.arrow-button-m {
padding: 6px 6px;
}

.icon-size-m {
width: 15px;
height: 15px;
}

.arrow-button-icon {
transform: rotate(-90deg);
transition: transform 200ms;
}

.arrow-button-icon--opened {
transform: rotate(0);
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
import type { Statistic } from "@allurereport/core-api";
import cx from "clsx";
import type { AllureAwesomeRecursiveTree, AllureAwesomeStatus, TreeFiltersState } from "global";
import type { FunctionComponent } from "preact";
import { useState } from "preact/hooks";
import type { AllureAwesomeRecursiveTree, AllureAwesomeStatus } from "types";
import TreeItem from "@/components/Tree/TreeItem";
import { route } from "@/stores/router";
import { collapsedTrees, toggleTree } from "@/stores/tree";
import TreeHeader from "./TreeHeader";
import * as styles from "./styles.scss";
import type { StoreSignalState } from "@/components/Loadable";
import { TreeItem } from "@/components/Tree/TreeItem";
import { TreeHeader } from "./TreeHeader";
import styles from "./styles.scss";

interface TreeProps {
statistic?: Statistic;
tree: AllureAwesomeRecursiveTree;
name?: string;
root?: boolean;
statusFilter?: AllureAwesomeStatus;
collapsedTrees: Set<string>;
toggleTree: (id: string) => void;
navigateTo: (id: string) => void;
routeId?: string;
statsStore: StoreSignalState<Statistic>;
treeFiltersStore: TreeFiltersState;
}

const Tree: FunctionComponent<TreeProps> = ({ tree, statusFilter, root, name, statistic }) => {
const { id } = route.value;
const isEarlyCollapsed = collapsedTrees.value.has(tree.nodeId);
export const Tree: FunctionComponent<TreeProps> = ({
tree,
statusFilter,
root,
name,
statistic,
collapsedTrees,
toggleTree,
routeId,
statsStore,
navigateTo,
treeFiltersStore,
}) => {
const isEarlyCollapsed = collapsedTrees.has(tree.nodeId as string);
const haveFailedSteps = statistic === undefined || !!statistic?.failed || !!statistic?.broken;
const [isOpened, setIsOpen] = useState(() => (isEarlyCollapsed ? !haveFailedSteps : haveFailedSteps));

const toggleTreeHeader = () => {
setIsOpen(!isOpened);
toggleTree(tree.nodeId);
toggleTree(tree.nodeId as string);
};
const emptyTree = !tree?.trees?.length && !tree?.leaves?.length;

Expand All @@ -48,6 +64,12 @@ const Tree: FunctionComponent<TreeProps> = ({ tree, statusFilter, root, name, st
tree={subTree}
statistic={subTree.statistic}
statusFilter={statusFilter}
collapsedTrees={collapsedTrees}
toggleTree={toggleTree}
routeId={routeId}
navigateTo={navigateTo}
statsStore={statsStore}
treeFiltersStore={treeFiltersStore}
/>
))}
{tree?.leaves?.map?.((leaf) => (
Expand All @@ -57,9 +79,10 @@ const Tree: FunctionComponent<TreeProps> = ({ tree, statusFilter, root, name, st
id={leaf.nodeId}
name={leaf.name}
status={leaf.status}
groupOrder={leaf.groupOrder}
groupOrder={leaf.groupOrder as number}
duration={leaf.duration}
marked={leaf.nodeId === id}
marked={leaf.nodeId === routeId}
navigateTo={navigateTo}
/>
))}
</div>
Expand All @@ -68,11 +91,16 @@ const Tree: FunctionComponent<TreeProps> = ({ tree, statusFilter, root, name, st
return (
<div className={styles.tree}>
{name && (
<TreeHeader categoryTitle={name} isOpened={isOpened} toggleTree={toggleTreeHeader} statistic={statistic} />
<TreeHeader
treeFiltersStore={treeFiltersStore}
statsStore={statsStore}
categoryTitle={name}
isOpened={isOpened}
toggleTree={toggleTreeHeader}
statistic={statistic}
/>
)}
{treeContent}
</div>
);
};

export default Tree;
Loading

0 comments on commit 98b0977

Please sign in to comment.