import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import Breadcrumb from "./Breadcrumb";
const items = [
{ label: "Home", href: "/" },
{ label: "Products", href: "/products" },
{ label: "Laptops", href: "/products/laptops" },
{ label: "MacBook Pro" },
];
describe("Breadcrumb", () => {
test("renders all item labels", () => {
render();
expect(screen.getByText("Home")).toBeInTheDocument();
expect(screen.getByText("Products")).toBeInTheDocument();
expect(screen.getByText("Laptops")).toBeInTheDocument();
expect(screen.getByText("MacBook Pro")).toBeInTheDocument();
});
test("renders links with the correct href for items with href", () => {
render();
expect(screen.getByRole("link", { name: "Home" })).toHaveAttribute(
"href",
"/",
);
expect(screen.getByRole("link", { name: "Products" })).toHaveAttribute(
"href",
"/products",
);
expect(screen.getByRole("link", { name: "Laptops" })).toHaveAttribute(
"href",
"/products/laptops",
);
});
test("does not render a link for the last item when href is omitted", () => {
render();
expect(
screen.queryByRole("link", { name: "MacBook Pro" }),
).not.toBeInTheDocument();
});
test("the current item has aria-current set to page", () => {
render();
expect(screen.getByText("MacBook Pro")).toHaveAttribute(
"aria-current",
"page",
);
});
test("linked items do not have aria-current", () => {
render();
expect(screen.getByRole("link", { name: "Home" })).not.toHaveAttribute(
"aria-current",
);
});
test("renders the default separator between items", () => {
const { container } = render();
const separators = container.querySelectorAll(".breadcrumb-separator");
expect(separators).toHaveLength(items.length - 1);
expect(separators[0]).toHaveTextContent("/");
});
test("does not render a separator before the first item", () => {
const { container } = render();
const firstItem = container.querySelector(".breadcrumb-item");
expect(
firstItem?.querySelector(".breadcrumb-separator"),
).not.toBeInTheDocument();
});
test("renders a custom separator when provided", () => {
const { container } = render();
const separators = container.querySelectorAll(".breadcrumb-separator");
expect(separators[0]).toHaveTextContent("›");
});
test("separators have aria-hidden to hide them from screen readers", () => {
const { container } = render();
for (const sep of container.querySelectorAll(".breadcrumb-separator")) {
expect(sep).toHaveAttribute("aria-hidden", "true");
}
});
test("wraps items in an ordered list", () => {
const { container } = render();
expect(container.querySelector("ol")).toBeInTheDocument();
});
test("renders a nav element with aria-label Breadcrumb", () => {
render();
expect(
screen.getByRole("navigation", { name: "Breadcrumb" }),
).toBeInTheDocument();
});
test("applies an additional className to the list", () => {
const { container } = render(
,
);
expect(container.querySelector("ol")).toHaveClass(
"breadcrumb",
"page-breadcrumb",
);
});
test("renders a single item with no separator", () => {
const { container } = render(
,
);
expect(container.querySelectorAll(".breadcrumb-separator")).toHaveLength(0);
});
test("works when all items have hrefs", () => {
const allLinked = [
{ label: "Home", href: "/" },
{ label: "Docs", href: "/docs" },
];
render();
expect(screen.getByRole("link", { name: "Home" })).toBeInTheDocument();
expect(screen.getByRole("link", { name: "Docs" })).toBeInTheDocument();
});
});