Skip to content
Vitest 2
Main Navigation РуководствоAPIКонфигурацияРежим браузераПродвинутый
3.2.0
2.1.9
1.6.1
0.34.6

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Внешний вид

Sidebar Navigation

Why Browser Mode?

Getting Started

Context API

Interactivity API

Locators

Assertion API

Commands API

Содержание страницы

Локаторы 2.1.0+ ​

Локатор представляет собой элемент или набор элементов. Каждый локатор определяется строкой, называемой селектором. Vitest абстрагирует этот селектор, предоставляя удобные методы, которые генерируют их в фоновом режиме.

API локаторов основан на форке локаторов Playwright под названием Ivya. Однако Vitest предоставляет этот API каждому провайдеру.

getByRole ​

ts
function getByRole(
  role: ARIARole | string,
  options?: LocatorByRoleOptions
): Locator;

Предоставляет способ поиска элемента по его роли ARIA, атрибутам ARIA и доступному имени.

TIP

Если вы запрашиваете только один элемент с помощью getByText('The name'), зачастую лучше использовать getByRole(expectedRole, { name: 'The name' }). Поиск по доступному имени не заменяет другие методы поиска, такие как *ByAltText или *ByTitle. Хотя доступное имя может быть равно этим атрибутам, оно не заменяет функциональность этих атрибутов.

Рассмотрим следующую структуру DOM.

html
<h3>Sign up</h3>
<label>
  Login
  <input type="text" />
</label>
<label>
  Password
  <input type="password" />
</label>
<br />
<button>Submit</button>

Вы можете найти каждый элемент по его неявной роли:

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

Роли сравниваются по точному совпадению строк, без наследования из иерархии ролей ARIA. В результате запрос роли суперкласса, такой как checkbox, не будет включать элементы с ролью подкласса, такой как switch.

Многие семантические элементы HTML по умолчанию имеют роль; например, <input type="radio"> имеет роль "radio". Несемантические элементы в HTML не имеют роли; <div> и <span> без добавленной семантики возвращают null. Атрибут role может предоставлять семантику.

Предоставление ролей через атрибуты role или aria-* встроенным элементам, которые уже имеют неявную роль, крайне не рекомендуется согласно рекомендациям ARIA.

