--- title: Context API | Browser Mode --- # Context API Vitest exposes a context module via `vitest/browser` entry point. As of 2.0, it exposes a small set of utilities that might be useful to you in tests. ## `userEvent` ::: tip The `userEvent` API is explained in detail at [Interactivity API](/api/browser/interactivity). ::: ```ts /** * Handler for user interactions. The support is implemented by the browser provider (`playwright` or `webdriverio`). * If used with `preview` provider, fallbacks to simulated events via `@testing-library/user-event`. * @experimental */ export const userEvent: { setup: () => UserEvent cleanup: () => Promise click: (element: Element, options?: UserEventClickOptions) => Promise dblClick: (element: Element, options?: UserEventDoubleClickOptions) => Promise tripleClick: (element: Element, options?: UserEventTripleClickOptions) => Promise selectOptions: ( element: Element, values: HTMLElement | HTMLElement[] | string | string[], options?: UserEventSelectOptions, ) => Promise keyboard: (text: string) => Promise type: (element: Element, text: string, options?: UserEventTypeOptions) => Promise clear: (element: Element) => Promise tab: (options?: UserEventTabOptions) => Promise hover: (element: Element, options?: UserEventHoverOptions) => Promise unhover: (element: Element, options?: UserEventHoverOptions) => Promise fill: (element: Element, text: string, options?: UserEventFillOptions) => Promise dragAndDrop: (source: Element, target: Element, options?: UserEventDragAndDropOptions) => Promise } ``` ## `commands` ::: tip This API is explained in detail at [Commands API](/api/browser/commands). ::: ```ts /** * Available commands for the browser. * A shortcut to `server.commands`. */ export const commands: BrowserCommands ``` ## `page` The `page` export provides utilities to interact with the current `page`. ::: warning While it exposes some utilities from Playwright's `page`, it is not the same object. Since the browser context is evaluated in the browser, your tests don't have access to Playwright's `page` because it runs on the server. Use [Commands API](/api/browser/commands) if you need to have access to Playwright's `page` object. ::: ```ts export const page: { /** * Change the size of iframe's viewport. */ viewport(width: number, height: number): Promise /** * Make a screenshot of the test iframe or a specific element. * @returns Path to the screenshot file or path and base64. */ screenshot(options: Omit & { base64: true }): Promise<{ path: string base64: string }> screenshot(options?: ScreenshotOptions): Promise /** * Add a trace marker when browser tracing is enabled. */ mark(name: string, options?: { stack?: string; kind?: BrowserTraceEntryKind }): Promise /** * Group multiple operations under a trace marker when browser tracing is enabled. */ mark(name: string, body: () => T | Promise, options?: { stack?: string; kind?: BrowserTraceEntryKind }): Promise /** * Extend default `page` object with custom methods. */ extend(methods: Partial): BrowserPage /** * Wrap an HTML element in a `Locator`. When querying for elements, the search will always return this element. */ elementLocator(element: Element): Locator /** * The iframe locator. This is a document locator that enters the iframe body * and works similarly to the `page` object. * **Warning:** At the moment, this is supported only by the `playwright` provider. */ frameLocator(iframeElement: Locator): FrameLocator /** * Locator APIs. See its documentation for more details. */ getByRole(role: ARIARole | string, options?: LocatorByRoleOptions): Locator getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator getByTestId(text: string | RegExp): Locator getByAltText(text: string | RegExp, options?: LocatorOptions): Locator getByPlaceholder(text: string | RegExp, options?: LocatorOptions): Locator getByText(text: string | RegExp, options?: LocatorOptions): Locator getByTitle(text: string | RegExp, options?: LocatorOptions): Locator } ``` ::: tip The `getBy*` API is explained at [Locators API](/api/browser/locators). ::: ::: warning WARNING 3.2.0 Note that `screenshot` will always return a base64 string if `save` is set to `false`. The `path` is also ignored in that case. ::: ### mark ```ts function mark(name: string, options?: { stack?: string; kind?: BrowserTraceEntryKind }): Promise function mark( name: string, body: () => T | Promise, options?: { stack?: string; kind?: BrowserTraceEntryKind }, ): Promise ``` Adds a named marker to the trace timeline for the current test. Pass `options.stack` to override the callsite location in trace metadata. This is useful for wrapper libraries that need to preserve the end-user source location. Pass `options.kind` to categorize your marker as specific type, for example as `'action'`. If you pass a callback, Vitest creates a trace group with this name, runs the callback, and closes the group automatically. ```ts import { page } from 'vitest/browser' await page.mark('before submit') await page.getByRole('button', { name: 'Submit' }).click() await page.mark('after submit') await page.mark('submit flow', async () => { await page.getByRole('textbox', { name: 'Email' }).fill('john@example.com') await page.getByRole('button', { name: 'Submit' }).click() }, { kind: 'action' }) ``` ::: tip This method is useful only when [`browser.trace`](/config/browser/trace) is enabled. A server-side equivalent is available on the [`BrowserCommandContext`](/api/browser/commands#recording-trace-markers) so [custom commands](/api/browser/commands#custom-commands) can record markers attributed to the test that triggered them. ::: ### frameLocator ```ts function frameLocator(iframeElement: Locator): FrameLocator ``` The `frameLocator` method returns a `FrameLocator` instance that can be used to find elements inside the iframe. The frame locator is similar to `page`. It does not refer to the Iframe HTML element, but to the iframe's document. ```ts const frame = page.frameLocator( page.getByTestId('iframe') ) await frame.getByText('Hello World').click() // ✅ await frame.click() // ❌ Not available ``` ::: danger IMPORTANT By default `frameLocator` does not support querying elements with `expect.element()` in cross-origin iframes. Interactive methods, such as `.click()` work fine. This is different behaviour than Playwright. ```ts const frame = page.frameLocator(page.getByTestId('cross-origin-iframe')) const button = frame.getByRole('button', { name: 'Submit' }) await button.click() // Interactive methods work fine ✅ await expect.element(button).toBeVisible() // Querying elements does not work ❌ ``` If you need to work with cross-origin iframes, you'll need to pass `args: ["--disable-web-security"]` in [`launchOptions`](/config/browser/playwright.html#launchoptions). Or alternatively create a custom [browser command](/api/browser/commands.html#custom-commands) that accesses the iframe on server side where it's available. ::: ::: danger IMPORTANT At the moment, the `frameLocator` method is only supported by the `playwright` provider. The interactive methods (like `click` or `fill`) are always available on elements within the iframe, but assertions with `expect.element` require the iframe to have the [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). ::: ## `cdp` ```ts function cdp(): CDPSession ``` The `cdp` export returns the current Chrome DevTools Protocol session. It is mostly useful to library authors to build tools on top of it. ::: warning CDP session works only with `playwright` provider and only when using `chromium` browser. You can read more about it in playwright's [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession) documentation. CDP is a privileged debugging API. It is available only when browser API write and exec operations are enabled through [`api.allowWrite`](/config/api#api-allowwrite), and [`api.allowExec`](/config/api#api-allowexec). ::: ```ts export const cdp: () => CDPSession ``` ## `server` The `server` export represents the Node.js environment where the Vitest server is running. It is mostly useful for debugging or limiting your tests based on the environment. ```ts export const server: { /** * Platform the Vitest server is running on. * The same as calling `process.platform` on the server. */ platform: Platform /** * Runtime version of the Vitest server. * The same as calling `process.version` on the server. */ version: string /** * Name of the browser provider. */ provider: string /** * Name of the current browser. */ browser: string /** * Available commands for the browser. */ commands: BrowserCommands /** * Serialized test config. */ config: SerializedConfig } ``` ## `utils` Utility functions useful for custom render libraries. ```ts export const utils: { /** * This is similar to calling `page.elementLocator`, but it returns only * locator selectors. */ getElementLocatorSelectors(element: Element): LocatorSelectors /** * Prints prettified HTML of an element. */ debug( el?: Element | Locator | null | (Element | Locator)[], maxLength?: number, options?: PrettyDOMOptions, ): void /** * Returns prettified HTML of an element. */ prettyDOM( dom?: Element | Locator | undefined | null, maxLength?: number, prettyFormatOptions?: PrettyDOMOptions, ): string /** * Configures default options of `prettyDOM` and `debug` functions. * This will also affect `vitest-browser-{framework}` package. */ configurePrettyDOM(options: StringifyOptions): void /** * Creates "Cannot find element" error. Useful for custom locators. */ getElementError(selector: string, container?: Element): Error /** * Utilities for generating and working with ARIA trees and templates. * @experimental */ aria: { generateAriaTree(rootElement: Element): AriaNode renderAriaTree(root: AriaNode): string renderAriaTemplate(template: AriaTemplateNode): string parseAriaTemplate(text: string): AriaTemplateNode matchAriaTree(root: AriaNode, template: AriaTemplateNode): { pass: boolean; resolved: string } } } ``` ### configurePrettyDOM 4.0.0 {#configureprettydom} The `configurePrettyDOM` function allows you to configure default options for the `prettyDOM` and `debug` functions. This is useful for customizing how HTML is formatted in test failure messages. ```ts import { utils } from 'vitest/browser' utils.configurePrettyDOM({ maxDepth: 3, filterNode: 'script, style, [data-test-hide]' }) ``` #### Options - **`maxDepth`** - Maximum depth to print nested elements (default: `Infinity`) - **`maxLength`** - Maximum length of the output string (default: `7000`) - **`filterNode`** - A CSS selector string or function to filter out nodes from the output. When a string is provided, elements matching the selector will be excluded. When a function is provided, it should return `false` to exclude a node. - **`highlight`** - Enable syntax highlighting (default: `true`) - And other options from [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format) #### Filtering with CSS Selectors 4.1.0 {#filtering-with-css-selectors} The `filterNode` option allows you to hide irrelevant markup (like scripts, styles, or hidden elements) from test failure messages, making it easier to identify the actual cause of failures. ```ts import { utils } from 'vitest/browser' // Filter out common noise elements utils.configurePrettyDOM({ filterNode: 'script, style, [data-test-hide]' }) // Or use directly with prettyDOM const html = utils.prettyDOM(element, undefined, { filterNode: 'script, style' }) ``` **Common Patterns:** Filter out scripts and styles: ```ts utils.configurePrettyDOM({ filterNode: 'script, style' }) ``` Hide specific elements with data attributes: ```ts utils.configurePrettyDOM({ filterNode: '[data-test-hide]' }) ``` Hide nested content within an element: ```ts // Hides all children of elements with data-test-hide-content utils.configurePrettyDOM({ filterNode: '[data-test-hide-content] *' }) ``` Combine multiple selectors: ```ts utils.configurePrettyDOM({ filterNode: 'script, style, [data-test-hide], svg' }) ``` ::: tip This feature is inspired by Testing Library's [`defaultIgnore`](https://testing-library.com/docs/dom-testing-library/api-configuration/#defaultignore) configuration. ::: ### aria 5.0.0 {#aria} The `aria` namespace exposes low-level utilities used by Vitest's ARIA snapshot matchers. ```ts import { utils } from 'vitest/browser' document.body.innerHTML = `

Hello, World!

` const tree = utils.aria.generateAriaTree(document.body) const yaml = utils.aria.renderAriaNode(tree) console.log(yaml) // - heading "Hello, World!" [level=1] // - button "Visible"" ```