Claude
Skills
Sign in
Back

dev-test-electron

Included with Lifetime
$97 forever

This skill should be used when the user asks to "test Electron app", "automate Electron desktop app", "debug Electron renderer", "test VS Code extension", "E2E test Electron", or needs Chrome DevTools Protocol automation for Electron applications. Use for renderer process debugging, main process control, native menu automation, and file dialog testing.

Code Reviewscripts

What this skill does


**Announce:** "I'm using dev-test-electron for Electron app automation via Chrome DevTools Protocol."

<EXTREMELY-IMPORTANT>
## REAL Test Requirements for Electron Apps

**A REAL Electron test must replicate what the user does. FAKE tests test something else.**

Before writing ANY test, verify from SPEC.md/PLAN.md:

| REAL Test Criteria | Your Test Must |
|-------------------|----------------|
| **User workflow** | Replicate exact steps (click → type → see result) |
| **Protocol** | Use SAME protocol as production (WebSocket, IPC, etc.) |
| **UI interaction** | Interact with ACTUAL UI elements user sees |
| **Verification** | Check what USER sees, not internal state |

### The Electron-Specific Fake Test Trap

**Electron apps often use WebSocket/IPC internally. Testing HTTP is a FAKE test.**

| FAKE Electron Test | Why It's Fake | REAL Test |
|--------------------|---------------|-----------|
| HTTP endpoint test | App uses WebSocket | Test WebSocket connection |
| Direct function call | User clicks button | CDP `Input.dispatchMouseEvent` or `Runtime.evaluate` click |
| Check internal state | User sees panel/status | CDP screenshot or DOM query |
| Mock IPC layer | Production uses real IPC | Test actual IPC messages |
| Skip main process | Main process has logic | Test BOTH renderer AND main |

### Before You Write a Test, Ask:

1. What protocol does this feature use? (WebSocket? IPC? HTTP?)
2. What does the user actually click/type?
3. What does the user actually SEE?
4. Am I testing the SAME code path as production?

**If any answer is "I don't know" → Go back to SPEC.md. Don't guess.**

### Rationalization Prevention (Electron-Specific)

| Thought | Reality |
|---------|---------|
| "HTTP is easier to test" | But app uses WebSocket. Test WebSocket. |
| "I can call the function directly" | User clicks a button. Use CDP Input events. |
| "CDP is complex, let me mock" | Mocking hides bugs. Use real CDP. |
| "Main process is hard to test" | Main process crashes break app. Test it. |
| "Panel state is internal" | User SEES the panel. Test what user sees. |
| "IPC is just plumbing" | IPC bugs cause silent failures. Test it. |
</EXTREMELY-IMPORTANT>

<EXTREMELY-IMPORTANT>
## Gate Reminder

Before taking screenshots or running E2E tests, you MUST complete all 6 gates from dev-tdd:

```
GATE 1: BUILD
GATE 2: LAUNCH (with file-based logging)
GATE 3: WAIT
GATE 4: CHECK PROCESS
GATE 5: READ LOGS ← MANDATORY, CANNOT SKIP
GATE 6: VERIFY LOGS
THEN: E2E tests/screenshots
```

**You loaded dev-tdd earlier. Follow the gates now.**
</EXTREMELY-IMPORTANT>

## Contents

