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

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

Interactivity API ​

Vitest реализует подмножество API @testing-library/user-event, используя Chrome DevTools Protocol или webdriver вместо имитации событий. Это обеспечивает более надежное и предсказуемое поведение браузера, соответствующее реальному взаимодействию пользователя со страницей.

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

await userEvent.click(document.querySelector('.button'));

Почти каждый метод userEvent наследует опции своего провайдера. Чтобы получить доступ ко всем доступным параметрам в вашей IDE, добавьте типы webdriver или playwright (в зависимости от используемого провайдера) в ваш файл настройки или файл конфигурации (в зависимости от того, что указано в included в вашем tsconfig.json):

ts
/// <reference types="@vitest/browser/providers/playwright" />
ts
/// <reference types="@vitest/browser/providers/webdriverio" />

userEvent.setup ​

ts
function setup(): UserEvent;

Создает новый экземпляр пользовательского события. Это полезно, если вам необходимо сохранить состояние клавиатуры для корректной обработки нажатий и отпусканий клавиш.

WARNING

В отличие от @testing-library/user-event, экземпляр userEvent по умолчанию из @vitest/browser/context создается один раз, а не при каждом вызове его методов! Вы можете увидеть разницу в его работе в этом фрагменте:

ts
import { userEvent as vitestUserEvent } from '@vitest/browser/context';
import { userEvent as originalUserEvent } from '@testing-library/user-event';

await vitestUserEvent.keyboard('{Shift}'); // нажать Shift без отпускания
await vitestUserEvent.keyboard('{/Shift}'); // отпустить Shift

await originalUserEvent.keyboard('{Shift}'); // нажать Shift без отпускания
await originalUserEvent.keyboard('{/Shift}'); // НЕ отпустил Shift, потому что состояние было иным

Такое поведение более полезно, поскольку мы не эмулируем клавиатуру, а фактически нажимаем Shift. Сохранение исходного поведения привело бы к неожиданным проблемам при вводе текста в поле.

userEvent.click ​

ts
function click(
  element: Element | Locator,
  options?: UserEventClickOptions
): Promise<void>;

Выполняет клик по элементу. Наследует параметры провайдера. Пожалуйста, обратитесь к документации вашего провайдера для подробного объяснения того, как работает этот метод.

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

test('clicks on an element', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.click(logo);
  // или вы можете обратиться к нему напрямую через локатор
  await logo.click();
});

Ссылки:

  • Playwright locator.click API
  • WebdriverIO element.click API
  • testing-library click API

userEvent.dblClick ​

ts
function dblClick(
  element: Element | Locator,
  options?: UserEventDoubleClickOptions
): Promise<void>;

Вызывает событие двойного клика на элементе.

Пожалуйста, обратитесь к документации вашего провайдера для подробного объяснения того, как работает этот метод.

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

test('triggers a double click on an element', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.dblClick(logo);
  // или вы можете обратиться к нему напрямую через локатор
  await logo.dblClick();
});

Ссылки:

  • Playwright locator.dblclick API
  • WebdriverIO element.doubleClick API
  • testing-library dblClick API

userEvent.tripleClick ​

ts
function tripleClick(
  element: Element | Locator,
  options?: UserEventTripleClickOptions
): Promise<void>;

Вызывает событие тройного клика на элементе. Поскольку в браузерном API нет tripleclick, этот метод будет вызывать три события клика подряд. Для фильтрации события необходимо проверить детали события клика: evt.detail === 3.

Пожалуйста, обратитесь к документации вашего провайдера для подробного объяснения того, как работает этот метод.

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

test('triggers a triple click on an element', async () => {
  const logo = page.getByRole('img', { name: /logo/ });
  let tripleClickFired = false;
  logo.addEventListener('click', evt => {
    if (evt.detail === 3) {
      tripleClickFired = true;
    }
  });

  await userEvent.tripleClick(logo);
  // или вы можете обратиться к нему напрямую через локатор
  await logo.tripleClick();

  expect(tripleClickFired).toBe(true);
});

Ссылки:

  • Playwright locator.click API: реализовано через click с clickCount: 3.
  • WebdriverIO browser.action API: реализовано через API действий с move плюс три события down + up + pause подряд.
  • testing-library tripleClick API

userEvent.fill ​

ts
function fill(element: Element | Locator, text: string): Promise<void>;

Устанавливает значение для поля input/textarea/contenteditable. Этот метод удалит любой существующий текст в поле ввода перед установкой нового значения.

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

test('update input', async () => {
  const input = page.getByRole('input');

  await userEvent.fill(input, 'foo'); // input.value == foo
  await userEvent.fill(input, '{{a[['); // input.value == {{a[[
  await userEvent.fill(input, '{Shift}'); // input.value == {Shift}

  // или вы можете обратиться к нему напрямую через локатор
  await input.fill('foo'); // input.value == foo
});

Этот метод фокусирует элемент, заполняет его значение и вызывает событие input после заполнения. Вы можете использовать пустую строку для очистки поля.

TIP

