diff --git a/tests/ComboBox.test.svelte b/tests/ComboBox.test.svelte
deleted file mode 100644
index c6bf6ac6..00000000
--- a/tests/ComboBox.test.svelte
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
- {
- console.log(e.detail.selectedId);
- }}
- on:clear={(e) => {
- console.log(e.detail);
- }}
- translateWithId={(id) => {
- console.log(id); // "open" | "close"
- return id;
- }}
- translateWithIdSelection={(id) => {
- console.log(id); // "clearSelection"
- return id;
- }}
- let:item
- let:index
->
- {item.id}
- {index}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/ComboBox/ComboBox.test.svelte b/tests/ComboBox/ComboBox.test.svelte
new file mode 100644
index 00000000..249f0dd5
--- /dev/null
+++ b/tests/ComboBox/ComboBox.test.svelte
@@ -0,0 +1,49 @@
+
+
+ {
+ console.log("select", e.detail);
+ }}
+ on:clear={(e) => {
+ console.log("clear", e.type);
+ }}
+/>
diff --git a/tests/ComboBox/ComboBox.test.ts b/tests/ComboBox/ComboBox.test.ts
new file mode 100644
index 00000000..c2ee66b6
--- /dev/null
+++ b/tests/ComboBox/ComboBox.test.ts
@@ -0,0 +1,186 @@
+import { render, screen } from "@testing-library/svelte";
+import { user } from "../setup-tests";
+import ComboBox from "./ComboBox.test.svelte";
+import ComboBoxCustom from "./ComboBoxCustom.test.svelte";
+
+describe("ComboBox", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("should render with default props", () => {
+ render(ComboBox);
+
+ expect(screen.getByText("Contact")).toBeInTheDocument();
+ const input = screen.getByRole("textbox");
+ expect(input).toHaveAttribute("placeholder", "Select contact method");
+ });
+
+ it("should open menu on click", async () => {
+ render(ComboBox);
+
+ const input = screen.getByRole("textbox");
+ await user.click(input);
+
+ const dropdown = screen.getAllByRole("listbox")[1];
+ expect(dropdown).toBeVisible();
+ });
+
+ it("should handle item selection", async () => {
+ const consoleLog = vi.spyOn(console, "log");
+ render(ComboBox);
+
+ await user.click(screen.getByRole("textbox"));
+ await user.click(screen.getByText("Email"));
+
+ expect(consoleLog).toHaveBeenCalledWith("select", {
+ selectedId: "1",
+ selectedItem: { id: "1", text: "Email" },
+ });
+ expect(screen.getByRole("textbox")).toHaveValue("Email");
+ });
+
+ it("should handle keyboard navigation", async () => {
+ render(ComboBox);
+
+ const input = screen.getByRole("textbox");
+ await user.click(input);
+ await user.keyboard("{ArrowDown}");
+ await user.keyboard("{Enter}");
+
+ expect(input).toHaveValue("Slack");
+ });
+
+ it("should handle clear selection", async () => {
+ const consoleLog = vi.spyOn(console, "log");
+ render(ComboBox, {
+ props: {
+ selectedId: "1",
+ value: "Email",
+ },
+ });
+
+ const clearButton = screen.getByRole("button", { name: /clear/i });
+ await user.click(clearButton);
+
+ expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String));
+ expect(screen.getByRole("textbox")).toHaveValue("");
+ });
+
+ it("should handle disabled state", () => {
+ render(ComboBox, { props: { disabled: true } });
+
+ expect(screen.getByRole("textbox")).toBeDisabled();
+ expect(screen.getByText("Contact")).toHaveClass("bx--label--disabled");
+ });
+
+ it("should handle invalid state", () => {
+ render(ComboBox, {
+ props: {
+ invalid: true,
+ invalidText: "Invalid selection",
+ },
+ });
+
+ expect(screen.getByRole("listbox")).toHaveAttribute("data-invalid", "true");
+ expect(screen.getByText("Invalid selection")).toBeInTheDocument();
+ });
+
+ it("should handle warning state", () => {
+ render(ComboBox, {
+ props: {
+ warn: true,
+ warnText: "Warning message",
+ },
+ });
+
+ expect(screen.getByText("Warning message")).toBeInTheDocument();
+ });
+
+ it("should handle helper text", () => {
+ render(ComboBox, { props: { helperText: "Helper message" } });
+
+ expect(screen.getByText("Helper message")).toBeInTheDocument();
+ });
+
+ it("should handle light variant", () => {
+ render(ComboBox, { props: { light: true } });
+
+ expect(screen.getByRole("textbox")).toHaveClass("bx--text-input--light");
+ });
+
+ test.each([
+ ["sm", "bx--list-box--sm"],
+ ["xl", "bx--list-box--xl"],
+ ] as const)("should handle size variants", (size, className) => {
+ render(ComboBox, { props: { size } });
+ expect(screen.getByRole("listbox")).toHaveClass(className);
+ });
+
+ it("should handle filtering items", async () => {
+ render(ComboBox);
+
+ const input = screen.getByRole("textbox");
+ await user.click(input);
+ await user.type(input, "em");
+
+ const options = screen.getAllByRole("option");
+ expect(options).toHaveLength(1);
+ expect(options[0]).toHaveTextContent("Email");
+ });
+
+ it("should handle disabled items", async () => {
+ render(ComboBoxCustom);
+
+ await user.click(screen.getByRole("textbox"));
+ const disabledOption = screen.getByText(/Fax/).closest('[role="option"]');
+ assert(disabledOption);
+ expect(disabledOption).toHaveAttribute("disabled", "true");
+
+ await user.click(disabledOption);
+ expect(screen.getByRole("textbox")).toHaveValue("");
+
+ // Dropdown remains open
+ const dropdown = screen.getAllByRole("listbox")[1];
+ expect(dropdown).toBeVisible();
+ });
+
+ it("should handle custom item display", async () => {
+ render(ComboBoxCustom);
+
+ await user.click(screen.getByRole("textbox"));
+ const options = screen.getAllByRole("option");
+
+ expect(options[0]).toHaveTextContent("Item Slack");
+ expect(options[1]).toHaveTextContent("Item Email");
+ expect(options[2]).toHaveTextContent("Item Fax");
+ });
+
+ it("should handle top direction", async () => {
+ render(ComboBoxCustom, { props: { direction: "top" } });
+
+ await user.click(screen.getAllByRole("button")[0]);
+ expect(screen.getByRole("listbox")).toHaveClass("bx--list-box--up");
+ });
+
+ it("should programmatically clear selection", async () => {
+ render(ComboBoxCustom, { props: { selectedId: "1" } });
+
+ expect(screen.getByRole("textbox")).toHaveValue("Email");
+ await user.click(screen.getByText("Clear"));
+ expect(screen.getByRole("textbox")).toHaveValue("");
+ });
+
+ it("should close menu on Escape key", async () => {
+ render(ComboBox);
+
+ const input = screen.getByRole("textbox");
+ await user.click(input);
+
+ const dropdown = screen.getAllByRole("listbox")[1];
+ expect(dropdown).toBeVisible();
+
+ await user.keyboard("{Escape}");
+ expect(dropdown).not.toBeVisible();
+ });
+});
diff --git a/tests/ComboBox/ComboBoxCustom.test.svelte b/tests/ComboBox/ComboBoxCustom.test.svelte
new file mode 100644
index 00000000..221aa005
--- /dev/null
+++ b/tests/ComboBox/ComboBoxCustom.test.svelte
@@ -0,0 +1,36 @@
+
+
+ {
+ console.log("select", e.detail);
+ }}
+ let:item
+>
+ Item {item.text}
+
+
+