quangpl/browser-extension-skills

extension-test

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

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/quangpl/browser-extension-skills --skill extension-test

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

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