import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import ProgressBar from "./ProgressBar";
describe("ProgressBar", () => {
test("renders the progressbar role", () => {
render();
expect(screen.getByRole("progressbar")).toBeInTheDocument();
});
test("sets the fill width to the correct percentage", () => {
const { container } = render();
const fill = container.querySelector(".progress-bar-fill");
expect(fill).toHaveStyle({ width: "75%" });
});
test("clamps value at 100% when value exceeds max", () => {
const { container } = render();
const fill = container.querySelector(".progress-bar-fill");
expect(fill).toHaveStyle({ width: "100%" });
});
test("clamps value at 0% when value is negative", () => {
const { container } = render();
const fill = container.querySelector(".progress-bar-fill");
expect(fill).toHaveStyle({ width: "0%" });
});
test("respects a custom max value", () => {
const { container } = render();
const fill = container.querySelector(".progress-bar-fill");
expect(fill).toHaveStyle({ width: "25%" });
});
test("sets aria-valuenow to the given value", () => {
render();
expect(screen.getByRole("progressbar")).toHaveAttribute(
"aria-valuenow",
"40",
);
});
test("sets aria-valuemin and aria-valuemax", () => {
render();
const bar = screen.getByRole("progressbar");
expect(bar).toHaveAttribute("aria-valuemin", "0");
expect(bar).toHaveAttribute("aria-valuemax", "200");
});
test("defaults aria-label to 'Progress'", () => {
render();
expect(screen.getByRole("progressbar")).toHaveAttribute(
"aria-label",
"Progress",
);
});
test("uses the label prop as aria-label", () => {
render();
expect(screen.getByRole("progressbar")).toHaveAttribute(
"aria-label",
"Upload progress",
);
});
test("renders the label text when provided", () => {
render();
expect(screen.getByText("Uploading...")).toBeInTheDocument();
});
test("does not render a header when label and showValue are both absent", () => {
const { container } = render();
expect(
container.querySelector(".progress-bar-header"),
).not.toBeInTheDocument();
});
test("shows the percentage value when showValue is true", () => {
render();
expect(screen.getByText("60%")).toBeInTheDocument();
});
test("applies the correct variant class to the fill", () => {
const { container } = render();
expect(container.querySelector(".progress-bar-fill")).toHaveClass(
"progress-bar-success",
);
});
test("applies the correct size class to the track", () => {
const { container } = render();
expect(container.querySelector(".progress-bar")).toHaveClass(
"progress-bar-lg",
);
});
test("applies the indeterminate class and omits aria-valuenow when indeterminate", () => {
const { container } = render();
expect(container.querySelector(".progress-bar-fill")).toHaveClass(
"progress-bar-indeterminate",
);
expect(screen.getByRole("progressbar")).not.toHaveAttribute(
"aria-valuenow",
);
});
test("does not show value text when indeterminate even if showValue is true", () => {
const { container } = render(
,
);
expect(
container.querySelector(".progress-bar-value"),
).not.toBeInTheDocument();
});
test("applies an additional className to the wrapper", () => {
const { container } = render();
expect(container.firstChild).toHaveClass("my-bar");
});
test("defaults to the md size", () => {
const { container } = render();
expect(container.querySelector(".progress-bar")).toHaveClass(
"progress-bar-md",
);
});
test("defaults to the default variant", () => {
const { container } = render();
expect(container.querySelector(".progress-bar-fill")).toHaveClass(
"progress-bar-default",
);
});
});