Geonode logo
Geonode Team

Geonode Team

Actualizado: 7 de octubre de 2026

Publicado: 2 de septiembre de 2026

Cómo hacer una captura de pantalla con Playwright

`await page.screenshot({ path: 'shot.png' })` Hace una captura de pantalla. Esa es la parte fácil, y también es donde se detienen la mayoría de las guías. Lo más difícil es conseguir que las capturas de pantalla sean idénticas en cada ocasión, algo que tiene una importancia enorme si las vas a comparar, pero que no tiene ninguna importancia si solo vas a mirar una. Esta guía aborda ambos aspectos, además de las opciones que controlan lo que se captura y los casos en los que las capturas de pantalla son realmente la herramienta de verificación adecuada.

Nuestro interés, sin rodeos: somos Geonode y vendemos proxies, y las capturas de pantalla a través de un proxy son uno de los usos más claros de nuestro producto —comprobar cómo se ve realmente una página desde otro país es algo que ninguna API te dice—. La advertencia sincera es el coste: un navegador descarga todas las imágenes, fuentes, scripts y vídeos en precarga, por lo que hacer capturas de pantalla es lo que más ancho de banda consume en un plan de tráfico medido. Más abajo hay una sección sobre cómo reducirlo, y la técnica que se describe allí te ahorrará más dinero que elegir un proveedor más barato.

Los tres tipos de captura de pantalla

Ventana de visualización: lo que está visible en ese momento; es la opción por defecto:

await page.screenshot({ path: 'viewport.png' });

Página completa: la documentación la describe como «una captura de pantalla de una página completa desplazable, como si tuvieras una pantalla muy alta y la página cupiera en ella por completo»:

await page.screenshot({ path: 'full.png', fullPage: true });

Elemento: «A veces resulta útil hacer una captura de pantalla de un único elemento»:

await page.getByRole('article').screenshot({ path: 'element.png' });

La elección entre ellas depende principalmente de lo que vayas a hacer con el resultado. Las capturas de pantalla de la ventana de visualización responden a «¿qué ve el usuario primero?». Las capturas de pantalla de página completa responden a «qué hay en esta página». Las capturas de pantalla de elementos responden a «¿se ve bien este componente?», y son las más fiables de las tres a efectos comparativos, ya que excluyen todo aquello sobre lo que no has preguntado.

Capturas de pantalla a página completa y dónde fallan

fullPage: true es la opción más utilizada y la que presenta más limitaciones.

Es posible que el contenido de carga diferida no aparezca. Playwright se desplaza para realizar la captura, pero es posible que las imágenes y los componentes que se cargan al pasar el cursor por encima no hayan terminado de cargarse cuando finaliza la captura. La solución fiable es desplazarse deliberadamente y esperar a que aparezca el contenido que esperas:

await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await expect(page.getByRole('img').last()).toBeVisible();
await page.evaluate(() => window.scrollTo(0, 0));
await page.screenshot({ path: 'full.png', fullPage: true });

Los encabezados fijos se repiten o se desplazan de forma extraña. Los elementos con position: fixed o sticky se comportan de forma impredecible en una captura unida. La opción style —una «cadena CSS que se inyecta en la página para aplicar estilos durante la captura»— es la solución más limpia:

await page.screenshot({
  path: 'full.png',
  fullPage: true,
  style: '.sticky-header { position: absolute !important; }',
});

Las páginas muy largas generan archivos muy grandes. Un feed de desplazamiento infinito no tiene un final natural. Considera utilizar clip para capturar una región definida en su lugar, lo cual requiere «un objeto que especifique el recorte de la imagen resultante».

Las superposiciones también se capturan. Los banners de cookies, los widgets de chat y las ventanas modales aparecen en la captura de pantalla exactamente como se ven para el usuario. Si no los quieres, ciérralos primero; y si no puedes, mask es la herramienta que necesitas.

Capturas de pantalla y búferes de elementos

Las capturas de pantalla de elementos desplazan el elemento hasta que queda visible y capturan únicamente su cuadro delimitador, lo que las convierte en la opción predeterminada adecuada para las comprobaciones a nivel de componente.

const card = page.getByTestId('product-card').first();
await card.screenshot({ path: 'card.png' });

