playwright-electron-config
Configure Playwright for comprehensive Electron application testing including E2E tests, visual regression, accessibility audits, and cross-platform test matrices
What this skill does
# playwright-electron-config
Configure Playwright for comprehensive Electron application testing. This skill sets up the complete testing infrastructure including E2E tests, visual regression testing, accessibility audits, and cross-platform test matrices with CI/CD integration.
## Capabilities
- Configure Playwright for Electron with `_electron` fixture
- Generate page object models for Electron windows
- Set up visual regression testing with snapshots
- Configure accessibility testing with axe-core
- Create cross-platform test matrices for CI
- Mock Electron APIs (dialog, shell, clipboard)
- Test IPC communication between main and renderer
- Generate test coverage reports
## Input Schema
```json
{
"type": "object",
"properties": {
"projectPath": {
"type": "string",
"description": "Path to the Electron project root"
},
"testDir": {
"type": "string",
"default": "tests/e2e"
},
"features": {
"type": "array",
"items": {
"enum": [
"visualRegression",
"accessibility",
"coverage",
"performance",
"ipcTesting",
"multiWindow",
"systemDialogMocks"
]
},
"default": ["visualRegression", "accessibility", "ipcTesting"]
},
"platforms": {
"type": "array",
"items": { "enum": ["windows", "macos", "linux"] },
"default": ["windows", "macos", "linux"]
},
"pageObjects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"selectors": { "type": "object" }
}
},
"description": "Page objects to generate"
},
"ciIntegration": {
"type": "object",
"properties": {
"provider": { "enum": ["github-actions", "azure-devops", "circleci", "gitlab"] },
"parallelization": { "type": "boolean", "default": true },
"sharding": { "type": "number", "description": "Number of shards" }
}
}
},
"required": ["projectPath"]
}
```
## Output Schema
```json
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": { "type": "string" },
"type": { "enum": ["config", "fixture", "pageObject", "test", "helper", "ci"] }
}
}
},
"commands": {
"type": "object",
"properties": {
"runTests": { "type": "string" },
"updateSnapshots": { "type": "string" },
"showReport": { "type": "string" }
}
},
"ciWorkflow": {
"type": "string",
"description": "Path to generated CI workflow file"
}
},
"required": ["success", "files"]
}
```
## Generated File Structure
```
tests/
e2e/
playwright.config.ts # Main Playwright config
fixtures/
electron-app.ts # Electron fixture
test-utils.ts # Test utilities
page-objects/
MainWindow.ts # Page object models
SettingsDialog.ts
specs/
app.spec.ts # Application tests
ipc.spec.ts # IPC tests
visual.spec.ts # Visual regression
a11y.spec.ts # Accessibility tests
mocks/
electron-api-mocks.ts # Electron API mocks
ipc-mocks.ts # IPC mocks
snapshots/ # Visual snapshots
reports/ # Test reports
```
## Code Templates
### Playwright Configuration for Electron
```typescript
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e/specs',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html', { outputFolder: 'tests/e2e/reports' }],
['json', { outputFile: 'tests/e2e/reports/results.json' }],
],
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{
name: 'electron',
testMatch: '**/*.spec.ts',
},
],
});
```
### Electron Test Fixture
```typescript
// fixtures/electron-app.ts
import { test as base, ElectronApplication, Page } from '@playwright/test';
import { _electron as electron } from 'playwright';
import path from 'path';
export type TestFixtures = {
electronApp: ElectronApplication;
mainWindow: Page;
};
export const test = base.extend<TestFixtures>({
electronApp: async ({}, use) => {
// Launch Electron app
const electronApp = await electron.launch({
args: [path.join(__dirname, '../../dist/main/main.js')],
env: {
...process.env,
NODE_ENV: 'test',
},
});
// Use the app in tests
await use(electronApp);
// Cleanup
await electronApp.close();
},
mainWindow: async ({ electronApp }, use) => {
// Wait for first window
const window = await electronApp.firstWindow();
// Wait for app to be ready
await window.waitForLoadState('domcontentloaded');
await use(window);
},
});
export { expect } from '@playwright/test';
```
### Page Object Model
```typescript
// page-objects/MainWindow.ts
import { Page, Locator } from '@playwright/test';
export class MainWindow {
readonly page: Page;
readonly titleBar: Locator;
readonly sidebar: Locator;
readonly mainContent: Locator;
readonly statusBar: Locator;
constructor(page: Page) {
this.page = page;
this.titleBar = page.locator('[data-testid="title-bar"]');
this.sidebar = page.locator('[data-testid="sidebar"]');
this.mainContent = page.locator('[data-testid="main-content"]');
this.statusBar = page.locator('[data-testid="status-bar"]');
}
async getTitle(): Promise<string> {
return this.page.title();
}
async openSettings(): Promise<void> {
await this.page.click('[data-testid="settings-button"]');
await this.page.waitForSelector('[data-testid="settings-dialog"]');
}
async navigateTo(section: string): Promise<void> {
await this.sidebar.locator(`[data-section="${section}"]`).click();
await this.page.waitForLoadState('networkidle');
}
async screenshot(name: string): Promise<Buffer> {
return this.page.screenshot({ path: `tests/e2e/snapshots/${name}.png` });
}
}
```
### IPC Testing
```typescript
// specs/ipc.spec.ts
import { test, expect } from '../fixtures/electron-app';
test.describe('IPC Communication', () => {
test('should send message to main process', async ({ electronApp, mainWindow }) => {
// Evaluate in main process
const result = await electronApp.evaluate(async ({ ipcMain }) => {
return new Promise((resolve) => {
ipcMain.once('test-channel', (event, data) => {
resolve(data);
});
});
});
// Send from renderer
await mainWindow.evaluate(() => {
window.electronAPI.send('test-channel', { message: 'hello' });
});
// Verify
expect(result).toEqual({ message: 'hello' });
});
test('should receive response from main process', async ({ mainWindow }) => {
const response = await mainWindow.evaluate(async () => {
return window.electronAPI.invoke('get-app-version');
});
expect(response).toMatch(/^\d+\.\d+\.\d+$/);
});
});
```
### Visual Regression Testing
```typescript
// specs/visual.spec.ts
import { test, expect } from '../fixtures/electron-app';
import { MainWindow } from '../page-objects/MainWindow';
test.describe('Visual Regression', () => {
test('main window matches snapshot', async ({ mainWindow }) => {
const page = new MainWindow(mainWindow);
// Wait for animations to complete
await mainWindow.waitForTimeout(500);
await expect(mainWindow).toHaveScreenshot('main-window.png', {
maxDiffPixels: 100,
});
});
test('dark mode matches snapshot', async ({ electronApp, mainWindow }) => {
/Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.