Prueba extensiones de Chrome con Puppeteer

Puppeteer proporciona un framework para compilar pruebas automatizadas de sitios web, que también incluye la capacidad de probar extensiones de Chrome. Estas son pruebas de extremo a extremo de alto nivel que prueban la funcionalidad de un sitio web o una extensión una vez que se incorporaron al producto final. En este instructivo, mostramos cómo escribir una prueba básica para una extensión de nuestro repositorio de muestras.

Antes de comenzar

Clona o descarga el repositorio chrome-extensions-samples. Usaremos la demostración de la API de History en api-samples/history/showHistory como nuestra extensión de prueba.

También deberás instalar Node.JS, que es el entorno de ejecución en el que se basa Puppeteer.

Cómo escribir tu prueba

Paso 1: Inicia tu proyecto de Node.js

Debemos configurar un proyecto básico de Node.js. En una carpeta nueva, crea un archivo package.json con el siguiente contenido:

package.json:

{
  "name": "puppeteer-demo",
  "version": "1.0"
}

Al igual que el archivo manifest.json de una extensión, todos los proyectos de Node requieren este archivo.

Paso 2: Instala Puppeteer y Jest

Ejecuta npm install puppeteer jest para agregar Puppeteer y Jest como dependencias. Se agregarán automáticamente a tu archivo package.json.

Es posible escribir pruebas de Puppeteer independientes, pero usaremos Jest como ejecutor de pruebas para proporcionar una estructura adicional a nuestro código.

Paso 3: Crea un punto de entrada

Crea un archivo nuevo llamado index.test.js y agrega el siguiente código:

index.test.js:

const puppeteer = require('puppeteer');

const EXTENSION_PATH = '../../api-samples/history/showHistory';

let browser;
let worker;

beforeEach(async () => {
  // TODO: Launch the browser.
});

afterEach(async () => {
  // TODO: Close the browser.
});

Paso 4: Inicia el navegador

Actualiza beforeEach y afterEach para iniciar y cerrar el navegador. Cuando ejecutes muchas pruebas, tal vez te convenga usar el mismo navegador. Sin embargo, por lo general, no se recomienda, ya que reduce el aislamiento entre las pruebas y puede hacer que una prueba afecte el resultado de otra.

index.test.js:

beforeEach(async () => {
  browser = await puppeteer.launch({
    headless: false,
    pipe: true,
    enableExtensions: [EXTENSION_PATH]
  });
});

afterEach(async () => {
  await browser.close();
  browser = undefined;
});

Paso 5: Espera al service worker de la extensión

Debemos esperar a que se inicie el trabajador de servicio de la extensión para poder usarlo más adelante y abrir la ventana emergente. Actualiza tu función beforeEach con el siguiente código:

beforeEach(async () => {
  browser = await puppeteer.launch({
    headless: false,
    pipe: true,
    enableExtensions: [EXTENSION_PATH]
  });

  const workerTarget = await browser.waitForTarget(
    // Assumes that there is only one service worker created by the extension
    // and its URL ends with service-worker.js.
    (target) =>
      target.type() === 'service_worker' &&
      target.url().endsWith('service-worker.js')
  );

  worker = await workerTarget.worker();
});

Paso 6: Agrega un alias

Para facilitar la ejecución de las pruebas, agrega un alias a tu archivo package.json:

package.json:

{
  "name": "puppeteer-demo",
  "version": "1.0",
  "dependencies": {
    "puppeteer": "^24.8.1"
  },
  "scripts": {
    "start": "jest ."
  }
}

Esto ejecutará todos los archivos que terminen en .test.js en el directorio actual.

Paso 7: Abre la ventana emergente

Agrega una prueba básica. Primero, abriremos una página nueva para que haya un elemento en el historial del navegador. Luego, abriremos la ventana emergente para ver el contenido del historial. Agrega el siguiente código:

index.test.js:

test('popup renders correctly', async () => {
  // Open a page to add a history item.
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Open the extension popup.
  await worker.evaluate('chrome.action.openPopup();');

  const popupTarget = await browser.waitForTarget(
    // Assumes that there is only one page with the URL ending with popup.html
    // and that is the popup created by the extension.
    (target) => target.type() === 'page' && target.url().endsWith('popup.html')
  );
});

Paso 8: Confirma el estado actual

Afirma algo para que nuestra prueba pueda fallar si la extensión no se comporta como se espera. Sabemos que nuestra ventana emergente debe mostrar las páginas visitadas recientemente, así que verifica que veamos una:

index.test.js:

test('popup renders correctly', async () => {
  // Open a page to add a history item.
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Open the extension popup.
  await worker.evaluate('chrome.action.openPopup();');

  const popupTarget = await browser.waitForTarget(
    // Assumes that there is only one page with the URL ending with popup.html
    // and that is the popup created by the extension.
    (target) => target.type() === 'page' && target.url().endsWith('popup.html')
  );

  const popup = await popupTarget.asPage();

  const list = await page.$('ul');
  const children = await list.$$('li');

  expect(children.length).toBe(1);
});

Paso 9: Ejecuta la prueba

Para ejecutar la prueba, usa npm start. Deberías ver un resultado que indique que se aprobó la prueba.

Puedes ver el proyecto completo en nuestro repositorio de chrome-extensions-samples.

Próximos pasos

Después de dominar los conceptos básicos, intenta compilar un conjunto de pruebas para tu propia extensión. La referencia de la API de Puppeteer contiene más información sobre lo que es posible hacer. Hay muchas capacidades que no se describen aquí.