Skip to content
Vitest 3
Main Navigation Руководство & APIКонфигурацияРежим браузераРасширенный 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

Введение

Почему режим браузера

Режим браузера

Конфигурация

Справочник по настройке браузера

Настройка Playwright

Настройка WebdriverIO

API

Context API

Interactivity API

Локаторы

Assertion API

Команды

Руководство

Несколько конфигураций

Настройка Vitest

Справочник по API тестирования

Расширенный API

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

Локаторы ​

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

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

TIP

Эта страница описывает использование API. Чтобы лучше понять локаторы и их применение, ознакомьтесь с документацией Playwright "Locators".

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 — связь между меткой и идентификатором элемента формы
<label for="username-input">Username</label>
<input id="username-input" />

// Атрибут aria-labelledby, используемый с элементами формы
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />

// Метки-обертки
<label>Username <input /></label>

// Метки-обертки, где текст метки находится в другом дочернем элементе
<label>
  <span>Username</span>
  <input />
</label>

// Атрибуты aria-label // Будьте внимательны, так как это не метка, видимая
пользователям на странице, поэтому назначение вашего поля ввода должно быть
очевидным для пользователей с визуальным восприятием.
<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

nth ​

ts
function nth(index: number): Locator;

Этот метод возвращает новый локатор, который соответствует только определенному индексу в результате запроса нескольких элементов. Индексация начинается с нуля, nth(0) выбирает первый элемент. В отличие от elements()[n], локатор nth будет повторять попытки до тех пор, пока элемент не появится.

html
<div aria-label="one"><input /><input /><input /></div>
<div aria-label="two"><input /></div>
tsx
page.getByRole('textbox').nth(0); // ✅
page.getByRole('textbox').nth(4); // ❌

TIP

Прежде чем прибегать к nth, может быть полезно использовать цепочки локаторов для сужения поиска. Иногда невозможно отличить элементы иначе, кроме как по их положению; хотя это может привести к нестабильным тестам, это лучше, чем ничего.

tsx
page.getByLabel('two').getByRole('input'); // ✅ лучшая альтернатива page.getByRole('textbox').nth(3)
page.getByLabel('one').getByRole('input'); // ❌ слишком неоднозначно
page.getByLabel('one').getByRole('input').nth(1); // ✅ прагматичный компромисс

first ​

ts
function first(): Locator;

Этот метод возвращает новый локатор, который соответствует только первому индексу результата запроса нескольких элементов. Это синтаксический сахар для nth(0).

html
<input /> <input /> <input />
tsx
page.getByRole('textbox').first(); // ✅

last ​

ts
function last(): Locator;

Этот метод возвращает новый локатор, который соответствует только последнему индексу результата запроса нескольких элементов. Это синтаксический сахар для nth(-1).

html
<input /> <input /> <input />
tsx
page.getByRole('textbox').last(); // ✅

and ​

ts
function and(locator: Locator): Locator;

Этот метод создает новый локатор, который соответствует как родительскому, так и предоставленному локатору. Следующий пример находит кнопку с определенным заголовком:

ts
page.getByRole('button').and(page.getByTitle('Subscribe'));

or ​

ts
function or(locator: Locator): Locator;

Этот метод создает новый локатор, который соответствует одному или обоим локаторам.

WARNING

Обратите внимание, что если локатор соответствует нескольким элементам, вызов другого метода может привести к ошибке, если он ожидает только один элемент:

tsx
<>
  <button>Click me</button>
  <a href="https://vitest.dev">Error happened!</a>
</>;

page.getByRole('button').or(page.getByRole('link')).click(); // ❌ соответствует нескольким элементам

filter ​

ts
function filter(options: LocatorOptions): Locator;

Этот метод сужает область действия локатора в соответствии с заданными опциями, например, фильтрацией по тексту. Его можно объединять в цепочку для применения нескольких фильтров.

has ​

  • Тип: Locator

Эта опция сужает селектор, чтобы он соответствовал элементам, которые содержат другие элементы, соответствующие указанному локатору. Например, с этим HTML:

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Мы можем сузить локатор, чтобы найти только article с текстом Vitest внутри:

ts
page.getByRole('article').filter({ has: page.getByText('Vitest') }); // ✅

WARNING

Указанный локатор (page.getByText('Vitest') в примере) должен быть относительным к родительскому локатору (page.getByRole('article') в примере). Поиск будет выполняться, начиная с родительского локатора, а не с корня документа.

Это означает, что вы не можете передать локатор, который запрашивает элемент вне родительского локатора:

ts
page.getByText('Vitest').filter({ has: page.getByRole('article') }); // ❌

Этот пример завершится ошибкой, потому что элемент article находится за пределами элемента с текстом Vitest.

TIP

Этот метод можно объединять в цепочку для дальнейшего уточнения поиска элемента:

ts
page
  .getByRole('article')
  .filter({ has: page.getByRole('button', { name: 'delete row' }) })
  .filter({ has: page.getByText('Vitest') });

hasNot ​

  • Тип: Locator

