Skip to content

Commit 0ff3713

Browse files
committed
feat: add initial dropdown test
1 parent bd7d8dc commit 0ff3713

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
2+
import type { StoryFn } from '@storybook/react';
3+
import { within, userEvent } from '@storybook/testing-library';
4+
import { expect, jest } from '@storybook/jest';
5+
import type { Mock } from 'jest-mock';
6+
import React from 'react';
7+
import type { DropdownProps } from '../';
8+
import { Dropdown } from '../';
9+
import { Box } from '~components/Box';
10+
11+
const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));
12+
13+
let onChange: Mock<unknown, unknown[]> | null = null;
14+
15+
const BasicDropdown = (props: DropdownProps): React.ReactElement => (
16+
<Box margin="auto" width={{ base: '100%', m: '100%' }} padding="spacing.4">
17+
<Dropdown {...props} />
18+
</Box>
19+
);
20+
21+
export const TestCarouselOnChange: StoryFn<typeof Dropdown> = (props): React.ReactElement => {
22+
onChange = jest.fn();
23+
return <BasicCarousel {...props} onChange={onChange} />;
24+
};
25+
26+
TestCarouselOnChange.play = async ({ canvasElement }) => {
27+
const { getByRole, getByText } = within(canvasElement);
28+
const nextButton = getByRole('button', { name: 'Next Slide' });
29+
const previousButton = getByRole('button', { name: 'Previous Slide' });
30+
await userEvent.click(nextButton);
31+
await sleep(1000);
32+
await expect(onChange).toBeCalledWith(1);
33+
await userEvent.click(previousButton);
34+
await sleep(1000);
35+
await expect(onChange).toBeCalledWith(0);
36+
getByText(/Single Flow To Collect And Disburse Payments/)?.scrollIntoView({ behavior: 'smooth' });
37+
await sleep(1000);
38+
await expect(onChange).toBeCalledWith(3);
39+
await expect(onChange).toBeCalledTimes(3);
40+
};
41+
42+
export const TestIndicatorButton: StoryFn<typeof CarouselComponent> = (
43+
props,
44+
): React.ReactElement => {
45+
onChange = jest.fn();
46+
return <BasicCarousel {...props} visibleItems={1} onChange={onChange} />;
47+
};
48+
49+
TestIndicatorButton.play = async ({ canvasElement }) => {
50+
const { getByLabelText } = within(canvasElement);
51+
const indicatorButton = getByLabelText('Slide 7');
52+
await userEvent.click(indicatorButton);
53+
await sleep(1000);
54+
await expect(onChange).toBeCalledWith(6);
55+
await expect(onChange).toBeCalledTimes(1);
56+
};
57+
58+
export const TestStartOverAfterStartEnd: StoryFn<typeof CarouselComponent> = (
59+
props,
60+
): React.ReactElement => {
61+
onChange = jest.fn();
62+
return <BasicCarousel {...props} visibleItems={1} onChange={onChange} />;
63+
};
64+
65+
TestStartOverAfterStartEnd.play = async ({ canvasElement }) => {
66+
const { getByRole } = within(canvasElement);
67+
const nextButton = getByRole('button', { name: 'Next Slide' });
68+
const previousButton = getByRole('button', { name: 'Previous Slide' });
69+
await userEvent.click(previousButton);
70+
await sleep(1000);
71+
await expect(onChange).toBeCalledWith(6);
72+
await userEvent.click(nextButton);
73+
await sleep(1000);
74+
await expect(onChange).toBeCalledWith(0);
75+
await expect(onChange).toBeCalledTimes(2);
76+
};
77+
78+
export const TestAutoPlay: StoryFn<typeof CarouselComponent> = (props): React.ReactElement => {
79+
onChange = jest.fn();
80+
return <BasicCarousel {...props} autoPlay visibleItems={2} onChange={onChange} />;
81+
};
82+
83+
TestAutoPlay.play = async ({ canvasElement }) => {
84+
const { getByRole } = within(canvasElement);
85+
await sleep(8000);
86+
await expect(onChange).toBeCalledWith(1);
87+
await expect(getByRole('tab', { selected: true })).toHaveAccessibleName('Slide 3');
88+
await expect(onChange).toBeCalledTimes(1);
89+
};
90+
91+
export const TestAutofit: StoryFn<typeof CarouselComponent> = (props): React.ReactElement => {
92+
onChange = jest.fn();
93+
return (
94+
<BasicCarousel
95+
{...props}
96+
visibleItems="autofit"
97+
navigationButtonPosition="side"
98+
showIndicators={true}
99+
onChange={onChange}
100+
shouldAddStartEndSpacing
101+
carouselItemWidth="300px"
102+
/>
103+
);
104+
};
105+
106+
TestAutofit.play = async ({ canvasElement }) => {
107+
await sleep(1000);
108+
const { getByLabelText, queryByRole } = within(canvasElement);
109+
const lastIndicatorButton = getByLabelText('Slide 7');
110+
await expect(onChange).not.toBeCalled();
111+
await userEvent.click(lastIndicatorButton);
112+
await sleep(1000);
113+
const nextButton = queryByRole('button', { name: 'Next Slide' });
114+
await expect(nextButton).toBeNull();
115+
const firstIndicatorButton = getByLabelText('Slide 1');
116+
await userEvent.click(firstIndicatorButton);
117+
await sleep(1000);
118+
const previousButton = queryByRole('button', { name: 'Previous Slide' });
119+
await expect(previousButton).toBeNull();
120+
await expect(onChange).toBeCalledTimes(2);
121+
};
122+
123+
export const TestAutoPlayPause: StoryFn<typeof CarouselComponent> = (props): React.ReactElement => {
124+
onChange = jest.fn();
125+
return <BasicCarousel {...props} autoPlay visibleItems={2} onChange={onChange} />;
126+
};
127+
128+
TestAutoPlayPause.play = async ({ canvasElement }) => {
129+
const { getByText } = within(canvasElement);
130+
const slide = getByText(/Acquire Customers From New Customer Segments/);
131+
await userEvent.hover(slide);
132+
await sleep(7000);
133+
await expect(onChange).not.toHaveBeenCalled();
134+
};
135+
136+
export const TestVisibleItemsOnMobile: StoryFn<typeof CarouselComponent> = (
137+
props,
138+
): React.ReactElement => {
139+
onChange = jest.fn();
140+
return <BasicCarousel {...props} visibleItems={3} onChange={onChange} />;
141+
};
142+
143+
TestVisibleItemsOnMobile.parameters = {
144+
viewport: {
145+
defaultViewport: 'iPhone6',
146+
},
147+
};
148+
149+
TestVisibleItemsOnMobile.play = async ({ canvasElement }) => {
150+
// on mobile regardless of the visible items prop we always show 1 item
151+
const { getByRole } = within(canvasElement);
152+
const nextButton = getByRole('button', { name: 'Next Slide' });
153+
await userEvent.click(nextButton);
154+
await sleep(1000);
155+
await expect(onChange).toBeCalledWith(1);
156+
};
157+
158+
// Test for onChange fires multiple times on parent component update
159+
// https://github.com/razorpay/blade/issues/1863
160+
const multipleOnChange = jest.fn();
161+
export const TestOnChangeParentUpdate: StoryFn<typeof CarouselComponent> = (
162+
props,
163+
): React.ReactElement => {
164+
const [, setCount] = React.useState(0);
165+
166+
React.useEffect(() => {
167+
const intervalId = setInterval(() => {
168+
setCount((prev) => prev++);
169+
}, 100);
170+
171+
return () => clearInterval(intervalId);
172+
}, []);
173+
174+
return <BasicCarousel {...props} onChange={multipleOnChange} />;
175+
};
176+
177+
TestOnChangeParentUpdate.play = async ({ canvasElement }) => {
178+
const { getByRole } = within(canvasElement);
179+
await expect(multipleOnChange).not.toBeCalled();
180+
const nextButton = getByRole('button', { name: 'Next Slide' });
181+
const previousButton = getByRole('button', { name: 'Previous Slide' });
182+
await userEvent.click(nextButton);
183+
await sleep(1000);
184+
await expect(multipleOnChange).toBeCalledWith(1);
185+
await userEvent.click(previousButton);
186+
await sleep(1000);
187+
await expect(multipleOnChange).toBeCalledWith(0);
188+
await expect(multipleOnChange).toBeCalledTimes(2);
189+
};
190+
191+
export default {
192+
title: 'Components/Interaction Tests/Dropdown',
193+
component: Dropdown,
194+
parameters: {
195+
controls: {
196+
disable: true,
197+
},
198+
a11y: { disable: true },
199+
essentials: { disable: true },
200+
actions: { disable: true },
201+
},
202+
};

0 commit comments

Comments
 (0)