new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vitest · Guide · all subjects

browser/locators

58 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

locators.extend overview

locators.extend adds domain-specific locators without losing the locator API. Custom locators preserve auto-retry, strict-mode protection, and chaining behavior. Available in Vitest 3.2.0 and later.

extend locators with Playwright string

locators.extend can return a Playwright locator string. Vitest treats the string as a child query: when called on page, it runs against the entire page; when called on a parent locator, it runs scoped to that parent's subtree. Use this form when the query has no good expression in built-in locators, like a CSS-with-text selector or XPath for legacy components.

extend locators example with Playwright string

Example of extending locators to return a Playwright string: ```ts import { locators } from 'vitest/browser' locators.extend({ getByCommentsCount(count: number) { return `.comments :text("${count} comments")` }, }) ``` Usage: ```ts import { expect, test } from 'vitest' import { page } from 'vitest/browser' test('article shows comment count', async () => { await expect.element(page.getByCommentsCount(1)).toBeVisible() await expect.element( page.getByRole('article', { name: 'Hello World' }) .getByCommentsCount(1) ).toBeVisible() }) ```

extend locators by composing existing locators

When locators.extend returns a locator instead of a string, Vitest uses that locator directly. Inside the extension, `this` is bound to the locator the method was called on (or to `page` for top-level calls), allowing you to chain existing locators or apply `filter` to express relationships between elements. This approach preserves accessibility-aware guarantees of built-in locators.

extend locators composing example with filter

Example of extending locators by composing existing locators with filter: ```ts import { locators } from 'vitest/browser' import type { Locator } from 'vitest/browser' locators.extend({ getRowWithAction(this: Locator, action: string) { return this.getByRole('row').filter({ has: this.getByRole('button', { name: action }), }) }, }) ``` Usage: ```ts await page.getRowWithAction('Delete').first().click() ```

extend locators with custom interactions

locators.extend can define custom interaction methods instead of returning a locator. These methods are reachable from both BrowserPage and Locator. For interaction helpers that should only work on locators, guard against `page` by comparing `this` against the `page` singleton and throwing an error if called on `page` directly, which lets TypeScript narrow `this` to `Locator` after the throw.

extend locators interaction example with guard

Example of extending locators with a custom interaction that includes a guard: ```ts import { locators, page } from 'vitest/browser' import type { BrowserPage, Locator } from 'vitest/browser' locators.extend({ async clickAndFill(this: BrowserPage | Locator, text: string) { if (this === page) { throw new TypeError( 'clickAndFill must be called on a locator, like page.getByRole(\'textbox\').clickAndFill(...)', ) } await this.click() await this.fill(text) }, }) await page.getByRole('textbox').clickAndFill('Hello World') ```

augment LocatorSelectors interface for TypeScript

locators.extend is a runtime registration. TypeScript doesn't know about new methods until you augment the LocatorSelectors interface, usually in a shared .d.ts file. LocatorSelectors is the interface that both Locator and BrowserPage extend, so any method declared on it shows up on both.

augment LocatorSelectors interface example

Example of augmenting the LocatorSelectors interface: ```ts import 'vitest/browser' declare module 'vitest/browser' { interface LocatorSelectors { getByCommentsCount: (count: number) => Locator getRowWithAction: (action: string) => Locator clickAndFill: (text: string) => Promise<void> } } ```

built-in locators coverage

Built-in locators like getByRole and getByText cover queries that map onto accessibility attributes. They do not cover app-specific shapes that don't fit ARIA, such as 'comment with N replies' or a row in a custom table component, which is where custom locators extend the functionality.

prefer composed locators over raw strings

When extending locators, prefer composing existing locators over the raw-string form when both can express the query. Built-in locators encode accessibility-aware lookups, and chaining or filtering them preserves those guarantees. Only reach for the raw-string form when no chain of built-ins covers the query.

Browser locators serialized as SerializedLocator objects

In Vitest 5.0, locators forwarded to browser commands are serialized as SerializedLocator objects with two fields: selector (the provider-specific selector string) and locator (human-readable representation like getByRole('button')). Custom commands accepting locators must destructure selector from the object: { selector }: SerializedLocator.

Browser locators are strict by default in Vitest 5.0

In Vitest 5.0, browser locators now match text exactly by default, requiring full case-sensitive match. Set browser.locators.exact to false to use the previous behavior of partial matching.

Locator fill method

Sets the value of the current input, textarea or contenteditable element. Signature: function fill(text: string, options?: UserEventFillOptions): Promise<void>.

Locator dropTo method

Drags the current element to the target location. Signature: function dropTo(target: Locator, options?: UserEventDragAndDropOptions): Promise<void>.

Locator definition and purpose

A locator is a representation of an element or a number of elements. Every locator is defined by a string called a selector. Vitest abstracts this selector by providing convenient methods that generate selectors behind the scenes.

