Combobox: text input + floating listbox with consumer-driven filtering, allowCustomValue, and aria-autocomplete support. DropdownMenu: activation-mode menu with menuitem, menuitemcheckbox, menuitemradio roles, keyboard navigation, and typeahead. ContextMenu: right-click triggered menu with virtual anchor positioning at pointer coordinates. Toast: imperative API (toast(), toast.success/error/dismiss/clear) with reactive signal-based store and Toast.Region declarative renderer.
108 lines
3.8 KiB
TypeScript
108 lines
3.8 KiB
TypeScript
import { fireEvent, render, screen } from "@solidjs/testing-library";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { ContextMenu } from "../../../src/components/context-menu/index";
|
|
|
|
describe("ContextMenu — open/close and roles", () => {
|
|
it("right-click opens menu", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit", "delete"]}>
|
|
<ContextMenu.Trigger>
|
|
<div data-testid="area">Right click me</div>
|
|
</ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
<ContextMenu.Item value="delete">Delete</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
expect(screen.queryByRole("menu")).toBeNull();
|
|
fireEvent.contextMenu(screen.getByTestId("area"));
|
|
expect(screen.getByRole("menu")).toBeTruthy();
|
|
});
|
|
|
|
it("content has role=menu", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit"]} defaultOpen>
|
|
<ContextMenu.Trigger><div>Area</div></ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
expect(screen.getByRole("menu")).toBeTruthy();
|
|
});
|
|
|
|
it("items have role=menuitem", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit", "delete"]} defaultOpen>
|
|
<ContextMenu.Trigger><div>Area</div></ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
<ContextMenu.Item value="delete">Delete</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
expect(screen.getAllByRole("menuitem")).toHaveLength(2);
|
|
});
|
|
|
|
it("trigger area does NOT have aria-haspopup", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit"]}>
|
|
<ContextMenu.Trigger>
|
|
<div data-testid="area">Area</div>
|
|
</ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
expect(screen.getByTestId("area").getAttribute("aria-haspopup")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("ContextMenu — keyboard navigation", () => {
|
|
it("Enter activates item", () => {
|
|
const onSelect = vi.fn();
|
|
render(() => (
|
|
<ContextMenu items={["edit"]} defaultOpen>
|
|
<ContextMenu.Trigger><div>Area</div></ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit" onSelect={onSelect}>Edit</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
const menu = screen.getByRole("menu");
|
|
fireEvent.keyDown(menu, { key: "ArrowDown" });
|
|
fireEvent.keyDown(menu, { key: "Enter" });
|
|
expect(onSelect).toHaveBeenCalled();
|
|
});
|
|
|
|
it("Escape closes", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit"]} defaultOpen>
|
|
<ContextMenu.Trigger><div>Area</div></ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
fireEvent.keyDown(screen.getByRole("menu"), { key: "Escape" });
|
|
expect(screen.queryByRole("menu")).toBeNull();
|
|
});
|
|
|
|
it("ArrowDown navigates items", () => {
|
|
render(() => (
|
|
<ContextMenu items={["edit", "delete"]} defaultOpen>
|
|
<ContextMenu.Trigger><div>Area</div></ContextMenu.Trigger>
|
|
<ContextMenu.Content>
|
|
<ContextMenu.Item value="edit">Edit</ContextMenu.Item>
|
|
<ContextMenu.Item value="delete">Delete</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu>
|
|
));
|
|
const menu = screen.getByRole("menu");
|
|
fireEvent.keyDown(menu, { key: "ArrowDown" });
|
|
expect(screen.getAllByRole("menuitem")[0].getAttribute("data-highlighted")).toBe("");
|
|
});
|
|
});
|