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", ); }); });