| name | electron-driver |
| description | E2E Testing & Automation for Electron Apps (Playwright) |
| model | sonnet |
| version | 0.1.0 |
| source | fork |
| checksum | e44a4288375c0d42cb602a811d60898e45f8ec8dc3eac176f5890244b7f1afc6 |
| updated_at | 2026-02-06T07:19:11.000Z |
| layer | domain |
Electron Driver Skill
The standard tool for End-to-End (E2E) Verification of Electron Applications.
Use this skill when you need to:
- Verify UI functionality (clicking buttons, checking text, form submission).
- Run automated regression tests on a packaged or local Electron app.
- Drive the application to reproduce bugs or set up state.
- Inspect the DOM and console of a running Electron process.
Supports two robust modes: Launch (Clean E2E Test) and Attach (Live Debugging).
- Launch: Start a new Electron instance with a controlled environment.
- Attach: Connect to an existing process via CDP (requires
--remote-debugging-port).
- Inspect: Smartly find the main window (ignoring DevTools).
- Interact: Click, type, and verify using modern Playwright Locators.
Integration with e2e and tdd
electron-driver is the Electron-specific execution backend in the testing stack:
$tdd validates core logic and IPC units first.
$e2e defines end-user journey scenarios.
$electron-driver executes those scenarios against real Electron runtime windows/processes.
Use this skill when $e2e detects Electron context or when desktop-runtime debugging is required.
Prerequisites
- Playwright:
npm install playwright-core (locally preferred) or npm install -g playwright-core.
- Electron Executable:
- For Launch: Path to the Electron executable (e.g.,
node_modules/.bin/electron or the packaged app).
- For Attach: The target app MUST be running with
--remote-debugging-port=<port>.
Strategy Selection
| Mode | Use Case | Pros | Cons |
|---|
| Launch | Automated tests, reproducible tasks | Clean env, no port conflicts, auto-close | Slower start, loses current app state |
| Attach | Debugging current session, "Drive my app" | Preserves state, instant feedback | Complex setup (ports), fragile |
Usage
1. Launch Mode (Recommended)
Create a script that launches the app.
File: test-driver.cjs (Use .cjs to avoid ESM/CJS issues)
const { _electron: electron } = require('playwright-core');
(async () => {
const app = await electron.launch({
args: ['.'],
env: { ...process.env, NODE_ENV: 'development' }
});
try {
const page = await app.firstWindow();
if (page.url().startsWith('devtools://')) {
}
console.log(`Title: ${await page.title()}`);
await page.getByRole('button', { name: 'Login' }).click();
await expect(page.getByText('Welcome')).toBeVisible();
page.().();
} (err) {
.(err);
} {
app.();
}
})();
2. Attach Mode (Debugging)
Pre-check: Ensure app is running with --remote-debugging-port=9222 (or check console for actual port).
File: attach-driver.cjs
const { chromium } = require('playwright-core');
(async () => {
try {
const browser = await chromium.connectOverCDP('http://localhost:9222');
const context = browser.contexts()[0];
const pages = context.pages();
const page = pages.find(p => !p.url().startsWith('devtools://'));
if (!page) throw new Error('No valid app window found');
await page.locator('#submit-btn').click();
await browser.close();
} catch (e) {
console.error(e);
}
})();
Playwright Modern Cheatsheet
- Locators (Preferred):
page.getByRole('button', { name: 'Save' })
page.getByText('Hello World')
page.getByPlaceholder('Email')
page.locator('.css-class')
- Actions:
await locator.click()
await locator.fill('text')
- Waiting:
- ❌
await page.waitForSelector(...) (Old)
- ✅
await locator.waitFor() (Explicit)
- ✅
await locator.click() (Auto-waits)
Troubleshooting
- ESM Error:
SyntaxError: Cannot use import statement... -> Save file as .mjs or change project type. Recommendation: Always save temp scripts as .cjs and use require.
- DevTools Window: If the script interacts with the inspector instead of the app, check the window filtering logic.
- Port Conflict: If 9222 is busy, try a different port in Launch args or Attach URL.