Skip to content

Commit eb7e65e

Browse files
authored
fix: 浮动气泡组件测试案例修改 (#72)
1 parent aef5284 commit eb7e65e

File tree

4 files changed

+112
-51
lines changed

4 files changed

+112
-51
lines changed

packages/rc-ui-lib/src/floating-bubble/FloatingBubble.tsx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const FloatingBubble: React.FC<FloatingBubbleProps> = (props) => {
2929
});
3030

3131
const [dragging, setDragging] = useState(false);
32-
const [show, setShow] = useState(false);
32+
const [show, setShow] = useState(true);
3333
const [initialized, setInitialized] = useState(false);
3434
const boundary = useMemo(() => {
3535
return {
@@ -71,7 +71,6 @@ const FloatingBubble: React.FC<FloatingBubbleProps> = (props) => {
7171
if (axis === 'lock') return;
7272
if (!touch.isTap.current) {
7373
if (axis === 'x' || axis === 'xy') {
74-
if (touch.deltaX.current === 0) return;
7574
let nextX = prevX.current + touch.deltaX.current;
7675
if (nextX < boundary.left) nextX = boundary.left;
7776
if (nextX > boundary.right) nextX = boundary.right;
@@ -90,29 +89,30 @@ const FloatingBubble: React.FC<FloatingBubbleProps> = (props) => {
9089
});
9190
const onTouchEnd = () => {
9291
setDragging(false);
93-
setTimeout(() => {
94-
if (magnetic === 'x') {
95-
const nextX = closest([boundary.left, boundary.right], state.x);
96-
setState({ x: nextX });
97-
}
98-
if (magnetic === 'y') {
99-
const nextY = closest([boundary.top, boundary.bottom], state.y);
100-
setState({ y: nextY });
101-
}
102-
if (!touch.isTap.current) {
103-
const updateOffset = pick(state, ['x', 'y']);
104-
if (prevX.current !== updateOffset.x || prevY.current !== updateOffset.y) {
105-
props?.onOffsetChange?.(updateOffset);
106-
}
92+
// setTimeout(() => {
93+
if (magnetic === 'x') {
94+
const nextX = closest([boundary.left, boundary.right], state.x);
95+
setState({ x: nextX });
96+
}
97+
if (magnetic === 'y') {
98+
const nextY = closest([boundary.top, boundary.bottom], state.y);
99+
setState({ y: nextY });
100+
}
101+
if (!touch.isTap.current) {
102+
const updateOffset = pick(state, ['x', 'y']);
103+
104+
if (prevX.current !== updateOffset.x || prevY.current !== updateOffset.y) {
105+
props?.onOffsetChange?.(updateOffset);
107106
}
108-
}, 0);
107+
}
108+
// }, 0);
109109
};
110110
useEffect(() => {
111-
setShow(true);
112-
setTimeout(() => {
113-
updateState();
114-
setInitialized(true);
115-
}, 0);
111+
// setShow(true);
112+
// setTimeout(() => {
113+
updateState();
114+
setInitialized(true);
115+
// }, 0);
116116
return () => {
117117
if (teleport) setShow(false);
118118
};
@@ -129,7 +129,7 @@ const FloatingBubble: React.FC<FloatingBubbleProps> = (props) => {
129129
onTouchCancel={onTouchEnd}
130130
onClick={(e) => {
131131
if (touch.isTap.current) {
132-
onClick(e);
132+
onClick?.(e);
133133
}
134134
}}
135135
style={rootStyle}
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`FloatingBubble should render correctly when icon set 1`] = `<div />`;
3+
exports[`FloatingBubble should render correctly when icon set 1`] = `
4+
<div
5+
class="rc-floating-bubble"
6+
style="transform: translate3d(952px, 696px, 0);"
7+
>
8+
<i
9+
class="rc-badge__wrapper rc-floating-bubble__icon van-icon van-icon-chat-o"
10+
/>
11+
</div>
12+
`;
413

514
exports[`FloatingBubble should teleport body when default 1`] = `<div />`;

packages/rc-ui-lib/src/floating-bubble/__test__/index.spec.tsx

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, cleanup, fireEvent } from '@testing-library/react';
1+
import { render, cleanup, fireEvent, act, waitFor } from '@testing-library/react';
22
import React from 'react';
33
import { sleep } from '../../../tests/utils';
44
import TestsEvent from '../../../tests/events';
@@ -7,6 +7,7 @@ import FloatingBubble from '../FloatingBubble';
77

88
describe('FloatingBubble', () => {
99
beforeEach(() => {
10+
jest.useFakeTimers();
1011
Object.defineProperty(window, 'inBrowser', { value: true });
1112
});
1213
afterEach(() => {
@@ -16,14 +17,14 @@ describe('FloatingBubble', () => {
1617
it('should render correctly when icon set', async () => {
1718
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
1819
const root = document.createElement('div');
19-
const { container } = render(<FloatingBubble icon="chat-o" teleport={root} />);
20+
render(<FloatingBubble icon="chat-o" teleport={root} />);
2021
await sleep(10);
2122
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
2223
expect(floatingBubbleEl.style.transform).toEqual(
2324
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
2425
);
2526
expect(floatingBubbleEl.querySelector('.van-icon-chat-o')).not.toBeNull();
26-
expect(container).toMatchSnapshot();
27+
expect(floatingBubbleEl).toMatchSnapshot();
2728
restore();
2829
});
2930
it('should render correctly when offset set', async () => {
@@ -45,53 +46,93 @@ describe('FloatingBubble', () => {
4546
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
4647
const root = document.createElement('div');
4748
render(<FloatingBubble icon="chat-o" teleport={root} />);
49+
await act(() => {
50+
jest.useRealTimers();
51+
});
4852
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
49-
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
50-
expect(floatingBubbleEl.style.transform).toEqual(
51-
`translate3d(${window.innerWidth - 48 - 24}px, 24px, 0)`,
52-
);
53+
await act(async () => {
54+
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
55+
});
56+
await sleep(1000);
57+
await waitFor(() => {
58+
expect(floatingBubbleEl.style.transform).toEqual(
59+
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24 - 100}px, 0)`,
60+
);
61+
});
5362
restore();
5463
});
5564
it('should only x axis direction move when axis is x', async () => {
5665
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
5766
const root = document.createElement('div');
58-
render(<FloatingBubble icon="chat-o" axis="x" teleport={root} />);
67+
render(<FloatingBubble icon="chat-o" teleport={root} axis="x" />);
68+
await act(() => {
69+
jest.useRealTimers();
70+
});
5971
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
60-
await TestsEvent.triggerDrag(floatingBubbleEl, [2000, -100]);
61-
expect(floatingBubbleEl.style.transform).toEqual(
62-
`translate3d(${window.innerWidth - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
63-
);
72+
await act(async () => {
73+
await TestsEvent.triggerDrag(floatingBubbleEl, [100, -100]);
74+
});
75+
76+
await sleep(1000);
77+
await waitFor(() => {
78+
expect(floatingBubbleEl.style.transform).toEqual(
79+
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
80+
);
81+
});
6482
restore();
6583
});
6684
it('should free direction move when axis is "xy"', async () => {
6785
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
6886
const root = document.createElement('div');
6987
render(<FloatingBubble icon="chat-o" axis="xy" teleport={root} />);
7088
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
71-
await TestsEvent.triggerDrag(floatingBubbleEl, [-1000, 24]);
89+
await act(async () => {
90+
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
91+
});
7292
expect(floatingBubbleEl.style.transform).toEqual(
73-
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
93+
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24 - 100}px, 0)`,
7494
);
7595
restore();
7696
});
7797
it('should magnetic to x axios when magnetic is "x" ', async () => {
7898
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
7999
const root = document.createElement('div');
80100
render(<FloatingBubble icon="chat-o" axis="xy" magnetic="x" teleport={root} />);
101+
await act(() => {
102+
jest.useRealTimers();
103+
});
81104
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
82-
await TestsEvent.triggerDrag(floatingBubbleEl, [100, 100]);
83-
await sleep(100);
84-
expect(floatingBubbleEl.style.transform).toEqual(`translate3d(24px, 100px, 0)`);
105+
await act(async () => {
106+
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
107+
});
108+
await act(() => {
109+
jest.useRealTimers();
110+
});
111+
await sleep(400);
112+
await waitFor(() => {
113+
expect(floatingBubbleEl.style.transform).toEqual(
114+
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24 - 100}px, 0)`,
115+
);
116+
});
85117
restore();
86118
});
87119
it('should magnetic to y axios when magnetic is "y" ', async () => {
88120
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
89121
const root = document.createElement('div');
90122
render(<FloatingBubble icon="chat-o" axis="xy" magnetic="y" teleport={root} />);
91123
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
92-
await TestsEvent.triggerDrag(floatingBubbleEl, [100, 100]);
93-
await sleep(100);
94-
expect(floatingBubbleEl.style.transform).toEqual(`translate3d(100px, 24px, 0)`);
124+
await act(async () => {
125+
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
126+
});
127+
await act(() => {
128+
jest.useRealTimers();
129+
});
130+
await sleep(1000);
131+
await waitFor(() => {
132+
expect(floatingBubbleEl.style.transform).toEqual(
133+
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
134+
);
135+
});
95136
restore();
96137
});
97138
it('should emit click when click wrapper', async () => {
@@ -121,18 +162,27 @@ describe('FloatingBubble', () => {
121162
);
122163
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
123164

124-
await TestsEvent.triggerDrag(floatingBubbleEl, [10, 10]);
165+
// await act(async () => {
166+
await TestsEvent.triggerDrag(floatingBubbleEl, [-100, -100]);
167+
// });
125168
expect(onClick).not.toHaveBeenCalled();
126-
await sleep(10);
169+
// await act(() => {
170+
// jest.useRealTimers();
171+
// });
172+
await sleep(400);
173+
// await waitFor(() => {
127174
expect(onOffsetChange).toHaveBeenCalled();
175+
// });
128176
restore();
129177
});
130178
it('should lock drag when axis is "lock"', async () => {
131179
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
132180
const root = document.createElement('div');
133181
render(<FloatingBubble icon="chat-o" axis="lock" magnetic="y" teleport={root} />);
134182
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
135-
await TestsEvent.triggerDrag(floatingBubbleEl, [0, 0]);
183+
await act(async () => {
184+
await TestsEvent.triggerDrag(floatingBubbleEl, [0, 0]);
185+
});
136186
expect(floatingBubbleEl.style.transform).toEqual(
137187
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
138188
);
@@ -141,17 +191,19 @@ describe('FloatingBubble', () => {
141191
it('should not move when drag distance belove TAP_OFFSET"', async () => {
142192
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
143193
const root = document.createElement('div');
144-
render(<FloatingBubble icon="chat-o" axis="x" magnetic="y" teleport={root} />);
194+
render(<FloatingBubble icon="chat-o" axis="xy" teleport={root} />);
145195
const floatingBubbleEl = root.querySelector<HTMLDivElement>('.rc-floating-bubble')!;
146-
await TestsEvent.triggerDrag(floatingBubbleEl, [4, 4]);
196+
await act(async () => {
197+
await TestsEvent.triggerDrag(floatingBubbleEl, [4, 4]);
198+
});
147199
expect(floatingBubbleEl.style.transform).toEqual(
148200
`translate3d(${window.innerWidth - 48 - 24}px, ${window.innerHeight - 48 - 24}px, 0)`,
149201
);
150202
restore();
151203
});
152204

153205
it('should teleport body when default', async () => {
154-
const { container } = render(<FloatingBubble icon="chat-o" axis="xy" magnetic="y" />);
206+
const { container } = render(<FloatingBubble icon="chat-o" axis="xy" />);
155207
expect(container.parentNode).toEqual(document.body);
156208
expect(container).toMatchSnapshot();
157209
});

packages/rc-ui-lib/src/hooks/use-touch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function useTouch() {
4545
const move = ((event: TouchEvent) => {
4646
const touch = event.touches[0];
4747
// Fix: Safari back will set clientX to negative number
48-
deltaX.current = touch.clientX < 0 ? 0 : touch.clientX - startX.current;
48+
deltaX.current = (touch.clientX < 0 ? 0 : touch.clientX) - startX.current;
4949
deltaY.current = touch.clientY - startY.current;
5050
offsetX.current = Math.abs(deltaX.current);
5151
offsetY.current = Math.abs(deltaY.current);

0 commit comments

Comments
 (0)