Cómo usar locators en Playwright: guía completa con ejemplos

Si hay una cosa que marca la diferencia entre una suite de tests frágil y una suite estable, es cómo localizas los elementos de la página. Un locator mal elegido hace que tus tests fallen cada vez que un desarrollador cambia una clase CSS o reordena el DOM. Un locator bien elegido sobrevive a esos cambios sin romperse.

En este artículo te explico todos los tipos de locators que tiene Playwright, cuándo usar cada uno y por qué algunos son mucho mejores que otros.


Qué es un locator en Playwright

Un locator es la forma en que Playwright identifica y encuentra un elemento en la página para interactuar con él — hacer clic, rellenar un campo, leer su texto o verificar que está visible.

A diferencia de otros frameworks, los locators de Playwright tienen auto-waiting incorporado. Antes de ejecutar cualquier acción, Playwright espera automáticamente a que el elemento esté visible, estable y listo para interactuar. Esto elimina la mayoría de los tests flaky relacionados con timing.


Los locators recomendados por Playwright

Playwright tiene una jerarquía clara de locators — algunos son más robustos y semánticos que otros. La documentación oficial recomienda usar los más semánticos siempre que sea posible.

get_by_role — el más recomendado

get_by_role localiza elementos por su rol ARIA — el tipo de elemento según las especificaciones de accesibilidad web. Es el locator más robusto porque está vinculado al significado del elemento, no a su apariencia o posición.

python

# Botón por su rol y nombre visible
page.get_by_role("button", name="Iniciar sesión").click()

# Campo de texto por su rol y label
page.get_by_role("textbox", name="Email").fill("usuario@test.com")

# Enlace por su texto
page.get_by_role("link", name="Volver al inicio").click()

# Checkbox por su label
page.get_by_role("checkbox", name="Recordarme").check()

Los roles más usados son button, link, textbox, checkbox, radio, combobox, heading, img y listitem.

get_by_label — para campos de formulario

get_by_label localiza campos de formulario por el texto de su etiqueta. Es perfecto para formularios bien construidos donde cada campo tiene su label asociado.

python

page.get_by_label("Nombre completo").fill("Fátima Ocaña")
page.get_by_label("Contraseña").fill("password123")
page.get_by_label("País").select_option("España")

get_by_placeholder — para campos con placeholder

get_by_placeholder localiza campos de input por su texto de placeholder — el texto gris que aparece dentro del campo cuando está vacío.

python

page.get_by_placeholder("Introduce tu email").fill("usuario@test.com")
page.get_by_placeholder("Buscar productos...").fill("zapatillas")

get_by_text — para elementos con texto visible

get_by_text localiza elementos por su contenido de texto visible. Útil para verificar que un texto está presente o para hacer clic en elementos de texto.

python

# Clic en un elemento con texto exacto
page.get_by_text("Añadir al carrito").click()

# Verificar que un texto está visible
expect(page.get_by_text("Pedido confirmado")).to_be_visible()

# Buscar texto parcial
page.get_by_text("Bienvenido", exact=False).click()

get_by_alt_text — para imágenes

get_by_alt_text localiza imágenes por su atributo alt. Es la forma correcta de interactuar con imágenes en tests.

python

page.get_by_alt_text("Logo de la empresa").click()
expect(page.get_by_alt_text("Foto de perfil")).to_be_visible()

get_by_title — por el atributo title

get_by_title localiza elementos por su atributo title, que normalmente aparece como tooltip al pasar el ratón.

python

page.get_by_title("Cerrar ventana").click()
expect(page.get_by_title("Ayuda").to_be_visible()

get_by_test_id — para atributos data-testid

get_by_test_id localiza elementos por su atributo data-testid. Es el locator preferido cuando el equipo de desarrollo añade atributos específicos para testing.

python

page.get_by_test_id("btn-checkout").click()
page.get_by_test_id("precio-total").text_content()

La ventaja de data-testid es que es completamente independiente del diseño y la estructura del DOM — los desarrolladores pueden refactorizar todo el HTML sin romper los tests, siempre que mantengan los atributos testid.


El locator CSS — cuándo usarlo

page.locator() con selectores CSS es más flexible pero también más frágil. Úsalo cuando los locators semánticos no sean suficientes.

python

# Por ID
page.locator("#btn-login").click()

# Por clase CSS
page.locator(".mensaje-error").text_content()

# Combinando selectores
page.locator("form.login-form input[type='email']").fill("usuario@test.com")

El problema con los selectores CSS es que son frágiles ante cambios de diseño. Si un desarrollador renombra una clase o cambia la estructura del HTML, el locator se rompe.


El locator XPath — úsalo como último recurso

XPath es el locator más potente pero también el más frágil y difícil de mantener. Úsalo solo cuando no haya otra alternativa.

python

# XPath básico
page.locator("//button[text()='Confirmar']").click()

# XPath con condición
page.locator("//input[@type='email']").fill("usuario@test.com")

La regla general es: si necesitas XPath para encontrar un elemento, probablemente hay un problema de accesibilidad en la aplicación que debería reportarse al equipo de desarrollo.


Cómo encadenar locators

Playwright permite encadenar locators para filtrar elementos dentro de otros elementos. Esto es muy útil cuando hay múltiples elementos similares en la página.

python

# Encontrar el botón "Eliminar" dentro de la fila del producto "Zapatillas"
fila_producto = page.get_by_role("row", name="Zapatillas")
fila_producto.get_by_role("button", name="Eliminar").click()

# Encontrar un checkbox dentro de un formulario específico
formulario = page.locator("form#formulario-envio")
formulario.get_by_role("checkbox", name="Acepto los términos").check()

El método filter — para refinar locators

Cuando get_by_role o get_by_text devuelven múltiples elementos, puedes usar filter para quedarte con el que necesitas.

python

# Si hay varios botones "Eliminar", filtrar por el que está visible
page.get_by_role("button", name="Eliminar").filter(has_text="Confirmar").click()

# Filtrar por elemento contenido
page.get_by_role("listitem").filter(
    has=page.get_by_text("En stock")
).first.click()

La jerarquía de locators — cuál elegir

Cuando tengas que elegir cómo localizar un elemento sigue esta jerarquía de mejor a peor:

Primero intenta con get_by_role — es el más semántico y robusto. Si no funciona, prueba get_by_label para campos de formulario o get_by_placeholder si el campo tiene placeholder. Para texto visible usa get_by_text. Si el equipo de desarrollo usa data-testid, usa get_by_test_id. Como último recurso usa selectores CSS simples por ID. Evita XPath salvo que no haya alternativa.

Si quieres ver cómo uso los locators en proyectos reales puedes visitar mi repositorio qa-suite-saucedemo en GitHub.

Si quieres profundizar en Playwright puedes leer qué es el Page Object Model o cómo eliminar tests flaky.

Y si necesitas implementar automatización con Playwright en tu proyecto puedes ver mis servicios en fatimaqa.com.

Scroll al inicio