Testing API
Brisa exposes a testing API that extends the Bun test runner with custom APIs to streamline the testing process. These APIs are designed to simplify the testing of Brisa components and their behavior.
render
Renders a Brisa component into a container and returns a set of actions to interact with the component.
Example:
import { render } from "brisa/test";
import { test, expect } from "bun:test";
function Button() {
return <button onClick={() => console.log("clicked")}>Click me</button>;
}
test("component", async () => {
const { container } = await render(<Button />);
const button = container.querySelector("button");
expect(button).toHaveTextContent("Click me");
});
The second argument are the options to render the component:
baseElement
: The element where the component will be rendered. By default, it uses thedocument.documentElement
.locale
: The locale to use when rendering the component when using i18n. By default, it uses thedefaultLocale
.
Example:
import { render } from "brisa/test";
import { test, expect } from "bun:test";
import { Component } from "./Component";
test("component", async () => {
const baseElement = document.createElement("div");
await render(<Component />, { baseElement, locale: "es" });
expect(baseElement.querySelector("button")).toHaveTextContent("Clica aquรญ");
});
Types:
render(element: JSX.Element | Response |ย string, options?: {
baseElement?: HTMLElement;
locale?: string;
}): Promise<{
container: HTMLElement;
unmount: () => void;
store: ReactiveMap;
}>;
container
The container where the component is rendered.
unmount
Unmounts the component from the container.
Example:
import { render } from "brisa/test";
import { test, expect } from "bun:test";
test("unmount", async () => {
const { container, unmount } = await render(<button>Click me</button>);
expect(container.querySelector("button")).toBeInTheDocument();
unmount();
expect(container.querySelector("button")).not.toBeInTheDocument();
});
store
The store
from WebContext
is useful for modifying the store to test how web components react to changes in it.
Example:
import { render } from "brisa/test";
import { test, expect } from "bun:test";
test("store", async () => {
const { container, store } = await render(<counter-example />);
const counter = container.querySelector("counter-example")?.shadowRoot;
expect(counter).toHaveTextContent("0");
store.set("count", 1);
expect(counter).toHaveTextContent("1");
});
serveRoute
Request a Brisa route and return the Response. These routes can be API endpoints, pages, assets, or any other type of route.
Example:
import { serveRoute } from "brisa/test";
import { test, expect } from "bun:test";
test("route", async () => {
const response = await serveRoute("/api/hello");
const data = await response.json();
expect(data).toEqual({ message: "Hello, world!" });
});
For the pages, you can use it with the render
function to render the page:
import { render, serveRoute } from "brisa/test";
import { test, expect } from "bun:test";
test("page", async () => {
const response = await serveRoute("/about");
const { container } = await render(response);
expect(container).toHaveTextContent("About us");
});
You can use
render
afterserveRoute
to render the page and interact with it, and you can pass theresponse
or theresponse.text()
directly to therender
function.
Types:
serveRoute(route: string): Promise<Response>;
cleanup
Cleans up the document after each test.
Example:
import { cleanup } from "brisa/test";
import { afterEach } from "bun:test";
afterEach(() => {
cleanup();
});
Types:
cleanup(): void;
userEvent
Simulates user events on a target element.
Example:
import { render, userEvent } from "brisa/test";
import { test, expect } from "bun:test";
test("user event", async () => {
const { container } = await render(<button>Click me</button>);
const button = container.querySelector("button");
userEvent.click(button); // Simulate a click event
});
Each method simulates a different user event:
click
: Simulates a click event.userEvent.click(button);
dblClick
: Simulates a double click event.userEvent.dblClick(button);
submit
: Simulates a submit event.userEvent.submit(form);
type
: Simulates typing text into an input.userEvent.type(input, "Hello, world!");
keyboard
: Simulates pressing a key.userEvent.keyboard("Enter");
hover
: Simulates hovering over an element.userEvent.hover(element);
unhover
: Simulates unhovering an element.userEvent.unhover(element);
focus
: Simulates focusing on an element.userEvent.focus(input);
blur
: Simulates blurring an element.userEvent.blur(input);
select
: Simulates selecting an option from a dropdown.userEvent.select(select, "option-1");
deselect
: Simulates deselecting an option from a dropdown.userEvent.deselect(select, "option-1");
upload
: Simulates uploading a file.userEvent.upload(input, file);
clear
: Simulates clearing an input.userEvent.clear(input);
tab
: Simulates pressing the tab key.userEvent.tab();
paste
: Simulates pasting text into an input.userEvent.paste(input, "Hello, world!");
Types:
type userEvent = {
click(element: Element): void;
dblClick(element: Element): void;
submit(element: HTMLFormElement): void;
type(element: HTMLInputElement, text: string): void;
keyboard(key: string, element?: HTMLElement): void;
hover(element: Element): void;
unhover(element: Element): void;
focus(element: Element): void;
blur(element: Element): void;
select(element: HTMLSelectElement, value: string): void;
deselect(element: HTMLSelectElement, value: string): void;
upload(element: HTMLInputElement, file: File): void;
clear(element: HTMLInputElement): void;
tab(): void;
paste(element: Element, text: string): void;
};
waitFor
Waits for a condition to be true before continuing with the test. This is useful when you need to wait for an element to be visible, for example, when testing animations or asynchronous behavior.
Example:
import { render, waitFor } from "brisa/test";
import { test, expect } from "bun:test";
test("wait for", async () => {
const { container } = await render(<button>Click me</button>);
const button = container.querySelector("button");
await waitFor(() => expect(button).toBeVisible());
});
You can use
waitFor
to wait for an element to be visible, to have a specific text content, or to have a specific class name.
Types:
async function waitFor(
fn: () => unknown,
maxMilliseconds: number,
): Promise<void>;
debug
Prints the HTML of the rendered component to the console in a readable format.
Example:
import { render, debug } from "brisa/test";
import { test, expect } from "bun:test";
test("debug a specific element", async () => {
const { container } = await render(<button>Click me</button>);
debug(container);
});
If no element is passed, it will debug the entire document.
Example:
import { debug, render, serveRoute } from "brisa/test";
import { test } from "bun:test";
test("debug all the document", async () => {
const pageResponse = await serveRoute("/about");
await render(pageResponse);
debug(); // Debug the entire document
});
In the console, you will see the HTML of the document in a readable format:
<html>
<body>
<button>Click me</button>
</body>
</html>
Types:
debug(element?: HTMLElement | DocumentFragment | ShadowRoot | null): void;