import React from "react"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import { describe, it, expect, vi } from "vitest"; import userEvent from "@testing-library/user-event"; import Switch from "../../app/components/Switch"; // Test form component const TestForm = ({ onSubmit }) => { const [switch1, setSwitch1] = React.useState(false); const [switch2, setSwitch2] = React.useState(true); const handleSubmit = (e) => { e.preventDefault(); onSubmit({ switch1, switch2 }); }; return (
setSwitch1(!switch1)} label="First Switch" /> setSwitch2(!switch2)} label="Second Switch" /> ); }; // Dynamic switch component const DynamicSwitch = ({ initialState = false }) => { const [checked, setChecked] = React.useState(initialState); // Update state when initialState prop changes React.useEffect(() => { setChecked(initialState); }, [initialState]); return (
setChecked(!checked)} label="Dynamic Switch" />
); }; describe("Switch Integration", () => { it("handles form submission", async () => { const user = userEvent.setup(); const handleSubmit = vi.fn(); render(); const submitButton = screen.getByRole("button", { name: "Submit" }); await user.click(submitButton); expect(handleSubmit).toHaveBeenCalledWith({ switch1: false, switch2: true, }); }); it("handles keyboard navigation between switches", async () => { const user = userEvent.setup(); render(
, ); const switches = screen.getAllByRole("switch"); expect(switches).toHaveLength(3); // Focus first switch await user.tab(); expect(switches[0]).toHaveFocus(); // Tab to second switch await user.tab(); expect(switches[1]).toHaveFocus(); // Tab to third switch await user.tab(); expect(switches[2]).toHaveFocus(); }); it("handles dynamic prop changes", () => { const { rerender } = render(); let switchButton = screen.getByRole("switch"); expect(switchButton).toHaveAttribute("aria-checked", "false"); // Change initial state - the DynamicSwitch component should handle this internally rerender(); switchButton = screen.getByRole("switch"); // The DynamicSwitch component manages its own state, so it should be checked expect(switchButton).toHaveAttribute("aria-checked", "true"); }); it("handles multiple switches in form", async () => { const user = userEvent.setup(); const handleSubmit = vi.fn(); const TestForm = () => { const [switch1, setSwitch1] = React.useState(false); const [switch2, setSwitch2] = React.useState(false); const [switch3, setSwitch3] = React.useState(false); return (
{ e.preventDefault(); handleSubmit(); }} > setSwitch1(!switch1)} /> setSwitch2(!switch2)} /> setSwitch3(!switch3)} /> ); }; render(); const switches = screen.getAllByRole("switch"); expect(switches).toHaveLength(3); // Toggle first switch await user.click(switches[0]); expect(switches[0]).toHaveAttribute("aria-checked", "true"); // Toggle second switch await user.click(switches[1]); expect(switches[1]).toHaveAttribute("aria-checked", "true"); // Submit form const submitButton = screen.getByRole("button", { name: "Submit" }); await user.click(submitButton); expect(handleSubmit).toHaveBeenCalled(); }); it("handles state changes", async () => { const user = userEvent.setup(); const TestComponent = () => { const [checked, setChecked] = React.useState(false); return (
setChecked(!checked)} label="Test Switch" />
); }; render(); const switchButton = screen.getByRole("switch"); // Initially unchecked expect(switchButton).toHaveAttribute("aria-checked", "false"); // Toggle checked state await user.click(switchButton); expect(switchButton).toHaveAttribute("aria-checked", "true"); }); it("handles content changes", () => { const { rerender } = render(); expect(screen.getByText("Original Label")).toBeInTheDocument(); rerender(); expect(screen.getByText("Updated Label")).toBeInTheDocument(); expect(screen.queryByText("Original Label")).not.toBeInTheDocument(); }); it("handles performance with many switches", () => { const switches = Array.from({ length: 100 }, (_, i) => ( )); const startTime = performance.now(); render(
{switches}
); const endTime = performance.now(); // Should render within reasonable time (less than 1 second) expect(endTime - startTime).toBeLessThan(1000); const renderedSwitches = screen.getAllByRole("switch"); expect(renderedSwitches).toHaveLength(100); }); it("handles rapid state changes", async () => { const user = userEvent.setup(); const TestComponent = () => { const [checked, setChecked] = React.useState(false); return ( setChecked(!checked)} label="Rapid Toggle Switch" /> ); }; render(); const switchButton = screen.getByRole("switch"); // Rapidly toggle the switch for (let i = 0; i < 10; i++) { await user.click(switchButton); await waitFor(() => { expect(switchButton).toHaveAttribute( "aria-checked", i % 2 === 0 ? "true" : "false", ); }); } }); it("handles mixed content types", () => { render(
, ); const switches = screen.getAllByRole("switch"); expect(switches).toHaveLength(4); // Check that labels are rendered correctly expect(screen.getByText("Text Switch")).toBeInTheDocument(); expect(screen.getByText("Another Text Switch")).toBeInTheDocument(); expect(screen.getByText("Final Switch")).toBeInTheDocument(); }); });