mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
test(data-table): add tests for DataTableSearch
This commit is contained in:
parent
b4b055270e
commit
b034378277
2 changed files with 310 additions and 0 deletions
78
tests/DataTable/DataTableSearch.test.svelte
Normal file
78
tests/DataTable/DataTableSearch.test.svelte
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
DataTable,
|
||||||
|
Toolbar,
|
||||||
|
ToolbarContent,
|
||||||
|
ToolbarSearch,
|
||||||
|
Pagination,
|
||||||
|
} from "carbon-components-svelte";
|
||||||
|
import type { ComponentProps } from "svelte";
|
||||||
|
|
||||||
|
export let value = "";
|
||||||
|
export let persistent = false;
|
||||||
|
export let shouldFilterRows: ComponentProps<ToolbarSearch>["shouldFilterRows"] = true;
|
||||||
|
|
||||||
|
const initialRows = Array.from({ length: 10 }).map((_, i) => ({
|
||||||
|
id: i,
|
||||||
|
name: "Load Balancer " + (i + 1),
|
||||||
|
protocol: "HTTP",
|
||||||
|
port: 3000 + i * 10,
|
||||||
|
rule: i % 2 ? "Round robin" : "DNS delegation",
|
||||||
|
}));
|
||||||
|
|
||||||
|
let rows = initialRows;
|
||||||
|
let pageSize = 5;
|
||||||
|
let page = 1;
|
||||||
|
let filteredRowIds: number[] = [];
|
||||||
|
let toggleRows = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
on:click={() => {
|
||||||
|
toggleRows = !toggleRows;
|
||||||
|
if (toggleRows) {
|
||||||
|
rows = Array.from({ length: 4 }).map((_, i) => ({
|
||||||
|
id: i,
|
||||||
|
name: "Server instance " + (i + 1),
|
||||||
|
protocol: "HTTP",
|
||||||
|
port: 3000 + i * 10,
|
||||||
|
rule: i % 2 ? "Round!" : "DNS!",
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
rows = initialRows;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Toggle rows
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<DataTable
|
||||||
|
headers={[
|
||||||
|
{ key: "name", value: "Name" },
|
||||||
|
{ key: "protocol", value: "Protocol" },
|
||||||
|
{ key: "port", value: "Port" },
|
||||||
|
{ key: "rule", value: "Rule" },
|
||||||
|
]}
|
||||||
|
{rows}
|
||||||
|
{pageSize}
|
||||||
|
{page}
|
||||||
|
>
|
||||||
|
<Toolbar>
|
||||||
|
<ToolbarContent>
|
||||||
|
<ToolbarSearch
|
||||||
|
{persistent}
|
||||||
|
{value}
|
||||||
|
{shouldFilterRows}
|
||||||
|
bind:filteredRowIds
|
||||||
|
/>
|
||||||
|
</ToolbarContent>
|
||||||
|
</Toolbar>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<Pagination
|
||||||
|
bind:pageSize
|
||||||
|
bind:page
|
||||||
|
totalItems={filteredRowIds.length}
|
||||||
|
pageSizeInputDisabled
|
||||||
|
/>
|
232
tests/DataTable/DataTableSearch.test.ts
Normal file
232
tests/DataTable/DataTableSearch.test.ts
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
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/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: fix reactivity
|
||||||
|
it.skip("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();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue