Skip to content

Commit 4a5a2f0

Browse files
authored
update toggle test to vitest (#302)
1 parent c4551f5 commit 4a5a2f0

File tree

3 files changed

+310
-272
lines changed

3 files changed

+310
-272
lines changed
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
import { $, type PropsOf, component$, useSignal } from "@qwik.dev/core";
2+
import { page, userEvent } from "@vitest/browser/context";
3+
import { expect, test } from "vitest";
4+
import { render } from "vitest-browser-qwik";
5+
import { Toggle } from "..";
6+
7+
// Top-level locator constants using data-testid
8+
const Root = page.getByTestId("root");
9+
const Indicator = page.getByTestId("indicator");
10+
11+
const Basic = component$((props: PropsOf<typeof Toggle.Root>) => {
12+
return (
13+
<Toggle.Root {...props} data-testid="root" aria-label="Toggle">
14+
Toggle
15+
</Toggle.Root>
16+
);
17+
});
18+
19+
const InitialPressed = component$(() => {
20+
return (
21+
<Toggle.Root pressed data-testid="root" aria-label="Toggle">
22+
Toggle
23+
</Toggle.Root>
24+
);
25+
});
26+
27+
const WithIndicator = component$(() => {
28+
return (
29+
<Toggle.Root data-testid="root" aria-label="Toggle State">
30+
<Toggle.Indicator data-testid="indicator" fallback={<span>Is Off</span>}>
31+
<span>Is On</span>
32+
</Toggle.Indicator>
33+
</Toggle.Root>
34+
);
35+
});
36+
37+
const WithSignal = component$(() => {
38+
const isPressedSig = useSignal(true);
39+
40+
return (
41+
<div>
42+
<Toggle.Root
43+
data-testid="root"
44+
aria-label="Toggle Mute"
45+
bind:pressed={isPressedSig}
46+
>
47+
Toggle
48+
</Toggle.Root>
49+
50+
<button
51+
type="button"
52+
data-testid="toggle-signal"
53+
onClick$={() => {
54+
isPressedSig.value = !isPressedSig.value;
55+
}}
56+
>
57+
Toggle Signal
58+
</button>
59+
60+
<p>Bound Signal: {isPressedSig.value.toString()}</p>
61+
</div>
62+
);
63+
});
64+
65+
const WithChange = component$(() => {
66+
const countSig = useSignal(0);
67+
68+
const handleChange = $(() => {
69+
countSig.value++;
70+
});
71+
72+
return (
73+
<div>
74+
<Toggle.Root data-testid="root" aria-label="Toggle Like" onChange$={handleChange}>
75+
Toggle
76+
</Toggle.Root>
77+
<p>Count: {countSig.value}</p>
78+
</div>
79+
);
80+
});
81+
82+
const Disabled = component$(() => {
83+
return (
84+
<Toggle.Root disabled data-testid="root" aria-label="Toggle">
85+
Toggle
86+
</Toggle.Root>
87+
);
88+
});
89+
90+
const CSR = component$(() => {
91+
const showToggleSig = useSignal(false);
92+
93+
return (
94+
<div>
95+
<button
96+
type="button"
97+
data-testid="render-toggle"
98+
onClick$={() => {
99+
showToggleSig.value = true;
100+
}}
101+
>
102+
Render Toggle
103+
</button>
104+
105+
{showToggleSig.value && (
106+
<Toggle.Root data-testid="root" aria-label="Toggle">
107+
Toggle
108+
</Toggle.Root>
109+
)}
110+
</div>
111+
);
112+
});
113+
114+
test("default toggle can be clicked to be pressed", async () => {
115+
render(<Basic />);
116+
117+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
118+
await expect.element(Root).not.toHaveAttribute("data-pressed");
119+
120+
await userEvent.click(Root);
121+
122+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
123+
await expect.element(Root).toHaveAttribute("data-pressed");
124+
});
125+
126+
test("pressed toggle can be clicked to be unpressed", async () => {
127+
render(<InitialPressed />);
128+
129+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
130+
await expect.element(Root).toHaveAttribute("data-pressed");
131+
132+
await userEvent.click(Root);
133+
134+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
135+
await expect.element(Root).not.toHaveAttribute("data-pressed");
136+
});
137+
138+
test("toggle can be toggled with Space key", async () => {
139+
render(<Basic />);
140+
141+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
142+
await expect.element(Root).not.toHaveAttribute("data-pressed");
143+
144+
await expect.element(Root).toBeVisible();
145+
((await Root.element()) as HTMLButtonElement).focus();
146+
await userEvent.keyboard("{Space}");
147+
148+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
149+
await expect.element(Root).toHaveAttribute("data-pressed");
150+
});
151+
152+
test("pressed toggle can be unpressed with Space key", async () => {
153+
render(<InitialPressed />);
154+
155+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
156+
await expect.element(Root).toHaveAttribute("data-pressed");
157+
158+
await expect.element(Root).toBeVisible();
159+
((await Root.element()) as HTMLButtonElement).focus();
160+
await userEvent.keyboard("{Space}");
161+
162+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
163+
await expect.element(Root).not.toHaveAttribute("data-pressed");
164+
});
165+
166+
test("toggle can be toggled with Enter key", async () => {
167+
render(<Basic />);
168+
169+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
170+
await expect.element(Root).not.toHaveAttribute("data-pressed");
171+
172+
await expect.element(Root).toBeVisible();
173+
((await Root.element()) as HTMLButtonElement).focus();
174+
await userEvent.keyboard("{Enter}");
175+
176+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
177+
await expect.element(Root).toHaveAttribute("data-pressed");
178+
});
179+
180+
test("pressed toggle can be unpressed with Enter key", async () => {
181+
render(<InitialPressed />);
182+
183+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
184+
await expect.element(Root).toHaveAttribute("data-pressed");
185+
186+
await expect.element(Root).toBeVisible();
187+
((await Root.element()) as HTMLButtonElement).focus();
188+
await userEvent.keyboard("{Enter}");
189+
190+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
191+
await expect.element(Root).not.toHaveAttribute("data-pressed");
192+
});
193+
194+
test("toggle has type button attribute", async () => {
195+
render(<Basic />);
196+
await expect.element(Root).toHaveAttribute("type", "button");
197+
});
198+
199+
test("toggle has aria-pressed false by default", async () => {
200+
render(<Basic />);
201+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
202+
});
203+
204+
test("aria-pressed updates when toggled", async () => {
205+
render(<Basic />);
206+
207+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
208+
209+
await userEvent.click(Root);
210+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
211+
212+
await userEvent.click(Root);
213+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
214+
});
215+
216+
test("data-pressed updates when state changes", async () => {
217+
render(<Basic />);
218+
219+
await expect.element(Root).not.toHaveAttribute("data-pressed");
220+
221+
await userEvent.click(Root);
222+
await expect.element(Root).toHaveAttribute("data-pressed");
223+
224+
await userEvent.click(Root);
225+
await expect.element(Root).not.toHaveAttribute("data-pressed");
226+
});
227+
228+
test("external signal changes update toggle state", async () => {
229+
render(<WithSignal />);
230+
231+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
232+
await expect.element(Root).toHaveAttribute("data-pressed");
233+
234+
await expect.element(page.getByText("true")).toBeVisible();
235+
236+
await userEvent.click(page.getByTestId("toggle-signal"));
237+
238+
await expect.element(Root).not.toHaveAttribute("data-pressed");
239+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
240+
241+
await expect.element(page.getByText("false")).toBeVisible();
242+
});
243+
244+
test("onChange$ is called when toggled on", async () => {
245+
render(<WithChange />);
246+
247+
await expect.element(page.getByText("Count: 0")).toBeVisible();
248+
249+
await userEvent.click(Root);
250+
251+
await expect.element(page.getByText("Count: 1")).toBeVisible();
252+
});
253+
254+
test("onChange$ is called when toggled off", async () => {
255+
render(<WithChange />);
256+
257+
await expect.element(page.getByText("Count: 0")).toBeVisible();
258+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
259+
260+
await userEvent.click(Root);
261+
262+
await expect.element(page.getByText("Count: 1")).toBeVisible();
263+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
264+
265+
await userEvent.click(Root);
266+
267+
await expect.element(page.getByText("Count: 2")).toBeVisible();
268+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
269+
});
270+
271+
test("disabled toggle has disabled and aria-disabled attributes", async () => {
272+
render(<Disabled />);
273+
274+
await expect.element(Root).toBeDisabled();
275+
await expect.element(Root).toHaveAttribute("aria-disabled", "true");
276+
});
277+
278+
test("indicator shows fallback content when not pressed", async () => {
279+
render(<WithIndicator />);
280+
281+
await expect.element(Indicator.getByText("Is Off")).toBeVisible();
282+
await expect.element(Indicator.getByText("Is On")).not.toBeInTheDocument();
283+
});
284+
285+
test("indicator shows pressed content when pressed", async () => {
286+
render(<WithIndicator />);
287+
288+
await userEvent.click(Root);
289+
290+
await expect.element(Indicator.getByText("Is On")).toBeVisible();
291+
await expect.element(Indicator.getByText("Is Off")).not.toBeInTheDocument();
292+
});
293+
294+
test("client-side rendered toggle is visible after render", async () => {
295+
render(<CSR />);
296+
297+
await userEvent.click(page.getByTestId("render-toggle"));
298+
await expect.element(Root).toBeVisible();
299+
});
300+
301+
test("client-side rendered toggle state changes when clicked", async () => {
302+
render(<CSR />);
303+
304+
await userEvent.click(page.getByTestId("render-toggle"));
305+
await expect.element(Root).toBeVisible();
306+
await expect.element(Root).toHaveAttribute("aria-pressed", "false");
307+
308+
await userEvent.click(Root);
309+
await expect.element(Root).toHaveAttribute("aria-pressed", "true");
310+
});

libs/components/src/toggle/toggle.driver.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)