Hay dos cosas que no hacen: capturar contenido recortado por overflow: hidden

, ni capturar nada que se encuentre fuera del cuadro del elemento, aunque se superponga visualmente.

Búferes en lugar de archivos. La documentación señala que «en lugar de escribir en un archivo, puedes obtener un búfer con la imagen y procesarla posteriormente o pasarla a una herramienta de comparación de píxeles de terceros». Si omites path

, obtienes los bytes:

const buffer = await page.screenshot();
const base64 = buffer.toString('base64');

Este es el formato que te interesa siempre que la captura de pantalla se vaya a guardar en algún lugar distinto del disco local —un almacén de objetos, una API, un informe o un servicio de comparación de píxeles—. Además, evita por completo el sistema de archivos, lo cual es importante en ejecutores en contenedores, donde el disco es efímero.

Las opciones que permiten reproducir las capturas de pantalla

Si vas a comparar varias capturas de pantalla entre sí, estas opciones no son opcionales. Si solo vas a echar un vistazo a una de ellas, ignóralas.

OpciónValoresQué hace
animations

| disabled

, allow

| «Cuando se establece en "disabled", detiene las animaciones CSS durante la captura» | | caret

| hide

, initial

| «Cuando se establece en "hide", oculta el cursor de texto durante la captura de pantalla» | | mask

| Locator[]

| «Especifica los localizadores que deben enmascararse al realizar la captura de pantalla» | | maskColor

| Color CSS, valor por defecto #F0F

| «Especifica el color que se utilizará para las regiones enmascaradas» | | scale

| css

, device

| «La escala de representación de la página web» | | omitBackground

| booleano, valor por defecto false

| «Oculta el fondo blanco predeterminado y permite realizar capturas de pantalla transparentes» | | type

| png

, jpeg

, por defecto png

| «Especifica el formato de archivo de la captura de pantalla» | | quality

| 0–100 | «La calidad de la imagen para el formato JPEG» — solo JPEG | | style

| Cadena CSS | Se inserta en la página mientras dura la captura |

Los cuatro que resuelven la mayoría de los problemas de reproducibilidad:

**animations: 'disabled'

** elimina la principal fuente de diferencias entre dos capturas de la misma página. Cualquier transición CSS en curso produce un resultado de píxeles diferente en cada ejecución.

**mask

** sustituye regiones por un color liso, lo que permite excluir contenido realmente variable —marcas de tiempo, identificadores de sesión, recomendaciones personalizadas, anuncios— sin renunciar por completo a la comparación:

await page.screenshot({
  path: 'page.png',
  mask: [page.getByTestId('timestamp'), page.locator('.ad-slot')],
  maskColor: '#000000',
});

**scale: 'css'

** captura con las dimensiones en píxeles CSS en lugar de la relación de píxeles del dispositivo, de modo que un equipo con alta resolución (DPI) y un ejecutor de CI producen imágenes de tamaño comparable. Configúralo explícitamente en lugar de confiar en el valor por defecto, ya que esta es la opción que más probablemente difiera entre tu portátil y el servidor de compilación.

**caret: 'hide'

** elimina el cursor de texto parpadeante, que de otro modo aparecería en aproximadamente la mitad de tus capturas de cualquier página con un campo de entrada activo.

Hay otras tres cosas que debes fijar para garantizar la reproducibilidad, ninguna de las cuales son opciones de captura de pantalla: fija el tamaño de la ventana de visualización en tu configuración, fija la configuración regional y la zona horaria, y fija las fuentes; la disponibilidad de fuentes varía entre el equipo de un desarrollador y un contenedor, y unas fuentes diferentes implican un diseño diferente.

Capturas de pantalla automáticas al fallar una prueba

La configuración de capturas de pantalla más útil en Playwright, y solo requiere una línea:

export default defineConfig({
  use: {
    screenshot: 'only-on-failure',
    trace: 'retain-on-failure',
    video: 'retain-on-failure',
  },
});

screenshot: 'only-on-failure' captura la página en el momento en que falla una prueba y la adjunta al informe. Las opciones son off , on y only-on-failure ; on captura en cada prueba y genera una gran cantidad de archivos.

Merece la pena insistir en combinarlo con trace , ya que un rastreo incluye instantáneas del DOM, la actividad de red y todas las acciones con sus tiempos correspondientes. Una captura de pantalla te indica que la página se veía mal; un rastreo te explica por qué. Para cualquier proceso que se ejecute de forma autónoma, ambas opciones deben estar activadas.

Esta configuración es también la forma más rápida de diagnosticar esa confusa categoría de fallos en la que una página se ha cargado, pero no es la que esperabas. Una página de desafío, una redirección de inicio de sesión o una variante regional producen tiempos de espera que parecen problemas de elementos hasta que ves la captura de pantalla.

Comparación visual con toHaveScreenshot

Para realizar pruebas de regresión visual reales, en lugar de capturas ad hoc:

await expect(page).toHaveScreenshot('homepage.png');
await expect(page.getByRole('navigation')).toHaveScreenshot('nav.png');

En la primera ejecución se genera una línea de referencia; en las ejecuciones posteriores, se compara y se marca como fallo si hay diferencias. Actualiza las líneas de referencia de forma deliberada con --update-snapshots .

Tres notas prácticas.

Las líneas de referencia son específicas de cada plataforma. La representación de las fuentes varía entre los distintos sistemas operativos, por lo que una línea de referencia generada en macOS no coincidirá con una generada en un contenedor de Linux. Genera las líneas de referencia en el mismo entorno en el que se ejecutan tus pruebas —normalmente en CI, a través de un contenedor que también puedas ejecutar localmente—.

Establece un umbral de tolerancia. La coincidencia exacta de píxeles produce fallos por diferencias de suavizado que ningún ser humano notaría. Incluir «maxDiffPixels » o «maxDiffPixelRatio » en tu configuración es lo que hace que el conjunto de pruebas sea útil.

Oculta todas las variables antes de empezar. Una prueba visual que falla cada vez que cambia una marca de tiempo se desactivará en una semana, lo cual es peor que no tenerla.

Capturas de pantalla a través de un proxy

Este es un caso en el que realmente estamos en nuestro terreno, y es un buen ejemplo.

Configura el proxy en tu instalación de Playwright:

const context = await browser.newContext({
  proxy: { server: 'http://proxy.example.com:9000', username: 'u', password: 'p' },
  locale: 'de-DE',
  timezoneId: 'Europe/Berlin',
});

Fíjate en locale

y timezoneId

junto al proxy. Una dirección de salida alemana con una configuración regional de en-US

y una zona horaria de Londres es una combinación que ningún visitante real utilizaría, y muchos sitios web utilizan la configuración regional independientemente de la dirección para decidir qué contenido mostrar. Configura los tres juntos o estarás probando algo distinto de lo que pretendías.

Lo que esto realmente responde: lo que ve un visitante real en ese país. Precios regionales, visualización de la moneda, disponibilidad, banners promocionales, si tu publicidad se muestra donde has pagado por ello y qué aparece junto a tu contenido. Ninguna API te ofrece esto, porque la respuesta es una página renderizada.

Cuánto cuesta y cómo reducirlo. Un navegador descarga todo. En el tráfico residencial con tarifa por consumo —el nuestro empieza en 0,79 $/GB, consultado en septiembre de 2026 en nuestra página de precios—, una captura de pantalla realizada en veinte mercados se acumula rápidamente. Bloquear los tipos de recursos que no necesitas es la medida más eficaz:

await page.route('**/*.{woff,woff2,mp4,webm}', route => route.abort());

Fíjate en lo que no aparece en esa lista. Si el resultado final es la captura de pantalla, no puedes bloquear las imágenes, ya que eso iría en contra del objetivo. Bloquea las fuentes y los archivos multimedia, mantén las imágenes y acepta que la verificación visual es, por naturaleza, el tipo de trabajo de proxy más costoso. Cuando solo necesites confirmar el contenido del texto en lugar de la apariencia, bloquea también las imágenes y omite por completo la captura de pantalla.

Y verifica que la geolocalización se haya aplicado correctamente. Haz la captura de pantalla y examínala. Si una página capturada a través de una salida brasileña muestra los mismos precios que tu oficina, la segmentación no está funcionando, independientemente de lo que indique una consulta de IP. Este es precisamente el fallo silencioso que describimos en por qué es importante probar los proxies — y las capturas de pantalla son excepcionalmente eficaces para detectarlo, porque una persona puede verlo de un solo vistazo.

Capturas de pantalla a gran escala

Cuando tienes que hacer más de unas cuantas, hay algunas prácticas que evitan que la tarea se vuelva inmanejable.

Reutiliza el navegador, no el contexto. Iniciar un navegador consume muchos recursos; crear un contexto, en cambio, no. Para una ejecución que abarque muchas páginas o muchas regiones, ábrelo una sola vez y crea un contexto nuevo por unidad de trabajo; así dispondrás de cookies y almacenamiento aislados sin tener que pagar el coste de inicio repetidamente:

const browser = await chromium.launch();
for (const country of countries) {
  const ctx = await browser.newContext({ proxy: { server: proxyFor(country) } });
  const page = await ctx.newPage();
  await page.goto(url, { waitUntil: 'domcontentloaded' });
  await page.screenshot({ path: `shots/${country}.png`, fullPage: true });
  await ctx.close();
}
await browser.close();

No utilices networkidle como condición de espera. Las páginas con balizas de análisis, websockets o sondeos nunca quedan inactivas, y la espera agota el tiempo de espera. Espera al elemento que te indique que la página está lista:

await page.goto(url);
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
await page.screenshot({ path: 'shot.png' });

Limita la concurrencia de forma deliberada. Cada contexto del navegador consume memoria real; es normal que se utilicen unos cientos de megabytes una vez cargada la página. Ejecutar treinta en paralelo en un servidor pequeño provoca fallos que parecen tiempos de espera agotados, pero que en realidad se deben a que el equipo se queda sin espacio. Empieza con cuatro o cinco y ve aumentando mientras vigilas la memoria.

Nombra los archivos de forma que puedas encontrarlos. Un directorio con nombres del tipo screenshot-1.png hasta screenshot-400.png es inutilizable. Incluye el destino, la región y una marca de tiempo en el nombre del archivo, y guarda la URL junto con la imagen.

Comprime antes de archivar. El formato PNG no tiene pérdida de calidad, pero ocupa mucho espacio. Si las imágenes están destinadas a la revisión humana y no a la comparación de píxeles, el formato JPEG, disponible en quality: 80, suele ocupar una fracción del tamaño y es visualmente indistinguible; y para una ejecución programada en veinte mercados, esa diferencia se traduce en la factura de almacenamiento.

Gestiona los fallos sin detener la ejecución. El hecho de que una página no se cargue no debería hacer que se abandonen las otras diecinueve. Encerra cada captura, registra el error y continúa; después, informa de qué objetivos han fallado en lugar de descubrir que todo el trabajo se ha interrumpido en el objetivo tres.

Cuándo una captura de pantalla no es la herramienta adecuada

Cuando lo que quieres son los datos. Si necesitas el precio, extrae el precio. Una captura de pantalla de un número es un número que luego tienes que leer a partir de una imagen. Las capturas de pantalla sirven para mostrar el aspecto; los selectores, para el contenido.

Cuando quieres saber por qué ha fallado una prueba. Un seguimiento es, sin duda, más informativo e incluye la captura de pantalla de todos modos.

Cuando la página es enorme. Las capturas de página completa de páginas con desplazamiento infinito generan archivos enormes que nadie abrirá. Recorta la zona que te interese.

Cuando estás comprobando texto. Verifica el texto. «expect(locator).toHaveText()» ofrece un mensaje de error legible; una comparación de píxeles solo te da una imagen del mismo.

Cuando necesitas archivarlo a gran escala. Las capturas de pantalla son grandes, y miles de ellas en muchos mercados suponen un gran volumen tanto de almacenamiento como de ancho de banda. Almacena hash o comparaciones y conserva las imágenes completas solo cuando haya habido algún cambio.

Preguntas frecuentes

¿Cómo se hace una captura de pantalla en Playwright?

await page.screenshot({ path: 'shot.png' }) para la ventana de visualización, { fullPage: true } para toda la página desplazable y locator.screenshot() para un único elemento. Omite path para obtener un búfer en lugar de guardar el archivo.

