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

Localizadores ​

Un localizador representa uno o varios elementos en el DOM. Cada localizador se define mediante una cadena llamada selector. Vitest simplifica el uso de selectores al proporcionar métodos convenientes que los generan automáticamente.

La API de localizadores de Vitest utiliza una adaptación de los localizadores de Playwright denominada Ivya. Sin embargo, Vitest extiende esta API a todos los proveedores de navegador, no solo a Playwright.

TIP

Esta página describe el uso de la API de localizadores. Para una comprensión más profunda de los localizadores y su aplicación, consulta la documentación de Playwright sobre "Localizadores".

getByRole ​

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

Crea un localizador para encontrar un elemento basándose en su rol ARIA, atributos ARIA y nombre accesible.

TIP

Si solo necesitas consultar un único elemento con getByText('El nombre'), a menudo es más apropiado usar getByRole(rolEsperado, { name: 'El nombre' }). La consulta por nombre accesible no reemplaza otras consultas como *ByAltText o *ByTitle. Aunque el nombre accesible pueda coincidir con dichos atributos, no sustituye su funcionalidad.

Considera la siguiente estructura DOM:

html
<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:

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

Los roles se comparan por igualdad de cadena, sin heredar de la jerarquía de roles ARIA. Por lo tanto, consultar 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 un rol; por ejemplo, <input type="radio"> tiene el rol de "radio". Los elementos no semánticos en HTML no tienen un rol; <div> y <span> sin semántica adicional devuelven null. El atributo role puede añadir semántica.

Proporcionar roles a través de atributos role o aria-* a elementos integrados que ya tienen un rol implícito está fuertemente desaconsejado por las directrices ARIA.

Opciones ​
  • exact: boolean

    Indica si el name debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si name 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

    Indica si se deben incluir los elementos marcados (establecidos por aria-checked o <input type="checkbox"/>). Por defecto, el filtro no se aplica.

    Consulta aria-checked para 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

    Indica si se deben incluir los elementos deshabilitados. 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 más información.

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

    Indica si se deben incluir los elementos expandidos. Por defecto, el filtro no se aplica.

    Consulta aria-expanded para 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

    Indica si se deben consultar 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 y presentation 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 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 es insensible a mayúsculas y minúsculas y busca una subcadena. Usa 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

    Indica si se deben incluir los elementos presionados. Por defecto, el filtro no se aplica.

    Consulta aria-pressed para más información.

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

    Indica si se deben incluir los elementos seleccionados. Por defecto, el filtro no se aplica.

    Consulta aria-selected para 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 ​
  • Lista de roles ARIA en MDN
  • Lista de roles ARIA en w3.org
  • ByRole de testing-library

getByAltText ​

ts
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 encontrará cualquier elemento que tenga un atributo alt coincidente.

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

page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByAltText de testing-library

getByLabelText ​

ts
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á todos los elementos input en el siguiente ejemplo:

html
// Relación for/htmlFor entre la etiqueta y el ID del elemento de formulario
<label for="username-input">Username</label>
<input id="username-input" />

// El atributo aria-labelledby en elementos de formulario
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />

// Etiquetas contenedoras
<label>Username <input /></label>

// Etiquetas contenedoras donde el texto de la etiqueta está en otro elemento hijo
<label>
  <span>Username</span>
  <input />
</label>

// Atributos aria-label
// ¡Atención! Esta no es una etiqueta visible para los usuarios en la página, por lo que el propósito de tu campo de entrada debe ser obvio para los usuarios visuales.
<input aria-label="Username" />

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByLabelText de testing-library

getByPlaceholder ​

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

Crea un localizador capaz de encontrar un elemento que tenga el atributo placeholder especificado. Vitest encontrará cualquier elemento que tenga un atributo placeholder coincidente, no solo input.

tsx
<input placeholder="Username" />;

page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌

WARNING

Generalmente es preferible usar una etiqueta con getByLabelText en lugar de un marcador de posición.

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByPlaceholderText de testing-library

getByText ​

ts
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 un TextNode o el valor de un input si el tipo es button o reset. La búsqueda por texto siempre normaliza los espacios en blanco, incluso con coincidencia exacta. Por ejemplo, convierte múltiples espacios en uno solo, transforma los saltos de línea en espacios e ignora los espacios en blanco iniciales y finales.

tsx
<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 un campo de entrada, prefiere getByRole.

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByText de testing-library

getByTitle ​

ts
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 con atributo title dentro de un SVG.

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

page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByTitle de testing-library

getByTestId ​

ts
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.

tsx
<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. El uso de atributos data-testid no refleja cómo se utiliza tu software y debe evitarse si es posible.

Opciones ​

  • exact: boolean

    Indica si el text debe coincidir exactamente: sensible a mayúsculas y minúsculas y cadena completa. Deshabilitado por defecto. Esta opción se ignora si text es una expresión regular. Ten en cuenta que la coincidencia exacta aún recorta los espacios en blanco.

