Skip to content

Commit 7b56494

Browse files
committed
test: Replace jsdom by browser mode with playwright
1 parent 78dcdb5 commit 7b56494

File tree

15 files changed

+379
-393
lines changed

15 files changed

+379
-393
lines changed

app/components/form/field-checkbox/field-checkbox.spec.tsx

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { expect, test, vi } from 'vitest';
2-
import { axe } from 'vitest-axe';
32
import { z } from 'zod';
43

5-
import { render, screen, setupUser } from '@/tests/utils';
4+
import {
5+
FAILED_CLICK_TIMEOUT_MS,
6+
page,
7+
render,
8+
setupUser,
9+
} from '@/tests/utils';
610

711
import { FormField, FormFieldController } from '..';
812
import { FormMocked } from '../form-test-utils';
@@ -14,36 +18,6 @@ const zFormSchema = () =>
1418
}),
1519
});
1620

17-
test('should have no a11y violations', async () => {
18-
const mockedSubmit = vi.fn();
19-
20-
HTMLCanvasElement.prototype.getContext = vi.fn();
21-
22-
const { container } = render(
23-
<FormMocked
24-
schema={zFormSchema()}
25-
useFormOptions={{ defaultValues: { lovesBears: false } }}
26-
onSubmit={mockedSubmit}
27-
>
28-
{({ form }) => (
29-
<FormField>
30-
<FormFieldController
31-
type="checkbox"
32-
control={form.control}
33-
name="lovesBears"
34-
>
35-
I love bears
36-
</FormFieldController>
37-
</FormField>
38-
)}
39-
</FormMocked>
40-
);
41-
42-
const results = await axe(container);
43-
44-
expect(results).toHaveNoViolations();
45-
});
46-
4721
test('should select checkbox on button click', async () => {
4822
const user = setupUser();
4923
const mockedSubmit = vi.fn();
@@ -68,13 +42,14 @@ test('should select checkbox on button click', async () => {
6842
</FormMocked>
6943
);
7044

71-
const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
72-
expect(checkbox).not.toBeChecked();
45+
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
46+
47+
await expect.element(checkbox).not.toBeChecked();
7348

7449
await user.click(checkbox);
75-
expect(checkbox).toBeChecked();
50+
await expect.element(checkbox).toBeChecked();
7651

77-
await user.click(screen.getByRole('button', { name: 'Submit' }));
52+
await user.click(page.getByRole('button', { name: 'Submit' }));
7853
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
7954
});
8055

@@ -102,16 +77,16 @@ test('should select checkbox on label click', async () => {
10277
</FormMocked>
10378
);
10479

105-
const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
106-
const label = screen.getByText('I love bears');
80+
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
81+
const label = page.getByText('I love bears');
10782

108-
expect(checkbox).not.toBeChecked();
83+
await expect.element(checkbox).not.toBeChecked();
10984

11085
// Test clicking the label specifically
11186
await user.click(label);
112-
expect(checkbox).toBeChecked();
87+
await expect.element(checkbox).toBeChecked();
11388

114-
await user.click(screen.getByRole('button', { name: 'Submit' }));
89+
await user.click(page.getByRole('button', { name: 'Submit' }));
11590
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
11691
});
11792

@@ -138,10 +113,10 @@ test('default value', async () => {
138113
</FormMocked>
139114
);
140115

141-
const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
142-
expect(checkbox).toBeChecked();
116+
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
117+
await expect.element(checkbox).toBeChecked();
143118

144-
await user.click(screen.getByRole('button', { name: 'Submit' }));
119+
await user.click(page.getByRole('button', { name: 'Submit' }));
145120
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
146121
});
147122

@@ -169,12 +144,18 @@ test('disabled', async () => {
169144
</FormMocked>
170145
);
171146

172-
const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
173-
expect(checkbox).toBeDisabled();
174-
expect(checkbox).not.toBeChecked();
175-
176-
await user.click(checkbox);
177-
expect(checkbox).not.toBeChecked();
178-
await user.click(screen.getByRole('button', { name: 'Submit' }));
147+
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
148+
await expect.element(checkbox).toBeDisabled();
149+
await expect.element(checkbox).not.toBeChecked();
150+
151+
try {
152+
await user.click(checkbox, {
153+
trial: true,
154+
timeout: FAILED_CLICK_TIMEOUT_MS,
155+
});
156+
} catch {
157+
await expect.element(checkbox).not.toBeChecked();
158+
}
159+
await user.click(page.getByRole('button', { name: 'Submit' }));
179160
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: undefined });
180161
});

app/components/form/field-otp/field-otp.spec.tsx

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { expect, test, vi } from 'vitest';
22
import { z } from 'zod';
33

4-
import { render, screen, setupUser } from '@/tests/utils';
4+
import {
5+
FAILED_CLICK_TIMEOUT_MS,
6+
page,
7+
render,
8+
setupUser,
9+
} from '@/tests/utils';
510

