From 015574902896d6b79166b3973c186a448b01aee2 Mon Sep 17 00:00:00 2001 From: Mats Bosson Date: Sun, 29 Mar 2026 05:56:42 +0700 Subject: [PATCH] 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 element is accessible in JSDOM. --- .../src/components/dialog/dialog-content.tsx | 1 + .../components/dialog/dialog-aria.test.tsx | 90 +++++++++++++++++++ .../dialog/dialog-keyboard.test.tsx | 47 ++++++++++ 3 files changed, 138 insertions(+) create mode 100644 packages/core/tests/components/dialog/dialog-aria.test.tsx create mode 100644 packages/core/tests/components/dialog/dialog-keyboard.test.tsx diff --git a/packages/core/src/components/dialog/dialog-content.tsx b/packages/core/src/components/dialog/dialog-content.tsx index e91fe7f..f39a157 100644 --- a/packages/core/src/components/dialog/dialog-content.tsx +++ b/packages/core/src/components/dialog/dialog-content.tsx @@ -64,6 +64,7 @@ export function DialogContent(props: DialogContentProps): JSX.Element { { + it("content has role=dialog", () => { + render(() => ( + + + Title + + + )); + expect(screen.getByRole("dialog")).toBeTruthy(); + }); + + it("content has aria-modal when modal prop is true", () => { + render(() => ( + + + Title + + + )); + expect(screen.getByRole("dialog").getAttribute("aria-modal")).toBe("true"); + }); + + it("content does not have aria-modal when modal is false", () => { + render(() => ( + + + Title + + + )); + expect(screen.getByRole("dialog").getAttribute("aria-modal")).toBeNull(); + }); + + it("content is linked to title via aria-labelledby", () => { + render(() => ( + + + My Title + + + )); + 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(() => ( + + + Title + My description + + + )); + 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(() => ( + + Open + + Title + + + )); + expect(screen.getByText("Open").getAttribute("aria-haspopup")).toBe("dialog"); + }); + + it("trigger aria-expanded reflects open state", () => { + render(() => ( + + Open + + Title + + + )); + const trigger = screen.getByText("Open"); + expect(trigger.getAttribute("aria-expanded")).toBe("false"); + }); +}); diff --git a/packages/core/tests/components/dialog/dialog-keyboard.test.tsx b/packages/core/tests/components/dialog/dialog-keyboard.test.tsx new file mode 100644 index 0000000..ad93a49 --- /dev/null +++ b/packages/core/tests/components/dialog/dialog-keyboard.test.tsx @@ -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(() => ( + + + Title + Close + + + )); + expect(screen.getByRole("dialog")).toBeTruthy(); + fireEvent.keyDown(document, { key: "Escape" }); + expect(screen.queryByRole("dialog")).toBeNull(); + }); + + it("Trigger click opens dialog", () => { + render(() => ( + + Open + + Title + + + )); + expect(screen.queryByRole("dialog")).toBeNull(); + fireEvent.click(screen.getByText("Open")); + expect(screen.getByRole("dialog")).toBeTruthy(); + }); + + it("Close button closes dialog", () => { + render(() => ( + + + Title + Close + + + )); + expect(screen.getByRole("dialog")).toBeTruthy(); + fireEvent.click(screen.getByText("Close")); + expect(screen.queryByRole("dialog")).toBeNull(); + }); +});