quangpl/browser-extension-skills

extension-test

Set up and run unit, integration, and E2E tests for Chrome extensions.

Ver código fuente

Cómo usar

  1. Copia el comando y revisa el paquete antes de instalarlo en tu entorno de agente.
  2. Consulta las herramientas, credenciales y entornos necesarios en el documento original.
  3. Describe las entradas y el resultado deseado; contrasta la salida con las fuentes.
npx skills add https://github.com/quangpl/browser-extension-skills --skill extension-test

Antes de empezar

  • La instalación no incluye suscripción al modelo, cuota API ni permisos sobre tus archivos.
  • Las estrellas e instalaciones reflejan actividad, no una prueba independiente de calidad o seguridad.
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

Extension Testing

🚀 Upgrade to Premium Get the Premium version at https://app.extensionbooster.net/dashboard/services/extension-ai-kit

Testing Layer Architecture

Unit Tests (Jest)          → Test isolated logic, chrome.* API mocks
Integration Tests (Jest)   → Test service interactions, message passing
E2E Tests (Puppeteer)      → Test in real Chrome with extension loaded

Critical constraint: Extensions CANNOT run in headless mode. E2E requires headless: false or Chrome's --headless=new (Chrome 112+).


Layer 1: Unit + Integration (Jest)

Install

bash
npm install -D jest @types/jest ts-jest jest-chrome
# For React popup:
npm install -D @testing-library/react @testing-library/jest-dom jsdom

jest.config.ts

ts
export default {
  preset: "ts-jest",
  testEnvironment: "jsdom",
  setupFilesAfterEnv: ["./jest.setup.ts"],
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1",
  },
};

jest.setup.ts (minimal)

ts
import chrome from "jest-chrome";
Object.assign(global, { chrome });

Full mock setup → chrome-api-mocks.md Unit/integration patterns → unit-integration-testing.md


Layer 2: E2E (Puppeteer)

Install

bash
npm install -D puppeteer

Launch extension in Chrome

ts
import puppeteer from "puppeteer";
import path from "path";

const browser = await puppeteer.launch({
  headless: false, // extensions require non-headless
  args: [
    `--disable-extensions-except=${path.resolve("dist")}`,
    `--load-extension=${path.resolve("dist")}`,
  ],
});

Get extension ID

ts
const targets = await browser.targets();
const extTarget = targets.find((t) => t.type() === "service_worker");
const extUrl = extTarget?.url() ?? "";
const [, , extId] = extUrl.split("/");

Full E2E patterns → e2e-testing-puppeteer.md


Chrome API Mocking Strategy

APIApproach
chrome.storageMock with in-memory store
chrome.runtime.sendMessagejest.fn() + mock response
chrome.tabsjest.fn() with createMockTab helper
chrome.actionjest.fn() stubs
chrome.alarmsjest.fn() stubs

All mocks → chrome-api-mocks.md


package.json Scripts

json
{
  "scripts": {
    "test:unit": "jest --testPathPattern=unit",
    "test:integration": "jest --testPathPattern=integration",
    "test:e2e": "jest --testPathPattern=e2e --runInBand",
    "test": "npm run test:unit && npm run test:integration"
  }
}
Run E2E separately (--runInBand) — Puppeteer tests must run serially.

Reference Files