611
import { FormField, FormFieldController, FormFieldLabel } from '..';
712
import { FormMocked } from '../form-test-utils';
@@ -29,10 +34,14 @@ test('update value', async () => {
2934
)}
3035
</FormMocked>
3136
);
32-
const input = screen.getByLabelText<HTMLInputElement>('Code');
37+
38+
const input = page.getByLabelText('Code');
3339
await user.click(input);
34-
await user.paste('000000');
35-
await user.click(screen.getByRole('button', { name: 'Submit' }));
40+
// Add the code to the user clipboard
41+
await navigator.clipboard.writeText('000000');
42+
43+
await user.paste();
44+
await user.click(page.getByRole('button', { name: 'Submit' }));
3645
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
3746
});
3847

@@ -62,7 +71,7 @@ test('default value', async () => {
6271
)}
6372
</FormMocked>
6473
);
65-
await user.click(screen.getByRole('button', { name: 'Submit' }));
74+
await user.click(page.getByRole('button', { name: 'Submit' }));
6675
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
6776
});
6877

@@ -90,9 +99,11 @@ test('auto submit', async () => {
9099
)}
91100
</FormMocked>
92101
);
93-
const input = screen.getByLabelText<HTMLInputElement>('Code');
102+
const input = page.getByLabelText('Code');
94103
await user.click(input);
95-
await user.paste('000000');
104+
// Add the code to the user clipboard
105+
await navigator.clipboard.writeText('000000');
106+
await user.paste();
96107
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
97108
});
98109

@@ -120,9 +131,17 @@ test('disabled', async () => {
120131
)}
121132
</FormMocked>
122133
);
123-
const input = screen.getByLabelText<HTMLInputElement>('Code');
124-
await user.click(input);
125-
await user.paste('123456');
126-
await user.click(screen.getByRole('button', { name: 'Submit' }));
134+
const input = page.getByLabelText('Code');
135+
try {
136+
await user.click(input, { timeout: FAILED_CLICK_TIMEOUT_MS });
137+
} catch {
138+
// Click expected to fail since input is disabled
139+
}
140+
// Add the code to the user clipboard
141+
await navigator.clipboard.writeText('123456');
142+
await user.paste();
143+
144+
await user.click(page.getByRole('button', { name: 'Submit' }));
145+
127146
expect(mockedSubmit).toHaveBeenCalledWith({ code: undefined });
128147
});

app/components/form/field-radio-group/field-radio-group.spec.tsx

Lines changed: 40 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { expect, test, vi } from 'vitest';
2-
import { axe } from 'vitest-axe';
32
import { z } from 'zod';
43

5-
import { render, screen, setupUser } from '@/tests/utils';
4+
import {
5+
FAILED_CLICK_TIMEOUT_MS,
6+
page,
7+
render,
8+
setupUser,
9+
} from '@/tests/utils';
610

711
import { FormField, FormFieldController, FormFieldLabel } from '..';
812
import { FormMocked } from '../form-test-utils';
@@ -27,36 +31,6 @@ const options = [
2731
},
2832
];
2933

30-
test('should have no a11y violations', async () => {
31-
const mockedSubmit = vi.fn();
32-
33-
HTMLCanvasElement.prototype.getContext = vi.fn();
34-
35-
const { container } = render(
36-
<FormMocked
37-
schema={z.object({ bear: z.string() })}
38-
useFormOptions={{ defaultValues: { bear: undefined } }}
39-
onSubmit={mockedSubmit}
40-
>
41-
{({ form }) => (
42-
<FormField>
43-
<FormFieldLabel>Bearstronaut</FormFieldLabel>
44-
<FormFieldController
45-
type="radio-group"
46-
control={form.control}
47-
name="bear"
48-
options={options}
49-
/>
50-
</FormField>
51-
)}
52-
</FormMocked>
53-
);
54-
55-
const results = await axe(container);
56-
57-
expect(results).toHaveNoViolations();
58-
});
59-
6034
test('should select radio on button click', async () => {
6135
const user = setupUser();
6236
const mockedSubmit = vi.fn();
@@ -81,13 +55,13 @@ test('should select radio on button click', async () => {
8155
</FormMocked>
8256
);
8357

84-
const radio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
85-
expect(radio).not.toBeChecked();
58+
const radio = page.getByRole('radio', { name: 'Buzz Pawdrin' });
59+
await expect.element(radio).not.toBeChecked();
8660

8761
await user.click(radio);
88-
expect(radio).toBeChecked();
62+
await expect.element(radio).toBeChecked();
8963

90-
await user.click(screen.getByRole('button', { name: 'Submit' }));
64+
await user.click(page.getByRole('button', { name: 'Submit' }));
9165
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'pawdrin' });
9266
});
9367

