--- title: Locators | Browser Mode outline: [2, 3] --- # Locators 2.1.0 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 those selectors behind the scenes. The locator API uses a fork of [Playwright's locators](https://playwright.dev/docs/api/class-locator) called [Ivya](https://npmjs.com/ivya). However, Vitest provides this API to every [provider](/guide/browser/#provider-configuration). ## getByRole - **Type:** `(role: ARIARole | string, options?: LocatorByRoleOptions) => Locator` Creates a way to locate an element by its [ARIA role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles), [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes) and [accessible name](https://developer.mozilla.org/en-US/docs/Glossary/Accessible_name). ::: tip If you only query for a single element with `getByText('The name')` it's oftentimes better to use `getByRole(expectedRole, { name: 'The name' })`. The accessible name query does not replace other queries such as `*ByAltText` or `*ByTitle`. While the accessible name can be equal to these attributes, it does not replace the functionality of these attributes. ::: Consider the following DOM structure. ```html

Sign up


``` You can locate each element by its implicit role: ```ts await expect.element( page.getByRole('heading', { name: 'Sign up' }) ).toBeVisible() await page.getByRole('textbox', { name: 'Login' }).fill('admin') await page.getByRole('textbox', { name: 'Password' }).fill('admin') await page.getByRole('button', { name: /submit/i }).click() ``` ::: warning Roles are matched by string equality, without inheriting from the ARIA role hierarchy. As a result, querying a superclass role like `checkbox` will not include elements with a subclass role like `switch`. By default, many semantic elements in HTML have a role; for example, `` has the "radio" role. Non-semantic elements in HTML do not have a role; `
` and `` without added semantics return `null`. The `role` attribute can provide semantics. Providing roles via `role` or `aria-*` attributes to built-in elements that already have an implicit role is **highly discouraged** by ARIA guidelines. ::: ##### Options - `exact: boolean` Whether the `name` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `name` is a regular expression. Note that exact match still trims whitespace. ```tsx page.getByRole('button', { name: 'hello world' }) // ✅ page.getByRole('button', { name: 'hello world', exact: true }) // ❌ page.getByRole('button', { name: 'Hello World', exact: true }) // ✅ ``` - `checked: boolean` Should checked elements (set by `aria-checked` or ``) be included or not. By default, the filter is not applied. See [`aria-checked`](https://www.w3.org/TR/wai-aria-1.2/#aria-checked) for more information ```tsx <> page.getByRole('button', { name: 'Click Me!' }) // ✅ page.getByRole('button', { name: 'click me!' }) // ✅ page.getByRole('button', { name: 'Click Me?' }) // ❌ ``` - `pressed: boolean` Should pressed elements be included or not. By default, the filter is not applied. See [`aria-pressed`](https://www.w3.org/TR/wai-aria-1.2/#aria-pressed) for more information ```tsx page.getByRole('button', { pressed: true }) // ✅ page.getByRole('button', { pressed: false }) // ❌ ``` - `selected: boolean` Should selected elements be included or not. By default, the filter is not applied. See [`aria-selected`](https://www.w3.org/TR/wai-aria-1.2/#aria-selected) for more information ```tsx page.getByRole('button', { selected: true }) // ✅ page.getByRole('button', { selected: false }) // ❌ ``` ##### See also - [List of ARIA roles at MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles) - [List of ARIA roles at w3.org](https://www.w3.org/TR/wai-aria-1.2/#role_definitions) - [testing-library's `ByRole`](https://testing-library.com/docs/queries/byrole/) ## getByAltText - **Type:** `(text: string | RegExp, options?: LocatorOptions) => 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. ```tsx Incredibles 2 Poster page.getByAltText(/incredibles.*? poster/i) // ✅ page.getByAltText('non existing alt text') // ❌ ``` #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByAltText`](https://testing-library.com/docs/queries/byalttext/) ## getByLabelText - **Type:** `(text: string | RegExp, options?: LocatorOptions) => Locator` Creates a locator capable of finding an element that has an assosiated label. The `page.getByLabelText('Username')` locator will find every input in the example bellow: ```html // for/htmlFor relationship between label and form element id // The aria-labelledby attribute with form elements // Wrapper labels // Wrapper labels where the label text is in another child element // aria-label attributes // Take care because this is not a label that users can see on the page, // so the purpose of your input must be obvious to visual users. ``` #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByLabelText`](https://testing-library.com/docs/queries/bylabeltext/) ## getByPlaceholder - **Type:** `(text: string | RegExp, options?: LocatorOptions) => 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`. ```tsx page.getByPlaceholder('Username') // ✅ page.getByPlaceholder('not found') // ❌ ``` ::: warning It is generally better to rely on a label using [`getByLabelText`](#getbylabeltext) than a placeholder. ::: #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByPlaceholderText`](https://testing-library.com/docs/queries/byplaceholdertext/) ## getByText - **Type:** `(text: string | RegExp, options?: LocatorOptions) => Locator` Creates a locator capable of finding an element that contains the specified text. The text will be matched against TextNode's [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue) or input's value if the type is `button` or `reset`. Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace. ```tsx About ℹ️ page.getByText(/about/i) // ✅ page.getByText('about', { exact: true }) // ❌ ``` ::: tip This locator is useful for locating non-interactive elements. If you need to locate an interactive element, like a button or an input, prefer [`getByRole`](#getbyrole). ::: #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByText`](https://testing-library.com/docs/queries/bytext/) ## getByTitle - **Type:** `(text: string | RegExp, options?: LocatorOptions) => 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. ```tsx page.getByTitle('Delete') // ✅ page.getByTitle('Create') // ❌ ``` #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByTitle`](https://testing-library.com/docs/queries/bytitle/) ## getByTestId - **Type:** `(text: string | RegExp) => Locator` Creates a locator capable of finding an element that matches the specified test id attribute. You can configure the attribute name with [`browser.locators.testIdAttribute`](/config/#browser-locators-testidattribute). ```tsx
page.getByTestId('custom-element') // ✅ page.getByTestId('non-existing-element') // ❌ ``` ::: warning It is recommended to use this only after the other locators don't work for your use case. Using `data-testid` attributes does not resemble how your software is used and should be avoided if possible. ::: #### Options - `exact: boolean` Whether the `text` is matched exactly: case-sensetive and whole-string. Disabled by default. This option is ignored if `text` is a regular expression. Note that exact match still trims whitespace. #### See also - [testing-library's `ByTestId`](https://testing-library.com/docs/queries/bytestid/) ## Methods ### click - **Type:** `(options?: UserEventClickOptions) => Promise` Click on an element. You can use the options to set the cursor position. ```ts import { page } from '@vitest/browser/context' await page.getByRole('img', { name: 'Rose' }).click() ``` - [See more at `userEvent.click`](/guide/browser/interactivity-api#userevent-click) ### dblClick - **Type:** `(options?: UserEventClickOptions) => Promise` Triggers a double click event on an element. You can use the options to set the cursor position. ```ts import { page } from '@vitest/browser/context' await page.getByRole('img', { name: 'Rose' }).dblClick() ``` - [See more at `userEvent.dblClick`](/guide/browser/interactivity-api#userevent-dblclick) ### tripleClick - **Type:** `(options?: UserEventClickOptions) => Promise` Triggers a triple click event on an element. Since there is no `tripleclick` in browser api, this method will fire three click events in a row. ```ts import { page } from '@vitest/browser/context' await page.getByRole('img', { name: 'Rose' }).tripleClick() ``` - [See more at `userEvent.tripleClick`](/guide/browser/interactivity-api#userevent-tripleclick) ### clear - **Type:** `() => Promise` Clears the input element content. ```ts import { page } from '@vitest/browser/context' await page.getByRole('textbox', { name: 'Full Name' }).clear() ``` - [See more at `userEvent.clear`](/guide/browser/interactivity-api#userevent-clear) ### hover - **Type:** `(options?: UserEventHoverOptions) => Promise` Moves the cursor position to the selected element. ```ts import { page } from '@vitest/browser/context' await page.getByRole('img', { name: 'Rose' }).hover() ``` - [See more at `userEvent.hover`](/guide/browser/interactivity-api#userevent-hover) ### unhover - **Type:** `(options?: UserEventHoverOptions) => Promise` This works the same as [`locator.hover`](#hover), but moves the cursor to the `document.body` element instead. ```ts import { page } from '@vitest/browser/context' await page.getByRole('img', { name: 'Rose' }).unhover() ``` - [See more at `userEvent.unhover`](/guide/browser/interactivity-api#userevent-unhover) ### fill - **Type:** `(text: string, options?: UserEventFillOptions) => Promise` Sets the value of the current `input`, `textarea` or `conteneditable` element. ```ts import { page } from '@vitest/browser/context' await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean') ``` - [See more at `userEvent.fill`](/guide/browser/interactivity-api#userevent-fill) ### dropTo - **Type:** `(target: Locator, options?: UserEventDragAndDropOptions) => Promise` Drags the current element to the target location. ```ts import { page } from '@vitest/browser/context' const paris = page.getByText('Paris') const france = page.getByText('France') await paris.dropTo(france) ``` - [See more at `userEvent.dragAndDrop`](/guide/browser/interactivity-api#userevent-draganddrop) ### selectOptions - **Type:** `(values: HTMLElement | HTMLElement[] | string | string[], options?: UserEventSelectOptions) => Promise` Choose one or more values from a `