Playwright es un marco de pruebas de extremo a extremo que, en palabras de su documentación, «empaqueta ejecutor, aserciones, aislamiento, paralelización y herramientas» en un solo lugar. En JavaScript se instala con npm init playwright@latest, que además descarga sus propias compilaciones de Chromium, Firefox y WebKit; en Python, con pip install pytest-playwright y playwright install. Sus tres rasgos distintivos son la espera automática, que elimina las esperas escritas a mano; los localizadores orientados a la persona usuaria, que sobreviven a los cambios de HTML; y el Trace Viewer, que permite diagnosticar un fallo de CI sin reproducirlo.
Ver índice de contenidos
- 01Qué es Playwright y qué trae incluido
- 02Requisitos antes de instalar
- 03Instalación en JavaScript y en Python
- 04Qué crea y cómo se configura
- 05Tu primer test
- 06Localizadores: la parte que más importa
- 07Espera automática y estrictez
- 08Codegen, modo UI y Trace Viewer
- 09Ejecutarlo en integración continua
- 10Errores frecuentes al empezar
- 11Preguntas frecuentes
- 12Fuentes
Qué es Playwright y qué trae incluido
Playwright es el más joven de las tres herramientas grandes de automatización de navegadores, y eso se nota en su diseño: cada decisión parece una respuesta a un problema conocido de las anteriores. Se distribuye con licencia Apache 2.0 y su versión estable al momento de escribir esta guía es la 1.62.0.
La diferencia práctica frente a Selenium está en el alcance de lo que instalás. Con Selenium obtenés control del navegador y tenés que sumarle ejecutor de pruebas, aserciones e informes; con Playwright, todo eso viene en la misma caja:
- Ejecutor de pruebas propio con paralelización y reintentos configurables.
- Aserciones que reintentan solas hasta que la condición se cumple.
- Los tres motores de navegador: Chromium, Firefox y WebKit, en compilaciones que descarga la propia herramienta.
- Aislamiento entre pruebas: cada una recibe un contexto de navegador limpio.
- Cliente HTTP para probar API en la misma suite que la interfaz.
- Codegen y Trace Viewer para generar pruebas y diagnosticar fallos.
Si todavía estás decidiendo entre las tres opciones, la comparación está en Selenium, Cypress o Playwright. Acá vamos directo a ponerlo a funcionar.
Requisitos antes de instalar
La documentación oficial declara requisitos distintos según el lenguaje:
| Requisito | JavaScript / TypeScript | Python |
|---|---|---|
| Versión del lenguaje | Node.js 22.x, 24.x o 26.x (últimas) | Python 3.8 o superior |
| Windows | Windows 11 o superior, Windows Server 2019+, o WSL | |
| macOS | macOS 14 (Sonoma) o posterior | |
| Linux | Debian 12 y 13, Ubuntu 22.04, 24.04 y 26.04 | |
| Arquitectura | x86-64 o arm64 | |
No hace falta instalar navegadores por tu cuenta: eso es parte del proceso de instalación y ocupa espacio en disco, porque baja tres motores completos.
Instalación en JavaScript y en Python
JavaScript y TypeScript
Un solo comando hace todo el trabajo, incluido el andamiaje del proyecto:
npm init playwright@latest
El comando hace cuatro preguntas: si querés TypeScript o JavaScript (TypeScript es el valor por defecto y la opción recomendada), cómo llamar a la carpeta de pruebas (tests, o e2e si tests ya existe), si querés que agregue un flujo de trabajo de GitHub Actions, y si querés que instale los navegadores —que sí, por defecto—.
Un detalle práctico: el comando se puede volver a ejecutar más adelante sin sobrescribir las pruebas que ya tengas.
Python
Acá son dos pasos, porque el complemento de pytest y los navegadores se instalan por separado:
# 1. El complemento de pytest, que es la vía recomendada
pip install pytest-playwright
# 2. Los navegadores
playwright install
# Para actualizar todo más adelante
pip install pytest-playwright playwright -U
La documentación recomienda el complemento de pytest en lugar de la biblioteca a secas, porque aporta el aislamiento de contextos y la configuración de varios navegadores sin que tengas que escribirlo.
Playwright usa sus propias compilaciones de Chromium, Firefox y WebKit, con parches que hacen posible el control directo. La documentación aclara que no funciona con las versiones de marca de Firefox ni de Safari por ese motivo. La contrapartida es muy conveniente: el motor de Safari viaja con la herramienta, así que podés probar WebKit en Windows y en Linux. Para Chrome y Edge sí puede usar los que ya tengas instalados, indicando el canal chrome o msedge.
Qué crea y cómo se configura
En un proyecto de JavaScript, la instalación deja esta estructura:
mi-proyecto/
├── playwright.config.ts # toda la configuración
├── package.json
└── tests/
└── example.spec.ts # prueba de ejemplo
Todo se centraliza en playwright.config.ts: navegadores, tiempos de espera, informes y la URL base. Una configuración mínima pero útil se ve así:
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
// Reintenta 2 veces solo en CI, donde la red es menos previsible
retries: process.env.CI ? 2 : 0,
use: {
baseURL: "https://underc0de.org/guias/",
// Guarda la traza cuando una prueba falla y se reintenta
trace: "on-first-retry"
},
// Cada "project" es una combinación de navegador y opciones
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
{ name: "firefox", use: { ...devices["Desktop Firefox"] } },
{ name: "webkit", use: { ...devices["Desktop Safari"] } }
]
});
Los projects son el mecanismo que hace que la misma prueba corra en los tres motores sin duplicar una línea de código. Y el trace: "on-first-retry" es la configuración que la documentación sugiere: no graba trazas siempre —eso cuesta rendimiento— sino solo cuando algo falló y se reintenta, que es justo cuando las necesitás.
Tu primer test
Sobre la misma página que usamos en el resto de esta serie: el índice de guías de este portal, que filtra en el cliente mientras escribís.
import { test, expect } from "@playwright/test";
test.describe("Buscador del índice de guías", () => {
test.beforeEach(async ({ page }) => {
// baseURL viene de la configuración
await page.goto("/");
});
test("filtra a una sola guía al buscar «wardriving»", async ({ page }) => {
await page.getByPlaceholder("Buscar").fill("wardriving");
// expect sobre un locator reintenta hasta que se cumpla
await expect(page.getByText("1 guía encontrada")).toBeVisible();
});
test("el título de la página es el esperado", async ({ page }) => {
await expect(page).toHaveTitle(/Underc0de/);
});
});
Y el mismo caso en Python, para ver que los conceptos son idénticos:
from playwright.sync_api import Page, expect
def test_busqueda_filtra(page: Page):
page.goto("https://underc0de.org/guias/")
page.get_by_placeholder("Buscar").fill("wardriving")
expect(page.get_by_text("1 guía encontrada")).to_be_visible()
Notá el cambio de convención de nombres —getByPlaceholder en JavaScript, get_by_placeholder en Python— pero la misma API conceptual. Eso hace que aprender Playwright en un lenguaje te sirva casi entero en los otros.
Un rasgo importante: cada prueba recibe un contexto de navegador limpio. La documentación lo resume así: «cada prueba obtiene un entorno nuevo, incluso cuando varias pruebas corren en un mismo navegador». No hay que limpiar cookies ni almacenamiento entre pruebas, y ninguna puede contaminar a la siguiente.
Localizadores: la parte que más importa
Si hay una sola sección de esta guía que conviene leer con atención, es esta. Los localizadores son lo que decide si tu suite sobrevive a los cambios de la aplicación o si hay que arreglarla cada semana.
Playwright propone un orden de preferencia explícito, con un criterio claro detrás: los localizadores «reflejan cómo perciben la página las personas y las tecnologías de asistencia». Los selectores de CSS y XPath, en cambio, «se pueden romper cuando cambia la estructura del DOM», porque dependen de detalles de implementación.
El primero de la lista merece una explicación aparte porque es el menos intuitivo y el más potente. getByRole() localiza por el rol de accesibilidad del elemento y su nombre accesible: getByRole("button", { name: "Enviar" }) encuentra el botón que una persona usuaria de lector de pantalla escucharía como «botón Enviar», sin importar si por dentro es un <button>, un <input type="submit"> o un <div> con role="button". Tiene un efecto secundario valioso: una prueba escrita así falla si alguien rompe la accesibilidad de ese control.
Esta es la diferencia conceptual con Selenium que más confusión genera. Un locator de Playwright no guarda una referencia al elemento: guarda la descripción de cómo encontrarlo, y la resuelve de nuevo en cada intento. Por eso no existe el equivalente del StaleElementReferenceException de Selenium: no hay referencia que pueda quedar huérfana.
Espera automática y estrictez
Dos mecanismos que trabajan juntos y explican por qué las suites de Playwright suelen ser más estables.
Espera automática
Antes de actuar sobre un elemento, Playwright comprueba que sea accionable: visible, estable —que no esté en movimiento—, habilitado y no tapado por otro elemento. Si todavía no cumple esas condiciones, reintenta hasta que las cumpla o se agote el tiempo. Las aserciones con expect() sobre un localizador siguen la misma lógica.
La consecuencia es que no se escriben esperas. Todo el andamiaje de WebDriverWait y condiciones esperadas que hay que montar en Selenium, acá simplemente no aparece en el código. Y como no hace falta, tampoco aparece la tentación de resolver la intermitencia con pausas fijas.
Estrictez
Los localizadores de Playwright son estrictos por diseño: si uno coincide con varios elementos y pedís una operación de un solo elemento —un clic, por ejemplo—, lanza una excepción en lugar de elegir uno al azar. Las operaciones sobre varios elementos, como count(), funcionan normalmente.
Al principio parece una molestia y en realidad es una red de seguridad: te avisa en el momento en que tu localizador se volvió ambiguo, en lugar de dejar que la prueba haga clic silenciosamente en el elemento equivocado y pase en verde por el motivo incorrecto.
Codegen, modo UI y Trace Viewer
Estas tres herramientas vienen con la instalación y son, en la práctica, la mitad del argumento a favor de Playwright.
Codegen: escribe la prueba por vos
npx playwright codegen https://underc0de.org/guias/
Se abren dos ventanas: el navegador donde interactuás con el sitio, y el Inspector de Playwright donde el código se va escribiendo mientras hacés clics. Sirve para dos cosas: arrancar rápido, y —más útil— descubrir qué localizador elegiría Playwright para un elemento que no sabés cómo referenciar. Acepta opciones de emulación como --device="iPhone 13", --color-scheme=dark o --viewport-size="800,600".
Modo UI: para trabajar mientras escribís
# Ejecutar toda la suite
npx playwright test
# Modo interactivo, con la línea de tiempo y el DOM de cada paso
npx playwright test --ui
Trace Viewer: entender un fallo sin reproducirlo
Es la herramienta que más tiempo ahorra cuando algo falla en integración continua y en tu máquina no se reproduce. Con trace: "on-first-retry" en la configuración, cada fallo reintentado deja un archivo que contiene:
- cada acción con su localizador y su duración;
- capturas en tira de película, mostrando el cambio visual;
- instantáneas del DOM antes, durante y después de cada acción;
- el código fuente con la línea correspondiente resaltada;
- registros de consola y todas las peticiones de red con cabeceras y cuerpos;
- los errores, marcados en la línea de tiempo.
npx playwright show-trace ruta/al/trace.zip
También se puede abrir arrastrando el archivo a trace.playwright.dev. La documentación aclara un punto que importa si tu traza contiene datos de un entorno interno: ese visor «carga la traza enteramente en tu navegador y no transmite ningún dato al exterior».
Ejecutarlo en integración continua
Si aceptaste la opción de GitHub Actions durante la instalación, ya tenés el flujo de trabajo listo. Si no, los comandos que hacen falta en cualquier servidor son estos dos:
# Instalar navegadores junto con sus dependencias del sistema
npx playwright install --with-deps
# Ejecutar la suite
npx playwright test
El --with-deps es el que evita el problema más habitual al montar CI en Linux: los navegadores necesitan bibliotecas del sistema que en un contenedor limpio no están, y esa opción las instala. Sin ella, el error que aparece es poco descriptivo y se pierde bastante tiempo buscando.
En modo headless por defecto y con retries: 2 solo en CI, como en la configuración de más arriba, tenés un comportamiento razonable: en tu máquina un fallo es un fallo inmediato, y en el servidor una intermitencia de red no rompe la construcción entera.
Errores frecuentes al empezar
- Escribir localizadores de CSS por costumbre. Si vienes de Selenium, la inercia es fuerte. Empezá siempre por
getByRole()y bajá en la escala solo si no queda alternativa. - Olvidar el
await. Casi toda la API es asincrónica. Una aserción sinawaitno espera nada y la prueba pasa en verde sin haber comprobado nada: es el fallo más peligroso, porque no da error. - No instalar las dependencias del sistema en CI. Usá
npx playwright install --with-deps. - Poner
trace: "on". Graba una traza de cada prueba y la documentación lo desaconseja por el costo de rendimiento.on-first-retryes el valor sensato. - Prometer «pruebas en Safari». Playwright prueba WebKit, el motor de Safari, no Safari. Alcanza para casi todo, pero no es lo mismo y conviene decirlo.
- Ignorar los errores de estrictez. Cuando avisa que un localizador coincide con varios elementos, está señalando una ambigüedad real. Precisá el localizador en lugar de agregar
.first()por reflejo.
Preguntas frecuentes
¿Por qué Playwright descarga sus propios navegadores?
Porque sus compilaciones de Chromium, Firefox y WebKit llevan parches propios que hacen posible el control directo sin driver intermedio. La documentación aclara que no funciona con las versiones de marca de Firefox ni de Safari por ese motivo. La ventaja práctica es enorme: el motor de Safari viaja con la herramienta, así que podés probar WebKit en Windows, Linux y CI sin tener una Mac. Para Chrome y Edge sí puede usar la instalación del sistema, indicando el canal chrome o msedge.
¿Playwright sirve solo para JavaScript?
No. Tiene cuatro lenguajes con soporte oficial: JavaScript y TypeScript, Python, Java y .NET. En JavaScript y TypeScript viene con su propio ejecutor de pruebas; en Python se usa con el complemento pytest-playwright; en Java con JUnit o TestNG; y en .NET con MSTest, NUnit o xUnit. Ruby no está entre los lenguajes oficiales, aunque a veces se lo mencione.
¿Qué es la espera automática y qué reemplaza?
Antes de actuar sobre un elemento, Playwright comprueba que sea accionable: visible, estable, habilitado y no tapado por otro elemento. Si todavía no lo es, reintenta hasta que lo sea o se agote el tiempo. Las aserciones con expect sobre un locator siguen la misma lógica. Eso reemplaza todas las esperas explícitas que en Selenium hay que escribir a mano, y sobre todo reemplaza las pausas fijas con sleep, que son la causa más común de suites lentas e inestables.
¿Para qué sirve el Trace Viewer?
Para entender un fallo sin reproducirlo. La traza guarda cada acción con su localizador y su duración, capturas en tira de película, instantáneas del DOM antes y después de cada acción, el código fuente resaltado, los registros de consola y todas las peticiones de red. Se activa en la configuración con la opción trace, habitualmente en on-first-retry, y se abre con npx playwright show-trace. Es lo que convierte un fallo de integración continua en algo diagnosticable.
¿Qué es la estrictez de los localizadores?
Es una decisión de diseño que previene errores silenciosos. Si un localizador coincide con varios elementos y pedís una operación de un solo elemento, como hacer clic, Playwright lanza una excepción en lugar de elegir uno al azar. Las operaciones sobre varios elementos, como contar, funcionan sin problema. En la práctica te obliga a escribir localizadores precisos, que es exactamente lo que hace que la prueba siga siendo correcta cuando la página crece.
¿Puedo probar la API además de la interfaz?
Sí, y en la misma suite. Playwright incluye un cliente HTTP propio que permite verificar respuestas de API, preparar datos antes de una prueba de interfaz o limpiar después, sin agregar otra herramienta al proyecto. Es una de las diferencias más útiles frente a Selenium, que no trae nada de eso, y una de las razones por las que conviene resolver por API todo lo que no necesite pasar por la pantalla.
Fuentes
Documentación oficial y registros de paquetes consultados para esta guía. Fecha de consulta: 27 de julio de 2026.
- Playwright. Installation. El comando
npm init playwright@latest, sus opciones, la estructura que genera y los requisitos de sistema. - Playwright. Installation (Python). Instalación con
pytest-playwrightyplaywright install, y requisitos de Python. - Playwright. Writing tests. Estructura de una prueba, aserciones y aislamiento entre pruebas.
- Playwright. Locators. Los localizadores integrados, el orden de preferencia y la estrictez.
- Playwright. Auto-waiting. Las comprobaciones de accionabilidad previas a cada acción.
- Playwright. Test generator. El comando
codegeny sus opciones de emulación. - Playwright. Trace viewer. Valores de la opción
trace, contenido de una traza y formas de abrirla. - Playwright. Browsers. Compilaciones propias con parches y uso de los canales de Chrome y Edge.
- Playwright. Release notes y archivo de licencia del repositorio. Versión 1.62.0 y licencia Apache 2.0 vigentes al 27 de julio de 2026.
- Underc0de, foro. «01 - Playwright - Capítulo piloto», por Mr. Bones, 16 de septiembre de 2023, sección QA. Serie de la comunidad que introdujo Playwright en el foro.
- Underc0de, foro. «Playc0de: ejecutando pruebas con Playwright desde 0», por Luca Ahumada, 14 de julio de 2023. Marco de automatización construido sobre Playwright por un integrante de la comunidad.