¿Cómo hago una captura de pantalla de toda la página?

Pasa fullPage: true. Ten en cuenta que es posible que el contenido de carga diferida aún no haya cargado y que los elementos fijos o «sticky» puedan comportarse de forma extraña en el resultado final; primero desplázate deliberadamente y utiliza la opción style para neutralizar el posicionamiento fijo durante la captura.

¿Cómo hago una captura de pantalla de un único elemento?

Llama a screenshot() sobre un localizador en lugar de sobre la página: await page.getByTestId('card').screenshot({ path: 'card.png' }). Playwright desplaza el elemento hasta que quede visible y captura su cuadro delimitador. El contenido recortado por overflow: hidden no se incluye.

¿Cómo consigo que las capturas de pantalla de Playwright sean consistentes entre ejecuciones?

Establece animations: 'disabled' y caret: 'hide', enmascara las regiones variables con mask y configura scale de forma explícita. A continuación, fija el tamaño de la ventana de visualización, la configuración regional, la zona horaria y las fuentes disponibles, ya que estos cuatro factores afectan al diseño y ninguno de ellos forma parte de las opciones de captura de pantalla.

¿Cómo puedo capturar una captura de pantalla automáticamente cuando falla una prueba?

Configura screenshot: 'only-on-failure' en el bloque use de tu configuración de Playwright. Combínalo con trace: 'retain-on-failure': un rastreo incluye instantáneas del DOM, la actividad de red y los tiempos de las acciones, lo que explica el fallo en lugar de limitarse a mostrarlo.

¿Puedo obtener una captura de pantalla en formato base64 en lugar de como un archivo?

Sí. Omite la opción path y screenshot() devolverá un búfer, que puedes convertir con buffer.toString('base64'). La documentación lo recomienda para el posprocesamiento o para enviarlo a un servicio de comparación de píxeles, y evita el uso del sistema de archivos en ejecutores de CI efímeros.

¿Cómo oculto el contenido dinámico de una captura de pantalla?

Utiliza la opción «mask» con una matriz de localizadores, lo que sustituye esas regiones por un color liso — maskColor tiene como valor predeterminado «#F0F» y se puede modificar. Así es como se mantiene la utilidad de la comparación visual en páginas que contienen marcas de tiempo, datos de sesión o publicidad.

¿Puedo realizar capturas de pantalla a través de un proxy para ver páginas regionales?

Sí, y es uno de los mejores usos que se le puede dar. Configura el proxy en el contexto del navegador y establece locale y timezoneId para que coincidan con el país —muchos sitios web utilizan la configuración regional independientemente de la dirección—. A continuación, examina la imagen resultante para confirmar que el contenido regional realmente difiere, en lugar de fiarte únicamente de una consulta de IP.

Conclusión

Hacer una captura de pantalla en Playwright es cuestión de una sola línea. Hacer una que tenga sentido requiere un poco más de trabajo.

Si la captura de pantalla está destinada a que un humano la vea de un solo vistazo —un error, un informe de fallo, una comprobación de cómo se ve una página desde Brasil—, los valores predeterminados están bien y screenshot: 'only-on-failure' en tu configuración es la línea más valiosa que puedes añadir. Combínala con un rastreo, porque un rastreo explica lo que una captura de pantalla solo muestra.

Si la captura de pantalla se va a comparar con otra, todo cambia. Desactiva las animaciones, oculta el cursor, enmascara las regiones variables, fija la escala y establece la ventana de visualización, la configuración regional, la zona horaria y las fuentes. A continuación, genera referencias en el mismo entorno en el que se ejecutan las pruebas, ya que la representación de las fuentes varía según la plataforma y una referencia de tu portátil nunca coincidirá con la de un contenedor.

Y para la verificación geográfica —que es donde una página renderizada supera realmente a los datos estructurados—, configura el proxy, la configuración regional y la zona horaria al mismo tiempo; a continuación, examina la imagen para confirmar que la segmentación ha funcionado. El ancho de banda es el coste; las imágenes son el único tipo de recurso que no se puede bloquear, y eso es, sencillamente, lo que cuesta la verificación visual.