@@ -115,16 +89,16 @@ test('should select radio on label click', async () => {
11589
</FormMocked>
11690
);
11791

118-
const radio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
119-
const label = screen.getByText('Buzz Pawdrin');
92+
const radio = page.getByRole('radio', { name: 'Buzz Pawdrin' });
93+
const label = page.getByText('Buzz Pawdrin');
12094

121-
expect(radio).not.toBeChecked();
95+
await expect.element(radio).not.toBeChecked();
12296

12397
// Test clicking the label specifically
12498
await user.click(label);
125-
expect(radio).toBeChecked();
99+
await expect.element(radio).toBeChecked();
126100

127-
await user.click(screen.getByRole('button', { name: 'Submit' }));
101+
await user.click(page.getByRole('button', { name: 'Submit' }));
128102
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'pawdrin' });
129103
});
130104

@@ -152,26 +126,26 @@ test('should handle keyboard navigation', async () => {
152126
</FormMocked>
153127
);
154128

155-
const firstRadio = screen.getByRole('radio', { name: 'Bearstrong' });
156-
const secondRadio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
157-
const thirdRadio = screen.getByRole('radio', { name: 'Yuri Grizzlyrin' });
129+
const firstRadio = page.getByRole('radio', { name: 'Bearstrong' });
130+
const secondRadio = page.getByRole('radio', { name: 'Buzz Pawdrin' });
131+
const thirdRadio = page.getByRole('radio', { name: 'Yuri Grizzlyrin' });
158132

159133
await user.tab();
160-
expect(firstRadio).toHaveFocus();
134+
await expect.element(firstRadio).toHaveFocus();
161135

162136
await user.keyboard('{ArrowDown}');
163-
expect(secondRadio).toHaveFocus();
137+
await expect.element(secondRadio).toHaveFocus();
164138
await user.keyboard(' ');
165-
expect(secondRadio).toBeChecked();
139+
await expect.element(secondRadio).toBeChecked();
166140

167141
await user.keyboard('{ArrowDown}');
168-
expect(thirdRadio).toHaveFocus();
142+
await expect.element(thirdRadio).toHaveFocus();
169143

170144
await user.keyboard('{ArrowUp}');
171-
expect(secondRadio).toHaveFocus();
172-
expect(secondRadio).toBeChecked(); // Second radio should still be checked
145+
await expect.element(secondRadio).toHaveFocus();
146+
await expect.element(secondRadio).toBeChecked(); // Second radio should still be checked
173147

174-
await user.click(screen.getByRole('button', { name: 'Submit' }));
148+
await user.click(page.getByRole('button', { name: 'Submit' }));
175149
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'pawdrin' });
176150
});
177151

@@ -202,10 +176,10 @@ test('default value', async () => {
202176
</FormMocked>
203177
);
204178

205-
const radio = screen.getByRole('radio', { name: 'Yuri Grizzlyrin' });
206-
expect(radio).toBeChecked();
179+
const radio = page.getByRole('radio', { name: 'Yuri Grizzlyrin' });
180+
await expect.element(radio).toBeChecked();
207181

208-
await user.click(screen.getByRole('button', { name: 'Submit' }));
182+
await user.click(page.getByRole('button', { name: 'Submit' }));
209183
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'grizzlyrin' });
210184
});
211185

@@ -237,10 +211,10 @@ test('disabled', async () => {
237211
</FormMocked>
238212
);
239213

240-
const radio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
241-
expect(radio).toBeDisabled();
214+
const radio = page.getByRole('radio', { name: 'Buzz Pawdrin' });
215+
await expect.element(radio).toBeDisabled();
242216

243-
await user.click(screen.getByRole('button', { name: 'Submit' }));
217+
await user.click(page.getByRole('button', { name: 'Submit' }));
244218
expect(mockedSubmit).toHaveBeenCalledWith({ bear: undefined });
245219
});
246220

@@ -271,12 +245,16 @@ test('disabled option', async () => {
271245
</FormMocked>
272246
);
273247

274-
const disabledRadio = screen.getByRole('radio', { name: 'Mae Jemibear' });
275-
expect(disabledRadio).toBeDisabled();
248+
const disabledRadio = page.getByRole('radio', { name: 'Mae Jemibear' });
249+
await expect.element(disabledRadio).toBeDisabled();
276250

277-
await user.click(disabledRadio);
278-
expect(disabledRadio).not.toBeChecked();
251+
try {
252+
await user.click(disabledRadio, { timeout: FAILED_CLICK_TIMEOUT_MS });
253+
} catch {
254+
// Expected to fail since input is disabled
255+
}
256+
await expect.element(disabledRadio).not.toBeChecked();
279257

280-
await user.click(screen.getByRole('button', { name: 'Submit' }));
258+
await user.click(page.getByRole('button', { name: 'Submit' }));
281259
expect(mockedSubmit).toHaveBeenCalledWith({ bear: '' });
282260
});

0 commit comments

Comments
 (0)