Этот API быстрее, чем использование userEvent.type или userEvent.keyboard, но он не поддерживает синтаксис keyboard user-event (например, {Shift}{selectall}).

Мы рекомендуем использовать этот API вместо userEvent.type в ситуациях, когда вам не нужно вводить специальные символы или требуется гранулярный контроль над событиями нажатия клавиш.

Ссылки:

  • Playwright locator.fill API
  • WebdriverIO element.setValue API
  • testing-library type API

userEvent.keyboard ​

ts
function keyboard(text: string): Promise<void>;

userEvent.keyboard позволяет вызывать нажатия клавиш. Если какой-либо элемент ввода имеет фокус, символы будут введены в него. В противном случае события клавиатуры будут вызваны на текущем сфокусированном элементе (document.body, если нет сфокусированных элементов).

Этот API поддерживает синтаксис keyboard user-event.

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

test('trigger keystrokes', async () => {
  await userEvent.keyboard('foo'); // эквивалентно: f, o, o
  await userEvent.keyboard('{{a[['); // эквивалентно: {, a, [
  await userEvent.keyboard('{Shift}{f}{o}{o}'); // эквивалентно: Shift, f, o, o
  await userEvent.keyboard('{a>5}'); // нажать a без отпускания и сгенерировать 5 событий keydown
  await userEvent.keyboard('{a>5/}'); // нажать a с 5 событиями keydown, а затем отпустить
});

Ссылки:

  • Playwright Keyboard API
  • WebdriverIO action('key') API
  • testing-library type API

userEvent.tab ​

ts
function tab(options?: UserEventTabOptions): Promise<void>;

Отправляет событие клавиши Tab. Это сокращение для userEvent.keyboard('{tab}').

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

test('tab works', async () => {
  const [input1, input2] = page.getByRole('input').elements();

  expect(input1).toHaveFocus();

  await userEvent.tab();

  expect(input2).toHaveFocus();

  await userEvent.tab({ shift: true });

  expect(input1).toHaveFocus();
});

Ссылки:

  • Playwright Keyboard API
  • WebdriverIO action('key') API
  • testing-library tab API

userEvent.type ​

ts
function type(
  element: Element | Locator,
  text: string,
  options?: UserEventTypeOptions
): Promise<void>;

WARNING

Если вы не полагаетесь на специальные символы (например, {shift} или {selectall}), рекомендуется использовать userEvent.fill вместо этого для лучшей производительности.

Метод type реализует утилиту type из @testing-library/user-event (type), построенную на основе API keyboard.

Эта функция позволяет вводить символы в элемент input/textarea/contenteditable. Она поддерживает синтаксис keyboard user-event.

Если вам просто нужно нажимать символы без ввода, используйте API userEvent.keyboard.

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

test('update input', async () => {
  const input = page.getByRole('input');

  await userEvent.type(input, 'foo'); // input.value == foo
  await userEvent.type(input, '{{a[['); // input.value == foo{a[
  await userEvent.type(input, '{Shift}'); // input.value == foo{a[
});

INFO

Vitest не предоставляет метод .type для локатора, подобный input.type, потому что он существует только для совместимости с библиотекой userEvent. Рассмотрите возможность использования .fill вместо него, так как он быстрее.

Ссылки:

  • Playwright locator.press API
  • WebdriverIO action('key') API
  • testing-library type API

userEvent.clear ​

ts
function clear(
  element: Element | Locator,
  options?: UserEventClearOptions
): Promise<void>;

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

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

test('clears input', async () => {
  const input = page.getByRole('input');

  await userEvent.fill(input, 'foo');
  expect(input).toHaveValue('foo');

  await userEvent.clear(input);
  // или вы можете обратиться к нему напрямую через локатор
  await input.clear();

  expect(input).toHaveValue('');
});

Ссылки:

  • Playwright locator.clear API
  • WebdriverIO element.clearValue API
  • testing-library clear API

userEvent.selectOptions ​

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

userEvent.selectOptions позволяет выбрать значение в элементе <select>.

WARNING

Если элемент select не имеет атрибута multiple, Vitest выберет только первый элемент из переданного массива.

В отличие от @testing-library, Vitest в настоящее время не поддерживает listbox, но мы планируем добавить его поддержку в будущем.

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

test('clears input', async () => {
  const select = page.getByRole('select');

  await userEvent.selectOptions(select, 'Option 1');
  // или вы можете обратиться к нему напрямую через локатор
  await select.selectOptions('Option 1');

  expect(select).toHaveValue('option-1');

  await userEvent.selectOptions(select, 'option-1');
  expect(select).toHaveValue('option-1');

  await userEvent.selectOptions(select, [
    page.getByRole('option', { name: 'Option 1' }),
    page.getByRole('option', { name: 'Option 2' }),
  ]);
  expect(select).toHaveValue(['option-1', 'option-2']);
});

WARNING

Провайдер webdriverio не поддерживает выбор нескольких элементов, поскольку он не предоставляет API для этого.

Ссылки:

  • Playwright locator.selectOption API
  • WebdriverIO element.selectByIndex API
  • testing-library selectOptions API

userEvent.hover ​

