Browser runner for Vitest enabling tests to run in actual browser environments with real DOM APIs and browser-specific features
npx @tessl/cli install tessl/npm-vitest--browser@3.2.0@vitest/browser is a browser runner for Vitest that enables tests to run in actual browser environments rather than in Node.js. It provides comprehensive testing capabilities with real DOM APIs, browser-specific features, and multiple automation providers including Playwright and WebdriverIO, allowing developers to test frontend applications in real browser contexts with full interaction simulation and cross-browser compatibility.
npm install @vitest/browserBrowser context API (client-side):
import { userEvent, page, commands, server, locators, cdp } from "@vitest/browser/context";Server-side API (Node.js):
import { createBrowserServer, createBrowserPool, distRoot } from "@vitest/browser";Provider imports:
import { playwright, webdriverio, preview } from "@vitest/browser/providers";Utilities and matchers:
import { debug, prettyDOM, getElementError, getElementLocatorSelectors } from "@vitest/browser/utils";
import "@vitest/browser/matchers";import { userEvent, page } from "@vitest/browser/context";
import { expect } from "vitest";
// Test with user interactions
test("form submission", async () => {
// Find elements using locators
const input = page.getByLabelText("Username");
const button = page.getByRole("button", { name: "Submit" });
// Simulate user interactions
await userEvent.fill(input, "testuser");
await userEvent.click(button);
// Assert results
await expect.element(page.getByText("Welcome testuser")).toBeVisible();
});
// Take screenshots
test("visual test", async () => {
const screenshot = await page.screenshot();
expect(screenshot).toMatchImageSnapshot();
});
// File system operations
import { commands } from "@vitest/browser/context";
test("config file test", async () => {
const config = await commands.readFile("./config.json");
const parsed = JSON.parse(config);
expect(parsed.version).toBe("1.0.0");
});@vitest/browser is built around several key components:
Client-side testing environment providing user interaction simulation, element location, and browser-specific utilities. The main interface for writing browser tests.
const userEvent: UserEvent;
const page: BrowserPage;
const commands: BrowserCommands;
const server: ServerInfo;
const locators: BrowserLocators;
function cdp(): CDPSession;Powerful element location system supporting CSS selectors, accessibility queries, chaining, and filtering for robust element targeting.
interface Locator {
getByRole(role: string, options?: LocatorByRoleOptions): Locator;
getByText(text: string | RegExp, options?: LocatorOptions): Locator;
getByTestId(testId: string | RegExp): Locator;
click(options?: UserEventClickOptions): Promise<void>;
element(): Element;
}Comprehensive user event simulation supporting keyboard input, mouse interactions, form manipulation, and file uploads with provider-specific implementations.
interface UserEvent {
click(element: Element | Locator, options?: UserEventClickOptions): Promise<void>;
type(element: Element | Locator, text: string, options?: UserEventTypeOptions): Promise<void>;
fill(element: Element | Locator, text: string, options?: UserEventFillOptions): Promise<void>;
keyboard(text: string): Promise<void>;
}Browser automation providers for running tests in different browser environments, each with specific capabilities and configuration options.
const playwright: BrowserProviderModule;
const webdriverio: BrowserProviderModule;
const preview: BrowserProviderModule;Node.js server-side functionality for creating browser test environments and managing browser pools in test suites.
function createBrowserServer(
project: TestProject,
configFile: string | undefined,
prePlugins?: Plugin[],
postPlugins?: Plugin[]
): Promise<ParentBrowserProject>;
function createBrowserPool(vitest: Vitest): ProcessPool;
const distRoot: string;Server-side file operations accessible from browser context for reading configuration files, test fixtures, and writing test outputs.
interface BrowserCommands {
readFile(path: string, options?: BufferEncoding | FsOptions): Promise<string>;
writeFile(path: string, content: string, options?: FsOptions): Promise<void>;
removeFile(path: string): Promise<void>;
}Development tools for debugging element queries, DOM inspection, and test development with pretty-printing and error formatting.
function debug(element?: Element | Locator | null | (Element | Locator)[], maxLength?: number, options?: PrettyDOMOptions): void;
function prettyDOM(dom?: Element | Locator | undefined | null, maxLength?: number, options?: PrettyDOMOptions): string;
function getElementError(selector: string, container?: Element): Error;
function getElementLocatorSelectors(element: Element): LocatorSelectors;DOM-specific matchers extending Vitest's expect API with browser-aware assertions and element polling for reliable test assertions.
interface ExpectStatic {
element<T extends Element | Locator | null>(element: T, options?: ExpectPollOptions): PromisifyDomAssertion<Awaited<Element | null>>;
}Core type definitions used across the API:
interface LocatorOptions {
exact?: boolean;
hasText?: string | RegExp;
hasNotText?: string | RegExp;
has?: Locator;
hasNot?: Locator;
}
interface ScreenshotOptions {
element?: Element | Locator;
path?: string;
base64?: boolean;
save?: boolean;
}
type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
interface ServerInfo {
platform: string;
version: string;
provider: string;
browser: string;
commands: BrowserCommands;
config: SerializedConfig;
}
interface BrowserLocators {
createElementLocators(element: Element): LocatorSelectors;
extend(methods: Record<string, Function>): void;
}
interface CDPSession {
// Methods are defined by the provider type augmentation
}
type ARIARole =
// Widget roles
| "button" | "checkbox" | "gridcell" | "link" | "menuitem" | "menuitemcheckbox"
| "menuitemradio" | "option" | "progressbar" | "radio" | "scrollbar" | "searchbox"
| "slider" | "spinbutton" | "switch" | "tab" | "tabpanel" | "textbox" | "treeitem"
// Composite widget roles
| "combobox" | "grid" | "listbox" | "menu" | "menubar" | "radiogroup" | "tablist" | "tree" | "treegrid"
// Document structure roles
| "application" | "article" | "blockquote" | "caption" | "cell" | "columnheader" | "definition"
| "deletion" | "directory" | "document" | "emphasis" | "feed" | "figure" | "generic" | "group"
| "heading" | "img" | "insertion" | "list" | "listitem" | "math" | "meter" | "none" | "note"
| "paragraph" | "presentation" | "row" | "rowgroup" | "rowheader" | "separator" | "strong"
| "subscript" | "superscript" | "table" | "term" | "time" | "toolbar" | "tooltip"
// Landmark roles
| "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "region" | "search"
// Live region roles
| "alert" | "log" | "marquee" | "status" | "timer"
// Window roles
| "alertdialog" | "dialog"
// Uncategorized roles
| "code";