diff --git a/tests/ProgressIndicator.test.svelte b/tests/ProgressIndicator.test.svelte
deleted file mode 100644
index 0f1e5cc7..00000000
--- a/tests/ProgressIndicator.test.svelte
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/ProgressIndicator/ProgressIndicator.test.svelte b/tests/ProgressIndicator/ProgressIndicator.test.svelte
new file mode 100644
index 00000000..4f8a4d06
--- /dev/null
+++ b/tests/ProgressIndicator/ProgressIndicator.test.svelte
@@ -0,0 +1,35 @@
+
+
+ {
+ console.log("change", e.detail);
+ }}
+>
+ {#each steps as step}
+
+ {/each}
+
diff --git a/tests/ProgressIndicator/ProgressIndicator.test.ts b/tests/ProgressIndicator/ProgressIndicator.test.ts
new file mode 100644
index 00000000..649d37cb
--- /dev/null
+++ b/tests/ProgressIndicator/ProgressIndicator.test.ts
@@ -0,0 +1,247 @@
+import { render, screen } from "@testing-library/svelte";
+import ProgressIndicator from "./ProgressIndicator.test.svelte";
+import { user } from "../setup-tests";
+
+describe("ProgressIndicator", () => {
+ describe("Default (horizontal)", () => {
+ it("should render steps with correct states", () => {
+ render(ProgressIndicator, {
+ currentIndex: 2,
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ { label: "Step 2", description: "Second step", complete: true },
+ { label: "Step 3", description: "Third step", complete: true },
+ { label: "Step 4", description: "Fourth step", complete: false },
+ ],
+ });
+
+ const listItems = screen.getAllByRole("listitem");
+
+ // Check if all steps are rendered
+ expect(listItems).toHaveLength(4);
+
+ // Check completed steps
+ const completedSteps = listItems.filter((step) =>
+ step.classList.contains("bx--progress-step--complete"),
+ );
+ expect(completedSteps).toHaveLength(3);
+
+ // Check current step
+ expect(listItems[2]).toHaveTextContent("Step 3");
+
+ // Check incomplete step
+ const incompleteStep = screen.getByText("Step 4");
+ expect(incompleteStep).toBeInTheDocument();
+ expect(incompleteStep.closest("li")).not.toHaveClass(
+ "bx--progress-step--complete",
+ );
+ });
+
+ it("should update currentIndex when clicking on completed steps", async () => {
+ const consoleLog = vi.spyOn(console, "log");
+ render(ProgressIndicator, {
+ currentIndex: 2,
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ { label: "Step 2", description: "Second step", complete: true },
+ { label: "Step 3", description: "Third step", complete: true },
+ { label: "Step 4", description: "Fourth step", complete: false },
+ ],
+ });
+
+ expect(consoleLog).not.toHaveBeenCalled();
+
+ // Click on a completed step
+ await user.click(screen.getByText("Step 1"));
+ expect(consoleLog).toHaveBeenCalledWith("change", 0);
+ });
+
+ it("should not update currentIndex when preventChangeOnClick is true", async () => {
+ const { component } = render(ProgressIndicator, {
+ currentIndex: 2,
+ preventChangeOnClick: true,
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ { label: "Step 2", description: "Second step", complete: true },
+ { label: "Step 3", description: "Third step", complete: true },
+ { label: "Step 4", description: "Fourth step", complete: false },
+ ],
+ });
+
+ const changeHandler = vi.fn();
+ component.$on("change", changeHandler);
+
+ // Click on a completed step
+ await user.click(screen.getByText("Step 1"));
+ expect(changeHandler).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("Invalid and disabled states", () => {
+ it("should render invalid step", () => {
+ render(ProgressIndicator, {
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ {
+ label: "Step 2",
+ description: "Second step",
+ complete: false,
+ invalid: true,
+ disabled: false,
+ },
+ { label: "Step 3", description: "Third step", complete: false },
+ ],
+ });
+
+ const invalidStep = screen.getByText("Step 2").closest("li");
+ expect(invalidStep).toHaveClass("bx--progress-step--incomplete");
+ });
+
+ it("should render disabled steps", () => {
+ render(ProgressIndicator, {
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ {
+ label: "Step 2",
+ description: "Second step",
+ complete: false,
+ invalid: false,
+ disabled: true,
+ },
+ {
+ label: "Step 3",
+ description: "Third step",
+ complete: false,
+ invalid: false,
+ disabled: true,
+ },
+ ],
+ });
+
+ const disabledSteps = screen.getAllByRole("listitem").slice(1);
+ disabledSteps.forEach((step) => {
+ expect(step).toHaveClass("bx--progress-step--disabled");
+ });
+ });
+ });
+
+ describe("Variants", () => {
+ it("should render vertical variant", () => {
+ render(ProgressIndicator, {
+ vertical: true,
+ steps: [
+ { label: "Step 1", description: "First step", complete: false },
+ { label: "Step 2", description: "Second step", complete: false },
+ { label: "Step 3", description: "Third step", complete: false },
+ ],
+ });
+
+ const progressIndicator = screen.getByRole("list");
+ expect(progressIndicator).toHaveClass("bx--progress--vertical");
+ });
+
+ it("should render with equal spacing", () => {
+ render(ProgressIndicator, {
+ spaceEqually: true,
+ steps: [
+ { label: "Step 1", description: "First step", complete: false },
+ { label: "Step 2", description: "Second step", complete: false },
+ { label: "Step 3", description: "Third step", complete: false },
+ ],
+ });
+
+ const progressIndicator = screen.getByRole("list");
+ expect(progressIndicator).toHaveClass("bx--progress--space-equal");
+ });
+
+ it("should not apply equal spacing in vertical variant", () => {
+ render(ProgressIndicator, {
+ vertical: true,
+ spaceEqually: true,
+ steps: [
+ { label: "Step 1", description: "First step", complete: false },
+ { label: "Step 2", description: "Second step", complete: false },
+ { label: "Step 3", description: "Third step", complete: false },
+ ],
+ });
+
+ const progressIndicator = screen.getByRole("list");
+ expect(progressIndicator).not.toHaveClass("bx--progress--space-equal");
+ });
+ });
+
+ describe("Accessibility", () => {
+ it("should have correct button attributes for different states", () => {
+ render(ProgressIndicator, {
+ currentIndex: 1,
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ { label: "Step 2", description: "Second step", complete: false },
+ { label: "Step 3", description: "Third step", complete: false },
+ ],
+ });
+
+ const buttons = screen.getAllByRole("button");
+
+ // Complete step button should be clickable
+ expect(buttons[0]).toHaveAttribute("tabindex", "0");
+ expect(buttons[0]).toHaveAttribute("aria-disabled", "false");
+ expect(buttons[0]).not.toHaveClass(
+ "bx--progress-step-button--unclickable",
+ );
+
+ // Current step button should be unclickable
+ expect(buttons[1]).toHaveAttribute("tabindex", "-1");
+ expect(buttons[1]).toHaveAttribute("aria-disabled", "false");
+ expect(buttons[1]).toHaveClass("bx--progress-step-button--unclickable");
+
+ // Incomplete step button should be unclickable
+ expect(buttons[2]).toHaveAttribute("tabindex", "0");
+ expect(buttons[2]).toHaveAttribute("aria-disabled", "false");
+ expect(buttons[2]).not.toHaveClass(
+ "bx--progress-step-button--unclickable",
+ );
+ });
+
+ it("should have correct button attributes for disabled state", () => {
+ render(ProgressIndicator, {
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ {
+ label: "Step 2",
+ description: "Second step",
+ complete: false,
+ disabled: true,
+ },
+ ],
+ });
+
+ const disabledButton = screen.getAllByRole("button")[1];
+ expect(disabledButton).toHaveAttribute("disabled");
+ expect(disabledButton).toHaveAttribute("aria-disabled", "true");
+ expect(disabledButton).toHaveAttribute("tabindex", "-1");
+ });
+
+ it("should support keyboard navigation for complete steps", async () => {
+ const consoleLog = vi.spyOn(console, "log");
+ render(ProgressIndicator, {
+ currentIndex: 1,
+ steps: [
+ { label: "Step 1", description: "First step", complete: true },
+ { label: "Step 2", description: "Second step", complete: false },
+ ],
+ });
+
+ expect(consoleLog).not.toHaveBeenCalled();
+ const completeStepButton = screen.getAllByRole("button")[0];
+ await user.tab();
+ expect(completeStepButton).toHaveFocus();
+
+ await user.keyboard("{Enter}");
+ expect(consoleLog).toHaveBeenCalledWith("change", 0);
+
+ await user.keyboard(" ");
+ expect(consoleLog).toHaveBeenCalledWith("change", 0);
+ });
+ });
+});