Locator API implementation

The locator API uses a fork of Playwright's locators called Ivya. Vitest provides this API to every browser provider, not just Playwright.

Locators vs testing-library differences

Vitest's page.getBy* methods return a locator object, not a DOM element. This makes locator queries composable and allows Vitest to retry interactions and assertions when needed. Key differences: use locator chaining instead of within(), keep locators around for later interaction, and single-element escape hatches like .element() and .query() are strict and throw if multiple elements match.

getByRole locator

Creates a way to locate an element by its ARIA role, ARIA attributes, and accessible name. Signature: function getByRole(role: ARIARole | string, options?: LocatorByRoleOptions): Locator. Roles are matched by string equality without inheriting from the ARIA role hierarchy.

getByRole options

getByRole accepts the following options: exact (boolean, default false) - case-sensitive and whole-string match; checked (boolean) - filter by checked state; disabled (boolean) - filter by disabled state; expanded (boolean) - filter by expanded state; includeHidden (boolean) - include normally excluded elements; level (number) - filter by aria-level attribute; name (string | RegExp) - filter by accessible name; pressed (boolean) - filter by pressed state; selected (boolean) - filter by selected state.

getByAltText locator

Creates a locator capable of finding an element with an alt attribute that matches the text. Unlike testing-library's implementation, Vitest will match any element that has a matching alt attribute. Signature: function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator.

getByLabelText locator

Creates a locator capable of finding an element that has an associated label. Supports for/htmlFor relationship, aria-labelledby attribute, wrapper labels, and aria-label attributes. Signature: function getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator.

getByPlaceholder locator

Creates a locator capable of finding an element that has the specified placeholder attribute. Vitest will match any element that has a matching placeholder attribute, not just input elements. Signature: function getByPlaceholder(text: string | RegExp, options?: LocatorOptions): Locator.

getByText locator

Creates a locator capable of finding an element that contains the specified text. The text will be matched against TextNode's nodeValue or input's value if the type is button or reset. Matching by text always normalizes whitespace, even with exact match, turning multiple spaces into one, line breaks into spaces, and ignoring leading and trailing whitespace. Signature: function getByText(text: string | RegExp, options?: LocatorOptions): Locator.

getByTitle locator

Creates a locator capable of finding an element that has the specified title attribute. Unlike testing-library's getByTitle, Vitest cannot find title elements within an SVG. Signature: function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator.

getByTestId locator

Creates a locator capable of finding an element that matches the specified test id attribute. The test id attribute name can be configured with browser.locators.testIdAttribute. Signature: function getByTestId(text: string | RegExp): Locator.

nth method for multi-element queries

Returns a new locator that matches only a specific index within a multi-element query result. It's zero based, nth(0) selects the first element. Unlike elements()[n], the nth locator will be retried until the element is present. Signature: function nth(index: number): Locator.

first method for locators

Returns a new locator that matches only the first index of a multi-element query result. It is sugar for nth(0). Signature: function first(): Locator.

last method for locators

Returns a new locator that matches only the last index of a multi-element query result. It is sugar for nth(-1). Signature: function last(): Locator.

and method for combining locators

Creates a new locator that matches both the parent and provided locator. Signature: function and(locator: Locator): Locator.

or method for combining locators

Creates a new locator that matches either one or both locators. If the resulting locator matches more than a single element, calling another method might throw an error if it expects a single element. Signature: function or(locator: Locator): Locator.

filter method with has option

The has option in filter narrows down the selector to match elements that contain other elements matching the provided locator. The provided locator must be relative to the parent locator and will be queried starting with the parent locator, not the document root. Signature: filter(options: { has: Locator }): Locator.

filter method with hasNot option

The hasNot option in filter narrows down the selector to match elements that do not contain other elements matching the provided locator. The provided locator is queried against the parent, not the document root. Signature: filter(options: { hasNot: Locator }): Locator.

filter method with hasNotText option

The hasNotText option narrows down the selector to only match elements that do not contain the provided text somewhere inside. When a string is passed, matching is case-insensitive and searches for a substring. Signature: filter(options: { hasNotText: string | RegExp }): Locator.

Locator click method

Clicks on an element. All locator methods are asynchronous and must be awaited. Since Vitest 3, tests will fail if a method is not awaited. Signature: function click(options?: UserEventClickOptions): Promise<void>.

Locator dblClick method

Triggers a double click event on an element. You can use the options to set the cursor position. Signature: function dblClick(options?: UserEventDoubleClickOptions): Promise<void>.

Locator tripleClick method

Triggers a triple click event on an element. Since there is no tripleclick event in browser API, this method fires three click events in a row. Signature: function tripleClick(options?: UserEventTripleClickOptions): Promise<void>.

Locator wheel method

Triggers a wheel event on an element. You can use the options to choose a general scroll direction or a precise delta value. Available since Vitest 4.1.0. Signature: function wheel(options: UserEventWheelOptions): Promise<void>.

