quangpl/browser-extension-skills

extension-test

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

Quelltext ansehen

Verwendung

  1. Installationsbefehl kopieren und das Quellpaket vor der Installation in der eigenen Agentenumgebung prüfen.
  2. Benötigte Werkzeuge, Zugangsdaten und Hosts im Original prüfen.
  3. Eingabe und gewünschtes Ergebnis beschreiben und die Ausgabe mit den Quellen abgleichen.
npx skills add https://github.com/quangpl/browser-extension-skills --skill extension-test

Vor dem Start

  • Die Installation umfasst weder Modellabo noch API-Kontingent oder Dateizugriffsrechte.
  • Sterne und Installationen zeigen Aktivität, keine unabhängige Qualitäts- oder Sicherheitsprüfung.
Originales Skill-Dokument

Aus dem Quell-Repository gerendert; Überschriften, Beispiele, Code, Tabellen, Links und Bilder bleiben erhalten.

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