Skip to content

Commit

Permalink
test(graph): e2e tests (#2812)
Browse files Browse the repository at this point in the history
* fix: update icon classname

* fix: translate react node origin

* test: e2e tests

* chore: test workflow

* chore: remove unnecessary dependencies

* chore: update dependencies

* chore: vite config

* chore: fix util version

* fix: dendrogram e2e tests

* chore: ci workflow

* test: update e2e
  • Loading branch information
yvonneyx authored Dec 19, 2024
1 parent 893eec3 commit f1fac17
Show file tree
Hide file tree
Showing 81 changed files with 477 additions and 196 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ jobs:
run: pnpm install
- name: test
run: pnpm test
- name: Run Playwright tests
run: |
pnpm exec playwright install chromium
pnpm exec playwright test --workers=10
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
# - name: Coveralls
# uses: coverallsapp/github-action@master
# with:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ logs

# temp
temp-gallery.md

# Tools
/test-results/
/playwright-report/
/playwright/.cache/
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
"scripts": {
"start": "pnpm run build:lib && pnpm -r --stream --filter=./site run start",
"test": "pnpm -r --stream --filter=./packages/* run test",
"test:e2e": "pnpm exec playwright test",
"lint": "pnpm -r --stream --filter=./packages/* run lint",
"build": "pnpm -r --stream --filter=!./site run build",
"build:site": "pnpm -r --stream --filter=./site run build",
"build:lib": "pnpm -r --stream --filter=!./site run build:lib",
"dev:graphs": "cd packages/graphs && pnpm run dev",
"profile": "webpack --config webpack.config.js --mode production --profile --json > stats.json",
"prettier": "prettier --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"",
"ci:version": "pnpm changeset version",
Expand All @@ -23,6 +25,7 @@
"@babel/preset-env": "^7.26.0",
"@babel/preset-typescript": "^7.26.0",
"@changesets/cli": "^2.27.9",
"@playwright/test": "^1.49.1",
"@swc/jest": "^0.2.37",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react-hooks": "^7.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/graphs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"test": "jest"
},
"dependencies": {
"@ant-design/charts-util": "workspace:*",
"@ant-design/charts-util": "0.0.1-alpha.7",
"@antv/g6": "^5.0.30",
"@antv/g6-extension-react": "^0.1.7",
"@antv/graphin": "^3.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ const StyledWrapper = styled.div<{
}
}}
.indented-icon-bar {
.arrow-count-icon-bar {
${({ $placement }) => {
const isVertical = $placement === 'top' || $placement === 'bottom';
return isVertical ? 'width: 3px; height: 8px; margin: 0 7px;' : 'width: 8px; height: 3px; margin: 7px 0;';
}}
background-color: ${({ $color }) => $color};
}
.indented-icon-circle {
.arrow-count-icon-circle {
width: 16px;
height: 16px;
color: #fff;
Expand All @@ -63,7 +63,7 @@ const StyledWrapper = styled.div<{
border-radius: 50%;
}
.indented-icon-circle-arrow {
.arrow-count-icon-circle-arrow {
width: 16px;
height: 16px;
transform: ${({ $isCollapsed, $placement }) => {
Expand Down Expand Up @@ -95,13 +95,19 @@ export const ArrowCountIcon: FC<ArrowCountIconProps> = (props) => {
.length;

return (
<StyledWrapper $color={color} $isCollapsed={isCollapsed} $placement={placement} className={className} style={style}>
<div className="indented-icon-bar" />
<div className="indented-icon-circle">
<StyledWrapper
$color={color}
$isCollapsed={isCollapsed}
$placement={placement}
className={`arrow-count-icon ${isCollapsed ? `arrow-count-icon-collapsed` : ''} ${className || ''}`}
style={style}
>
<div className="arrow-count-icon-bar" />
<div className="arrow-count-icon-circle">
{isCollapsed ? (
count
) : (
<div className="indented-icon-circle-arrow">
<div className="arrow-count-icon-circle-arrow">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path
d="M11,4 L5.5,8 L11,12"
Expand Down
42 changes: 20 additions & 22 deletions packages/graphs/src/core/transform/translate-react-node-origin.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
import { BaseTransform, idOf } from '@antv/g6';
import type { DrawData, Size } from '@antv/g6';
import { BaseTransform, parseSize } from '@antv/g6';

/**
* HTML 元素的默认原点位置在左上角,而 G6 的默认原点位置在中心,所以需要调整 dx 和 dy
*/
export class TranslateReactNodeOrigin extends BaseTransform {
public afterLayout() {
const { graph, model, element } = this.context;
public beforeDraw(input: DrawData): DrawData {
const { graph, element } = this.context;

graph.getNodeData().forEach((datum) => {
const nodeId = idOf(datum);
const {
add: { nodes: nodesToAdd },
update: { nodes: nodesToUpdate },
} = input;

const node = element!.getElement(nodeId);
if (!node) return;

const style = graph.getElementRenderStyle(nodeId);
const { size } = style;

model.updateNodeData([
{
id: nodeId,
// HTML 元素的默认原点位置在左上角,而 G6 的默认原点位置在中心,所以需要调整 dx 和 dy
style: {
dx: -size[0] / 2,
dy: -size[1] / 2,
},
},
]);
[...nodesToAdd.values(), ...nodesToUpdate.values()].forEach((datum) => {
// @ts-expect-error private method invoke
element!.computeElementDefaultStyle('node', { graph, datum });
const style = element!.getDefaultStyle(datum.id);
const [width, height] = parseSize(style.size as Size);
if (!datum.style) datum.style = {};
datum.style.dx = -width / 2;
datum.style.dy = -height / 2;
});

graph.draw();
return input;
}
}
1 change: 1 addition & 0 deletions packages/graphs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ export { CollapseExpandIcon, RCNode } from './core/base';
export type { OrganizationChartNodeProps, TextNodeProps } from './core/base/node';
export { measureTextSize } from './core/utils/measure-text';
export { getNodeSide } from './core/utils/node';
export { mergeOptions } from './core/utils/options';
export type { GraphOptions } from './types';
export { G6 };
2 changes: 1 addition & 1 deletion packages/graphs/tests/datasets/algorithm-category.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"children": [
{ "id": "Multiple linear regression" },
{ "id": "Partial least squares" },
{ "id": "Multi-layer feed forward neural network" },
{ "id": "Multi-layer feedforward neural network" },
{ "id": "General regression neural network" },
{ "id": "Support vector regression" }
]
Expand Down
20 changes: 4 additions & 16 deletions packages/graphs/tests/demos/dendrogram.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import { Dendrogram as DendrogramComponent, DendrogramOptions } from '@ant-design/graphs';
import { treeToGraphData } from '@antv/g6';
import React from 'react';
import data from '../datasets/algorithm-category.json';
import { useGraphOptions } from './hooks/useQueryOptions';

export const Dendrogram = () => {
const options: DendrogramOptions = {
const options = useGraphOptions<DendrogramOptions>({
autoFit: 'view',
data: treeToGraphData(data),
direction: 'vertical',
compact: true,
behaviors: (prev) => [
...prev,
{
key: 'hover-activate',
type: 'hover-activate',
degree: Infinity,
direction: 'in',
inactiveState: 'inactive',
},
],
};
data,
});

return <DendrogramComponent {...options} />;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Fishbone, FishboneOptions } from '@ant-design/graphs';
import { treeToGraphData } from '@antv/g6';
import { Fishbone as ADCFishbone } from '@ant-design/graphs';
import React from 'react';
import { useGraphOptions } from './hooks/useQueryOptions';

const data = {
id: 'Product Profitability Below Expectations',
Expand Down Expand Up @@ -52,11 +52,11 @@ const data = {
],
};

export const FishboneDefault = () => {
const options: FishboneOptions = {
export const Fishbone = () => {
const options = useGraphOptions({
autoFit: 'view',
data: treeToGraphData(data),
type: 'decision',
};
return <Fishbone {...options} />;
data
});

return <ADCFishbone {...options} />;
};
5 changes: 3 additions & 2 deletions packages/graphs/tests/demos/flow-graph-product-launch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isBoolean } from 'lodash';
import React, { FC } from 'react';
import styled from 'styled-components';
import data from '../datasets/product-launch.json';
import { useGraphOptions } from './hooks/useQueryOptions';

interface StepData {
name: string;
Expand Down Expand Up @@ -152,7 +153,7 @@ function isSingleStep(data: NodeData) {
}

export const FlowGraphProductLaunch = () => {
const options: FlowGraphOptions = {
const options = useGraphOptions<FlowGraphOptions>({
autoFit: 'view',
data,
node: {
Expand Down Expand Up @@ -192,7 +193,7 @@ export const FlowGraphProductLaunch = () => {
nodeSize: (data: NodeData) => (isSingleStep(data) ? 160 : 400),
animation: false,
},
};
});

return <FlowGraphComponent {...options} />;
};
5 changes: 3 additions & 2 deletions packages/graphs/tests/demos/flow-graph-task-scheduling.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import styled from 'styled-components';
import { hexToRgba } from '../../src/core/utils/color';
import data from '../datasets/task-scheduling.json';
import { useGraphOptions } from './hooks/useQueryOptions';

const { Text } = Typography;

Expand Down Expand Up @@ -115,7 +116,7 @@ const TaskNode: React.FC<{
};

export const FlowGraphTaskScheduling = () => {
const options: FlowGraphOptions = {
const options = useGraphOptions<FlowGraphOptions>({
autoFit: 'view',
data,
node: {
Expand Down Expand Up @@ -143,7 +144,7 @@ export const FlowGraphTaskScheduling = () => {
},
},
behaviors: (prev) => [...prev, 'hover-activate-chain'],
};
});

return <FlowGraphComponent {...options} />;
};
5 changes: 3 additions & 2 deletions packages/graphs/tests/demos/flow-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { FlowGraph as FlowGraphComponent, RCNode, type FlowGraphOptions } from '
import type { NodeData } from '@antv/g6';
import React from 'react';
import data from '../datasets/task-scheduling.json';
import { useGraphOptions } from './hooks/useQueryOptions';

const { TextNode } = RCNode;

export const FlowGraph = () => {
const options: FlowGraphOptions = {
const options = useGraphOptions<FlowGraphOptions>({
autoFit: 'view',
data,
node: {
Expand All @@ -18,7 +19,7 @@ export const FlowGraph = () => {
},
},
behaviors: (prev) => [...prev, 'hover-activate-chain'],
};
});

return <FlowGraphComponent {...options} />;
};
33 changes: 33 additions & 0 deletions packages/graphs/tests/demos/hooks/useQueryOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GraphOptions, mergeOptions } from '@ant-design/graphs';
import { useSearchParams } from 'react-router-dom';

export const useGraphOptions = <T extends Omit<GraphOptions, 'data'>>(options: T): T => {
const [params] = useSearchParams();
const queryParams = Object.fromEntries(params) as any;

Object.keys(queryParams).forEach((key) => {
if (queryParams[key] === 'true') {
queryParams[key] = true;
}
if (queryParams[key] === 'false') {
queryParams[key] = false;
}
});

queryParams.devicePixelRatio = 4;

queryParams.transforms = () => {
return (transforms) => {
return [
...transforms.filter((transform: any) => transform.key !== 'collapse-expand-react-node'),
{
...transforms.find((transform: any) => transform.key === 'collapse-expand-react-node'),
enable: queryParams.collapseExpand,
...(queryParams.collapseExpandTrigger && { trigger: queryParams.collapseExpandTrigger }),
},
];
};
};

return mergeOptions(options, queryParams) as any;
};
16 changes: 0 additions & 16 deletions packages/graphs/tests/demos/indented-tree-boxed.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions packages/graphs/tests/demos/indented-tree-linear.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type { IndentedTreeOptions } from '@ant-design/graphs';
import { G6, IndentedTree as IndentedTreeComponent } from '@ant-design/graphs';
import { IndentedTree as IndentedTreeComponent } from '@ant-design/graphs';
import React from 'react';
import data from '../datasets/algorithm-category.json';

const { treeToGraphData } = G6;
import { useGraphOptions } from './hooks/useQueryOptions';

export const IndentedTree = () => {
const options: IndentedTreeOptions = {
const options = useGraphOptions<IndentedTreeOptions>({
autoFit: 'view',
type: 'default',
data: treeToGraphData(data),
};
data,
animation: false,
});

return <IndentedTreeComponent {...options} />;
};
Loading

0 comments on commit f1fac17

Please sign in to comment.