mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
test(progress-indicator): add unit tests
This commit is contained in:
parent
1478486d8f
commit
f7ac0e3f22
3 changed files with 282 additions and 83 deletions
|
@ -1,83 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
ProgressIndicator,
|
|
||||||
ProgressStep,
|
|
||||||
ProgressIndicatorSkeleton,
|
|
||||||
} from "carbon-components-svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ProgressIndicator currentIndex={2}>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 1"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 2"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 3"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Step 4"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
</ProgressIndicator>
|
|
||||||
|
|
||||||
<ProgressIndicator preventChangeOnClick currentIndex={2}>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 1"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 2"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
complete
|
|
||||||
label="Step 3"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Step 4"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
</ProgressIndicator>
|
|
||||||
|
|
||||||
<ProgressIndicator spaceEqually>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
</ProgressIndicator>
|
|
||||||
|
|
||||||
<ProgressIndicator vertical>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
<ProgressStep
|
|
||||||
label="Really long label"
|
|
||||||
description="The progress indicator will listen for clicks on the steps"
|
|
||||||
/>
|
|
||||||
</ProgressIndicator>
|
|
||||||
|
|
||||||
<ProgressIndicatorSkeleton count={3} />
|
|
35
tests/ProgressIndicator/ProgressIndicator.test.svelte
Normal file
35
tests/ProgressIndicator/ProgressIndicator.test.svelte
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { ProgressIndicator, ProgressStep } from "carbon-components-svelte";
|
||||||
|
|
||||||
|
export let currentIndex = 0;
|
||||||
|
export let vertical = false;
|
||||||
|
export let spaceEqually = false;
|
||||||
|
export let preventChangeOnClick = false;
|
||||||
|
export let steps: Array<{
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
complete: boolean;
|
||||||
|
invalid?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
}> = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ProgressIndicator
|
||||||
|
{currentIndex}
|
||||||
|
{vertical}
|
||||||
|
{spaceEqually}
|
||||||
|
{preventChangeOnClick}
|
||||||
|
on:change={(e) => {
|
||||||
|
console.log("change", e.detail);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#each steps as step}
|
||||||
|
<ProgressStep
|
||||||
|
label={step.label}
|
||||||
|
description={step.description}
|
||||||
|
complete={step.complete}
|
||||||
|
invalid={step.invalid}
|
||||||
|
disabled={step.disabled}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</ProgressIndicator>
|
247
tests/ProgressIndicator/ProgressIndicator.test.ts
Normal file
247
tests/ProgressIndicator/ProgressIndicator.test.ts
Normal file
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue