Locators en Playwright: roles, texto, CSS y XPath
Casi todo lo que se hace con Playwright empieza por encontrar un elemento. Para eso existen los locators, y elegir bien el tipo de locator es lo que más influye en que un script siga funcionando cuando la página cambia un poco de diseño.
Qué es un locator
Un locator no es el elemento en sí, sino la descripción de cómo encontrarlo. Se crea sin buscar nada, y la búsqueda ocurre cada vez que se usa. Esto tiene una consecuencia útil: se puede guardar un locator en una variable, y si la página se vuelve a cargar o el elemento cambia, el locator sigue funcionando porque la búsqueda se repite.
boton = page.get_by_role("button", name="Enviar")
boton.click() # aquí es cuando se busca el elemento
Por rol
Es la opción preferida por la documentación de Playwright. El rol es lo que el elemento es para una persona o para un lector de pantalla: un botón, un enlace, un campo de texto, un encabezado.
page.get_by_role("button", name="Enviar")
page.get_by_role("link", name="Ver más")
page.get_by_role("textbox", name="Email")
page.get_by_role("heading", name="Quotes to Scrape")
Ese tipo de locator depende de lo que se ve en pantalla y no de la estructura interna del HTML, así que sobrevive a rediseños que cambian las clases de CSS.
Por etiqueta y por placeholder
Para los campos de formulario hay dos atajos. El primero busca por el texto de la etiqueta asociada, y el segundo por el texto de ayuda que aparece dentro del campo vacío.
page.get_by_label("Username")
page.get_by_placeholder("Escribe tu email")
Por texto
page.get_by_text("Iniciar sesión")
page.get_by_text("Iniciar sesión", exact=True)
Aquí hay una confusión muy extendida. Sin exact=True, la búsqueda encuentra cualquier elemento cuyo texto contenga lo indicado, sin distinguir mayúsculas de minúsculas. Con exact=True el texto tiene que coincidir completo y respetando las mayúsculas. Es decir, el comportamiento por defecto es el de una coincidencia parcial.
Existen además get_by_alt_text() para imágenes, get_by_title() para el atributo title y get_by_test_id() para elementos con un atributo data-testid, que algunos equipos añaden al HTML precisamente para facilitar la automatización.
Por selector CSS
page.locator("h1") # etiqueta
page.locator(".card-title") # clase
page.locator("#submit-btn") # id
page.locator("ul.results li") # elemento anidado
page.locator("input[type='email']") # atributo
Es el método más flexible y el que más se encuentra en código antiguo. Su debilidad es que depende de nombres de clase que los desarrolladores cambian con frecuencia. Si se usan, es preferible elegir atributos estables como name, id o data-*, y evitar las clases generadas automáticamente, con nombres como css-1x2y3z.
Por XPath
page.locator("//div[@class='producto']//span[@class='precio']")
XPath resuelve situaciones que CSS no alcanza, como subir al elemento padre o buscar por el texto de un hermano. Se usa solo cuando no queda otra opción, porque estas expresiones se vuelven difíciles de leer enseguida.
Elegir uno entre varios
Un locator puede encontrar más de un elemento. Playwright es estricto en eso: si una acción como click() se aplica a un locator con varios resultados, lanza un error de “strict mode violation” que indica cuántos elementos coinciden. No elige uno al azar, y es una protección útil. Para especificar cuál se quiere hay varias opciones:
citas = page.locator(".quote")
citas.first # la primera
citas.last # la última
citas.nth(2) # la tercera (se cuenta desde cero)
citas.filter(has_text="Einstein") # solo las que contienen ese texto
citas.nth(0).locator(".author") # buscar dentro de un elemento
El último ejemplo muestra el encadenado: un locator se puede usar como punto de partida para buscar dentro de él, y así se limita la búsqueda a una parte de la página.
Cuál conviene usar
| Situación | Locator recomendado |
|---|---|
| Botones, enlaces y encabezados | get_by_role |
| Campos de formulario | get_by_label o get_by_placeholder |
| Texto visible que identifica al elemento | get_by_text |
| Elementos sin nada visible que los distinga | CSS con atributos estables |
| Relaciones entre elementos que CSS no expresa | XPath |
Cuando no se sabe qué locator escribir, el generador de código de Playwright lo propone al hacer clic sobre el elemento.