Skip to content

Commit 24448c1

Browse files
committed
Transform Modal jest tests into playwright (#596)
1 parent 36bb792 commit 24448c1

File tree

62 files changed

+1104
-671
lines changed

Some content is hidden

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

62 files changed

+1104
-671
lines changed
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
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+
ModalWithInputsForTest,
9+
ModalForTest,
10+
ModalWithPartiallyDisabledInputsForTest,
11+
ModalWithButtonsAndWithoutInputsForTest,
12+
} from './Modal.story';
13+
import { positionPropTest } from './_propTests/Modal/positionPropTest';
14+
import { sizePropTest } from './_propTests/Modal/sizePropTest';
15+
16+
test.describe('Modal', () => {
17+
test.describe('visual', () => {
18+
[
19+
...propTests.defaultComponentPropTest,
20+
...propTests.feedbackColorPropTest,
21+
...positionPropTest,
22+
...sizePropTest,
23+
].forEach(({
24+
name,
25+
onBeforeTest,
26+
onBeforeSnapshot,
27+
props,
28+
}) => {
29+
test(name, async ({
30+
mount,
31+
page,
32+
}) => {
33+
if (onBeforeTest) {
34+
await onBeforeTest(page);
35+
}
36+
37+
const component = await mount(
38+
<ModalForTest
39+
{...props}
40+
/>,
41+
);
42+
43+
if (onBeforeSnapshot) {
44+
await onBeforeSnapshot(page, component);
45+
}
46+
47+
const screenshot = await component.screenshot({ animations: 'disabled' });
48+
expect(screenshot).toMatchSnapshot();
49+
});
50+
});
51+
});
52+
53+
test.describe('non-visual', () => {
54+
test('id', async ({ mount }) => {
55+
const testId = 'testId';
56+
57+
const component = await mount(
58+
<div>
59+
<ModalForTest id={testId} />
60+
</div>,
61+
);
62+
63+
await expect(component.locator('dialog')).toHaveAttribute('id', testId);
64+
});
65+
});
66+
67+
test.describe('functionality', () => {
68+
test.describe('allowCloseOnEscapeKey', () => {
69+
test('close on esc key press when enabled', async ({ mount }) => {
70+
let called = false;
71+
72+
const component = await mount(
73+
<ModalWithInputsForTest
74+
allowCloseOnEscapeKey
75+
closeButtonOnClick={() => {
76+
called = true;
77+
}}
78+
/>,
79+
);
80+
81+
const dialog = component.locator('dialog');
82+
await dialog.focus();
83+
await dialog.press('Escape');
84+
expect(called).toBe(true);
85+
});
86+
87+
test('do not close on esc key press when disabled', async ({ mount }) => {
88+
let called = false;
89+
90+
const component = await mount(
91+
<ModalWithInputsForTest
92+
allowCloseOnEscapeKey={false}
93+
closeButtonOnClick={() => {
94+
called = true;
95+
}}
96+
/>,
97+
);
98+
99+
const dialog = component.locator('dialog');
100+
await dialog.focus();
101+
await dialog.press('Escape');
102+
expect(called).toBe(false);
103+
});
104+
});
105+
106+
test.describe('allowPrimaryActionOnEnterKey', () => {
107+
test('call primary action on enter key press when input/select content focused', async ({ mount }) => {
108+
let called = false;
109+
110+
const component = await mount(
111+
<ModalWithInputsForTest
112+
allowPrimaryActionOnEnterKey
113+
primaryButtonOnClick={() => {
114+
called = true;
115+
}}
116+
/>,
117+
);
118+
119+
const input = component.locator('input[name="input1"]');
120+
await input.focus();
121+
await input.press('Enter');
122+
expect(called).toBe(true);
123+
});
124+
125+
test('do not call primary action on enter key press when is disabled', async ({ mount }) => {
126+
let called = false;
127+
128+
const component = await mount(
129+
<ModalWithInputsForTest
130+
allowPrimaryActionOnEnterKey={false}
131+
primaryButtonOnClick={() => {
132+
called = true;
133+
}}
134+
/>,
135+
);
136+
137+
const input = component.locator('input[name="input1"]');
138+
await input.focus();
139+
await input.press('Enter');
140+
expect(called).toBe(false);
141+
});
142+
});
143+
144+
test.describe('autoFocus', () => {
145+
test('focus first input element when enabled', async ({ mount }) => {
146+
const component = await mount(
147+
<ModalWithInputsForTest autoFocus />,
148+
);
149+
150+
const input = component.locator('input[name="input1"]');
151+
await expect(input).toBeFocused();
152+
});
153+
154+
test('focus first non disabled input element when enabled', async ({ mount }) => {
155+
const component = await mount(
156+
<ModalWithPartiallyDisabledInputsForTest autoFocus />,
157+
);
158+
159+
const input = component.locator('input[name="input2"]');
160+
await expect(input).toBeFocused();
161+
});
162+
163+
test('focus primary button when no input content and autoFocus is enabled', async ({ mount }) => {
164+
const component = await mount(
165+
<ModalWithButtonsAndWithoutInputsForTest autoFocus />,
166+
);
167+
168+
const button = component.getByText('Primary button');
169+
await expect(button).toBeFocused();
170+
});
171+
172+
test('focus modal itself, when no focusable element and autoFocus enabled', async ({ mount }) => {
173+
const component = await mount(
174+
<ModalForTest autoFocus />,
175+
);
176+
177+
const dialog = component.locator('dialog');
178+
await expect(dialog).toBeFocused();
179+
});
180+
181+
test('no focused element when disabled', async ({ mount }) => {
182+
const component = await mount(
183+
<ModalWithInputsForTest autoFocus={false} />,
184+
);
185+
186+
const promises: Promise<void>[] = [];
187+
const inputs = await component.locator('input').all();
188+
const buttons = await component.locator('button').all();
189+
190+
inputs.forEach((input) => promises.push(expect(input).not.toBeFocused()));
191+
buttons.forEach((button) => promises.push(expect(button).not.toBeFocused()));
192+
193+
await Promise.allSettled(promises);
194+
});
195+
});
196+
197+
test.describe('allowCloseOnBackdropClick', () => {
198+
test('close on backdrop click when enabled', async ({
199+
mount,
200+
page,
201+
}) => {
202+
let called = false;
203+
204+
const component = await mount(
205+
<ModalWithInputsForTest
206+
allowCloseOnBackdropClick
207+
closeButtonOnClick={() => {
208+
called = true;
209+
}}
210+
/>,
211+
);
212+
213+
const dialog = component.locator('dialog');
214+
const box = await dialog.evaluate((element) => element.getBoundingClientRect());
215+
await page.mouse.click(box.x - 50, box.y - 50);
216+
await page.waitForTimeout(2000);
217+
expect(called).toBe(true);
218+
});
219+
220+
test('do not close on backdrop click when disabled', async ({
221+
mount,
222+
page,
223+
}) => {
224+
let called = false;
225+
226+
const component = await mount(
227+
<div>
228+
<ModalWithInputsForTest
229+
allowCloseOnBackdropClick={false}
230+
closeButtonOnClick={() => {
231+
called = true;
232+
}}
233+
/>
234+
</div>,
235+
);
236+
237+
const dialog = component.locator('dialog');
238+
const box = await dialog.evaluate((element) => element.getBoundingClientRect());
239+
await page.mouse.click(box.x - 50, box.y - 50);
240+
expect(called).toBe(false);
241+
});
242+
});
243+
244+
test.describe('portalId', () => {
245+
test('render in portal when defined', async ({
246+
mount,
247+
page,
248+
}) => {
249+
const portalId = 'portal-id';
250+
251+
await page.evaluate(() => {
252+
document.body.innerHTML += '<div id="portal-id" />';
253+
});
254+
255+
await mount(
256+
<ModalForTest portalId={portalId} />,
257+
);
258+
259+
const portalHTMLContent = await page
260+
.evaluate((id) => document.getElementById(id).innerHTML, portalId);
261+
262+
expect(portalHTMLContent).toContain('dialog');
263+
});
264+
});
265+
});
266+
});
11.5 KB
Loading
11.5 KB
Loading
11.6 KB
Loading
11.5 KB
Loading
11.6 KB
Loading
11.5 KB
Loading
11.4 KB
Loading
11.4 KB
Loading
11.4 KB
Loading

0 commit comments

Comments
 (0)