Ver también ​

  • ByTestId de testing-library

nth ​

ts
function nth(index: number): Locator;

Este método devuelve un nuevo localizador que coincide solo con un índice específico dentro de un resultado de consulta de múltiples elementos. Se basa en un índice de cero, donde nth(0) selecciona el primer elemento. A diferencia de elements()[n], el localizador nth se volverá a intentar hasta que el elemento esté presente.

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

Antes de recurrir a nth, te puede resultar útil usar localizadores encadenados para acotar tu búsqueda. A veces no hay mejor manera de distinguir los elementos que por su posición; aunque esto puede llevar a resultados inconsistentes, es mejor que nada.

tsx
page.getByLabel('two').getByRole('input'); // ✅ mejor alternativa a page.getByRole('textbox').nth(3)
page.getByLabel('one').getByRole('input'); // ❌ demasiado ambiguo
page.getByLabel('one').getByRole('input').nth(1); // ✅ compromiso pragmático

first ​

ts
function first(): Locator;

Este método devuelve un nuevo localizador que coincide solo con el primer índice de un resultado de consulta de múltiples elementos. Es una forma abreviada de nth(0).

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

last ​

ts
function last(): Locator;

Este método devuelve un nuevo localizador que coincide solo con el último índice de un resultado de consulta de múltiples elementos. Es una forma abreviada de nth(-1).

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

and ​

ts
function and(locator: Locator): Locator;

Este método crea un nuevo localizador que coincide tanto con el localizador padre como con el localizador proporcionado. El siguiente ejemplo encuentra un botón con un título específico:

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

or ​

ts
function or(locator: Locator): Locator;

Este método crea un nuevo localizador que coincide con uno o ambos localizadores.

WARNING

Ten en cuenta que si el localizador encuentra más de un elemento, llamar a otro método podría lanzar un error si este espera un solo elemento:

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

page.getByRole('button').or(page.getByRole('link')).click(); // ❌ coincide con múltiples elementos

filter ​

ts
function filter(options: LocatorOptions): Locator;

Este método acota el localizador según las opciones, como filtrar por texto. Se puede encadenar para aplicar múltiples filtros.

has ​

  • Tipo: Locator

Esta opción acota el selector para que coincida con elementos que contengan otros elementos que también coincidan con el localizador proporcionado. Por ejemplo, con este HTML:

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

Podemos acotar el localizador para encontrar solo el article con el texto Vitest dentro:

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

WARNING

El localizador proporcionado (page.getByText('Vitest') en el ejemplo) debe ser relativo al localizador padre (page.getByRole('article') en el ejemplo). La consulta se realizará a partir del localizador padre, no de la raíz del documento.

Es decir, no puedes pasar un localizador que busque un elemento fuera del ámbito del localizador padre:

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

Este ejemplo fallará porque el elemento article está fuera del elemento que contiene el texto Vitest.

TIP

Este método se puede encadenar para refinar aún más la búsqueda del elemento:

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

hasNot ​

  • Tipo: Locator

Esta opción acota el selector para que coincida con elementos que NO contengan otros elementos que también coincidan con el localizador proporcionado. Por ejemplo, con este HTML:

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

Podemos acotar el localizador para encontrar solo el article que no tenga Rolldown dentro.

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

WARNING

Ten en cuenta que el localizador proporcionado se consulta en relación con el padre, no con la raíz del documento, al igual que la opción has.

hasText ​

  • Tipo: string | RegExp

Esta opción acota el selector para que solo coincida con elementos que contengan el texto proporcionado en su interior. Cuando se pasa un string, la coincidencia es insensible a mayúsculas y minúsculas y busca una subcadena.

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

Ambos localizadores encontrarán el mismo elemento porque la búsqueda no distingue entre mayúsculas y minúsculas:

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

hasNotText ​

  • Tipo: string | RegExp

Esta opción acota el selector para que solo coincida con elementos que NO contengan el texto proporcionado en su interior. Cuando se pasa un string, la coincidencia es insensible a mayúsculas y minúsculas y busca una subcadena.

Métodos ​

Todos los métodos son asíncronos y requieren el uso de await. Desde Vitest 3, las pruebas fallarán si un método no se espera (no se usa await).

click ​

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

Haz clic en un elemento. Puedes usar las opciones para establecer la posición del cursor.

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

await page.getByRole('img', { name: 'Rose' }).click();
  • Ver más en userEvent.click

dblClick ​

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

Activa un evento de doble clic en un elemento. Puedes usar las opciones para establecer la posición del cursor.

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

await page.getByRole('img', { name: 'Rose' }).dblClick();
  • Ver más en userEvent.dblClick

tripleClick ​

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