Опции ​
  • exact: boolean

    Совпадает ли name точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если name является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

    tsx
    <button>Hello World</button>;
    
    page.getByRole('button', { name: 'hello world' }); // ✅ Да
    page.getByRole('button', { name: 'hello world', exact: true }); // ❌ Нет
    page.getByRole('button', { name: 'Hello World', exact: true }); // ✅ Да
  • checked: boolean

    Включать ли отмеченные элементы (установленные с помощью aria-checked или <input type="checkbox"/>). По умолчанию фильтр не применяется.

    См. aria-checked для получения дополнительной информации.

    tsx
    <>
      <button role="checkbox" aria-checked="true" />
      <input type="checkbox" checked />
    </>;
    
    page.getByRole('checkbox', { checked: true }); // ✅ Да
    page.getByRole('checkbox', { checked: false }); // ❌ Нет
  • disabled: boolean

    Включать ли отключенные элементы. По умолчанию фильтр не применяется. Обратите внимание, что в отличие от других атрибутов, состояние disabled наследуется.

    См. aria-disabled для получения дополнительной информации.

    tsx
    <input type="text" disabled />;
    
    page.getByRole('textbox', { disabled: true }); // ✅ Да
    page.getByRole('textbox', { disabled: false }); // ❌ Нет
  • expanded: boolean

    Включать ли развернутые элементы. По умолчанию фильтр не применяется.

    См. aria-expanded для получения дополнительной информации.

    tsx
    <a aria-expanded="true" href="example.com">
      Link
    </a>;
    
    page.getByRole('link', { expanded: true }); // ✅ Да
    page.getByRole('link', { expanded: false }); // ❌ Нет
  • includeHidden: boolean

    Следует ли запрашивать элементы, которые обычно исключаются из дерева доступности. По умолчанию по селектору роли сопоставляются только нескрытые элементы.

    Обратите внимание, что роли none и presentation всегда включаются.

    tsx
    <button style="display: none" />;
    
    page.getByRole('button'); // ❌ Нет
    page.getByRole('button', { includeHidden: false }); // ❌ Нет
    page.getByRole('button', { includeHidden: true }); // ✅ Да
  • level: number

    Числовой атрибут, который обычно присутствует для ролей heading, listitem, row, treeitem со значениями по умолчанию для элементов <h1>-<h6>. По умолчанию фильтр не применяется.

    См. aria-level для получения дополнительной информации.

    tsx
    <>
      <h1>Heading Level One</h1>
      <div role="heading" aria-level="1">
        Second Heading Level One
      </div>
    </>;
    
    page.getByRole('heading', { level: 1 }); // ✅ Да
    page.getByRole('heading', { level: 2 }); // ❌ Нет
  • name: string | RegExp

    Доступное имя. По умолчанию сопоставление нечувствительно к регистру и ищет подстроку. Используйте опцию exact для управления этим поведением.

    tsx
    <button>Click Me!</button>;
    
    page.getByRole('button', { name: 'Click Me!' }); // ✅ Да
    page.getByRole('button', { name: 'click me!' }); // ✅ Да
    page.getByRole('button', { name: 'Click Me?' }); // ❌ Нет
  • pressed: boolean

    Включать ли нажатые элементы. По умолчанию фильтр не применяется.

    См. aria-pressed для получения дополнительной информации.

    tsx
    <button aria-pressed="true">👍</button>;
    
    page.getByRole('button', { pressed: true }); // ✅ Да
    page.getByRole('button', { pressed: false }); // ❌ Нет
  • selected: boolean

    Включать ли выбранные элементы. По умолчанию фильтр не применяется.

    См. aria-selected для получения дополнительной информации.

    tsx
    <button role="tab" aria-selected="true">
      Vue
    </button>;
    
    page.getByRole('button', { selected: true }); // ✅ Да
    page.getByRole('button', { selected: false }); // ❌ Нет
См. также ​
  • Список ролей ARIA на MDN
  • Список ролей ARIA на w3.org
  • ByRole в testing-library

getByAltText ​

ts
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;

Создает локатор, способный найти элемент с атрибутом alt, который соответствует тексту. В отличие от реализации в testing-library, Vitest будет сопоставлять любой элемент, имеющий соответствующий атрибут alt.

tsx
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;

page.getByAltText(/incredibles.*? poster/i); // ✅ Да
page.getByAltText('non existing alt text'); // ❌ Нет

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByAltText в testing-library

getByLabelText ​

