diff --git a/tests/OverflowMenu/OverflowMenu.test.svelte b/tests/OverflowMenu/OverflowMenu.test.svelte
index 9ddb5e0d..18d23727 100644
--- a/tests/OverflowMenu/OverflowMenu.test.svelte
+++ b/tests/OverflowMenu/OverflowMenu.test.svelte
@@ -1,8 +1,25 @@
{
console.log("close", e.detail); // { index: number; text: string; }
}}
diff --git a/tests/OverflowMenu/OverflowMenu.test.ts b/tests/OverflowMenu/OverflowMenu.test.ts
index ed20fb74..49ff18ef 100644
--- a/tests/OverflowMenu/OverflowMenu.test.ts
+++ b/tests/OverflowMenu/OverflowMenu.test.ts
@@ -127,4 +127,164 @@ describe("OverflowMenu", () => {
expect(menu).toHaveStyle("--overflow-menu-options-after-width: 2rem");
});
});
+
+ test.each([
+ ["sm", "bx--overflow-menu--sm"],
+ ["xl", "bx--overflow-menu--xl"],
+ ] as const)("should support %s size", (size, expectedClass) => {
+ render(OverflowMenu, { props: { size } });
+
+ const menuButton = screen.getByRole("button");
+ expect(menuButton).toHaveClass(expectedClass);
+ });
+
+ it("should not apply size classes when size is undefined", () => {
+ render(OverflowMenu, { props: { size: undefined } });
+
+ const menuButton = screen.getByRole("button");
+ expect(menuButton).not.toHaveClass("bx--overflow-menu--sm");
+ expect(menuButton).not.toHaveClass("bx--overflow-menu--xl");
+ });
+
+ it("applies light variant styling", () => {
+ render(OverflowMenu, { props: { light: true } });
+
+ const menuButton = screen.getByRole("button");
+ expect(menuButton).toHaveClass("bx--overflow-menu--light");
+ });
+
+ it("applies flipped styling", async () => {
+ render(OverflowMenu, { props: { flipped: true } });
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menu = screen.getByRole("menu");
+ expect(menu).toHaveClass("bx--overflow-menu--flip");
+ });
+
+ it("applies direction attribute", async () => {
+ render(OverflowMenu, { props: { direction: "top" } });
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menu = screen.getByRole("menu");
+ expect(menu).toHaveAttribute("data-floating-menu-direction", "top");
+ });
+
+ it("applies custom menu options class", async () => {
+ render(OverflowMenu, { props: { menuOptionsClass: "custom-class" } });
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menu = screen.getByRole("menu");
+ expect(menu).toHaveClass("custom-class");
+ });
+
+ it("applies custom icon class", () => {
+ render(OverflowMenu, { props: { iconClass: "custom-icon-class" } });
+
+ const icon = screen.getByRole("button").querySelector("svg");
+ expect(icon).toHaveClass("custom-icon-class");
+ });
+
+ it("uses custom icon description", () => {
+ render(OverflowMenu, { props: { iconDescription: "Custom description" } });
+
+ const icon = screen.getByRole("button").querySelector("svg");
+ expect(icon).toHaveAttribute("aria-label", "Custom description");
+ });
+
+ it("uses custom id", () => {
+ render(OverflowMenu, { props: { id: "custom-id" } });
+
+ const menuButton = screen.getByRole("button");
+ expect(menuButton).toHaveAttribute("id", "custom-id");
+ });
+
+ it("applies danger styling to menu items", async () => {
+ render(OverflowMenu);
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menuItems = screen.getAllByRole("menuitem");
+ const dangerItem = menuItems.find(
+ (item) => item.textContent === "Delete service",
+ );
+ expect(dangerItem?.parentElement).toHaveClass(
+ "bx--overflow-menu-options__option--danger",
+ );
+ });
+
+ it("handles link menu items correctly", async () => {
+ render(OverflowMenu);
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menuItems = screen.getAllByRole("menuitem");
+ const linkItem = menuItems.find(
+ (item) => item.textContent === "API documentation",
+ );
+ expect(linkItem).toHaveAttribute(
+ "href",
+ "https://cloud.ibm.com/docs/api-gateway/",
+ );
+ });
+
+ it("returns focus to button after menu closes", async () => {
+ render(OverflowMenu);
+
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menuItems = screen.getAllByRole("menuitem");
+ expect(menuItems[0]).toHaveFocus();
+
+ await user.keyboard("{Escape}");
+ expect(menuButton).toHaveFocus();
+ });
+
+ it("handles close event with item click", async () => {
+ render(OverflowMenu);
+
+ const spy = vi.spyOn(console, "log");
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ const menuItems = screen.getAllByRole("menuitem");
+ await user.click(menuItems[0]);
+
+ expect(spy).toHaveBeenCalledWith("close", {
+ index: 0,
+ text: "Manage credentials",
+ });
+ });
+
+ it("handles close event with escape key", async () => {
+ render(OverflowMenu);
+
+ const spy = vi.spyOn(console, "log");
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ await user.keyboard("{Escape}");
+
+ expect(spy).toHaveBeenCalledWith("close", null);
+ });
+
+ it("handles close event with outside click", async () => {
+ render(OverflowMenu);
+
+ const spy = vi.spyOn(console, "log");
+ const menuButton = screen.getByRole("button");
+ await user.click(menuButton);
+
+ await user.click(document.body);
+
+ expect(spy).toHaveBeenCalledWith("close", null);
+ });
});