chrome-ext-testing — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited chrome-ext-testing (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Extension testing spans three tiers: unit tests for pure logic, integration tests for messaging/storage/UI, and E2E tests for multi-context journeys. Vitest with @webext-core/fake-browser handles the first two. Playwright handles E2E with real browser contexts.
| Tier | Framework | Why |
|---|---|---|
| Unit | Vitest | Fast, Vite-native, works with WXT |
| Integration | Vitest Browser Mode | Real browser DOM for authentic behavior |
| E2E | Playwright | Isolated browser contexts, Shadow DOM piercing |
Test pure logic, utilities, and API-mocked code with @webext-core/fake-browser:
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
setupFiles: ['./test/setup.ts'],
},
});
// test/setup.ts
import { fakeBrowser } from '@webext-core/fake-browser';
vi.stubGlobal('browser', fakeBrowser);
vi.stubGlobal('chrome', fakeBrowser);What to test:
import { describe, it, expect } from 'vitest';
describe('storage utils', () => {
it('reads with defaults', async () => {
const result = await chrome.storage.local.get({ theme: 'light' });
expect(result.theme).toBe('light');
});
it('persists and retrieves data', async () => {
await chrome.storage.local.set({ count: 42 });
const { count } = await chrome.storage.local.get('count');
expect(count).toBe(42);
});
});Test UI interactions, messaging, and storage flows:
describe('Popup', () => {
it('loads settings from storage', async () => {
await chrome.storage.local.set({ theme: 'dark' });
render(<Popup />);
expect(screen.getByRole('button', { name: /dark/i })).toBeInTheDocument();
});
it('saves settings on change', async () => {
render(<Popup />);
fireEvent.click(screen.getByRole('button', { name: /toggle/i }));
const { theme } = await chrome.storage.local.get('theme');
expect(theme).toBe('dark');
});
});Test multi-context journeys across service worker, content scripts, and UI:
import { test, expect, chromium } from '@playwright/test';
test('content script injects UI', async () => {
const context = await chromium.launchPersistentContext('', {
args: [`--load-extension=.output/chrome-mv3`],
});
const page = await context.newPage();
await page.goto('https://example.com');
// Pierce Shadow DOM to find injected UI
const button = page.locator('my-extension >> button');
await expect(button).toBeVisible();
});chrome.processes, verify UI detects and retries)getByRole, getByLabelText, data-testidtoBeVisible())sleep() or timeouts~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.