import { render, screen } from "@testing-library/svelte"; import { user } from "../setup-tests"; import DataTableSearch from "./DataTableSearch.test.svelte"; describe("DataTableSearch", () => { beforeEach(() => { vi.clearAllMocks(); }); // Remove first row since it's the header const getTableRows = () => screen.getAllByRole("row").slice(1); const getNextPageButton = () => screen.getByRole("button", { name: "Next page" }); const getPrevPageButton = () => screen.getByRole("button", { name: "Previous page" }); const allRowsRendered = () => { const tableRows = getTableRows(); expect(tableRows).toHaveLength(5); tableRows.forEach((row) => { expect(row).toHaveTextContent(/Round robin|DNS delegation/); }); expect(screen.getByText("1–5 of 10 items")).toBeInTheDocument(); expect(screen.getByText("of 2 pages")).toBeInTheDocument(); expect(getNextPageButton()).toBeEnabled(); expect(getPrevPageButton()).toBeDisabled(); }; it("renders non-persistent search input", async () => { render(DataTableSearch); const searchBar = screen.getByRole("search"); expect(searchBar).not.toHaveClass( "bx--toolbar-search-container-persistent", ); expect(searchBar).not.toHaveClass("bx--toolbar-search-container-active"); const searchInput = screen.getByRole("searchbox"); expect(searchInput).toHaveValue(""); expect(searchInput).not.toHaveFocus(); allRowsRendered(); await user.type(searchInput, "dns"); expect(searchInput).toHaveValue("dns"); expect(searchInput).toHaveFocus(); expect(searchBar).toHaveClass("bx--toolbar-search-container-active"); expect(screen.getByText("1–5 of 5 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); let tableRows = getTableRows(); expect(tableRows).toHaveLength(5); tableRows.forEach((row) => { expect(row).toHaveTextContent("DNS"); }); await user.keyboard("{Tab}{Enter}"); expect(searchInput).toHaveValue(""); expect(searchInput).toHaveFocus(); allRowsRendered(); await user.keyboard("{Tab}"); expect(searchBar).not.toHaveClass("bx--toolbar-search-container-active"); }); it("renders persistent search input", async () => { render(DataTableSearch, { props: { persistent: true, }, }); const searchBar = screen.getByRole("search"); expect(searchBar).toHaveClass("bx--toolbar-search-container-persistent"); const searchInput = screen.getByRole("searchbox"); expect(searchInput).toHaveValue(""); expect(searchInput).not.toHaveFocus(); allRowsRendered(); await user.type(searchInput, "dns"); expect(searchInput).toHaveValue("dns"); expect(searchInput).toHaveFocus(); expect(screen.getByText("1–5 of 5 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); let tableRows = getTableRows(); expect(tableRows).toHaveLength(5); tableRows.forEach((row) => { expect(row).toHaveTextContent("DNS"); }); await user.keyboard("{Tab}{Enter}"); expect(searchInput).toHaveValue(""); expect(searchInput).toHaveFocus(); allRowsRendered(); }); it("renders with initial search value in non-persistent search input", async () => { render(DataTableSearch, { props: { value: "round", }, }); const searchInput = screen.getByRole("searchbox"); expect(searchInput).toHaveValue("round"); expect(searchInput).not.toHaveFocus(); // Search bar should be active. const searchBar = screen.getByRole("search"); expect(searchBar).toHaveClass("bx--toolbar-search-container-active"); expect(screen.getByText("1–5 of 5 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); let tableRows = getTableRows(); expect(tableRows).toHaveLength(5); tableRows.forEach((row) => { expect(row).toHaveTextContent("Round"); }); await user.click( screen.getByRole("button", { name: "Clear search input" }), ); expect(searchInput).toHaveValue(""); expect(searchInput).toHaveFocus(); allRowsRendered(); await user.type(searchInput, "rr"); tableRows = getTableRows(); expect(tableRows).toHaveLength(0); expect(screen.getByText("0–0 of 0 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); await user.keyboard("{Escape}"); expect(searchInput).toHaveValue(""); expect(searchInput).toHaveFocus(); allRowsRendered(); await user.keyboard("{Tab}"); expect(searchBar).not.toHaveClass("bx--toolbar-search-container-active"); }); it("can filter with a custom filter function", async () => { render(DataTableSearch, { props: { shouldFilterRows: (row, value) => { return ( /(6|8)$/.test(row.name) && row.rule.toLowerCase().includes((value + "").toLowerCase()) ); }, }, }); allRowsRendered(); const searchInput = screen.getByRole("searchbox"); await user.type(searchInput, "round"); expect(searchInput).toHaveValue("round"); expect(searchInput).toHaveFocus(); expect(screen.getByText("1–2 of 2 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); let tableRows = getTableRows(); expect(tableRows).toHaveLength(2); tableRows.forEach((row) => { expect(row).toHaveTextContent("Round"); expect(row).toHaveTextContent(/Load Balancer 6|Load Balancer 8/); }); }); it("re-filters rows when toggled", async () => { render(DataTableSearch); allRowsRendered(); const searchInput = screen.getByRole("searchbox"); await user.type(searchInput, "round"); expect(searchInput).toHaveValue("round"); expect(searchInput).toHaveFocus(); expect(screen.getByText("1–5 of 5 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); const toggleButton = screen.getByRole("button", { name: "Toggle rows" }); await user.click(toggleButton); expect(searchInput).toHaveValue("round"); expect(searchInput).not.toHaveFocus(); expect(screen.getByText("1–2 of 2 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); let tableRows = getTableRows(); expect(tableRows).toHaveLength(2); tableRows.forEach((row) => { expect(row).toHaveTextContent("Round!"); }); await user.click(toggleButton); expect(searchInput).toHaveValue("round"); expect(searchInput).not.toHaveFocus(); expect(screen.getByText("1–5 of 5 items")).toBeInTheDocument(); expect(screen.getByText("of 1 page")).toBeInTheDocument(); expect(getNextPageButton()).toBeDisabled(); expect(getPrevPageButton()).toBeDisabled(); await user.click( screen.getByRole("button", { name: "Clear search input" }), ); expect(searchInput).toHaveValue(""); expect(searchInput).toHaveFocus(); allRowsRendered(); }); });