Localizadores (Locators) de Playwright
Locator (localizador) es uno de los conceptos más centrales de Playwright; representa una forma de encontrar elementos en la página.
Este capítulo presenta los métodos de localización recomendados por Playwright: localizar elementos mediante rol, texto, etiqueta y marcador de posición.
¿Qué es un Locator?
Locator es un objeto abstracto que Playwright utiliza para encontrar elementos en la página.
A diferencia de losdocument.querySelector()métodos tradicionales, el Locator de Playwright tieneespera automática y reintento automáticocapacidad.
Cuando el contenido de la página cambia dinámicamente, Locator vuelve a buscar elementos constantemente hasta que encuentra un elemento que coincida o se agota el tiempo de espera.
Ejemplo
const button = page.getByRole('button', { name: 'Enviar' });
// Al realizar la operación, Playwright esperará automáticamente a que el botón aparezca y esté en estado operable.
await button.click();
Cómo funciona Locator
Al crear un Locator, Playwright solo registra una regla de búsqueda.
Cuando llamas a.click()、.fill()tales operaciones oexpect(locator)aserciones, el Locator realmente comienza a buscar elementos.
Si no encuentra el elemento, Locator sigue reintentando hasta que la operación agota el tiempo de espera.
Localizar por rol: getByRole()
getByRole()Es el método de localización más recomendado por Playwright.
Se basa en elrol de accesibilidad (ARIA Role)para encontrar elementos; es la forma más cercana a la percepción del usuario.
Uso básico
Ejemplo
const submitBtn = page.getByRole('button', { name: 'Enviar' });
await submitBtn.click();
// Localizar un enlace — mediante el rol "link"
const homeLink = page.getByRole('link', { name: 'Inicio' });
await homeLink.click();
// Localizar un encabezado — mediante el rol "heading"
const mainTitle = page.getByRole('heading', { name: 'Bienvenido a EJEMPLO' });
// Localizar un cuadro de texto — mediante el rol "textbox"
const searchBox = page.getByRole('textbox', { name: 'Buscar' });
await searchBox.fill('Playwright');
Roles ARIA comunes
| Role | Elemento HTML correspondiente | Ejemplo de uso |
|---|---|---|
'button' | <button>、role="button" | getByRole('button', { name: '登录' }) |
'link' | <a> | getByRole('link', { name: '了解更多' }) |
'heading' | <h1>~<h6> | getByRole('heading', { name: 'EJEMPLO 教程' }) |
'textbox' | <input type="text">、<textarea> | getByRole('textbox', { name: '用户名' }) |
'checkbox' | <input type="checkbox"> | getByRole('checkbox', { name: '记住我' }) |
'radio' | <input type="radio"> | getByRole('radio', { name: '男' }) |
'combobox' | <select> | getByRole('combobox', { name: '城市' }) |
'img' | <img> | getByRole('img', { name: 'Logo' }) |
'list' | <ul>、<ol> | getByRole('list') |
'listitem' | <li> | getByRole('listitem') |
'navigation' | <nav> | getByRole('navigation') |
'table' | <table> | getByRole('table') |
Opción name
nameLa opción se especifica mediante elnombre accesiblepara reducir el alcance.
Las fuentes del nombre accesible incluyen: el contenido de texto del elemento,aria-labelatributos asociados<label>etc.
Ejemplo
page.getByRole('button', { name: 'Iniciar sesión' });
// Coincidir mediante aria-label
page.getByRole('button', { name: 'Cerrar diálogo' });
// Coincidencia con expresión regular
page.getByRole('link', { name: /EJEMPLO|novato/ });
Opciones de estado
Además dename,getByRoletambién admite varias opciones de estado:
Ejemplo
page.getByRole('checkbox', { checked: true });
// Localizar un botón deshabilitado
page.getByRole('button', { disabled: true });
// Localizar un menú desplegable expandido
page.getByRole('button', { expanded: true });
// Localizar una opción seleccionada
page.getByRole('option', { selected: true });
// Combinar múltiples estados
page.getByRole('checkbox', { name: 'Aceptar el acuerdo', checked: false });
Localizar por texto: getByText()
getByText()Mediante elcontenido de texto del elementopara localizar.
Ejemplo
page.getByText('Bienvenido a EJEMPLO');
// Coincidencia parcial (por defecto)
page.getByText('EJEMPLO');
// Forzar coincidencia exacta
page.getByText('EJEMPLO', { exact: true });
// Coincidencia con expresión regular
page.getByText(/EJEMPLO|tutorial para novatos/);
getByTextCoincide con el contenido de texto completo del elemento, por lo tantogetByText('EJEMPLO', { exact: true })solo coincidirá con elementos cuyo contenido de texto sea exactamente "EJEMPLO".
Cuando no se usa coincidencia exacta por defecto, basta con la coincidencia de subcadena (por ejemplo,getByText('EJEMPLO')coincidirá con "Bienvenido a EJEMPLO").
Localizar por etiqueta: getByLabel()
getByLabel()Se utiliza para localizar<label>los controles de formulario asociados.
Ejemplo
// <label for="username">nombre de usuario</label>
// <input id="username" type="text" />
// Localizar el input mediante el texto de la label
await page.getByLabel('nombre de usuario').fill('ejemplo_user');
// Estructura HTML:
// <label>contraseña <input type="password" /></label>
// La label anidada también es válida
await page.getByLabel('contraseña').fill('password123');
También admite{ exact: true }la opción de coincidencia exacta.
Localizar por marcador de posición: getByPlaceholder()
getByPlaceholder()Mediante elplaceholderatributo se localiza el cuadro de entrada.
Ejemplo
await page.getByPlaceholder('Ingrese la palabra clave de búsqueda').fill('Playwright');
// Estructura HTML: <textarea placeholder="Cuéntanos lo que piensas..."></textarea>
await page.getByPlaceholder('Cuéntanos lo que piensas...').fill('¡Los tutoriales de EJEMPLO son increíbles!');
Elección entre getByLabel y getByPlaceholder
| Método | Escenario aplicable | Prioridad |
|---|---|---|
getByLabel() | Cuando hay un elemento <label> | Usar preferentemente |
getByPlaceholder() | Cuando no hay label, pero hay placeholder | Segunda opción |
getByRoleEs el método de localización más recomendado por Playwright, porque simula la forma en que los usuarios identifican los elementos por su rol. El siguiente esgetByLabelygetByPlaceholder. Solo considere usar XPathgetByTestIdo selectores CSS.
getByAltText() Localización de imágenes
getByAltText()Mediante elaltatributo se localiza el<img>elemento.
Ejemplo
await expect(page.getByAltText('EJEMPLO Logo')).toBeVisible();
// Coincidencia con expresión regular
await expect(page.getByAltText(/logo/i)).toBeVisible();
getByTitle() Localización por atributo title
getByTitle()Mediante eltitleatributo se localiza.
Ejemplo
await page.getByTitle('Cerrar la página actual').click();
getByAltTextygetByTitleSe usa con poca frecuencia, solo cuando el elemento tiene atributos alt o title claros y no se puede localizar de otra manera.
getByTestId() Localización por ID de prueba
getByTestId()SíPlan de respaldo, mediantedata-testidel atributo para localizar el elemento.
Ejemplo
await page.getByTestId('submit-btn').click();
// Puede contener múltiples coincidencias (como elementos de lista)
const items = page.getByTestId('todo-item');
await expect(items).toHaveCount(3);
Atributo testId personalizado
Si tu proyecto no usadata-testid, puedesplaywright.config.tspersonalizar el nombre del atributo en:
Ejemplo
export default defineConfig({
use: {
// Usar data-cy en lugar de data-testid (para migración desde Cypress)
testIdAttribute: 'data-cy',
// O usar id como testId
// testIdAttribute: 'id',
},
});
page.locator() Localización con CSS y XPath
page.locator()Admite selectores CSS y XPath, es una alternativa más flexible.
Selectores CSS
Ejemplo
await page.locator('.submit-btn').click();
// Mediante el ID
await page.locator('#username').fill('ejemplo_user');
// Mediante el atributo
await page.locator('[data-type="primary"]').click();
// Mediante la combinación de etiqueta + clase
await page.locator('button.primary').click();
// Mediante la relación padre-hijo
await page.locator('nav a').first().click();
// Selector CSS que contiene un texto específico
await page.locator('button:has-text("Enviar")').click();
Localización con XPath
Ejemplo
await page.locator('xpath=//button[@type="submit"]').click();
// Localizar por texto
await page.locator('xpath=//h1[contains(text(), "EJEMPLO")]').click();
Los selectores CSS y XPath son la última opción, prioriza usar
getByRole、getByTextmétodos de localización semánticos, etc. Los selectores CSS pueden fallar fácilmente por la refactorización de estilos, XPath es menos legible y más lento.
Operaciones en cadena de Locator
El Locator de Playwright admite llamadas en cadena, lo que permite filtrar aún más sobre los resultados coincidentes actuales.
.first()、.last()、.nth()
Ejemplo
const firstItem = page.getByRole('listitem').first();
// Obtener el último
const lastItem = page.getByRole('listitem').last();
// Obtener el segundo (el índice comienza en 0)
const secondItem = page.getByRole('listitem').nth(1);
.filter() Filtrar
Ejemplo
page.getByRole('button').filter({ hasText: 'Guardar' });
// Filtrar los que no contienen un texto específico
page.getByRole('listitem').filter({ hasNotText: 'Eliminado' });
// Filtrar los que contienen un elemento hijo específico
page.getByRole('listitem').filter({ has: page.getByRole('button') });
// Filtrar los que no contienen un elemento hijo específico
page.getByRole('listitem').filter({ hasNot: page.getByTestId('badge') });
.locator() Localizar elementos hijos
Ejemplo
const list = page.getByTestId('todo-list');
const deleteBtn = list.locator('button.delete');
await deleteBtn.click();
// Anidamiento de varios niveles
page
.getByRole('dialog')
.locator('div.content')
.locator('button')
.filter({ hasText: 'Confirmar' })
.click();
.and() y .or() Combinación lógica (1.63+)
Ejemplo
const btn = page.getByRole('button')
.and(page.getByText('Enviar'));
// Cumplir cualquiera de las condiciones
const target = page.getByText('EJEMPLO')
.or(page.getByTitle('EJEMPLO'));
Resumen de prioridades de localización en Locator
Ordenados de mayor a menor recomendación:
| Prioridad | Método | Condición de uso |
|---|---|---|
| 1 (más recomendado) | getByRole() | El elemento tiene un rol ARIA explícito |
| 2 | getByLabel() | El elemento de formulario tiene una etiqueta (label) asociada |
| 3 | getByPlaceholder() | El campo de entrada tiene placeholder |
| 4 | getByText() | El elemento tiene contenido de texto explícito |
| 5 | getByAltText() | La imagen tiene el atributo alt |
| 6 | getByTitle() | El elemento tiene el atributo title |
| 7 (respaldo) | getByTestId() | Cuando no se puede localizar con los métodos anteriores. |
| 8 (última opción) | locator() | Selectores CSS / XPath |