Эта опция сужает селектор, чтобы он соответствовал элементам, которые не содержат другие элементы, соответствующие указанному локатору. Например, с этим HTML:

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Мы можем сузить локатор, чтобы найти только article, который не содержит Rolldown внутри.

ts
page.getByRole('article').filter({ hasNot: page.getByText('Rolldown') }); // ✅
page.getByRole('article').filter({ hasNot: page.getByText('Vitest') }); // ❌

WARNING

Обратите внимание, что указанный локатор ищется относительно родителя, а не корня документа, аналогично опции has.

hasText ​

  • Тип: string | RegExp

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

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Оба локатора найдут один и тот же элемент, потому что поиск выполняется без учета регистра:

ts
page.getByRole('article').filter({ hasText: 'Vitest' }); // ✅
page.getByRole('article').filter({ hasText: 'Vite' }); // ✅

hasNotText ​

  • Тип: string | RegExp

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

Методы ​

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

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(options?: UserEventClearOptions): 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> или contenteditable.

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 & { save: false }
): Promise<string>;
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, // также вернуть строку base64
});
// path - полный путь к скриншоту
// base64 - строка скриншота, закодированная в формате base64

ВНИМАНИЕ 3.2.0+

Обратите внимание, что screenshot всегда будет возвращать строку base64, если save установлено в значение false. В этом случае path также игнорируется.

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
// возвращает несколько элементов
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
// возвращает несколько элементов
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌

// не возвращает элементов
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()

Свойства ​

selector ​

selector — это строка, которая будет использоваться провайдером браузера для поиска элемента. Playwright будет использовать синтаксис локаторов Playwright, в то время как preview и webdriverio будут использовать CSS.

DANGER

Эту строку не следует использовать в вашем тестовом коде. Строка selector должна использоваться исключительно при работе с Commands API:

ts
import type { BrowserCommand } from 'vitest/node';

const test: BrowserCommand<string> = function test(context, selector) {
  // playwright
  await context.iframe.locator(selector).click();
  // webdriverio
  await context.browser.$(selector).click();
};
ts
import { test } from 'vitest';
import { commands, page } from '@vitest/browser/context';

test('works correctly', async () => {
  await commands.test(page.getByText('Hello').selector); // ✅
  // vitest автоматически преобразует его в строку
  await commands.test(page.getByText('Hello')); // ✅
});

Пользовательские локаторы 3.2.0+ продвинутый ​

Вы можете расширить встроенный API локаторов, определив объект, содержащий фабрики локаторов. Эти методы будут доступны как методы объекта page и любого созданного локатора.

Эти локаторы могут быть полезны, если встроенных локаторов недостаточно. Например, когда вы используете пользовательский фреймворк для своего пользовательского интерфейса.

Фабрика локаторов должна возвращать строку селектора или сам объект локатора.

TIP

Синтаксис селектора идентичен синтаксису локаторов Playwright. Пожалуйста, прочитайте их руководство, чтобы лучше понять принципы работы с ними.

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

locators.extend({
  getByArticleTitle(title) {
    return `[data-title="${title}"]`;
  },
  getByArticleCommentsCount(count) {
    return `.comments :text("${count} comments")`;
  },
  async previewComments() {
    // у вас есть доступ к текущему локатору через ключевое слово "this"
    // будьте осторожны: если метод был вызван на объекте page, this будет указывать на page,
    // а не на локатор!
    if (this !== page) {
      await this.click();
    }
    // ...
  },
});

// если вы используете TypeScript, вы можете расширить интерфейс LocatorSelectors
// для обеспечения автодополнения в методах locators.extend, page.* и locator.*
declare module '@vitest/browser/context' {
  interface LocatorSelectors {
    // если пользовательский метод возвращает строку, она будет автоматически преобразована в локатор
    // если он возвращает что-либо иное, то будет возвращено как есть
    getByArticleTitle(title: string): Locator;
    getByArticleCommentsCount(count: number): Locator;

    // Vitest вернет промис и не будет пытаться преобразовать его в локатор
    previewComments(this: Locator): Promise<void>;
  }
}

Если метод вызывается на глобальном объекте page, селектор будет применен ко всей странице. В примере ниже getByArticleTitle найдет все элементы с атрибутом data-title, значение которого равно title. Однако, если метод вызывается на локаторе, его область действия будет ограничена этим локатором.

html
<article data-title="Hello, World!">
  Hello, World!
  <button id="comments">2 comments</button>
</article>

<article data-title="Hello, Vitest!">
  Hello, Vitest!
  <button id="comments">0 comments</button>
</article>
ts
const articles = page.getByRole('article');
const worldArticle = page.getByArticleTitle('Hello, World!'); // ✅
const commentsElement = worldArticle.getByArticleCommentsCount(2); // ✅
const wrongCommentsElement = worldArticle.getByArticleCommentsCount(0); // ❌
const wrongElement = page.getByArticleTitle('No Article!'); // ❌

await commentsElement.previewComments(); // ✅
await wrongCommentsElement.previewComments(); // ❌
Pager
Предыдущая страницаInteractivity API
Следующая страницаAssertion API

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

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

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

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

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