Activa un evento de triple clic en un elemento. Dado que no existe tripleclick en la API del navegador, este método activará tres eventos de clic seguidos.

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

await page.getByRole('img', { name: 'Rose' }).tripleClick();
  • Ver más en userEvent.tripleClick

clear ​

ts
function clear(options?: UserEventClearOptions): Promise<void>;

Borra el contenido del campo de entrada.

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

await page.getByRole('textbox', { name: 'Full Name' }).clear();
  • Ver más en userEvent.clear

hover ​

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

Mueve la posición del cursor al elemento seleccionado.

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

await page.getByRole('img', { name: 'Rose' }).hover();
  • Ver más en userEvent.hover

unhover ​

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

Esto funciona igual que locator.hover, pero mueve el cursor al elemento document.body en su lugar.

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

await page.getByRole('img', { name: 'Rose' }).unhover();
  • Ver más en userEvent.unhover

fill ​

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

Establece el valor del elemento input, textarea o contenteditable actual.

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

await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
  • Ver más en userEvent.fill

dropTo ​

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

Arrastra el elemento actual a la ubicación de destino.

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

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

await paris.dropTo(france);
  • Ver más en userEvent.dragAndDrop

selectOptions ​

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

Selecciona uno o más valores de un elemento <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' }),
]);
  • Ver más en 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>;

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 utilizará 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 obtenerlo junto con la ruta del archivo donde se guarda la captura de pantalla.

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, // también devuelve la cadena base64
});
// path - ruta completa a la captura de pantalla
// base64 - cadena codificada en base64 de la captura de pantalla

ADVERTENCIA 3.2.0+

Ten en cuenta que screenshot siempre devolverá una cadena base64 si save se establece en false. La path también se ignora en ese caso.

query ​

ts
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:

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

Estos localizadores no lanzarán un error:

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

Estos localizadores lanzarán un error:

ts
// devuelve múltiples elementos
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌

element ​

ts
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 múltiples 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 el localizador se usa con expect.element cada vez que se reintenta la aserción:

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

Considera la siguiente estructura DOM:

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

Estos localizadores no lanzarán un error:

ts
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:

ts
// devuelve múltiples elementos
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌

// no devuelve elementos
page.getByText('Hello USA').element(); // ❌

elements ​

ts
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:

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

Estos localizadores siempre tendrán éxito:

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[];

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.

  • Ver locator.elements()

Propiedades ​

selector ​

El selector es una cadena que será utilizada por el proveedor del navegador para localizar el elemento. Playwright utilizará una sintaxis de localizador de playwright mientras que preview y webdriverio usarán CSS.

DANGER

No debes usar esta cadena directamente en tu código de prueba. La cadena del selector solo debe usarse cuando se trabaja con la API de Comandos:

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 lo convertirá automáticamente en una cadena
  await commands.test(page.getByText('Hello')); // ✅
});

Localizadores Personalizados 3.2.0+ avanzado ​

Puedes extender la API de localizadores incorporados definiendo un objeto de fábricas de localizadores. Estos métodos existirán como métodos en el objeto page y en cualquier localizador creado.

Estos localizadores pueden ser útiles si los localizadores incorporados no son suficientes. Por ejemplo, cuando usas un framework personalizado para tu UI.

La fábrica de localizadores debe devolver una cadena de selector o un localizador en sí mismo.

TIP

La sintaxis del selector es idéntica a la de los localizadores de Playwright. Por favor, lee su guía para comprender mejor cómo trabajar con ellos.

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

locators.extend({
  getByArticleTitle(title) {
    return `[data-title="${title}"]`;
  },
  getByArticleCommentsCount(count) {
    return `.comments :text("${count} comments")`;
  },
  async previewComments() {
    // tienes acceso al localizador actual a través de "this"
    // ¡Atención! Si el método fue llamado en `page`, `this` será `page`,
    // no el localizador!
    if (this !== page) {
      await this.click();
    }
    // ...
  },
});

// si estás usando typescript, puedes extender la interfaz LocatorSelectors
// para tener autocompletado en locators.extend, page.* y locator.* methods
declare module '@vitest/browser/context' {
  interface LocatorSelectors {
    // si el método personalizado devuelve una cadena, se convertirá en un localizador
    // si devuelve cualquier otra cosa, se devolverá como de costumbre
    getByArticleTitle(title: string): Locator;
    getByArticleCommentsCount(count: number): Locator;

    // Vitest devolverá una promesa y no intentará convertirla en un localizador
    previewComments(this: Locator): Promise<void>;
  }
}

Si el método se llama en el objeto global page, el selector se aplicará a toda la página. En el ejemplo siguiente, getByArticleTitle encontrará todos los elementos con un atributo data-title cuyo valor sea title. Sin embargo, si el método se llama en el localizador, su alcance se restringirá a ese localizador.

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
AnteriorAPI de interactividad
SiguienteAPI de Aserciones

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team

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

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team