Skip to content
Vitest 3
Main Navigation Guía & APIConfiguraciónModo NavegadorAPI avanzada
3.2.0
2.1.9
1.6.1
0.34.6

Español

English
简体中文
繁體中文
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Español

English
简体中文
繁體中文
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Apariencia

Sidebar Navigation

Introducción

Por qué el modo navegador

Modo Navegador

Configuración

Referencia de Configuración del Navegador

Configuración de Playwright

Configuración de WebdriverIO

API

API de Contexto

API de interactividad

Localizadores

API de Aserciones

Comandos

Guía

Múltiples configuraciones

Configuración de Vitest

Referencia de la API de prueba

API Avanzadas

En esta página

API de interactividad ​

Vitest implementa un subconjunto de las API de @testing-library/user-event utilizando el Protocolo de Herramientas de Desarrollo de Chrome o webdriver en lugar de simular eventos. Esto resulta en un comportamiento del navegador más confiable y consistente con la interacción real del usuario.

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

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

Casi todos los métodos de userEvent utilizan las opciones de su proveedor. Para ver todas las opciones disponibles en tu IDE, añade los tipos de webdriver o playwright (según tu proveedor) a tu archivo de configuración o a un archivo de configuración (dependiendo de las inclusiones en tu tsconfig.json):

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

userEvent.setup ​

ts
function setup(): UserEvent;

Crea una nueva instancia de evento de usuario. Esto es útil si necesitas mantener el estado del teclado para una correcta pulsación y liberación de teclas.

WARNING

A diferencia de @testing-library/user-event, la instancia predeterminada de userEvent de @vitest/browser/context se crea una única vez, no cada vez que se llaman sus métodos. Puedes ver la diferencia en cómo funciona en este fragmento:

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

await vitestUserEvent.keyboard('{Shift}'); // presiona shift sin soltar
await vitestUserEvent.keyboard('{/Shift}'); // suelta shift

await originalUserEvent.keyboard('{Shift}'); // presiona shift sin soltar
await originalUserEvent.keyboard('{/Shift}'); // NO liberó la tecla Shift porque el estado es diferente

Este comportamiento es más útil porque no emulamos el teclado, sino que realmente presionamos la tecla Shift. Por lo tanto, mantener el comportamiento original podría causar problemas inesperados al escribir en el campo.

userEvent.click ​

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

Realiza un clic en un elemento. Hereda las opciones del proveedor. Para una explicación detallada sobre el funcionamiento de este método, consulta la documentación de tu proveedor.

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

test('hace clic en un elemento', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.click(logo);
  // o puedes acceder a él directamente en el localizador
  await logo.click();
});

Referencias:

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

userEvent.dblClick ​

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

Realiza un doble clic en un elemento.

Para una explicación detallada sobre el funcionamiento de este método, consulta la documentación de tu proveedor.

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

test('dispara un doble clic en un elemento', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.dblClick(logo);
  // o puedes acceder a él directamente en el localizador
  await logo.dblClick();
});

Referencias:

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

userEvent.tripleClick ​

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

Realiza un triple clic en un elemento. Dado que no existe tripleclick en la API del navegador, este método generará tres eventos de clic consecutivos. Por lo tanto, debes verificar el detalle del evento de clic (evt.detail === 3) para filtrar el evento deseado.

Para una explicación detallada sobre el funcionamiento de este método, consulta la documentación de tu proveedor.

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

test('dispara un triple clic en un elemento', 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);
  // o puedes acceder a él directamente en el localizador
  await logo.tripleClick();

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

Referencias:

  • API locator.click de Playwright: implementado mediante click con clickCount: 3.
  • API browser.action de WebdriverIO: implementado mediante la API de acciones con move más tres eventos down + up + pause consecutivos.
  • API tripleClick de testing-library

userEvent.fill ​

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

Asigna un valor al campo input/textarea/contenteditable. Esto eliminará cualquier texto existente en el campo antes de establecer el nuevo valor.

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

test('actualiza la entrada', 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}

  // o puedes acceder a él directamente en el localizador
  await input.fill('foo'); // input.value == foo
});

Este método enfoca el elemento, lo rellena y genera un evento input una vez completado el relleno. Se puede usar una cadena vacía para borrar el campo.

TIP

Esta API es más rápida que usar userEvent.type o userEvent.keyboard, pero no es compatible con la sintaxis de teclado de user-event (por ejemplo, {Shift}{selectall}).

Recomendamos usar esta API en lugar de userEvent.type en situaciones en las que no necesites introducir caracteres especiales o un control granular sobre los eventos de pulsación de teclas.

Referencias:

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

userEvent.keyboard ​

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

userEvent.keyboard permite disparar pulsaciones de teclado. Si algún campo de entrada tiene el foco, escribirá caracteres en dicho campo. De lo contrario, generará eventos de teclado en el elemento actualmente enfocado (o en document.body si no hay elementos con foco).

Esta API soporta la sintaxis de teclado de user-event.

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

test('dispara pulsaciones de teclas', async () => {
  await userEvent.keyboard('foo'); // se traduce en: f, o, o
  await userEvent.keyboard('{{a[['); // se traduce en: {, a, [
  await userEvent.keyboard('{Shift}{f}{o}{o}'); // se traduce en: Shift, f, o, o
  await userEvent.keyboard('{a>5}'); // presiona 'a' sin soltarla y activa 5 eventos 'keydown'
  await userEvent.keyboard('{a>5/}'); // presiona 'a' durante 5 eventos 'keydown' y luego la suelta
});

Referencias:

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

userEvent.tab ​

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

