import { useState } from "react"; import { render, screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { Field, FieldDescription, FieldError } from "./field"; import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from "./select"; function ReviewLaneSelect(props?: React.ComponentProps) { return ( ); } describe("Select", () => { it("renders default value and opens selectable content", async () => { const user = userEvent.setup(); render(); const trigger = screen.getByRole("combobox", { name: "Review lane" }); expect(trigger).toHaveTextContent("Design review"); expect(trigger).toHaveAttribute("data-slot", "trigger"); await user.click(trigger); const listbox = await screen.findByRole("listbox"); const designOption = within(listbox).getByRole("option", { name: "Design review" }); expect(listbox).toHaveAttribute("data-slot", "content"); expect(designOption).toHaveAttribute("data-slot", "item"); }); it("updates controlled value after selecting an option", async () => { const user = userEvent.setup(); function ControlledSelect() { const [value, setValue] = useState("editorial"); return ; } render(); const trigger = screen.getByRole("combobox", { name: "Review lane" }); expect(trigger).toHaveTextContent("Editorial review"); await user.click(trigger); await user.click(await screen.findByRole("option", { name: "Legal review" })); expect(trigger).toHaveTextContent("Legal review"); expect(screen.queryByRole("listbox")).not.toBeInTheDocument(); }); it("supports field invalid state and described-by wiring", async () => { const user = userEvent.setup(); render( Choose the primary owner. Select a team before publishing. ); const trigger = screen.getByRole("combobox", { name: "Routing team" }); expect(trigger).toHaveAttribute("aria-invalid", "true"); expect(trigger).toHaveAttribute( "aria-describedby", expect.stringContaining("routing-description") ); expect(trigger).toHaveAttribute( "aria-describedby", expect.stringContaining("routing-error") ); await user.click(trigger); expect(await screen.findByRole("option", { name: "Product" })).toBeInTheDocument(); }); it("exposes disabled state on the trigger", () => { render( ); const trigger = screen.getByRole("combobox", { name: "Disabled select" }); expect(trigger).toBeDisabled(); expect(trigger).toHaveAttribute("data-disabled", ""); }); it("opens from the keyboard so combobox interaction stays accessible", async () => { const user = userEvent.setup(); render(); const trigger = screen.getByRole("combobox", { name: "Review lane" }); trigger.focus(); await user.keyboard("{ArrowDown}"); const listbox = await screen.findByRole("listbox"); expect(trigger).toHaveAttribute("aria-expanded", "true"); expect(within(listbox).getByRole("option", { name: "Editorial review" })).toBeInTheDocument(); }); });