mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
test(expandable-tile): add unit tests
This commit is contained in:
parent
490d3b42ea
commit
f89e9df8f0
5 changed files with 263 additions and 22 deletions
|
@ -1,22 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { ExpandableTile } from "carbon-components-svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ExpandableTile>
|
|
||||||
<div slot="above" style="height: 10rem">Above the fold content here</div>
|
|
||||||
<div slot="below" style="height: 10rem">Below the fold content here</div>
|
|
||||||
</ExpandableTile>
|
|
||||||
|
|
||||||
<ExpandableTile expanded>
|
|
||||||
<div slot="above" style="height: 10rem">Above the fold content here</div>
|
|
||||||
<div slot="below" style="height: 10rem">Below the fold content here</div>
|
|
||||||
</ExpandableTile>
|
|
||||||
|
|
||||||
<ExpandableTile
|
|
||||||
light
|
|
||||||
tileExpandedLabel="View less"
|
|
||||||
tileCollapsedLabel="View more"
|
|
||||||
>
|
|
||||||
<div slot="above" style="height: 10rem">Above the fold content here</div>
|
|
||||||
<div slot="below" style="height: 10rem">Below the fold content here</div>
|
|
||||||
</ExpandableTile>
|
|
46
tests/ExpandableTile/ExpandableTile.test.svelte
Normal file
46
tests/ExpandableTile/ExpandableTile.test.svelte
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { ExpandableTile } from "carbon-components-svelte";
|
||||||
|
import type { ComponentProps } from "svelte";
|
||||||
|
|
||||||
|
export let expanded: ComponentProps<ExpandableTile>["expanded"] = false;
|
||||||
|
export let light: ComponentProps<ExpandableTile>["light"] = false;
|
||||||
|
export let tileMaxHeight: ComponentProps<ExpandableTile>["tileMaxHeight"] = 0;
|
||||||
|
export let tilePadding: ComponentProps<ExpandableTile>["tilePadding"] = 0;
|
||||||
|
export let tileCollapsedIconText: ComponentProps<ExpandableTile>["tileCollapsedIconText"] =
|
||||||
|
"Interact to expand Tile";
|
||||||
|
export let tileExpandedIconText: ComponentProps<ExpandableTile>["tileExpandedIconText"] =
|
||||||
|
"Interact to collapse Tile";
|
||||||
|
export let tileExpandedLabel: ComponentProps<ExpandableTile>["tileExpandedLabel"] =
|
||||||
|
"";
|
||||||
|
export let tileCollapsedLabel: ComponentProps<ExpandableTile>["tileCollapsedLabel"] =
|
||||||
|
"";
|
||||||
|
export let tabindex: ComponentProps<ExpandableTile>["tabindex"] = "0";
|
||||||
|
export let id: ComponentProps<ExpandableTile>["id"] = "ccs-test";
|
||||||
|
export let ref: ComponentProps<ExpandableTile>["ref"] = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ExpandableTile
|
||||||
|
bind:expanded
|
||||||
|
{light}
|
||||||
|
{tileMaxHeight}
|
||||||
|
{tilePadding}
|
||||||
|
{tileCollapsedIconText}
|
||||||
|
{tileExpandedIconText}
|
||||||
|
{tileExpandedLabel}
|
||||||
|
{tileCollapsedLabel}
|
||||||
|
{tabindex}
|
||||||
|
{id}
|
||||||
|
bind:ref
|
||||||
|
on:click
|
||||||
|
on:keypress
|
||||||
|
on:mouseover
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
>
|
||||||
|
<div slot="above" data-testid="above-content">
|
||||||
|
Above the fold content here
|
||||||
|
</div>
|
||||||
|
<div slot="below" data-testid="below-content">
|
||||||
|
Below the fold content here
|
||||||
|
</div>
|
||||||
|
</ExpandableTile>
|
149
tests/ExpandableTile/ExpandableTile.test.ts
Normal file
149
tests/ExpandableTile/ExpandableTile.test.ts
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
import { render, screen } from "@testing-library/svelte";
|
||||||
|
import { user } from "../setup-tests";
|
||||||
|
import ExpandableTile from "./ExpandableTile.test.svelte";
|
||||||
|
import ExpandableTileCustom from "./ExpandableTileCustom.test.svelte";
|
||||||
|
|
||||||
|
describe("ExpandableTile", () => {
|
||||||
|
it("should render with default props", () => {
|
||||||
|
render(ExpandableTile);
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
expect(tile).toBeInTheDocument();
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "false");
|
||||||
|
expect(tile).toHaveAttribute("title", "Interact to expand Tile");
|
||||||
|
expect(screen.getByTestId("above-content")).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId("below-content")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle expanded state", () => {
|
||||||
|
render(ExpandableTile, { props: { expanded: true } });
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "true");
|
||||||
|
expect(tile).toHaveAttribute("title", "Interact to collapse Tile");
|
||||||
|
expect(tile).toHaveClass("bx--tile--is-expanded");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle light variant", () => {
|
||||||
|
render(ExpandableTile, { props: { light: true } });
|
||||||
|
|
||||||
|
expect(screen.getByRole("button")).toHaveClass("bx--tile--light");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle custom icon text", async () => {
|
||||||
|
render(ExpandableTile, {
|
||||||
|
props: {
|
||||||
|
tileCollapsedIconText: "Custom collapsed text",
|
||||||
|
tileExpandedIconText: "Custom expanded text",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
expect(tile).toHaveAttribute("title", "Custom collapsed text");
|
||||||
|
|
||||||
|
await user.click(tile);
|
||||||
|
expect(tile).toHaveAttribute("title", "Custom expanded text");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle custom labels", async () => {
|
||||||
|
render(ExpandableTile, {
|
||||||
|
props: {
|
||||||
|
tileCollapsedLabel: "Show more",
|
||||||
|
tileExpandedLabel: "Show less",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByText("Show more")).toBeInTheDocument();
|
||||||
|
|
||||||
|
await user.click(screen.getByRole("button"));
|
||||||
|
expect(screen.getByText("Show less")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle custom tabindex", () => {
|
||||||
|
render(ExpandableTile, { props: { tabindex: "1" } });
|
||||||
|
|
||||||
|
expect(screen.getByRole("button")).toHaveAttribute("tabindex", "1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle custom id", () => {
|
||||||
|
render(ExpandableTile, { props: { id: "custom-id" } });
|
||||||
|
|
||||||
|
expect(screen.getByRole("button")).toHaveAttribute("id", "custom-id");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should toggle expanded state on click", async () => {
|
||||||
|
render(ExpandableTile);
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "false");
|
||||||
|
|
||||||
|
await user.click(tile);
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "true");
|
||||||
|
|
||||||
|
await user.click(tile);
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "false");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle keyboard events", async () => {
|
||||||
|
render(ExpandableTile);
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
await user.tab();
|
||||||
|
expect(tile).toHaveFocus();
|
||||||
|
|
||||||
|
await user.keyboard("{Enter}");
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "true");
|
||||||
|
|
||||||
|
await user.keyboard(" ");
|
||||||
|
expect(tile).toHaveAttribute("aria-expanded", "false");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle interactive content without toggling", async () => {
|
||||||
|
render(ExpandableTileCustom);
|
||||||
|
|
||||||
|
const tileButton = screen.getAllByRole("button")[0];
|
||||||
|
const link = screen.getByTestId("test-link");
|
||||||
|
const button = screen.getByTestId("test-button");
|
||||||
|
|
||||||
|
expect(tileButton).toHaveAttribute("aria-expanded", "false");
|
||||||
|
|
||||||
|
await user.click(link);
|
||||||
|
expect(tileButton).toHaveAttribute("aria-expanded", "false");
|
||||||
|
|
||||||
|
await user.click(button);
|
||||||
|
expect(tileButton).toHaveAttribute("aria-expanded", "false");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle mouse events", async () => {
|
||||||
|
render(ExpandableTile);
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
await user.hover(tile);
|
||||||
|
await user.unhover(tile);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle custom content slots", () => {
|
||||||
|
render(ExpandableTile);
|
||||||
|
|
||||||
|
const aboveContent = screen.getByTestId("above-content");
|
||||||
|
const belowContent = screen.getByTestId("below-content");
|
||||||
|
|
||||||
|
expect(aboveContent).toHaveTextContent("Above the fold content here");
|
||||||
|
expect(belowContent).toHaveTextContent("Below the fold content here");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle max height and padding", async () => {
|
||||||
|
render(ExpandableTile, {
|
||||||
|
props: {
|
||||||
|
tileMaxHeight: 200,
|
||||||
|
tilePadding: 20,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tile = screen.getByRole("button");
|
||||||
|
expect(tile.getAttribute("style")).toBe("max-height: 105px;");
|
||||||
|
|
||||||
|
await user.click(tile);
|
||||||
|
expect(tile.getAttribute("style")).toBe("max-height: none;");
|
||||||
|
});
|
||||||
|
});
|
31
tests/ExpandableTile/ExpandableTileCustom.test.svelte
Normal file
31
tests/ExpandableTile/ExpandableTileCustom.test.svelte
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { ExpandableTile, Button } from "carbon-components-svelte";
|
||||||
|
|
||||||
|
export let buttonClicked = false;
|
||||||
|
export let linkClicked = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ExpandableTile tileExpandedLabel="View less" tileCollapsedLabel="View more">
|
||||||
|
<div slot="above">
|
||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
data-testid="test-link"
|
||||||
|
on:click|preventDefault|stopPropagation={() => {
|
||||||
|
linkClicked = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test link
|
||||||
|
</a>
|
||||||
|
<br /><br />
|
||||||
|
<Button
|
||||||
|
data-testid="test-button"
|
||||||
|
on:click={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
buttonClicked = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test button
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div slot="below">Below the fold content here</div>
|
||||||
|
</ExpandableTile>
|
|
@ -6,4 +6,41 @@ import "../css/all.css";
|
||||||
// Mock scrollIntoView since it's not implemented in JSDOM
|
// Mock scrollIntoView since it's not implemented in JSDOM
|
||||||
Element.prototype.scrollIntoView = vi.fn();
|
Element.prototype.scrollIntoView = vi.fn();
|
||||||
|
|
||||||
|
// Mock ResizeObserver since it's not implemented in JSDOM
|
||||||
|
class ResizeObserverMock {
|
||||||
|
callback: ResizeObserverCallback;
|
||||||
|
elements: Element[];
|
||||||
|
|
||||||
|
constructor(callback: ResizeObserverCallback) {
|
||||||
|
this.callback = callback;
|
||||||
|
this.elements = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
observe(element: Element) {
|
||||||
|
this.elements.push(element);
|
||||||
|
this.callback(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
target: element,
|
||||||
|
contentRect: { height: 100 } as DOMRectReadOnly,
|
||||||
|
borderBoxSize: [],
|
||||||
|
contentBoxSize: [],
|
||||||
|
devicePixelContentBoxSize: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unobserve(element: Element) {
|
||||||
|
this.elements = this.elements.filter((el) => el !== element);
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
this.elements = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global.ResizeObserver = ResizeObserverMock;
|
||||||
|
|
||||||
export const user = userEvent.setup();
|
export const user = userEvent.setup();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue