Skip to content

Commit 9584029

Browse files
committed
test(tabs): add more unit tests (#2201)
1 parent bb04824 commit 9584029

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

tests/Tabs/Tab.test.svelte

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import { Tabs, Tab } from "carbon-components-svelte";
3+
4+
export let label = "Test Tab";
5+
export let href = "#test";
6+
export let disabled = false;
7+
export let tabindex = "0";
8+
export let id = "test-tab";
9+
</script>
10+
11+
<Tabs>
12+
<Tab {label} {href} {disabled} {tabindex} {id} />
13+
<svelte:fragment slot="content">
14+
<div>Test Content</div>
15+
</svelte:fragment>
16+
</Tabs>

tests/Tabs/Tabs.test.ts

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { render, screen } from "@testing-library/svelte";
22
import { user } from "../setup-tests";
33
import Tabs from "./Tabs.test.svelte";
4+
import Tab from "./Tab.test.svelte";
5+
import TabsSkeleton from "./TabsSkeleton.test.svelte";
46

57
describe("Tabs", () => {
68
let consoleLog: ReturnType<typeof vi.spyOn>;
@@ -127,3 +129,172 @@ describe("Tabs", () => {
127129
expect(screen.getByTitle("Custom description")).toBeInTheDocument();
128130
});
129131
});
132+
133+
describe("Tab", () => {
134+
it("should render with default props", () => {
135+
render(Tab);
136+
137+
const tab = screen.getByRole("tab", { name: "Test Tab" });
138+
expect(tab).toBeInTheDocument();
139+
expect(tab).toHaveAttribute("href", "#test");
140+
expect(tab).toHaveAttribute("tabindex", "0");
141+
expect(tab).toHaveAttribute("id", "test-tab");
142+
});
143+
144+
it("should render with custom label", () => {
145+
render(Tab, { props: { label: "Custom Label" } });
146+
147+
expect(
148+
screen.getByRole("tab", { name: "Custom Label" }),
149+
).toBeInTheDocument();
150+
});
151+
152+
it("should render with custom href", () => {
153+
render(Tab, { props: { href: "/custom" } });
154+
155+
const tab = screen.getByRole("tab");
156+
expect(tab).toHaveAttribute("href", "/custom");
157+
});
158+
159+
it("should handle disabled state", () => {
160+
render(Tab, { props: { disabled: true } });
161+
162+
const tab = screen.getByRole("tab");
163+
expect(tab).toHaveAttribute("aria-disabled", "true");
164+
expect(tab).toHaveAttribute("tabindex", "-1");
165+
});
166+
167+
it("should handle custom tabindex", () => {
168+
render(Tab, { props: { tabindex: "1" } });
169+
170+
const tab = screen.getByRole("tab");
171+
expect(tab).toHaveAttribute("tabindex", "1");
172+
});
173+
174+
it("should handle custom id", () => {
175+
render(Tab, { props: { id: "custom-id" } });
176+
177+
const tab = screen.getByRole("tab");
178+
expect(tab).toHaveAttribute("id", "custom-id");
179+
});
180+
181+
it("should be clickable when enabled", async () => {
182+
render(Tab);
183+
184+
const tab = screen.getByRole("tab");
185+
await user.click(tab);
186+
187+
expect(tab).toHaveAttribute("aria-selected", "true");
188+
});
189+
190+
it("should handle keyboard navigation with arrow keys", async () => {
191+
render(Tab);
192+
193+
const tab = screen.getByRole("tab");
194+
await user.click(tab);
195+
await user.keyboard("{ArrowRight}");
196+
197+
expect(tab).toHaveFocus();
198+
});
199+
200+
it("should handle space key activation", async () => {
201+
render(Tab);
202+
203+
const tab = screen.getByRole("tab");
204+
await user.click(tab);
205+
await user.keyboard(" ");
206+
207+
expect(tab).toHaveAttribute("aria-selected", "true");
208+
});
209+
210+
it("should handle enter key activation", async () => {
211+
render(Tab);
212+
213+
const tab = screen.getByRole("tab");
214+
await user.click(tab);
215+
await user.keyboard("{Enter}");
216+
217+
expect(tab).toHaveAttribute("aria-selected", "true");
218+
});
219+
220+
it("should render slot content when no label provided", () => {
221+
render(Tab, { props: { label: "" } });
222+
223+
const tab = screen.getByRole("tab");
224+
expect(tab).toHaveTextContent("");
225+
});
226+
});
227+
228+
describe("TabsSkeleton", () => {
229+
it("should render with default props", () => {
230+
const { container } = render(TabsSkeleton);
231+
232+
const skeleton = container.querySelector(".bx--tabs");
233+
expect(skeleton).toBeInTheDocument();
234+
expect(skeleton).toHaveClass("bx--skeleton");
235+
expect(skeleton).toHaveClass("bx--tabs--scrollable");
236+
237+
const navItems = container.querySelectorAll(
238+
".bx--tabs--scrollable__nav-item",
239+
);
240+
expect(navItems).toHaveLength(4);
241+
});
242+
243+
it("should render with custom count", () => {
244+
const { container } = render(TabsSkeleton, { props: { count: 6 } });
245+
246+
const navItems = container.querySelectorAll(
247+
".bx--tabs--scrollable__nav-item",
248+
);
249+
expect(navItems).toHaveLength(6);
250+
});
251+
252+
it("should render with container type", () => {
253+
const { container } = render(TabsSkeleton, {
254+
props: { type: "container" },
255+
});
256+
257+
const skeleton = container.querySelector(".bx--tabs");
258+
expect(skeleton).toHaveClass("bx--tabs--scrollable--container");
259+
});
260+
261+
it("should render with default type", () => {
262+
const { container } = render(TabsSkeleton, { props: { type: "default" } });
263+
264+
const skeleton = container.querySelector(".bx--tabs");
265+
expect(skeleton).not.toHaveClass("bx--tabs--scrollable--container");
266+
});
267+
268+
it("should render skeleton nav items with correct structure", () => {
269+
const { container } = render(TabsSkeleton);
270+
271+
const navItems = container.querySelectorAll(
272+
".bx--tabs--scrollable__nav-item",
273+
);
274+
navItems.forEach((item) => {
275+
const link = item.querySelector(".bx--tabs__nav-link");
276+
const span = link?.querySelector("span");
277+
278+
expect(link).toBeInTheDocument();
279+
expect(span).toBeInTheDocument();
280+
});
281+
});
282+
283+
it("should handle zero count", () => {
284+
const { container } = render(TabsSkeleton, { props: { count: 0 } });
285+
286+
const navItems = container.querySelectorAll(
287+
".bx--tabs--scrollable__nav-item",
288+
);
289+
expect(navItems).toHaveLength(0);
290+
});
291+
292+
it("should handle large count", () => {
293+
const { container } = render(TabsSkeleton, { props: { count: 20 } });
294+
295+
const navItems = container.querySelectorAll(
296+
".bx--tabs--scrollable__nav-item",
297+
);
298+
expect(navItems).toHaveLength(20);
299+
});
300+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script lang="ts">
2+
import { TabsSkeleton } from "carbon-components-svelte";
3+
4+
export let count = 4;
5+
export let type: "default" | "container" = "default";
6+
</script>
7+
8+
<TabsSkeleton {count} {type} />

0 commit comments

Comments
 (0)