import React from "react"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import "@testing-library/jest-dom/vitest"; import Create from "../../app/components/Create"; import Input from "../../app/components/Input"; type CreateProps = React.ComponentProps; describe("Create", () => { const defaultProps: CreateProps = { isOpen: true, onClose: vi.fn(), title: "Test Create Dialog", description: "Test description", }; beforeEach(() => { vi.clearAllMocks(); }); it("renders when isOpen is true", () => { render(Create dialog content); expect(screen.getByRole("dialog")).toBeInTheDocument(); expect(screen.getByText("Test Create Dialog")).toBeInTheDocument(); expect(screen.getByText("Create dialog content")).toBeInTheDocument(); }); it("does not render when isOpen is false", () => { render(); expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); }); it("calls onClose when close button is clicked", () => { const onClose = vi.fn(); render(); const closeButton = screen.getByLabelText("Close dialog"); fireEvent.click(closeButton); expect(onClose).toHaveBeenCalledTimes(1); }); it("calls onClose when ESC key is pressed", () => { const onClose = vi.fn(); render(); fireEvent.keyDown(document, { key: "Escape" }); expect(onClose).toHaveBeenCalledTimes(1); }); it("calls onClose when overlay is clicked", () => { const onClose = vi.fn(); render(); const overlay = document.querySelector(".fixed.inset-0"); if (overlay) { fireEvent.click(overlay); expect(onClose).toHaveBeenCalledTimes(1); } }); it("renders footer buttons when provided", () => { const onBack = vi.fn(); const onNext = vi.fn(); render( , ); expect(screen.getByText("Go Back")).toBeInTheDocument(); expect(screen.getByText("Continue")).toBeInTheDocument(); }); it("calls onBack when back button is clicked", () => { const onBack = vi.fn(); render( , ); const backButton = screen.getByText("Back"); fireEvent.click(backButton); expect(onBack).toHaveBeenCalledTimes(1); }); it("calls onNext when next button is clicked", () => { const onNext = vi.fn(); render( , ); const nextButton = screen.getByText("Next"); fireEvent.click(nextButton); expect(onNext).toHaveBeenCalledTimes(1); }); it("disables next button when nextButtonDisabled is true", () => { render( , ); const nextButton = screen.getByText("Next"); expect(nextButton).toBeDisabled(); }); it("renders stepper when currentStep and totalSteps are provided", () => { render( , ); const steppers = screen.getAllByRole("progressbar"); // Find the stepper in the footer (not the progress bar if any) const footerStepper = steppers.find((stepper) => { const parent = stepper.closest(".absolute.bottom-0"); return parent !== null; }); expect(footerStepper).toBeInTheDocument(); if (footerStepper) { expect(footerStepper).toHaveAttribute("aria-valuenow", "2"); expect(footerStepper).toHaveAttribute("aria-valuemax", "5"); } }); it("renders custom footer content", () => { render( Custom Footer} />, ); expect(screen.getByText("Custom Footer")).toBeInTheDocument(); }); it("has proper ARIA attributes", () => { render(); const dialog = screen.getByRole("dialog"); expect(dialog).toHaveAttribute("aria-modal", "true"); expect(dialog).toHaveAttribute("aria-label", "Test create dialog"); }); it("locks body scroll when open", () => { render(); expect(document.body.style.overflow).toBe("hidden"); }); it("restores body scroll when closed", () => { const { rerender } = render(); expect(document.body.style.overflow).toBe("hidden"); rerender(); expect(document.body.style.overflow).toBe(""); }); it("traps focus within create dialog", async () => { render( , ); const closeButton = screen.getByLabelText("Close dialog"); const input = screen.getByLabelText("Test Input"); // Focus should start on first focusable element (close button) await waitFor(() => { expect(closeButton).toHaveFocus(); }); // Tab should move focus to next element fireEvent.keyDown(document, { key: "Tab" }); await waitFor(() => { // Should focus on the more options button or input const focusedElement = document.activeElement; expect(focusedElement).toBeInTheDocument(); }); }); });