Envía un evento de la tecla Tab. Esto es una abreviatura de userEvent.keyboard('{tab}').

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

test('tab funciona', 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();
});

Referencias:

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

userEvent.type ​

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

WARNING

Si no necesitas caracteres especiales (por ejemplo, {shift} o {selectall}), se recomienda usar userEvent.fill en su lugar para un mejor rendimiento.

El método type implementa la utilidad type de @testing-library/user-event, basada en la API keyboard.

Esta función permite escribir caracteres en un elemento de entrada (input/textarea/contenteditable). Soporta la sintaxis de teclado de user-event.

Si solo necesitas presionar caracteres sin un campo de entrada, utiliza la API userEvent.keyboard.

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

test('actualiza la entrada', 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 no expone el método .type directamente en el localizador (como input.type) porque su existencia se limita a la compatibilidad con la biblioteca userEvent. Se recomienda usar .fill en su lugar, ya que es más rápido.

Referencias:

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

userEvent.clear ​

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

Este método vacía el contenido del elemento de entrada.

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

test('borra la entrada', async () => {
  const input = page.getByRole('input');

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

  await userEvent.clear(input);
  // o puedes acceder a él directamente en el localizador
  await input.clear();

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

Referencias:

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

userEvent.selectOptions ​

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

userEvent.selectOptions permite la selección de un valor en un elemento <select>.

WARNING

Si el elemento <select> no tiene el atributo multiple, Vitest seleccionará únicamente el primer elemento del array.

A diferencia de @testing-library, Vitest no es compatible con listbox en este momento, pero planeamos añadirle soporte en el futuro.

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

test('borra la entrada', async () => {
  const select = page.getByRole('select');

  await userEvent.selectOptions(select, 'Option 1');
  // o puedes acceder a él directamente en el localizador
  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

El proveedor webdriverio no es compatible con la selección de múltiples elementos, ya que no proporciona una API para ello.

Referencias:

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

userEvent.hover ​

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

Este método desplaza el cursor al elemento seleccionado. Para una explicación detallada sobre el funcionamiento de este método, consulta la documentación de tu proveedor.

WARNING

Si se utiliza el proveedor webdriverio, el cursor se moverá al centro del elemento por defecto.

Si se utiliza el proveedor playwright, el cursor se mueve a un punto visible "cualquiera" del elemento.

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

test('pasa el ratón sobre el elemento del logo', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.hover(logo);
  // o puedes acceder a él directamente en el localizador
  await logo.hover();
});

Referencias:

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

userEvent.unhover ​

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

Esto funciona igual que userEvent.hover, pero mueve el cursor al elemento document.body.

WARNING

Por defecto, la posición del cursor se encuentra en un lugar visible "cualquiera" (en el proveedor playwright) o en el centro (en el proveedor webdriverio) del elemento body. Por lo tanto, si el elemento actualmente sobrevolado ya está en la misma posición, este método no tendrá ningún efecto.

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

test('quita el ratón del elemento del logo', async () => {
  const logo = page.getByRole('img', { name: /logo/ });

  await userEvent.unhover(logo);
  // o puedes acceder a él directamente en el localizador
  await logo.unhover();
});

Referencias:

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

userEvent.upload ​

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

Asigna los archivos especificados a un elemento de entrada de archivo.

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

test('puede subir un archivo', async () => {
  const input = page.getByRole('button', { name: /Upload files/ });

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

  await userEvent.upload(input, file);
  // o puedes acceder a él directamente en el localizador
  await input.upload(file);

  // también se pueden usar rutas de archivo relativas a la raíz del proyecto
  await userEvent.upload(input, './fixtures/file.png');
});

WARNING

El proveedor webdriverio solo es compatible con este comando en los navegadores Chrome y Edge. Además, actualmente solo admite tipos de cadena.

Referencias:

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

userEvent.dragAndDrop ​

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

Arrastra el elemento de origen hasta el elemento de destino. Es importante recordar que el elemento source debe tener el atributo draggable establecido en true.

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

test('el arrastrar y soltar funciona', async () => {
  const source = page.getByRole('img', { name: /logo/ });
  const target = page.getByTestId('logo-target');

  await userEvent.dragAndDrop(source, target);
  // o puedes acceder a él directamente en el localizador
  await source.dropTo(target);

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

WARNING

Esta API no es compatible con el proveedor preview predeterminado.

Referencias:

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

userEvent.copy ​

ts
function copy(): Promise<void>;

Copia el texto seleccionado en el portapapeles.

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

test('copiar y pegar', async () => {
  // escribe en 'source'
  await userEvent.click(page.getByPlaceholder('source'));
  await userEvent.keyboard('hello');

  // selecciona y copia 'source'
  await userEvent.dblClick(page.getByPlaceholder('source'));
  await userEvent.copy();

  // pega en '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');
});

Referencias:

  • API copy de testing-library

userEvent.cut ​

ts
function cut(): Promise<void>;

Corta el texto seleccionado en el portapapeles.

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

test('copiar y pegar', async () => {
  // escribe en 'source'
  await userEvent.click(page.getByPlaceholder('source'));
  await userEvent.keyboard('hello');

  // selecciona y corta 'source'
  await userEvent.dblClick(page.getByPlaceholder('source'));
  await userEvent.cut();

  // pega en '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');
});

Referencias:

  • API cut de testing-library

userEvent.paste ​

ts
function paste(): Promise<void>;

Pega el texto desde el portapapeles. Para ver ejemplos de uso, consulta userEvent.copy y userEvent.cut.

Referencias:

  • API paste de testing-library
Pager
AnteriorAPI de Contexto
SiguienteLocalizadores

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team

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

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team