Automatización de Google Chrome con Node.js

¿Sabías que Chrome ahora viene con la opción de ejecutarse en modo autónomo? La característica se llama Headless Chrome y hace que sea muy fácil para los desarrolladores configurar un entorno de navegador sin cabeza y ejecutar potentes pruebas automatizadas.

En este tutorial, hablaremos sobre sus diversas funciones y ejecutaremos un par de ejemplos interesantes. ¡Comencemos!

¿Qué es Chrome sin cabeza?

Headless Chrome nos permite ejecutar el navegador desde la línea de comandos sin abrir una ventana de Chrome. El entorno del navegador simulado tiene las mismas características que Chrome normal y puede cargar cualquier sitio web o aplicación que le indiquemos.

Además de eso, tenemos una gran cantidad de controles para interactuar con la página. Podemos hacer clic en los elementos, simular la entrada del teclado, cambiar el tamaño del navegador y mucho más. Usando estos controles podemos escribir una variedad de guiones útiles.

Estos son algunos ejemplos de tareas que normalmente se realizan en un entorno sin cabeza:

  • Genera capturas de pantalla y archivos PDF.
  • Navegar entre enlaces y estados de aplicaciones.
  • Automatice la entrada del usuario y las pruebas de validación de formularios.
  • Recupere datos de sitios web y SPA.
  • Supervise el rendimiento.

Debido a que Headless Chrome tiene una API de bajo nivel, es preferible acceder a ella a través de una biblioteca. Para este tutorial vamos a utilizar Titiritero. El equipo de Chrome DevTools mantiene el proyecto y tiene una excelente API con la que es muy fácil trabajar.

Instalación

Para usar Puppeteer necesitará tener instalado Node.js. Puedes averiguar cómo hacerlo aquí. Tenga en cuenta que todos los ejemplos de este tutorial se basan en gran medida en la sintaxis async/away. Solo está disponible en las versiones más recientes de Node.js, así que asegúrese de ejecutar una versión superior a v7.6.0.

node --version
v8.3.0

Vaya al directorio de su proyecto, inicialice npm e instale Puppeteer. Es posible que necesite acceso sudo.

npm init
npm i puppeteer

La instalación puede tardar un par de minutos. Esto se debe a que, a diferencia de la mayoría de los otros marcos para pruebas sin cabeza, Puppeteer descarga automáticamente una versión de Chromium para usted (alrededor de 100 MB). De hecho, es una característica muy buena, ya que no tendrá que configurar y mantener una instancia local de Chrome manualmente.

Crear un index.js archivo para trabajar y ¡estamos listos para empezar!

Captura de pantalla

Tomar capturas de pantalla con titiritero es muy fácil y hay muchas opciones disponibles para obtener los resultados exactos que necesitamos. Comenzaremos con un ejemplo básico y nos basaremos en eso.

A continuación, simplemente iniciamos un navegador sin cabeza, abrimos una página y tomamos una captura de pantalla de todo su contenido.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://tutorialzine.com');
  await page.screenshot({
    path: 'landing-page.png',
    fullPage: true
  });

  browser.close();
})();

Para ejecutar nuestra aplicación Puppeteer, solo llamaremos a index.js archivo con nodo. En un proyecto real, probablemente necesitará tener algunos scripts npm que automaticen aún más el proceso.

node index.js

Si no hubiera ningún error, deberíamos tener un langing-page.png archivo en nuestro directorio de trabajo. De forma predeterminada, las dimensiones de una captura de pantalla son 800 px por 600 px, pero como hemos establecido el fullPage marca a verdadero, nuestra imagen tiene un ancho de 800 px y una altura que se ajusta a todo el contenido de la página.

Al tomar la captura de pantalla, Puppeteer simulará una ventana del navegador con el ancho deseado. Si la página que estamos probando responde, obtendremos una instantánea de cómo se ve en esa ventana gráfica. Podemos cambiar sus dimensiones mediante el método setViewport.

await page.setViewport({
  width: 1600, 
  height: 1000
});

Usando este método, podemos modificar nuestro script para tomar múltiples capturas de pantalla de varios tamaños de dispositivos. Esto nos permitirá ver rápidamente si la capacidad de respuesta de nuestra página funciona según lo previsto.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Ann array of viewport sizes for different devices.
  const viewports = [1600, 1000, 800, 600, 500];

  await page.goto('https://tutorialzine.com');

  for(let i=0; i < viewports.length; i++) {
    let vw = viewports[i];

    // The height doesn't matter since we are screenshotting the full page.
    await page.setViewport({
      width: vw,
      height: 1000
    });

    await page.screenshot({
      path: `screen-${vw}.png`,
      fullPage: true
    });
  }

  browser.close();
})();

Ejecutar este script generará 5 imágenes, una para cada ventana que hayamos definido.

Hay muchas otras cosas que puedes hacer con el screenshot() método. Puede capturar una parte aislada de la página, cambiar la calidad y el formato de la imagen y más. Consulte los documentos aquí.

Interacción con la interfaz de usuario

Con Puppeteer podemos acceder a todos los elementos de la página. Esto incluye todo el contenido estático, como texto e imágenes, así como elementos interactivos, como enlaces, campos de entrada, botones, etc. Con controles automatizados, podemos rastrear sitios web, probar enlaces y validar formularios.

Por ejemplo, aquí hay un script que carga nuestra página de destino, abre el formulario de búsqueda y busca el término 'JavaScript'. Ejecutaremos este ejemplo con el modo sin cabeza desactivado para que podamos ver qué está pasando.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: false
  });
  const page = await browser.newPage();

  // Open page.
  await page.goto('https://tutorialzine.com');

  // Show search form.
  await page.click('.search-trigger');

  // Focus input field.
  await page.focus('#search-form-top input');

  // Type in query.
  await page.type('JavaScript', {delay: 200});

  // Submit the form.
  const searchForm = await page.$('#search-form-top');
  await searchForm.evaluate(searchForm => searchForm.submit());

  // Keep the browser open.
  // browser.close();
})();

Como estamos usando la sintaxis async/await, todos los pasos se ejecutarán en el orden correcto y esperarán a que terminen.

Conclusión

Si está buscando una manera de automatizar las pruebas de su navegador, Puppeteer es probablemente la herramienta más fácil de usar que existe. Tiene una API muy bien estructurada y una documentación clara y solo esencial que es muy fácil de seguir.

Dado que Puppeteer se basa en Headless Chrome, no podrá probar ningún navegador que no sea Chrome. Para automatizar otras plataformas, es posible que desee probar el marco de Selenium.