Skip to content

Commit 28d15ff

Browse files
authored
test(overflow-menu): add more unit tests (#2199)
1 parent 14edf41 commit 28d15ff

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

tests/OverflowMenu/OverflowMenu.test.svelte

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
<script lang="ts">
22
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte";
3+
4+
export let size: "sm" | "xl" | undefined = undefined;
5+
export let light: boolean = false;
6+
export let flipped: boolean = false;
7+
export let direction: "top" | "bottom" = "bottom";
8+
export let menuOptionsClass: string | undefined = undefined;
9+
export let iconClass: string | undefined = undefined;
10+
export let iconDescription: string = "Open and close list of options";
11+
export let id: string = "ccs-" + Math.random().toString(36);
312
</script>
413

514
<OverflowMenu
15+
{size}
16+
{light}
17+
{flipped}
18+
{direction}
19+
{menuOptionsClass}
20+
{iconClass}
21+
{iconDescription}
22+
{id}
623
on:close={(e) => {
724
console.log("close", e.detail); // { index: number; text: string; }
825
}}

tests/OverflowMenu/OverflowMenu.test.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,164 @@ describe("OverflowMenu", () => {
127127
expect(menu).toHaveStyle("--overflow-menu-options-after-width: 2rem");
128128
});
129129
});
130+
131+
test.each([
132+
["sm", "bx--overflow-menu--sm"],
133+
["xl", "bx--overflow-menu--xl"],
134+
] as const)("should support %s size", (size, expectedClass) => {
135+
render(OverflowMenu, { props: { size } });
136+
137+
const menuButton = screen.getByRole("button");
138+
expect(menuButton).toHaveClass(expectedClass);
139+
});
140+
141+
it("should not apply size classes when size is undefined", () => {
142+
render(OverflowMenu, { props: { size: undefined } });
143+
144+
const menuButton = screen.getByRole("button");
145+
expect(menuButton).not.toHaveClass("bx--overflow-menu--sm");
146+
expect(menuButton).not.toHaveClass("bx--overflow-menu--xl");
147+
});
148+
149+
it("applies light variant styling", () => {
150+
render(OverflowMenu, { props: { light: true } });
151+
152+
const menuButton = screen.getByRole("button");
153+
expect(menuButton).toHaveClass("bx--overflow-menu--light");
154+
});
155+
156+
it("applies flipped styling", async () => {
157+
render(OverflowMenu, { props: { flipped: true } });
158+
159+
const menuButton = screen.getByRole("button");
160+
await user.click(menuButton);
161+
162+
const menu = screen.getByRole("menu");
163+
expect(menu).toHaveClass("bx--overflow-menu--flip");
164+
});
165+
166+
it("applies direction attribute", async () => {
167+
render(OverflowMenu, { props: { direction: "top" } });
168+
169+
const menuButton = screen.getByRole("button");
170+
await user.click(menuButton);
171+
172+
const menu = screen.getByRole("menu");
173+
expect(menu).toHaveAttribute("data-floating-menu-direction", "top");
174+
});
175+
176+
it("applies custom menu options class", async () => {
177+
render(OverflowMenu, { props: { menuOptionsClass: "custom-class" } });
178+
179+
const menuButton = screen.getByRole("button");
180+
await user.click(menuButton);
181+
182+
const menu = screen.getByRole("menu");
183+
expect(menu).toHaveClass("custom-class");
184+
});
185+
186+
it("applies custom icon class", () => {
187+
render(OverflowMenu, { props: { iconClass: "custom-icon-class" } });
188+
189+
const icon = screen.getByRole("button").querySelector("svg");
190+
expect(icon).toHaveClass("custom-icon-class");
191+
});
192+
193+
it("uses custom icon description", () => {
194+
render(OverflowMenu, { props: { iconDescription: "Custom description" } });
195+
196+
const icon = screen.getByRole("button").querySelector("svg");
197+
expect(icon).toHaveAttribute("aria-label", "Custom description");
198+
});
199+
200+
it("uses custom id", () => {
201+
render(OverflowMenu, { props: { id: "custom-id" } });
202+
203+
const menuButton = screen.getByRole("button");
204+
expect(menuButton).toHaveAttribute("id", "custom-id");
205+
});
206+
207+
it("applies danger styling to menu items", async () => {
208+
render(OverflowMenu);
209+
210+
const menuButton = screen.getByRole("button");
211+
await user.click(menuButton);
212+
213+
const menuItems = screen.getAllByRole("menuitem");
214+
const dangerItem = menuItems.find(
215+
(item) => item.textContent === "Delete service",
216+
);
217+
expect(dangerItem?.parentElement).toHaveClass(
218+
"bx--overflow-menu-options__option--danger",
219+
);
220+
});
221+
222+
it("handles link menu items correctly", async () => {
223+
render(OverflowMenu);
224+
225+
const menuButton = screen.getByRole("button");
226+
await user.click(menuButton);
227+
228+
const menuItems = screen.getAllByRole("menuitem");
229+
const linkItem = menuItems.find(
230+
(item) => item.textContent === "API documentation",
231+
);
232+
expect(linkItem).toHaveAttribute(
233+
"href",
234+
"https://cloud.ibm.com/docs/api-gateway/",
235+
);
236+
});
237+
238+
it("returns focus to button after menu closes", async () => {
239+
render(OverflowMenu);
240+
241+
const menuButton = screen.getByRole("button");
242+
await user.click(menuButton);
243+
244+
const menuItems = screen.getAllByRole("menuitem");
245+
expect(menuItems[0]).toHaveFocus();
246+
247+
await user.keyboard("{Escape}");
248+
expect(menuButton).toHaveFocus();
249+
});
250+
251+
it("handles close event with item click", async () => {
252+
render(OverflowMenu);
253+
254+
const spy = vi.spyOn(console, "log");
255+
const menuButton = screen.getByRole("button");
256+
await user.click(menuButton);
257+
258+
const menuItems = screen.getAllByRole("menuitem");
259+
await user.click(menuItems[0]);
260+
261+
expect(spy).toHaveBeenCalledWith("close", {
262+
index: 0,
263+
text: "Manage credentials",
264+
});
265+
});
266+
267+
it("handles close event with escape key", async () => {
268+
render(OverflowMenu);
269+
270+
const spy = vi.spyOn(console, "log");
271+
const menuButton = screen.getByRole("button");
272+
await user.click(menuButton);
273+
274+
await user.keyboard("{Escape}");
275+
276+
expect(spy).toHaveBeenCalledWith("close", null);
277+
});
278+
279+
it("handles close event with outside click", async () => {
280+
render(OverflowMenu);
281+
282+
const spy = vi.spyOn(console, "log");
283+
const menuButton = screen.getByRole("button");
284+
await user.click(menuButton);
285+
286+
await user.click(document.body);
287+
288+
expect(spy).toHaveBeenCalledWith("close", null);
289+
});
130290
});

0 commit comments

Comments
 (0)