ts
function hover(
  element: Element | Locator,
  options?: UserEventHoverOptions
): Promise<void>;

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

WARNING

Если вы используете провайдер webdriverio, курсор по умолчанию перемещается в центр элемента.

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

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

test('hovers logo element', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.hover(logo);
  // или вы можете обратиться к нему напрямую через локатор
  await logo.hover();
});

Ссылки:

  • Playwright locator.hover API
  • WebdriverIO element.moveTo API
  • testing-library hover API

userEvent.unhover ​

ts
function unhover(
  element: Element | Locator,
  options?: UserEventHoverOptions
): Promise<void>;

Этот метод работает так же, как userEvent.hover, но вместо этого перемещает курсор к элементу document.body.

WARNING

По умолчанию положение курсора находится в любой видимой точке (в провайдере playwright) или в центре (в провайдере webdriverio) элемента body. Поэтому, если текущий наведенный элемент уже находится в том же положении, этот метод не окажет никакого эффекта.

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

test('unhover logo element', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.unhover(logo);
  // или вы можете обратиться к нему напрямую через локатор
  await logo.unhover();
});

Ссылки:

  • Playwright locator.hover API
  • WebdriverIO element.moveTo API
  • testing-library hover API

userEvent.upload ​

ts
function upload(
  element: Element | Locator,
  files: string[] | string | File[] | File,
  options?: UserEventUploadOptions
): Promise<void>;

Изменяет файловый элемент ввода, устанавливая для него указанные файлы.

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

test('can upload a file', async () => {
  const input = page.getByRole('button', { name: /Upload files/ });

  const file = new File(['file'], 'file.png', { type: 'image/png' });

  await userEvent.upload(input, file);
  // или вы можете обратиться к нему напрямую через локатор
  await input.upload(file);

  // вы также можете использовать пути к файлам относительно корня проекта
  await userEvent.upload(input, './fixtures/file.png');
});

WARNING

Провайдер webdriverio поддерживает эту команду только в браузерах chrome и edge. Он также в настоящее время поддерживает только строковые значения.

Ссылки:

  • Playwright locator.setInputFiles API
  • WebdriverIO browser.uploadFile API
  • testing-library upload API

userEvent.dragAndDrop ​

ts
function dragAndDrop(
  source: Element | Locator,
  target: Element | Locator,
  options?: UserEventDragAndDropOptions
): Promise<void>;

Перетаскивает исходный элемент на целевой элемент. Убедитесь, что исходный элемент имеет атрибут draggable со значением true.

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

test('drag and drop works', async () => {
  const source = page.getByRole('img', { name: /logo/ });
  const target = page.getByTestId('logo-target');

  await userEvent.dragAndDrop(source, target);
  // или вы можете обратиться к нему напрямую через локатор
  await source.dropTo(target);

  await expect.element(target).toHaveTextContent('Logo is processed');
});

WARNING

Этот API не поддерживается провайдером preview по умолчанию.

Ссылки:

  • Playwright frame.dragAndDrop API
  • WebdriverIO element.dragAndDrop API

userEvent.copy ​

ts
function copy(): Promise<void>;

Копирует выделенный текст в буфер обмена.

js
import { page, userEvent } from '@vitest/browser/context';

test('copy and paste', async () => {
  // ввести в 'source'
  await userEvent.click(page.getByPlaceholder('source'));
  await userEvent.keyboard('hello');

  // выделить и скопировать содержимое 'source'
  await userEvent.dblClick(page.getByPlaceholder('source'));
  await userEvent.copy();

  // вставить в 'target'
  await userEvent.click(page.getByPlaceholder('target'));
  await userEvent.paste();

  await expect
    .element(page.getByPlaceholder('source'))
    .toHaveTextContent('hello');
  await expect
    .element(page.getByPlaceholder('target'))
    .toHaveTextContent('hello');
});

Ссылки:

  • testing-library copy API

userEvent.cut ​

ts
function cut(): Promise<void>;

Вырезает выделенный текст в буфер обмена.

js
import { page, userEvent } from '@vitest/browser/context';

test('copy and paste', async () => {
  // ввести в 'source'
  await userEvent.click(page.getByPlaceholder('source'));
  await userEvent.keyboard('hello');

  // выделить и вырезать содержимое 'source'
  await userEvent.dblClick(page.getByPlaceholder('source'));
  await userEvent.cut();

  // вставить в 'target'
  await userEvent.click(page.getByPlaceholder('target'));
  await userEvent.paste();

  await expect.element(page.getByPlaceholder('source')).toHaveTextContent('');
  await expect
    .element(page.getByPlaceholder('target'))
    .toHaveTextContent('hello');
});

Ссылки:

  • testing-library cut API

userEvent.paste ​

ts
function paste(): Promise<void>;

Вставляет текст из буфера обмена. Примеры использования приведены в разделах userEvent.copy и userEvent.cut.

Ссылки:

  • testing-library paste API
Pager
Предыдущая страницаContext API
Следующая страницаЛокаторы

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

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

https://vitest.dev/guide/browser/interactivity-api

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

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