Skip to content

Commit b827206

Browse files
committed
Transform scrollview jest tests into playwright (#596)
1 parent 38424df commit b827206

File tree

58 files changed

+813
-153
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+813
-153
lines changed
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
import React from 'react';
2+
import {
3+
expect,
4+
test,
5+
} from '@playwright/experimental-ct-react';
6+
import { propTests } from '../../../../tests/playwright';
7+
import {
8+
ScrollViewForDetectEndAutoscrollTest,
9+
ScrollViewForRefTest,
10+
ScrollViewForTest,
11+
} from './ScrollView.story';
12+
import { arrowsPropTest } from './_propTests/arrowsPropTest';
13+
import { directionPropTest } from './_propTests/directionPropTest';
14+
import { nextArrowColorPropTest } from './_propTests/nextArrowColorPropTest';
15+
import { nextArrowElementPropTest } from './_propTests/nextArrowElementPropTest';
16+
import { prevArrowColorPropTest } from './_propTests/prevArrowColorPropTest';
17+
import { prevArrowElementPropTest } from './_propTests/prevArrowElementPropTest';
18+
import { endShadowBackgroundPropTest } from './_propTests/endShadowBackgroundPropTest';
19+
import { startShadowBackgroundPropTest } from './_propTests/startShadowBackgroundPropTest';
20+
import { endShadowSizePropTest } from './_propTests/endShadowSizePropTest';
21+
import { startShadowSizePropTest } from './_propTests/startShadowSizePropTest';
22+
import { shadowsPropTest } from './_propTests/shadowsPropTest';
23+
import type { ExtendedWindow } from './types';
24+
25+
test.describe('ScrollView', () => {
26+
test.describe('visual', () => {
27+
[
28+
...propTests.defaultComponentPropTest,
29+
...arrowsPropTest,
30+
...directionPropTest,
31+
...endShadowBackgroundPropTest,
32+
...endShadowSizePropTest,
33+
...nextArrowColorPropTest,
34+
...nextArrowElementPropTest,
35+
...prevArrowColorPropTest,
36+
...prevArrowElementPropTest,
37+
...shadowsPropTest,
38+
...startShadowBackgroundPropTest,
39+
...startShadowSizePropTest,
40+
].forEach(({
41+
name,
42+
onBeforeTest,
43+
onBeforeSnapshot,
44+
props,
45+
}) => {
46+
test(name, async ({
47+
mount,
48+
page,
49+
}) => {
50+
if (onBeforeTest) {
51+
await onBeforeTest(page);
52+
}
53+
54+
const component = await mount(
55+
<ScrollViewForTest
56+
{...props}
57+
/>,
58+
);
59+
60+
if (onBeforeSnapshot) {
61+
await onBeforeSnapshot(page, component);
62+
}
63+
64+
const screenshot = await component.screenshot({ animations: 'disabled' });
65+
expect(screenshot).toMatchSnapshot();
66+
});
67+
});
68+
});
69+
70+
test.describe('non-visual', () => {
71+
test('id', async ({ mount }) => {
72+
const id = 'testId';
73+
74+
const component = await mount(
75+
<ScrollViewForTest
76+
arrows
77+
id={id}
78+
/>,
79+
);
80+
81+
expect(component.locator(`div[id="${id}"]`)).toBeDefined();
82+
expect(component.locator(`div[id="${id}__content"]`)).toBeDefined();
83+
expect(component.locator(`div[id="${id}__arrowPrevButton"]`)).toBeDefined();
84+
expect(component.locator(`div[id="${id}__arrowNextButton"]`)).toBeDefined();
85+
});
86+
87+
test('ref', async ({ mount }) => {
88+
const id = 'testId';
89+
90+
const component = await mount(
91+
<ScrollViewForRefTest
92+
id={id}
93+
testRefAttrName="test-ref"
94+
testRefAttrValue="test-ref-value"
95+
/>,
96+
);
97+
98+
const refValue = await component.evaluate((_, idArg) => document.getElementById(idArg).firstElementChild.getAttribute('test-ref'), id);
99+
100+
expect(refValue).toBe('test-ref-value');
101+
});
102+
});
103+
104+
test.describe('functionality', () => {
105+
test('scroll by arrowScrollStep when click on arrow', async ({
106+
mount,
107+
page,
108+
}) => {
109+
const id = 'testId';
110+
111+
const component = await mount(
112+
<ScrollViewForTest
113+
arrows
114+
arrowsScrollStep={600}
115+
id={id}
116+
/>,
117+
);
118+
119+
const arrow = component.locator(`button[id="${id}__arrowNextButton"]`);
120+
await page.evaluate((idArg) => {
121+
const parent = document.getElementById(idArg);
122+
parent.children[0].setAttribute('style', 'scroll-behavior: unset;');
123+
}, id);
124+
const scroll = component.locator(`div[id="${id}"] > div:first-child`);
125+
await arrow.click();
126+
127+
const atrValue = await scroll.evaluate((element) => element.scrollTop);
128+
129+
expect(atrValue).toBe(600);
130+
});
131+
132+
test('scroll at end when content change and autoScroll is "always"', async ({
133+
mount,
134+
page,
135+
}) => {
136+
const id = 'testId';
137+
138+
const component = await mount(
139+
<ScrollViewForTest
140+
autoScroll="always"
141+
id={id}
142+
/>,
143+
);
144+
145+
await page.evaluate((idArg) => {
146+
(window as ExtendedWindow).scrollEnd = false;
147+
const parent = document.getElementById(idArg);
148+
parent.children[0].setAttribute('style', 'scroll-behavior: unset;');
149+
}, id);
150+
151+
await page.evaluate((idArg) => {
152+
const parent = document.getElementById(idArg);
153+
parent.children[0].addEventListener('scrollend', () => {
154+
(window as ExtendedWindow).scrollEnd = true;
155+
});
156+
parent.children[0].textContent += 'content fragment content fragment content fragment';
157+
}, id);
158+
159+
await page.waitForFunction(() => (window as ExtendedWindow).scrollEnd === true);
160+
161+
const scroll = component.locator(`div[id="${id}"] > div:first-child`);
162+
const atrValue = await scroll.evaluate((element) => element.scrollTop);
163+
164+
expect(atrValue).not.toBe(0);
165+
});
166+
167+
test('scroll at end when scrolled down and content change and autoScroll is "detectEnd"', async ({
168+
mount,
169+
page,
170+
}) => {
171+
const id = 'testId';
172+
let initialScrollTop = 0;
173+
174+
await page.exposeFunction('onScrollEnd', (value: number) => {
175+
initialScrollTop = value;
176+
});
177+
178+
const component = await mount(
179+
<ScrollViewForDetectEndAutoscrollTest
180+
id={id}
181+
/>,
182+
);
183+
184+
/**
185+
* First need to wait for initial scroll down.
186+
*/
187+
await page.evaluate((idArg) => {
188+
(window as ExtendedWindow).scrollEnd = false;
189+
190+
const parent = document.getElementById(idArg);
191+
parent.children[0].addEventListener('scrollend', () => {
192+
(window as ExtendedWindow).scrollEnd = true;
193+
(window as ExtendedWindow)?.onScrollEnd(parent.children[0].scrollTop);
194+
}, { once: true });
195+
}, id);
196+
197+
await page.waitForFunction(() => (window as ExtendedWindow).scrollEnd === true);
198+
199+
/**
200+
* Add scroll detect setup.
201+
*/
202+
await page.evaluate((idArg) => {
203+
(window as ExtendedWindow).scrollEnd = false;
204+
const parent = document.getElementById(idArg);
205+
parent.children[0].addEventListener('scrollend', () => {
206+
(window as ExtendedWindow).scrollEnd = true;
207+
});
208+
}, id);
209+
210+
const button = component.getByRole('button');
211+
await button.click();
212+
213+
/**
214+
* Wait for scroll down.
215+
*/
216+
await page.waitForFunction(() => (window as ExtendedWindow).scrollEnd === true);
217+
218+
const scrollTopAfter = await page.evaluate((idArg) => {
219+
const parent = document.getElementById(idArg);
220+
return parent.children[0].scrollTop;
221+
}, id);
222+
223+
expect(scrollTopAfter).toBeGreaterThan(initialScrollTop);
224+
});
225+
226+
test('do not display top arrow after scroll when debounce expires', async ({
227+
mount,
228+
page,
229+
}) => {
230+
const id = 'testId';
231+
const debounceTimeout = 5000;
232+
233+
const component = await mount(
234+
<ScrollViewForTest
235+
arrows
236+
debounce={debounceTimeout}
237+
id={id}
238+
/>,
239+
);
240+
241+
/**
242+
* Setup scroll down listener.
243+
*/
244+
await page.evaluate((idArg) => {
245+
(window as ExtendedWindow).scrollEnd = false;
246+
const parent = document.getElementById(idArg);
247+
parent.children[0].addEventListener('scrollend', () => {
248+
(window as ExtendedWindow).scrollEnd = true;
249+
}, { once: true });
250+
}, id);
251+
252+
/**
253+
* Scroll down
254+
*/
255+
await page.evaluate((idArg) => {
256+
const parent = document.getElementById(idArg);
257+
parent.children[0].scrollTop += 200;
258+
}, id);
259+
await page.waitForFunction(() => (window as ExtendedWindow).scrollEnd === true);
260+
261+
const topArrowBefore = component.locator(`button[id="${id}__arrowPrevButton"]`);
262+
await expect(topArrowBefore).toBeVisible();
263+
264+
/**
265+
* Wait on debounce timeout to expire.
266+
*/
267+
await page.waitForTimeout(1.5 * debounceTimeout);
268+
269+
const bottomArrowAfter = component.locator(`button[id="${id}__arrowPrevButton"]`);
270+
await expect(bottomArrowAfter).not.toBeVisible();
271+
});
272+
273+
test('do not display bottom arrow after scroll when debounce expires', async ({
274+
mount,
275+
page,
276+
}) => {
277+
const id = 'testId';
278+
const debounceTimeout = 5000;
279+
280+
const component = await mount(
281+
<ScrollViewForTest
282+
arrows
283+
debounce={debounceTimeout}
284+
id={id}
285+
/>,
286+
);
287+
288+
/**
289+
* Setup scroll down listener.
290+
*/
291+
await page.evaluate((idArg) => {
292+
(window as ExtendedWindow).scrollEnd = false;
293+
const parent = document.getElementById(idArg);
294+
parent.children[0].addEventListener('scrollend', () => {
295+
(window as ExtendedWindow).scrollEnd = true;
296+
}, { once: true });
297+
}, id);
298+
299+
/**
300+
* Scroll down
301+
*/
302+
await page.evaluate((idArg) => {
303+
const parent = document.getElementById(idArg);
304+
parent.children[0].scrollTop = parent.children[0].children[0].clientHeight;
305+
}, id);
306+
await page.waitForFunction(() => (window as ExtendedWindow).scrollEnd === true);
307+
308+
const bottomArrowBefore = component.locator(`button[id="${id}__arrowNextButton"]`);
309+
await expect(bottomArrowBefore).toBeVisible();
310+
311+
/**
312+
* Wait on debounce timeout to expire.
313+
*/
314+
await page.waitForTimeout(1.5 * debounceTimeout);
315+
316+
const bottomArrowAfter = component.locator(`button[id="${id}__arrowNextButton"]`);
317+
await expect(bottomArrowAfter).not.toBeVisible();
318+
});
319+
});
320+
});

0 commit comments

Comments
 (0)