Files
cadence-ui/packages/ui/src/components/dialog.test.tsx
T

134 lines
4.0 KiB
TypeScript

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();
});
it("returns focus to the trigger after Escape closes the dialog", async () => {
const user = userEvent.setup();
render(
<Dialog>
<DialogTrigger>Open accessible dialog</DialogTrigger>
<DialogContent>
<DialogTitle>Accessibility</DialogTitle>
</DialogContent>
</Dialog>
);
const trigger = screen.getByRole("button", { name: "Open accessible dialog" });
await user.click(trigger);
expect(await screen.findByRole("dialog")).toBeInTheDocument();
await user.keyboard("{Escape}");
await waitFor(() => {
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
expect(trigger).toHaveFocus();
});
});
});