ts
function getByLabelText(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

Создает локатор, способный найти элемент, имеющий связанную метку.

Локатор page.getByLabelText('Username') найдет каждый ввод в примере ниже:

html
<!-- for/htmlFor relationship between label and form element id -->
<label for="username-input">Username</label>
<input id="username-input" />

<!-- The aria-labelledby attribute with form elements -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />

<!-- Wrapper labels -->
<label>Username <input /></label>

<!-- Wrapper labels where the label text is in another child element -->
<label>
  <span>Username</span>
  <input />
</label>

<!-- 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. -->
<input aria-label="Username" />

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByLabelText в testing-library

getByPlaceholder ​

ts
function getByPlaceholder(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

Создает локатор, способный найти элемент, имеющий указанный атрибут placeholder. Vitest будет сопоставлять любой элемент, имеющий соответствующий атрибут placeholder, а не только input.

tsx
<input placeholder="Username" />;

page.getByPlaceholder('Username'); // ✅ Да
page.getByPlaceholder('not found'); // ❌ Нет

WARNING

Как правило, лучше полагаться на метку с помощью getByLabelText, чем на заполнитель.

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByPlaceholderText в testing-library

getByText ​

ts
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;

Создает локатор, способный найти элемент, содержащий указанный текст. Текст будет сопоставляться со значением nodeValue текстового узла или значением ввода, если тип — button или reset. Сопоставление по тексту всегда нормализует пробелы, даже при точном совпадении. Например, оно превращает несколько пробелов в один, превращает разрывы строк в пробелы и игнорирует начальные и конечные пробелы.

tsx
<a href="/about">About ℹ️</a>;

page.getByText(/about/i); // ✅ Да
page.getByText('about', { exact: true }); // ❌ Нет

TIP

Этот локатор полезен для поиска неинтерактивных элементов. Если вам нужно найти интерактивный элемент, такой как кнопка или ввод, предпочтительнее использовать getByRole.

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByText в testing-library

getByTitle ​

ts
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;

Создает локатор, способный найти элемент, имеющий указанный атрибут title. В отличие от getByTitle из testing-library, Vitest не может найти элементы title внутри SVG.

tsx
<span title="Delete" id="2"></span>;

page.getByTitle('Delete'); // ✅ Да
page.getByTitle('Create'); // ❌ Нет

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByTitle в testing-library

getByTestId ​

ts
function getByTestId(text: string | RegExp): Locator;

Создает локатор, способный найти элемент, соответствующий указанному атрибуту тестового идентификатора. Вы можете настроить имя атрибута с помощью browser.locators.testIdAttribute.

tsx
<div data-testid="custom-element" />;

page.getByTestId('custom-element'); // ✅ Да
page.getByTestId('non-existing-element'); // ❌ Нет

WARNING

Рекомендуется использовать это только после того, как другие локаторы не подходят для вашего случая использования. Использование атрибутов data-testid не отражает то, как используется ваше программное обеспечение, и по возможности следует избегать этого.

Опции ​

  • exact: boolean

    Совпадает ли text точно: с учетом регистра и всей строки. По умолчанию не включено. Эта опция игнорируется, если text является регулярным выражением. Обратите внимание, что точное совпадение все равно обрезает пробелы.

См. также ​

  • ByTestId в testing-library

Методы ​

Все методы асинхронны и должны быть ожидаемы. Начиная с Vitest 2.2, тесты будут завершаться с ошибкой, если метод не ожидается.

click ​

ts
function click(options?: UserEventClickOptions): Promise<void>;

Нажимает на элемент. Вы можете использовать опции для установки положения курсора.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).click();
  • Подробнее см. в userEvent.click

dblClick ​

ts
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;

Генерирует событие двойного щелчка на элементе. Вы можете использовать опции для установки положения курсора.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).dblClick();
  • Подробнее см. в userEvent.dblClick

tripleClick ​

ts
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;

Вызывает событие тройного щелчка на элементе. Поскольку в API браузера нет tripleclick, этот метод вызовет три события щелчка подряд.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).tripleClick();
  • Подробнее см. в userEvent.tripleClick

clear ​

ts
function clear(): Promise<void>;

Очищает содержимое элемента ввода.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('textbox', { name: 'Full Name' }).clear();
  • Подробнее см. в userEvent.clear

hover ​

ts
function hover(options?: UserEventHoverOptions): Promise<void>;

Перемещает положение курсора к выбранному элементу.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).hover();
  • Подробнее см. в userEvent.hover

unhover ​

ts
function unhover(options?: UserEventHoverOptions): Promise<void>;

Работает так же, как locator.hover, но перемещает курсор к элементу document.body.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).unhover();
  • Подробнее см. в userEvent.unhover

fill ​

ts
function fill(text: string, options?: UserEventFillOptions): Promise<void>;

Устанавливает значение текущего элемента input, textarea или conteneditable.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
  • Подробнее см. в userEvent.fill

dropTo ​

ts
function dropTo(
  target: Locator,
  options?: UserEventDragAndDropOptions
): Promise<void>;

Перемещает текущий элемент методом перетаскивания в целевое местоположение.

ts
import { page } from '@vitest/browser/context';

const paris = page.getByText('Paris');
const france = page.getByText('France');

await paris.dropTo(france);
  • Подробнее см. в userEvent.dragAndDrop

selectOptions ​

