- Mar 17, 2026
Locators en Playwright: por qué ya no vas a extrañar a Selenium (o sí, pero solo un poco)
Si venís del mundo de Selenium (y siendo parte de la comunidad de Free Range Testers, hay bastantes chances de que así sea) probablemente ya tengas una relación de amor/odio con los locators. Por un lado, lograste dominar XPath como si fuera tu idioma nativo. Por el otro, más de una vez quisiste tirar la computadora cuando un test que funcionaba perfecto empezó a fallar sin que nadie tocara nada... solo porque el dev movió un <div>.
Buenas noticias: Playwright tiene una forma de localizar elementos que cambia bastante las reglas del juego. Veamos por qué.
Primero, un repaso de cómo localiza elementos Selenium
En Selenium, para interactuar con un elemento web necesitás identificarlo usando la clase By, que te da varias estrategias: By.ID, By.NAME, By.CLASS_NAME, By.CSS_SELECTOR, By.XPATH, entre otras.
En Java, se ve algo así:
WebDriver driver = new ChromeDriver();
driver.get("<https://ejemplo.com>");
// Por ID
WebElement boton = driver.findElement(By.id("submit-btn"));
// Por XPath
WebElement campo = driver.findElement(By.xpath("//input[@name='username']"));
// Por CSS
WebElement titulo = driver.findElement(By.cssSelector("h1.main-title"));
Y en Python:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("<https://ejemplo.com>")
# Por ID
boton = driver.find_element(By.ID, "submit-btn")
# Por XPath
campo = driver.find_element(By.XPATH, "//input[@name='username']")
# Por CSS
titulo = driver.find_element(By.CSS_SELECTOR, "h1.main-title")
El problema no está tanto en la sintaxis sino en lo que pasa después: ¿el elemento está visible? ¿Ya cargó? ¿Está habilitado? Selenium, por defecto, no se hace cargo de esas preguntas. Vos sí. Y ahí empiezan los Thread.sleep(), los WebDriverWait y el festival de TimeoutException a las 2 de la mañana.
Ahora hablemos de Playwright
Playwright toma un camino completamente distinto. En lugar de darte una lista de estrategias intercambiables, te propone locators semánticos que piensan como lo haría un usuario (o como lo haría un test de accesibilidad bien escrito).
getByRole
Este es el que Playwright te va a recomendar en casi todos los casos. Localiza elementos según su rol ARIA, que es justamente cómo los navegadores y las tecnologías de asistencia ven la página.
await page.getByRole('button', { name: 'Enviar' }).click();
await page.getByRole('textbox', { name: 'Usuario' }).fill('agustina');
await page.getByRole('heading', { name: 'Bienvenida' }).isVisible();
¿Por qué esto es más robusto? Porque si el dev cambia el id del botón o mueve el elemento en el DOM, el test sigue funcionando siempre y cuando el botón siga siendo un botón con el texto "Enviar". Estás testeando comportamiento, no implementación.
getByText
Para cuando necesitás encontrar un elemento por su contenido de texto visible.
await page.getByText('¿Olvidaste tu contraseña?').click();
getByLabel
Perfecto para formularios. Busca inputs asociados a una <label>.
await page.getByLabel('Correo electrónico').fill('agustina@ejemplo.com');
getByPlaceholder
Para inputs que tienen un placeholder pero no una label visible.
await page.getByPlaceholder('Buscá un producto...').fill('zapatillas');
getByTestId
Cuando el equipo de desarrollo agrega atributos data-testid específicos para testing.
await page.getByTestId('checkout-button').click();
getByAltText y getByTitle
Para imágenes y elementos con atributo title.
await page.getByAltText('Logo de la empresa').isVisible();
La comparativa que estabas esperando
Escenario 1: hacer login
Selenium (Java)
driver.findElement(By.id("username")).sendKeys("agustina");
driver.findElement(By.id("password")).sendKeys("1234");
driver.findElement(By.cssSelector("button[type='submit']")).click();
Playwright (TypeScript)
await page.getByLabel('Usuario').fill('agustina');
await page.getByLabel('Contraseña').fill('1234');
await page.getByRole('button', { name: 'Ingresar' }).click();
La versión de Playwright describe qué hace el usuario, no qué atributo tiene el elemento. Es más fácil de leer, de mantener y de entender cuando falla.
Escenario 2: verificar un mensaje de error
Selenium (Python)
mensaje = driver.find_element(By.XPATH, "//div[@class='error-message' and contains(text(),'Usuario incorrecto')]")
assert mensaje.is_displayed()
Playwright (TypeScript)
await expect(page.getByText('Usuario incorrecto')).toBeVisible();
Menos código. Sin XPath. Y encima Playwright va a reintentar automáticamente esta assertion hasta que el elemento aparezca o hasta que se acabe el timeout. No necesitás escribir un wait explícito.
Escenario 3: trabajar con un menú desplegable
Selenium (Java)
WebElement dropdown = driver.findElement(By.id("categoria"));
Select select = new Select(dropdown);
select.selectByVisibleText("Electrónica");
Playwright (TypeScript)
await page.getByLabel('Categoría').selectOption('Electrónica');
¿Y si igual necesito CSS o XPath en Playwright?
Totalmente válido. Playwright también los soporta para casos donde los locators semánticos no alcanzan:
// CSS Selector
await page.locator('input.search-box').fill('playwright');
// XPath
await page.locator('//table//tr[2]/td[1]').innerText();
// Combinando locators
await page.getByRole('list').getByRole('listitem').filter({ hasText: 'Destacado' }).click();
Pero la recomendación de Playwright es clara: los locators semánticos primero. El CSS y el XPath quedan para cuando no hay otra.
¿Qué hace a los locators de Playwright más robustos?
Todo se reduce a tres cosas:
Piensan como el usuario. getByRole('button', { name: 'Comprar' }) falla si y solo si ese botón deja de existir o de llamarse "Comprar". No le importa si le cambiaron el id o si alguien le agregó una clase CSS.
El auto-waiting está incorporado. Playwright no intenta interactuar con un elemento hasta que esté visible, habilitado y listo para recibir acciones. En Selenium, eso era tu problema.
Los locators son lazy. Un page.getByRole('button', { name: 'Enviar' }) no busca el elemento en el momento en que se declara, sino cuando se usa. Esto permite encadenarlos, filtrarlos y componerlos sin preocuparte por el orden de carga de la página.
¿Querés aprender más?
Si todo esto te despertó el apetito y querés ir más a fondo, en Free Range Testers tenemos cursos completos para que domines estas herramientas:
🎓 Curso de Playwright con TypeScript — para que domines E2E testing moderno de punta a punta.
☕ Curso de Selenium con Java — si tu stack es Java, acá aprendés a usarlo bien: locators, waits, Page Object Model y más.
🐍 Curso de Selenium con Python — la misma potencia pero en Python, ideal si preferís ese lenguaje para tu automatización.
Los cursos de Java y Python son independientes entre sí, así que podés elegir el que mejor se adapte a tu stack sin tener que hacer los dos.
La conclusión es bastante clara: Playwright no solo modernizó la forma en que hacemos testing, sino que cambió la filosofía detrás de cómo encontramos los elementos. Menos frágil, más expresivo, más cercano a la experiencia real del usuario. Si todavía no lo probaste, este es un buen momento para arrancar.
Y si ya lo estás usando pero seguís escribiendo XPaths por costumbre... bueno, no te juzgamos. Pero ahora ya no tenés excusas. 😄
- Entrega gratuita por correo electrónico
La guía 2025 para conseguir trabajo en Testing de Software
- Descarga digital
- 1 archivo