Localizadores 2.1.0+
Un localizador representa uno o varios elementos en la página. Cada localizador se define mediante una cadena llamada selector. Vitest abstrae este selector proporcionando métodos convenientes que generan esos selectores internamente.
La API de localizadores utiliza una versión derivada de los localizadores de Playwright llamada Ivya. Sin embargo, Vitest proporciona esta API a cada proveedor.
getByRole
function getByRole(
role: ARIARole | string,
options?: LocatorByRoleOptions
): Locator;
Crea un localizador para encontrar un elemento por su rol ARIA, atributos ARIA y nombre accesible.
TIP
Si solo buscas un elemento con getByText('El nombre')
, a menudo es mejor usar getByRole(expectedRole, { name: 'El nombre' })
. La búsqueda por nombre accesible no reemplaza otras búsquedas como *ByAltText
o *ByTitle
. Aunque el nombre accesible puede ser igual a estos atributos, no sustituye la funcionalidad de estos.
Considera la siguiente estructura DOM:
<h3>Sign up</h3>
<label>
Login
<input type="text" />
</label>
<label>
Password
<input type="password" />
</label>
<br />
<button>Submit</button>
Puedes localizar cada elemento por su rol implícito:
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
Los roles se comparan por igualdad de cadenas, sin heredar de la jerarquía de roles ARIA. Como resultado, buscar un rol de superclase como checkbox
no incluirá elementos con un rol de subclase como switch
.
Por defecto, muchos elementos semánticos en HTML tienen roles; por ejemplo, <input type="radio">
tiene el rol "radio". Los elementos no semánticos en HTML no tienen un rol; <div>
y <span>
sin semántica añadida devuelven null
. El atributo role
puede proporcionar semántica.
Proporcionar roles a través de atributos role
o aria-*
a elementos integrados que ya tienen un rol implícito está altamente desaconsejado por las directrices ARIA.
Opciones
exact: boolean
Si el
name
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora siname
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.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
Si se deben incluir o no los elementos marcados (establecidos por
aria-checked
o<input type="checkbox"/>
). Por defecto, el filtro no se aplica.Consulta
aria-checked
para obtener más información.tsx<> <button role="checkbox" aria-checked="true" /> <input type="checkbox" checked /> </>; page.getByRole('checkbox', { checked: true }); // ✅ page.getByRole('checkbox', { checked: false }); // ❌
disabled: boolean
Si se deben incluir o no los elementos desactivados. Por defecto, el filtro no se aplica. Ten en cuenta que, a diferencia de otros atributos, el estado
disabled
se hereda.Consulta
aria-disabled
para obtener más información.tsx<input type="text" disabled />; page.getByRole('textbox', { disabled: true }); // ✅ page.getByRole('textbox', { disabled: false }); // ❌
expanded: boolean
Si se deben incluir o no los elementos expandidos. Por defecto, el filtro no se aplica.
Consulta
aria-expanded
para obtener más información.tsx<a aria-expanded="true" href="example.com"> Link </a>; page.getByRole('link', { expanded: true }); // ✅ page.getByRole('link', { expanded: false }); // ❌
includeHidden: boolean
Si se deben buscar los elementos que normalmente se excluyen del árbol de accesibilidad. Por defecto, solo los elementos no ocultos coinciden con el selector de rol.
Ten en cuenta que los roles
none
ypresentation
siempre se incluyen.tsx<button style="display: none" />; page.getByRole('button'); // ❌ page.getByRole('button', { includeHidden: false }); // ❌ page.getByRole('button', { includeHidden: true }); // ✅
level: number
Un atributo numérico que suele estar presente para los roles
heading
,listitem
,row
,treeitem
con valores predeterminados para los elementos<h1>-<h6>
. Por defecto, el filtro no se aplica.Consulta
aria-level
para obtener más información.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
Un nombre accesible. Por defecto, la coincidencia no distingue entre mayúsculas y minúsculas y busca una subcadena. Utiliza la opción
exact
para controlar este comportamiento.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
Si se deben incluir o no los elementos presionados. Por defecto, el filtro no se aplica.
Consulta
aria-pressed
para obtener más información.tsx<button aria-pressed="true">👍</button>; page.getByRole('button', { pressed: true }); // ✅ page.getByRole('button', { pressed: false }); // ❌
selected: boolean
Si se deben incluir o no los elementos seleccionados. Por defecto, el filtro no se aplica.
Consulta
aria-selected
para obtener más información.tsx<button role="tab" aria-selected="true"> Vue </button>; page.getByRole('button', { selected: true }); // ✅ page.getByRole('button', { selected: false }); // ❌
Ver también
getByAltText
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
Crea un localizador capaz de encontrar un elemento con un atributo alt
que coincida con el texto. A diferencia de la implementación de testing-library, Vitest coincidirá con cualquier elemento que tenga un atributo alt
coincidente.
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;
page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
getByLabelText
function getByLabelText(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Crea un localizador capaz de encontrar un elemento que tenga una etiqueta asociada.
El localizador page.getByLabelText('Username')
encontrará cada entrada en el siguiente ejemplo:
<!-- relación for/htmlFor entre la etiqueta y el ID del elemento del formulario -->
<label for="username-input">Username</label>
<input id="username-input" />
<!-- El atributo aria-labelledby con elementos de formulario -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />
<!-- Etiquetas envolventes -->
<label>Username <input /></label>
<!-- Etiquetas envolventes donde el texto de la etiqueta está en otro elemento hijo -->
<label>
<span>Username</span>
<input />
</label>
<!-- atributos aria-label -->
<!-- Ten cuidado porque esta no es una etiqueta que los usuarios puedan ver en la página, -->
<!-- por lo que el propósito de tu entrada debe ser obvio para los usuarios visuales. -->
<input aria-label="Username" />
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
getByPlaceholder
function getByPlaceholder(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Crea un localizador capaz de encontrar un elemento que tenga el atributo placeholder
especificado. Vitest coincidirá con cualquier elemento que tenga un atributo placeholder
coincidente, no solo input
.
<input placeholder="Username" />;
page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌
WARNING
Generalmente es mejor confiar en una etiqueta usando getByLabelText
que en un marcador de posición.
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
getByText
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;
Crea un localizador capaz de encontrar un elemento que contenga el texto especificado. El texto se comparará con el nodeValue
de TextNode o el valor de la entrada si el tipo es button
o reset
. La coincidencia por texto siempre normaliza los espacios en blanco, incluso con coincidencia exacta. Por ejemplo, convierte múltiples espacios en uno, convierte saltos de línea en espacios e ignora los espacios en blanco iniciales y finales.
<a href="/about">About ℹ️</a>;
page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌
TIP
Este localizador es útil para localizar elementos no interactivos. Si necesitas localizar un elemento interactivo, como un botón o una entrada, prefiere getByRole
.
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
getByTitle
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;
Crea un localizador capaz de encontrar un elemento que tenga el atributo title
especificado. A diferencia de getByTitle
de testing-library, Vitest no puede encontrar elementos title
dentro de un SVG.
<span title="Delete" id="2"></span>;
page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
getByTestId
function getByTestId(text: string | RegExp): Locator;
Crea un localizador capaz de encontrar un elemento que coincida con el atributo de ID de prueba especificado. Puedes configurar el nombre del atributo con browser.locators.testIdAttribute
.
<div data-testid="custom-element" />;
page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌
WARNING
Se recomienda usar esto solo después de que los otros localizadores no funcionen para tu caso de uso. Usar atributos data-testid
no se parece a cómo se usa tu software y debe evitarse si es posible.
Opciones
exact: boolean
Si el
text
se compara exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora sitext
es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.
Ver también
Métodos
Todos los métodos son asíncronos y deben ser esperados (awaited
). Desde Vitest 2.2, las pruebas fallarán si un método no es esperado.
click
function click(options?: UserEventClickOptions): Promise<void>;
Haz clic en un elemento. Puedes usar las opciones para establecer la posición del cursor.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).click();
dblClick
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;
Genera un evento de doble clic en un elemento. Puedes usar las opciones para establecer la posición del cursor.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).dblClick();
tripleClick
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;
Genera un evento de triple clic en un elemento. Dado que no existe tripleclick
en la API del navegador, este método disparará tres eventos de clic seguidos.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).tripleClick();
clear
function clear(): Promise<void>;
Borra el contenido del elemento de entrada.
import { page } from '@vitest/browser/context';
await page.getByRole('textbox', { name: 'Full Name' }).clear();
hover
function hover(options?: UserEventHoverOptions): Promise<void>;
Mueve la posición del cursor al elemento seleccionado.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).hover();
unhover
function unhover(options?: UserEventHoverOptions): Promise<void>;
Esto funciona igual que locator.hover
, pero mueve el cursor al elemento document.body
en su lugar.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).unhover();
fill
function fill(text: string, options?: UserEventFillOptions): Promise<void>;
Establece el valor del elemento input
, textarea
o contenteditable
actual.
import { page } from '@vitest/browser/context';
await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
dropTo
function dropTo(
target: Locator,
options?: UserEventDragAndDropOptions
): Promise<void>;
Arrastra el elemento actual a la ubicación de destino.
import { page } from '@vitest/browser/context';
const paris = page.getByText('Paris');
const france = page.getByText('France');
await paris.dropTo(france);
selectOptions
function selectOptions(
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
options?: UserEventSelectOptions
): Promise<void>;
Elige uno o más valores de un elemento <select>
.
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' }),
]);
screenshot
function screenshot(
options: LocatorScreenshotOptions & { base64: true }
): Promise<{
path: string;
base64: string;
}>;
function screenshot(
options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;
Crea una captura de pantalla del elemento que coincide con el selector del localizador.
Puedes especificar la ubicación de guardado para la captura de pantalla usando la opción path
, que es relativa al archivo de prueba actual. Si la opción path
no está configurada, Vitest usará por defecto browser.screenshotDirectory
(__screenshot__
por defecto), junto con los nombres del archivo y la prueba para determinar la ruta del archivo de la captura de pantalla.
Si también necesitas el contenido de la captura de pantalla, puedes especificar base64: true
para que se devuelva junto con la ruta del archivo donde se guarda la captura de pantalla.
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, // también devuelve la cadena base64
});
// path - ruta completa a la captura de pantalla
// bas64 - cadena codificada en base64 de la captura de pantalla
query
function query(): Element | null;
Este método devuelve un único elemento que coincide con el selector del localizador o null
si no se encuentra ningún elemento.
Si varios elementos coinciden con el selector, este método lanzará un error. Usa .elements()
cuando necesites todos los elementos DOM coincidentes o .all()
si necesitas un array de localizadores que coincidan con el selector.
Considera la siguiente estructura DOM:
<div>Hello <span>World</span></div>
<div>Hello</div>
Estos localizadores no lanzarán un error:
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement
Estos localizadores lanzarán un error:
// devuelve varios elementos
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌
element
function element(): Element;
Este método devuelve un único elemento que coincide con el selector del localizador.
Si ningún elemento coincide con el selector, se lanza un error. Considera usar .query()
cuando solo necesites verificar si el elemento existe.
Si varios elementos coinciden con el selector, se lanza un error. Usa .elements()
cuando necesites todos los elementos DOM coincidentes o .all()
si necesitas un array de localizadores que coincidan con el selector.
TIP
Este método puede ser útil si necesitas pasarlo a una biblioteca externa. Se llama automáticamente cuando se usa un localizador con expect.element
cada vez que se reintenta la aserción:
await expect.element(page.getByRole('button')).toBeDisabled();
Considera la siguiente estructura DOM:
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>
Estos localizadores no lanzarán un error:
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅
Estos localizadores lanzarán un error:
// devuelve varios elementos
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌
// no devuelve elementos
page.getByText('Hello USA').element(); // ❌
elements
function elements(): Element[];
Este método devuelve un array de elementos que coinciden con el selector del localizador.
Esta función nunca lanza un error. Si no hay elementos que coincidan con el selector, este método devolverá un array vacío.
Considera la siguiente estructura DOM:
<div>Hello <span>World</span></div>
<div>Hello</div>
Estos localizadores siempre tendrán éxito:
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').elements(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []
all
function all(): Locator[];
Este método devuelve un array de nuevos localizadores que coinciden con el selector.
Internamente, este método llama a .elements
y envuelve cada elemento usando page.elementLocator
.