- [Tool Availability Gate](#tool-availability-gate)
- [When to Use Electron CDP](#when-to-use-electron-cdp)
- [Connecting to Electron](#connecting-to-electron)
- [CDP Domains](#cdp-domains)
- [Renderer Process Automation](#renderer-process-automation)
- [Main Process Control](#main-process-control)
- [Verification](#verification)
- [Complete E2E Examples](#complete-e2e-examples)

# Electron E2E Testing via Chrome DevTools Protocol

<EXTREMELY-IMPORTANT>
## Tool Availability Gate

**Verify CDP tooling is available before proceeding.**

Check for these tools:
```bash
# Check for curl (CDP communication)
which curl || echo "MISSING: curl"

# Check for jq (JSON parsing)
which jq || echo "MISSING: jq"

# Check for websocat or wscat (WebSocket CLI)
which websocat || which wscat || echo "MISSING: WebSocket CLI"
```

**If missing tools:**
```
STOP: Cannot proceed with Electron CDP automation.

Missing tools needed for CDP:
- curl (for HTTP requests)
- jq (for JSON parsing)
- websocat or wscat (for WebSocket communication)

Install with:
  # macOS: Install via nix-darwin (see ~/nix/). Do NOT use brew.
  # Linux: sudo apt install curl jq websocat

Reply when installed and I'll continue testing.
```

**This gate is non-negotiable. Missing tools = full stop.**
</EXTREMELY-IMPORTANT>

<EXTREMELY-IMPORTANT>
## When to Use Electron CDP

**USE Electron CDP when you need:**
- Test Electron desktop applications (VS Code, Slack, etc.)
- Debug Electron renderer process (console, DOM, network)
- Automate Electron main process (native menus, dialogs, IPC)
- Multi-window Electron testing
- Electron-specific features (webContents, BrowserWindow)
- File system operations from Electron app

**DO NOT use Electron CDP when:**
- Testing web applications only (use Chrome MCP or Playwright)
- Testing non-Electron desktop apps (use Hammerspoon for macOS, dev-test-linux for Linux)
- Need headless CI/CD for web apps (use Playwright MCP)

**For web apps or native desktop apps, discover and read the relevant skill:**
Related skills:
- Read `${CLAUDE_SKILL_DIR}/../../skills/dev-test-chrome/SKILL.md` and follow its instructions.
- Read `${CLAUDE_SKILL_DIR}/../../skills/dev-test-playwright/SKILL.md` and follow its instructions.
- Read `${CLAUDE_SKILL_DIR}/../../skills/dev-test-hammerspoon/SKILL.md` and follow its instructions.
- Read `${CLAUDE_SKILL_DIR}/../../skills/dev-test-linux/SKILL.md` and follow its instructions.
- Chrome MCP skill - web debugging
- Playwright skill - headless CI/CD
- Hammerspoon skill - macOS native
- Linux skill - Linux native

### Rationalization Prevention

| Thought | Reality |
|---------|---------|
| "Chrome MCP works for Electron" | NO. Electron has main process + renderer. Need Electron-specific CDP. |
| "Playwright can test Electron apps" | NO. Playwright is for web browsers, not Electron main process. |
| "I'll just test the renderer" | Main process matters. File dialogs, native menus need testing too. |
| "CDP is too complex" | It's the ONLY way to properly test Electron apps. Learn it. |
| "I can skip the main process" | NO. Main process crashes break the app. Test both. |

### Capability Comparison

| Capability | Electron CDP | Chrome MCP | Playwright MCP | Hammerspoon |
|------------|--------------|------------|----------------|-------------|
| Electron renderer | ✅ | ❌ | ❌ | ❌ |
| Electron main process | ✅ | ❌ | ❌ | ❌ |
| Native menus/dialogs | ✅ | ❌ | ❌ | ✅ (macOS only) |
| Multi-window Electron | ✅ | ❌ | ❌ | ✅ (macOS only) |
| Console/network debugging | ✅ | ✅ (web only) | ❌ | ❌ |
| Headless mode | ✅ | ❌ | ✅ (web only) | ❌ |
| WebSocket IPC | ✅ | ❌ | ❌ | ❌ |
</EXTREMELY-IMPORTANT>

## Connecting to Electron

<EXTREMELY-IMPORTANT>
### The Iron Law of Connection

**EVERY Electron E2E test MUST establish CDP connection BEFORE any automation.**

You CANNOT automate without:
1. Launching Electron with CDP enabled
2. Discovering the CDP WebSocket URL
3. Connecting to the WebSocket
4. Verifying the connection works

| Action | Why It Fails Without Connection |
|--------|----------------------------------|
| Send CDP command | No connection = command never sent |
| Read console logs | Can't receive events without WebSocket |
| Navigate to page | CDP Page.navigate requires connection |
| Take screenshot | CDP Page.captureScreenshot requires connection |

**"App is running" ≠ "CDP is connected". Verify connection first.**
</EXTREMELY-IMPORTANT>

### Enable Remote Debugging

Launch Electron with remote debugging port:

```bash
# Option 1: Fixed port
/path/to/electron-app --remote-debugging-port=9222

# Option 2: Random port (app outputs port number)
/path/to/electron-app --remote-debugging-port=0

# Option 3: With logging
/path/to/electron-app --remote-debugging-port=9222 --enable-logging --log-file=/tmp/electron.log 2>&1 &
```

**CRITICAL:** For GATE 2 (LAUNCH), always use `--log-file` flag for file-based logging.

### Discover CDP WebSocket URL

```bash
# Get list of inspectable targets
curl -s http://localhost:9222/json/list | jq '.'

# Extract WebSocket URL for main target
WS_URL=$(curl -s http://localhost:9222/json/list | jq -r '.[0].webSocketDebuggerUrl')
echo "WebSocket URL: $WS_URL"
```

Example response:
```json
[
  {
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/...",
    "id": "page-id",
    "title": "My Electron App",
    "type": "pag
Files: 9
Size: 121.5 KB
Complexity: 73/100
Category: Code Review

Related in Code Review