Locator clear method

Clears the input element content. Signature: function clear(options?: UserEventClearOptions): Promise<void>.

Locator hover method

Moves the cursor position to the selected element. Signature: function hover(options?: UserEventHoverOptions): Promise<void>.

Locator unhover method

Works the same as hover, but moves the cursor to the document.body element instead. Signature: function unhover(options?: UserEventHoverOptions): Promise<void>.

Locator selectOptions method

Chooses one or more values from a select element. Values can be HTMLElement, HTMLElement[], Locator, Locator[], string, or string[]. Signature: function selectOptions(values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[], options?: UserEventSelectOptions): Promise<void>.

Locator screenshot method

Creates a screenshot of the element matching the locator's selector. The save location can be specified using the path option relative to the current test file. If path is not set, Vitest defaults to browser.screenshotDirectory (__screenshot__ by default) with names of the file and test. You can specify base64: true to return content alongside the filepath. Note: screenshot always returns a base64 string if save is set to false, and path is ignored in that case. Signature: function screenshot(options?: LocatorScreenshotOptions): Promise<string>.

Locator mark method

Adds a named marker to the trace timeline and uses the current locator as marker context. Pass options.stack to override the callsite location in trace metadata. Pass options.kind to categorize the marker as a specific type, for example 'action'. This method is useful only when browser.trace is enabled. Signature: function mark(name: string, options?: { stack?: string; kind?: BrowserTraceEntryKind }): Promise<void>.

Locator query method

Returns a single element matching the locator's selector or null if no element is found. If multiple elements match the selector, this method throws an error. Use .elements() when you need all matching DOM elements or .all() for an array of locators. Signature: function query(): Element | null.

Locator element method

Returns a single element matching the locator's selector. If no element matches, an error is thrown. If multiple elements match and the selector is strict, an error is thrown. This is an escape hatch for external APIs that do not support locators. It is called automatically when locator is used with expect.element and the assertion is retried. Signature: function element(): Element.

Locator elements method

Returns an array of elements matching the locator's selector. This function never throws an error. If there are no elements matching the selector, this method returns an empty array. Signature: function elements(): Element[].

Locator findElement method

Returns an element matching the locator and waits/retries until a matching element appears in the DOM with increasing intervals (0, 20, 50, 100, 100, 500ms). If no element is found before timeout, an error is thrown. By default timeout matches the test timeout. If multiple elements match and strict is true (default), an error is thrown immediately. Set strict to false to return the first matching element. Available since Vitest 4.1.0. Signature: function findElement(options?: SelectorOptions): Promise<HTMLElement | SVGElement>.

Locator all method

Returns an array of new locators that match the selector. Internally, this method calls .elements() and wraps every element using page.elementLocator. Signature: function all(): Locator[].

Locator serialize method

Returns a JSON-serializable representation of the locator with two fields: selector (provider-specific selector string) and locator (human-readable description for error messages and tracing). Vitest automatically serializes any Locator argument passed to a command, so calling serialize() explicitly is rarely necessary. Signature: function serialize(): SerializedLocator.

Locator toJSON method

Alias of serialize(). Defined so that JSON.stringify(locator) and structured-clone-based transports return a SerializedLocator object. Signature: function toJSON(): SerializedLocator.

Locator asLocator method

Returns a human-readable description of the locator using JavaScript locator syntax (e.g. getByRole('button', { name: 'Submit' })). This is the same string exposed in the locator field of serialize() and is used in error messages and traces. The returned string is not meant to be re-used to query elements. Signature: function asLocator(): string.

Locator selector property

The selector is a provider-specific string used to locate the element by the browser provider. Playwright uses Playwright locator syntax, while preview and webdriverio use CSS. Should only be used when working with the Commands API, not in test code directly.

Locator length property

The length getter returns the number of elements that the locator is matching. It is equivalent to calling locator.elements().length.

Custom locators extension

You can extend built-in locators API by defining an object of locator factories using locators.extend(). Custom locators can return a selector string or a locator itself. The selector syntax is identical to Playwright locators. If a custom method returns a string, it will be converted into a locator. If it returns anything else, it will be returned as usual. When called on page, the selector applies to the whole page. When called on a locator, it is scoped to that locator. Available since Vitest 3.2.0.

Custom locators this context

In custom locator methods, you have access to the current locator via 'this'. If the method was called on page, 'this' will be 'page', not the locator.

LocatorOptions exact parameter

The exact option in locator methods (boolean, default false) controls whether text is matched exactly: case-sensitive and whole-string. This option is ignored if text is a regular expression. Exact match still trims whitespace.

RenderResult locator property

The locator property is a locator of the container. It can be used to run queries scoped only to the component or passed down to other assertions: await expect.element(locator).toHaveTextContent('Hello World').

Give your agent this brain