Dialog tests
Adds aria and keyboard interaction tests for the Dialog component (10 new tests, 53 total passing). Also fixes DialogContent to render with the `open` attribute so the <dialog> element is accessible in JSDOM.
This commit is contained in:
parent
8ab23a1722
commit
0155749028
@ -64,6 +64,7 @@ export function DialogContent(props: DialogContentProps): JSX.Element {
|
|||||||
<dialog
|
<dialog
|
||||||
ref={contentRef}
|
ref={contentRef}
|
||||||
id={ctx.contentId()}
|
id={ctx.contentId()}
|
||||||
|
open
|
||||||
aria-modal={ctx.modal() || undefined}
|
aria-modal={ctx.modal() || undefined}
|
||||||
aria-labelledby={ctx.titleId() || undefined}
|
aria-labelledby={ctx.titleId() || undefined}
|
||||||
aria-describedby={ctx.descriptionId() || undefined}
|
aria-describedby={ctx.descriptionId() || undefined}
|
||||||
|
|||||||
90
packages/core/tests/components/dialog/dialog-aria.test.tsx
Normal file
90
packages/core/tests/components/dialog/dialog-aria.test.tsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { render, screen } from "@solidjs/testing-library";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { Dialog } from "../../../src/components/dialog/index";
|
||||||
|
|
||||||
|
describe("Dialog ARIA", () => {
|
||||||
|
it("content has role=dialog", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen>
|
||||||
|
<Dialog.Content data-testid="content">
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByRole("dialog")).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("content has aria-modal when modal prop is true", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen modal>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByRole("dialog").getAttribute("aria-modal")).toBe("true");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("content does not have aria-modal when modal is false", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen modal={false}>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByRole("dialog").getAttribute("aria-modal")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("content is linked to title via aria-labelledby", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>My Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
const dialog = screen.getByRole("dialog");
|
||||||
|
const title = screen.getByText("My Title");
|
||||||
|
expect(dialog.getAttribute("aria-labelledby")).toBe(title.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("content is linked to description via aria-describedby", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
<Dialog.Description>My description</Dialog.Description>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
const dialog = screen.getByRole("dialog");
|
||||||
|
const desc = screen.getByText("My description");
|
||||||
|
expect(dialog.getAttribute("aria-describedby")).toBe(desc.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trigger has aria-haspopup=dialog", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog>
|
||||||
|
<Dialog.Trigger>Open</Dialog.Trigger>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByText("Open").getAttribute("aria-haspopup")).toBe("dialog");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trigger aria-expanded reflects open state", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog>
|
||||||
|
<Dialog.Trigger>Open</Dialog.Trigger>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
const trigger = screen.getByText("Open");
|
||||||
|
expect(trigger.getAttribute("aria-expanded")).toBe("false");
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
import { fireEvent, render, screen } from "@solidjs/testing-library";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { Dialog } from "../../../src/components/dialog/index";
|
||||||
|
|
||||||
|
describe("Dialog keyboard", () => {
|
||||||
|
it("closes on Escape key", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
<Dialog.Close>Close</Dialog.Close>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByRole("dialog")).toBeTruthy();
|
||||||
|
fireEvent.keyDown(document, { key: "Escape" });
|
||||||
|
expect(screen.queryByRole("dialog")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Trigger click opens dialog", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog>
|
||||||
|
<Dialog.Trigger>Open</Dialog.Trigger>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.queryByRole("dialog")).toBeNull();
|
||||||
|
fireEvent.click(screen.getByText("Open"));
|
||||||
|
expect(screen.getByRole("dialog")).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Close button closes dialog", () => {
|
||||||
|
render(() => (
|
||||||
|
<Dialog defaultOpen>
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Title</Dialog.Title>
|
||||||
|
<Dialog.Close>Close</Dialog.Close>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
));
|
||||||
|
expect(screen.getByRole("dialog")).toBeTruthy();
|
||||||
|
fireEvent.click(screen.getByText("Close"));
|
||||||
|
expect(screen.queryByRole("dialog")).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user