Lección 1 de 7 · 2 min
Locators accesibles y web-first assertions
La jerarquía de locators de Playwright
En orden de preferencia oficial (y con razón):
page.getByRole('button', { name: 'Reservar hora' }) // 1º semántica accesible
page.getByLabel('Teléfono') // 2º formularios
page.getByPlaceholder('+56 9 ...') // 3º si no hay label (mal HTML)
page.getByText('Reserva confirmada') // 4º contenido estático
page.getByTestId('booking-submit') // 5º cuando nada semántico aplica
page.locator('css=...') // último recurso
getByRole usa el árbol de accesibilidad, no el DOM. Si el botón cambia de button a a estilizado con role correcto, el test sigue pasando — porque la experiencia del usuario no cambió.
Efecto secundario valioso: si getByRole no encuentra tu elemento, tu HTML probablemente tampoco funciona con lector de pantalla. Los tests te auditan accesibilidad gratis.
Encadenar y filtrar
// La card de "Corte" y su botón, sin CSS frágil
const card = page.getByRole('listitem').filter({ hasText: 'Corte de pelo' });
await card.getByRole('button', { name: 'Reservar' }).click();
Web-first assertions: la diferencia clave
// ❌ Evalúa UNA vez — race condition garantizada
expect(await page.locator('.total').textContent()).toBe('$18.500');
// ✅ Reintenta hasta 5s — espera a que la UI se estabilice
await expect(page.locator('.total')).toHaveText('$18.500');
La regla: expect(locator) con matchers to* asíncronos siempre que el sujeto sea la página. expect(valor) solo para datos ya extraídos.
Auto-waiting: qué cubre y qué no
Antes de cada acción, Playwright espera solo que el elemento esté visible, estable, habilitado y reciba eventos. No espera que tu app termine de cargar datos — eso lo declaras con assertions:
await page.getByRole('button', { name: 'Buscar' }).click();
// El click no espera los resultados; esto sí:
await expect(page.getByRole('list', { name: 'Resultados' })).toBeVisible();
Y por eso waitForTimeout() no tiene lugar en una suite seria: siempre hay una condición concreta que esperar.
Ejercicio
Elige una página pública y escribe 5 locators para sus elementos principales usando solo los niveles 1–4 de la jerarquía (sin test-id ni CSS). Si alguno es imposible, anota por qué — acabas de encontrar un problema de accesibilidad real.