feat: add core UI components and baseline tests
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { render, screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger
|
||||
} from "./dialog";
|
||||
|
||||
describe("Dialog", () => {
|
||||
it("opens from the trigger and closes from the close control", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(
|
||||
<Dialog>
|
||||
<DialogTrigger>Open dialog</DialogTrigger>
|
||||
<DialogContent size="lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Review launch</DialogTitle>
|
||||
<DialogDescription>Check the launch checklist before shipping.</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<DialogClose>Done</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Open dialog" }));
|
||||
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
expect(dialog).toHaveAttribute("data-slot", "content");
|
||||
expect(dialog).toHaveAttribute("data-size", "lg");
|
||||
expect(screen.getByText("Review launch")).toHaveAttribute("data-slot", "label");
|
||||
expect(screen.getByText("Check the launch checklist before shipping.")).toHaveAttribute(
|
||||
"data-slot",
|
||||
"description"
|
||||
);
|
||||
expect(document.querySelector('[data-slot="overlay"]')).toBeInTheDocument();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Close dialog" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("notifies controlled open state changes from trigger and Escape", async () => {
|
||||
const user = userEvent.setup();
|
||||
const onOpenChange = vi.fn();
|
||||
|
||||
render(
|
||||
<Dialog open={false} onOpenChange={onOpenChange}>
|
||||
<DialogTrigger>Launch dialog</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogTitle>Controlled</DialogTitle>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Launch dialog" }));
|
||||
expect(onOpenChange).toHaveBeenCalledWith(true);
|
||||
|
||||
render(
|
||||
<Dialog open onOpenChange={onOpenChange}>
|
||||
<DialogTrigger>Launch dialog</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogTitle>Controlled</DialogTitle>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
await user.keyboard("{Escape}");
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it("renders header and footer slots when provided", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(
|
||||
<Dialog>
|
||||
<DialogTrigger>Open summary</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Summary</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<DialogClose>Close</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Open summary" }));
|
||||
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
expect(within(dialog).getByText("Summary").closest('[data-slot="header"]')).toBeInTheDocument();
|
||||
expect(within(dialog).getByRole("button", { name: "Close" }).closest('[data-slot="footer"]')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user