ts
function selectOptions(
  values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
  options?: UserEventSelectOptions
): Promise<void>;

Выбирает одно или несколько значений из элемента <select>.

ts
import { page } from '@vitest/browser/context';

const languages = page.getByRole('select', { name: 'Languages' });

await languages.selectOptions('EN');
await languages.selectOptions(['ES', 'FR']);
await languages.selectOptions([
  languages.getByRole('option', { name: 'Spanish' }),
  languages.getByRole('option', { name: 'French' }),
]);
  • Подробнее см. в userEvent.selectOptions

screenshot ​

ts
function screenshot(
  options: LocatorScreenshotOptions & { base64: true }
): Promise<{
  path: string;
  base64: string;
}>;
function screenshot(
  options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;

Создает скриншот элемента, соответствующего селектору локатора.

Вы можете указать место сохранения скриншота с помощью опции path, которая является относительной к текущему тестовому файлу. Если опция path не установлена, Vitest по умолчанию будет использовать browser.screenshotDirectory (по умолчанию __screenshot__), а также имена файла и теста для определения пути к файлу скриншота.

Если вам также нужно содержимое скриншота, вы можете указать base64: true, чтобы вернуть его вместе с путем к файлу, где сохранен скриншот.

ts
import { page } from '@vitest/browser/context';

const button = page.getByRole('button', { name: 'Click Me!' });

const path = await button.screenshot();

const { path, base64 } = await button.screenshot({
  path: './button-click-me.png',
  base64: true, // also return base64 string
});
// path - полный путь к скриншоту
// base64 - строка скриншота в кодировке base64

query ​

ts
function query(): Element | null;

Данный метод возвращает один элемент, соответствующий селектору локатора, или null, если элемент не найден.

Если селектору соответствует несколько элементов, этот метод вызывает ошибку. Используйте .elements(), когда вам нужны все соответствующие элементы DOM, или .all(), если вам нужен массив локаторов, соответствующих селектору.

Рассмотрим следующую структуру DOM:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

Эти локаторы не вызовут ошибку:

ts
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement

Эти локаторы вызовут ошибку:

ts
// returns multiple elements
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌

element ​

ts
function element(): Element;

Этот метод возвращает один элемент, соответствующий селектору локатора.

Если ни один элемент не соответствует селектору, выдается ошибка. Рассмотрите возможность использования .query(), когда вам просто нужно проверить, существует ли элемент.

Если несколько элементов соответствуют селектору, выдается ошибка. Используйте .elements(), когда вам нужны все соответствующие элементы DOM, или .all(), если вам нужен массив локаторов, соответствующих селектору.

TIP

Этот метод может быть полезен, если вам нужно передать его во внешнюю библиотеку. Он вызывается автоматически, когда локатор используется с expect.element при каждой повторной попытке утверждения:

ts
await expect.element(page.getByRole('button')).toBeDisabled();

Рассмотрим следующую структуру DOM:

html
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>

Эти локаторы не вызовут ошибку:

ts
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅

Эти локаторы вызовут ошибку:

ts
// returns multiple elements
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌

// returns no elements
page.getByText('Hello USA').element(); // ❌

elements ​

ts
function elements(): Element[];

Этот метод возвращает массив элементов, соответствующих селектору локатора.

Данный метод никогда не вызывает ошибку. Если нет элементов, соответствующих селектору, этот метод вернет пустой массив.

Рассмотрим следующую структуру DOM:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

Эти локаторы всегда будут успешными:

ts
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').element(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []

all ​

ts
function all(): Locator[];

Этот метод возвращает массив новых локаторов, соответствующих селектору.

Внутри этот метод вызывает .elements и оборачивает каждый элемент с помощью page.elementLocator.

  • См. locator.elements()
Pager
Предыдущая страницаInteractivity API
Следующая страницаAssertion API

Выпущено на условиях лицензии MIT.

Авторские права (c) 2021-Present Vitest Team

https://v2.vitest.dev/guide/browser/locators

Выпущено на условиях лицензии MIT.

Авторские права (c) 2021-Present Vitest Team