import React, { useState } from "react"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, it, expect, vi } from "vitest"; import RadioButton from "../../app/components/RadioButton"; describe("RadioButton Integration", () => { it("works in form context", async () => { const user = userEvent.setup(); const handleSubmit = vi.fn(); function TestForm() { const [value, setValue] = useState("option1"); return (
checked && setValue("option1")} /> checked && setValue("option2")} /> ); } render(); const option2 = screen.getByText("Option 2").closest("label"); const submitButton = screen.getByRole("button"); // Initially option1 should be selected expect(screen.getByDisplayValue("option1")).toBeChecked(); expect(screen.getByDisplayValue("option2")).not.toBeChecked(); // Click option2 await user.click(option2); expect(screen.getByDisplayValue("option2")).toBeChecked(); expect(screen.getByDisplayValue("option1")).not.toBeChecked(); // Submit form await user.click(submitButton); expect(handleSubmit).toHaveBeenCalled(); }); it("handles keyboard navigation", async () => { const user = userEvent.setup(); function KeyboardForm() { const [value, setValue] = useState("option1"); return (
checked && setValue("option1")} /> checked && setValue("option2")} />
); } render(); const radioButtons = screen.getAllByRole("radio"); // Focus first radio button radioButtons[0].focus(); expect(radioButtons[0]).toHaveFocus(); // Navigate to second radio button await user.tab(); expect(radioButtons[1]).toHaveFocus(); // Activate with Space await user.keyboard(" "); expect(screen.getByDisplayValue("option2")).toBeChecked(); }); it("handles mode switching", async () => { function ModeSwitchForm() { const [mode, setMode] = useState("standard"); const [value, setValue] = useState("option1"); return (
checked && setValue("option1")} />
); } const user = userEvent.setup(); render(); const toggleButton = screen.getByRole("button"); const radioButton = screen.getByRole("radio"); // Initially standard mode expect(radioButton).toHaveClass( "outline-[var(--color-border-default-tertiary)]", ); // Switch to inverse mode await user.click(toggleButton); expect(radioButton).toHaveClass( "outline-[var(--color-border-inverse-primary)]", ); }); it("maintains state across re-renders", () => { function StateForm() { const [value, setValue] = useState("option1"); const [count, setCount] = useState(0); return (
checked && setValue("option1")} />
); } const user = userEvent.setup(); render(); const radioButton = screen.getByRole("radio"); const reRenderButton = screen.getByRole("button"); // Should be checked initially expect(radioButton).toHaveAttribute("aria-checked", "true"); // Re-render should maintain state user.click(reRenderButton); expect(radioButton).toHaveAttribute("aria-checked", "true"); }); it("works with multiple radio groups", async () => { function MultiGroupForm() { const [group1Value, setGroup1Value] = useState("option1"); const [group2Value, setGroup2Value] = useState("option1"); return (

Group 1

checked && setGroup1Value("option1")} /> checked && setGroup1Value("option2")} />

Group 2

checked && setGroup2Value("option1")} /> checked && setGroup2Value("option2")} />
); } const user = userEvent.setup(); render(); // Both groups should work independently const group1OptionB = screen.getByText("Option B").closest("label"); const group2OptionY = screen.getByText("Option Y").closest("label"); await user.click(group1OptionB); await user.click(group2OptionY); const group1Inputs = screen .getAllByDisplayValue("option2") .filter((input) => input.getAttribute("name") === "group1"); const group2Inputs = screen .getAllByDisplayValue("option2") .filter((input) => input.getAttribute("name") === "group2"); expect(group1Inputs[0]).toBeChecked(); expect(group2Inputs[0]).toBeChecked(); }); it("handles controlled and uncontrolled scenarios", async () => { function ControlledForm() { const [controlledValue, setControlledValue] = useState("option1"); const [uncontrolledValue, setUncontrolledValue] = useState("option1"); return (

Controlled

checked && setControlledValue("option1") } /> checked && setControlledValue("option2") } />

Uncontrolled

checked && setUncontrolledValue("option1") } /> checked && setUncontrolledValue("option2") } />
); } const user = userEvent.setup(); render(); // Both should work the same way const controlledOption2 = screen .getByText("Controlled Option 2") .closest("label"); const uncontrolledOption2 = screen .getByText("Uncontrolled Option 2") .closest("label"); await user.click(controlledOption2); await user.click(uncontrolledOption2); const controlledInputs = screen .getAllByDisplayValue("option2") .filter((input) => input.getAttribute("name") === "controlled"); const uncontrolledInputs = screen .getAllByDisplayValue("option2") .filter((input) => input.getAttribute("name") === "uncontrolled"); expect(controlledInputs[0]).toBeChecked(); expect(uncontrolledInputs[0]).toBeChecked(); }); it("handles accessibility in complex forms", () => { function AccessibleForm() { const [value, setValue] = useState("option1"); return (
Choose an option checked && setValue("option1")} ariaLabel="First option" /> checked && setValue("option2")} ariaLabel="Second option" />
); } render(); const radioButtons = screen.getAllByRole("radio"); // Should have proper accessibility attributes radioButtons.forEach((button) => { expect(button).toHaveAttribute("role", "radio"); expect(button).toHaveAttribute("aria-checked"); expect(button).toHaveAttribute("tabIndex", "0"); }); // Should have aria-labels expect(radioButtons[0]).toHaveAttribute("aria-label", "First option"); expect(radioButtons[1]).toHaveAttribute("aria-label", "Second option"); }); });