From 306e09961f9a99c3e69af579653fa7466eeb69cf Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 29 Jan 2025 19:28:16 -0800 Subject: [PATCH] test(overflow-menu): add unit tests --- tests/App.test.svelte | 6 ++ tests/OverflowMenu.test.svelte | 81 -------------------- tests/OverflowMenu/OverflowMenu.test.svelte | 30 ++++++++ tests/OverflowMenu/OverflowMenu.test.ts | 84 +++++++++++++++++++++ 4 files changed, 120 insertions(+), 81 deletions(-) delete mode 100644 tests/OverflowMenu.test.svelte create mode 100644 tests/OverflowMenu/OverflowMenu.test.svelte create mode 100644 tests/OverflowMenu/OverflowMenu.test.ts diff --git a/tests/App.test.svelte b/tests/App.test.svelte index 525454e545..962a0110f2 100644 --- a/tests/App.test.svelte +++ b/tests/App.test.svelte @@ -10,6 +10,7 @@ import RecursiveList from "./RecursiveList/RecursiveList.test.svelte"; import RecursiveListHierarchy from "./RecursiveList/RecursiveList.hierarchy.test.svelte"; import Tag from "./Tag/Tag.test.svelte"; + import OverflowMenu from "./OverflowMenu/OverflowMenu.test.svelte"; import { onMount } from "svelte"; const routes = [ @@ -63,6 +64,11 @@ name: "Tag", component: Tag, }, + { + path: "/overflow-menu", + name: "OverflowMenu", + component: OverflowMenu, + }, ] as const; let currentPath = window.location.pathname; diff --git a/tests/OverflowMenu.test.svelte b/tests/OverflowMenu.test.svelte deleted file mode 100644 index 2e90e28912..0000000000 --- a/tests/OverflowMenu.test.svelte +++ /dev/null @@ -1,81 +0,0 @@ - - - { - console.log(e.detail); // { index: number; text: string; } - }} -> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Custom trigger
- - - -
diff --git a/tests/OverflowMenu/OverflowMenu.test.svelte b/tests/OverflowMenu/OverflowMenu.test.svelte new file mode 100644 index 0000000000..9ddb5e0d0f --- /dev/null +++ b/tests/OverflowMenu/OverflowMenu.test.svelte @@ -0,0 +1,30 @@ + + + { + console.log("close", e.detail); // { index: number; text: string; } + }} +> + { + console.log("click", "Manage credentials"); + }} + /> + { + console.log("click", "API documentation"); + }} + /> + { + console.log("click", "Delete service"); + }} + /> + diff --git a/tests/OverflowMenu/OverflowMenu.test.ts b/tests/OverflowMenu/OverflowMenu.test.ts new file mode 100644 index 0000000000..59b07a296a --- /dev/null +++ b/tests/OverflowMenu/OverflowMenu.test.ts @@ -0,0 +1,84 @@ +import { render, screen } from "@testing-library/svelte"; +import { user } from "../setup-tests"; +import OverflowMenu from "./OverflowMenu.test.svelte"; + +describe("OverflowMenu", () => { + it("renders and functions correctly", async () => { + render(OverflowMenu); + + const menuButton = screen.getByRole("button"); + expect(menuButton).toHaveAttribute("aria-haspopup", "true"); + expect(menuButton).toHaveAttribute("aria-expanded", "false"); + + await user.click(menuButton); + expect(menuButton).toHaveAttribute("aria-expanded", "true"); + + const menuItems = screen.getAllByRole("menuitem"); + expect(menuItems).toHaveLength(3); + expect(menuItems[0]).toHaveFocus(); + + expect(menuItems[0]).toHaveTextContent("Manage credentials"); + expect(menuItems[1]).toHaveTextContent("API documentation"); + expect(menuItems[2]).toHaveTextContent("Delete service"); + + expect(menuItems[1]).toHaveAttribute( + "href", + "https://cloud.ibm.com/docs/api-gateway/", + ); + + expect(menuItems[2].parentElement).toHaveClass( + "bx--overflow-menu-options__option--danger", + ); + + const spy = vi.spyOn(console, "log"); + await user.click(menuItems[0]); + expect(spy).toHaveBeenCalledWith("click", "Manage credentials"); + + expect(menuButton).toHaveAttribute("aria-expanded", "false"); + expect(spy).toHaveBeenCalledWith("close", { + index: 0, + text: "Manage credentials", + }); + }); + + it("handles keyboard navigation", async () => { + render(OverflowMenu); + + const spy = vi.spyOn(console, "log"); + + const menuButton = screen.getByRole("button"); + await user.click(menuButton); + expect(menuButton).toHaveAttribute("aria-expanded", "true"); + + let menuItems = screen.getAllByRole("menuitem"); + expect(menuItems[0]).toHaveFocus(); + + await user.keyboard("{ArrowDown}"); + expect(menuItems[1]).toHaveFocus(); + + await user.keyboard("{Enter}"); + expect(spy).toHaveBeenCalledWith("click", "API documentation"); + + await user.click(menuButton); + menuItems = screen.getAllByRole("menuitem"); + expect(menuItems[0]).toHaveFocus(); + + await user.keyboard("{ArrowUp}"); + expect(menuItems[2]).toHaveFocus(); + + await user.keyboard("{Escape}"); + expect(menuButton).toHaveAttribute("aria-expanded", "false"); + expect(spy).toHaveBeenCalledWith("close", null); + }); + + it("closes when clicking outside", async () => { + render(OverflowMenu); + + const menuButton = screen.getByRole("button"); + await user.click(menuButton); + expect(menuButton).toHaveAttribute("aria-expanded", "true"); + + await user.click(document.body); + expect(menuButton).toHaveAttribute("aria-expanded", "false"); + }); +});