electron-dev-bridge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +555 -0
- package/dist/cdp-tools/dom-query.d.ts +2 -0
- package/dist/cdp-tools/dom-query.js +307 -0
- package/dist/cdp-tools/helpers.d.ts +17 -0
- package/dist/cdp-tools/helpers.js +48 -0
- package/dist/cdp-tools/index.d.ts +5 -0
- package/dist/cdp-tools/index.js +26 -0
- package/dist/cdp-tools/interaction.d.ts +2 -0
- package/dist/cdp-tools/interaction.js +195 -0
- package/dist/cdp-tools/lifecycle.d.ts +2 -0
- package/dist/cdp-tools/lifecycle.js +78 -0
- package/dist/cdp-tools/navigation.d.ts +2 -0
- package/dist/cdp-tools/navigation.js +128 -0
- package/dist/cdp-tools/state.d.ts +2 -0
- package/dist/cdp-tools/state.js +109 -0
- package/dist/cdp-tools/types.d.ts +22 -0
- package/dist/cdp-tools/types.js +1 -0
- package/dist/cdp-tools/visual.d.ts +2 -0
- package/dist/cdp-tools/visual.js +130 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +146 -0
- package/dist/cli/register.d.ts +1 -0
- package/dist/cli/register.js +40 -0
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +34 -0
- package/dist/cli/validate.d.ts +1 -0
- package/dist/cli/validate.js +65 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +3 -0
- package/dist/scanner/ipc-scanner.d.ts +6 -0
- package/dist/scanner/ipc-scanner.js +14 -0
- package/dist/scanner/schema-scanner.d.ts +6 -0
- package/dist/scanner/schema-scanner.js +14 -0
- package/dist/server/cdp-bridge.d.ts +12 -0
- package/dist/server/cdp-bridge.js +72 -0
- package/dist/server/mcp-server.d.ts +2 -0
- package/dist/server/mcp-server.js +126 -0
- package/dist/server/resource-builder.d.ts +9 -0
- package/dist/server/resource-builder.js +15 -0
- package/dist/server/tool-builder.d.ts +9 -0
- package/dist/server/tool-builder.js +39 -0
- package/dist/utils/load-config.d.ts +5 -0
- package/dist/utils/load-config.js +17 -0
- package/package.json +75 -0
- package/skills/electron-app-dev/SKILL.md +140 -0
- package/skills/electron-debugging/SKILL.md +203 -0
- package/skills/electron-e2e-testing/SKILL.md +181 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { pathToFileURL } from 'node:url';
|
|
2
|
+
/**
|
|
3
|
+
* Load an electron-mcp config file, with TypeScript support via tsx.
|
|
4
|
+
*/
|
|
5
|
+
export async function loadConfig(configPath) {
|
|
6
|
+
let mod;
|
|
7
|
+
if (configPath.endsWith('.ts')) {
|
|
8
|
+
// Use tsx's tsImport for TypeScript configs
|
|
9
|
+
const { tsImport } = await import('tsx/esm/api');
|
|
10
|
+
mod = await tsImport(configPath, import.meta.url);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
// Standard import for .js/.mjs configs
|
|
14
|
+
mod = await import(pathToFileURL(configPath).href);
|
|
15
|
+
}
|
|
16
|
+
return mod.default;
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "electron-dev-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Expose Electron IPC handlers as MCP tools for Claude Code, with 22 built-in CDP tools for DOM automation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"electron-mcp": "dist/cli/index.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"test": "node --test dist/**/*.test.js",
|
|
21
|
+
"lint": "tsc --noEmit"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"electron",
|
|
25
|
+
"mcp",
|
|
26
|
+
"model-context-protocol",
|
|
27
|
+
"claude",
|
|
28
|
+
"claude-code",
|
|
29
|
+
"cdp",
|
|
30
|
+
"chrome-devtools-protocol",
|
|
31
|
+
"ipc",
|
|
32
|
+
"testing",
|
|
33
|
+
"automation",
|
|
34
|
+
"desktop-app"
|
|
35
|
+
],
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/nicholasgriffintn/electron-dev-bridge.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/nicholasgriffintn/electron-dev-bridge/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/nicholasgriffintn/electron-dev-bridge#readme",
|
|
44
|
+
"author": "",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
47
|
+
"chrome-remote-interface": "^0.33.2",
|
|
48
|
+
"tsx": "^4.19.0",
|
|
49
|
+
"zod-to-json-schema": "^3.24.5"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"zod": "^3.0.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"zod": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=18"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"dist",
|
|
64
|
+
"skills",
|
|
65
|
+
"LICENSE",
|
|
66
|
+
"!dist/**/*.test.js",
|
|
67
|
+
"!dist/**/*.test.d.ts"
|
|
68
|
+
],
|
|
69
|
+
"license": "MIT",
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/chrome-remote-interface": "^0.33.0",
|
|
72
|
+
"@types/node": "^25.3.2",
|
|
73
|
+
"typescript": "^5.9.3"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electron-app-dev
|
|
3
|
+
description: >
|
|
4
|
+
Develop and automate Electron apps using the electron-dev-bridge bridge.
|
|
5
|
+
Trigger on: Electron app, desktop app, UI automation, DOM inspection,
|
|
6
|
+
IPC handler, screenshot, BrowserWindow, webContents, CDP tools,
|
|
7
|
+
electron-mcp, preload script, contextBridge.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Electron App Development with electron-dev-bridge
|
|
11
|
+
|
|
12
|
+
Use the MCP bridge to connect, inspect, interact with, and screenshot your Electron app directly from Claude Code.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
1. Install: `npm install electron-dev-bridge`
|
|
17
|
+
2. Generate config: `npx electron-mcp init`
|
|
18
|
+
3. Register: `npx electron-mcp register`
|
|
19
|
+
4. Start your app with `--remote-debugging-port=9229`
|
|
20
|
+
|
|
21
|
+
## Connecting
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
# Launch and connect in one step
|
|
25
|
+
electron_launch appPath="/path/to/{YOUR_APP}"
|
|
26
|
+
|
|
27
|
+
# Or connect to an already-running app (uses the port from your config)
|
|
28
|
+
electron_connect
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Always connect before using any other tools.
|
|
32
|
+
|
|
33
|
+
## Tool Reference
|
|
34
|
+
|
|
35
|
+
### Connection
|
|
36
|
+
| Tool | Use for |
|
|
37
|
+
|------|---------|
|
|
38
|
+
| `electron_launch` | Launch app with debug port and connect |
|
|
39
|
+
| `electron_connect` | Connect to running app |
|
|
40
|
+
|
|
41
|
+
### DOM Queries
|
|
42
|
+
| Tool | Use for |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `electron_query_selector` | Find one element by CSS selector |
|
|
45
|
+
| `electron_query_selector_all` | Find all matching elements (max 50) |
|
|
46
|
+
| `electron_find_by_text` | Find elements by visible text content |
|
|
47
|
+
| `electron_find_by_role` | Find elements by ARIA role |
|
|
48
|
+
| `electron_get_accessibility_tree` | Full a11y tree with roles and names |
|
|
49
|
+
|
|
50
|
+
### Interaction
|
|
51
|
+
| Tool | Use for |
|
|
52
|
+
|------|---------|
|
|
53
|
+
| `electron_click` | Click by selector or coordinates |
|
|
54
|
+
| `electron_type_text` | Type into input (provide `selector` to auto-focus) |
|
|
55
|
+
| `electron_press_key` | Press Enter, Tab, Escape, arrows, etc. |
|
|
56
|
+
| `electron_select_option` | Select dropdown option by value or text |
|
|
57
|
+
|
|
58
|
+
### State Reading
|
|
59
|
+
| Tool | Use for |
|
|
60
|
+
|------|---------|
|
|
61
|
+
| `electron_get_text` | Get innerText of element |
|
|
62
|
+
| `electron_get_value` | Get input/textarea/select value |
|
|
63
|
+
| `electron_get_attribute` | Get specific attribute |
|
|
64
|
+
| `electron_get_bounding_box` | Get element position and size |
|
|
65
|
+
| `electron_get_url` | Get current page URL |
|
|
66
|
+
|
|
67
|
+
### Navigation & Viewport
|
|
68
|
+
| Tool | Use for |
|
|
69
|
+
|------|---------|
|
|
70
|
+
| `electron_wait_for_selector` | Wait for element to appear (default 5s) |
|
|
71
|
+
| `electron_set_viewport` | Override viewport metrics for responsive testing (`width`, `height` required) |
|
|
72
|
+
| `electron_scroll` | Scroll page or element (`direction`: up/down/left/right, `amount`: pixels, `selector`: optional) |
|
|
73
|
+
|
|
74
|
+
### Screenshots & Visual
|
|
75
|
+
| Tool | Use for |
|
|
76
|
+
|------|---------|
|
|
77
|
+
| `electron_screenshot` | Capture full page or element |
|
|
78
|
+
| `electron_compare_screenshots` | Byte-level diff of two screenshots (returns `diffPercent`) |
|
|
79
|
+
| `electron_highlight_element` | Outline element in red for 3 seconds |
|
|
80
|
+
|
|
81
|
+
## Selector Strategy (priority order)
|
|
82
|
+
|
|
83
|
+
1. `[data-testid="..."]` -- most stable
|
|
84
|
+
2. `[role="..."]`, `[aria-label="..."]` -- semantic
|
|
85
|
+
3. `.bem-class-name` -- reasonably stable
|
|
86
|
+
4. Element hierarchy -- last resort
|
|
87
|
+
|
|
88
|
+
## Waiting Pattern
|
|
89
|
+
|
|
90
|
+
Always wait before interacting or capturing:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
electron_wait_for_selector selector=".content-loaded" timeout=10000
|
|
94
|
+
electron_screenshot
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Never use arbitrary sleep/delays.
|
|
98
|
+
|
|
99
|
+
## IPC Tools
|
|
100
|
+
|
|
101
|
+
If the app uses electron-dev-bridge with configured IPC handlers, tools are named by replacing colons with underscores:
|
|
102
|
+
|
|
103
|
+
| IPC channel | MCP tool name | Preload path |
|
|
104
|
+
|-------------|---------------|--------------|
|
|
105
|
+
| `{domain}:{action}` | `{domain}_{action}` | `window.electronAPI.{domain}.{action}` |
|
|
106
|
+
|
|
107
|
+
Call IPC tools directly by name once the server is registered. Tool names depend on your app's config — e.g., `profiles_query`, `settings_get`.
|
|
108
|
+
|
|
109
|
+
## Playbook: Build & Verify
|
|
110
|
+
|
|
111
|
+
1. Make code changes
|
|
112
|
+
2. `electron_launch` (or restart the app)
|
|
113
|
+
3. `electron_wait_for_selector` on the changed element
|
|
114
|
+
4. `electron_screenshot` to capture current state
|
|
115
|
+
5. Evaluate the screenshot visually
|
|
116
|
+
6. If issues: fix code, restart, re-verify
|
|
117
|
+
|
|
118
|
+
## Playbook: Explore App Structure
|
|
119
|
+
|
|
120
|
+
1. `electron_connect`
|
|
121
|
+
2. `electron_get_accessibility_tree maxDepth=5` to see the component hierarchy
|
|
122
|
+
3. `electron_query_selector_all selector="[data-testid]"` to find test hooks
|
|
123
|
+
4. `electron_screenshot` for visual context
|
|
124
|
+
5. Use findings to plan automation or testing
|
|
125
|
+
|
|
126
|
+
## Playbook: Call IPC Handlers
|
|
127
|
+
|
|
128
|
+
1. `electron_connect`
|
|
129
|
+
2. Call the IPC tool directly, e.g. `profiles_query query="test"`
|
|
130
|
+
3. Inspect the returned JSON
|
|
131
|
+
4. Use `electron_screenshot` to verify UI updated
|
|
132
|
+
|
|
133
|
+
## Screenshot Evaluation Checklist
|
|
134
|
+
|
|
135
|
+
When reviewing a screenshot, check:
|
|
136
|
+
- Layout: positioning, overlaps, overflow, alignment
|
|
137
|
+
- Text: visibility, truncation, correct content
|
|
138
|
+
- Colors: contrast, theme consistency
|
|
139
|
+
- States: hover, focus, disabled, loading, error, empty
|
|
140
|
+
- Responsiveness: behavior at current viewport size
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electron-debugging
|
|
3
|
+
description: >
|
|
4
|
+
Debug and troubleshoot Electron apps via electron-dev-bridge bridge tools.
|
|
5
|
+
Trigger on: debug, bug, broken, not working, UI issue, element not found,
|
|
6
|
+
blank screen, can't connect, crash, stale, timeout, click not working,
|
|
7
|
+
missing element, wrong text, layout broken.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Electron App Debugging with electron-dev-bridge
|
|
11
|
+
|
|
12
|
+
Systematic debugging workflows for Electron apps using the MCP bridge.
|
|
13
|
+
|
|
14
|
+
## Diagnostic Flowchart
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Problem reported
|
|
18
|
+
|
|
|
19
|
+
+-- Can you connect?
|
|
20
|
+
| NO --> See "Connection Troubleshooting"
|
|
21
|
+
| YES
|
|
22
|
+
|
|
|
23
|
+
+-- Take screenshot. Is the UI visible?
|
|
24
|
+
| NO --> See "Blank Screen / Loading Issues"
|
|
25
|
+
| YES
|
|
26
|
+
|
|
|
27
|
+
+-- Is the expected element present?
|
|
28
|
+
| NO --> See "Element Not Found"
|
|
29
|
+
| YES
|
|
30
|
+
|
|
|
31
|
+
+-- Does interaction work?
|
|
32
|
+
| NO --> See "Interaction Failures"
|
|
33
|
+
| YES
|
|
34
|
+
|
|
|
35
|
+
+-- Is the displayed content correct?
|
|
36
|
+
NO --> See "Wrong Content / State"
|
|
37
|
+
YES --> Issue may be intermittent. Add waits and retry.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Connection Troubleshooting
|
|
41
|
+
|
|
42
|
+
**Symptom:** `electron_connect` or `electron_launch` fails.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
# Step 1: Verify the app is running with debug port
|
|
46
|
+
# (run in terminal)
|
|
47
|
+
lsof -i :9229
|
|
48
|
+
|
|
49
|
+
# Step 2: If no process on port, launch with debug flag
|
|
50
|
+
electron_launch appPath="/path/to/{YOUR_APP}"
|
|
51
|
+
|
|
52
|
+
# Step 3: If port is in use by another process, use a different port
|
|
53
|
+
electron_connect port=9230
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| Error | Cause | Fix |
|
|
57
|
+
|-------|-------|-----|
|
|
58
|
+
| Connection refused | App not running or no debug port | Start app with `--remote-debugging-port=9229` |
|
|
59
|
+
| Port already in use | Another process on 9229 | Kill the process or use `electron_connect port=9230` |
|
|
60
|
+
| Target not found | App has no renderer window | Ensure a BrowserWindow is created |
|
|
61
|
+
| Connection lost mid-session | App crashed or reloaded | `electron_connect` to reconnect |
|
|
62
|
+
|
|
63
|
+
## Blank Screen / Loading Issues
|
|
64
|
+
|
|
65
|
+
**Symptom:** Screenshot shows blank or loading state.
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
# 1. Screenshot to confirm state
|
|
69
|
+
electron_screenshot
|
|
70
|
+
|
|
71
|
+
# 2. Check the URL -- is the app loading the right page?
|
|
72
|
+
electron_get_url
|
|
73
|
+
|
|
74
|
+
# 3. Wait for a known root element
|
|
75
|
+
electron_wait_for_selector selector="{YOUR_APP_ROOT}" timeout=15000
|
|
76
|
+
|
|
77
|
+
# 4. If timeout: check the accessibility tree for any content
|
|
78
|
+
electron_get_accessibility_tree maxDepth=3
|
|
79
|
+
|
|
80
|
+
# 5. Re-screenshot after waiting
|
|
81
|
+
electron_screenshot
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Common causes:**
|
|
85
|
+
- App still loading (increase timeout)
|
|
86
|
+
- Wrong URL loaded (check `electron_get_url`)
|
|
87
|
+
- JavaScript error blocking render (check app console logs)
|
|
88
|
+
- Missing preload script (app can't access IPC)
|
|
89
|
+
|
|
90
|
+
## Element Not Found
|
|
91
|
+
|
|
92
|
+
**Symptom:** `electron_query_selector` returns no match.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
# 1. Verify what IS on the page
|
|
96
|
+
electron_get_accessibility_tree maxDepth=5
|
|
97
|
+
|
|
98
|
+
# 2. Search by text instead of selector
|
|
99
|
+
electron_find_by_text text="Submit"
|
|
100
|
+
|
|
101
|
+
# 3. Search by role
|
|
102
|
+
electron_find_by_role role="button"
|
|
103
|
+
|
|
104
|
+
# 4. Try a broader selector
|
|
105
|
+
electron_query_selector_all selector="button"
|
|
106
|
+
|
|
107
|
+
# 5. Check if element is in a different part of the tree
|
|
108
|
+
electron_query_selector_all selector="iframe"
|
|
109
|
+
# If iframes exist, the element may be inside one
|
|
110
|
+
|
|
111
|
+
# 6. Highlight a similar element to verify targeting
|
|
112
|
+
electron_highlight_element selector=".some-visible-element"
|
|
113
|
+
electron_screenshot
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Common causes:**
|
|
117
|
+
- Selector typo or stale selector (class names changed)
|
|
118
|
+
- Element not yet rendered (add `electron_wait_for_selector`)
|
|
119
|
+
- Element inside shadow DOM or iframe
|
|
120
|
+
- Element conditionally rendered (check app state)
|
|
121
|
+
|
|
122
|
+
## Interaction Failures
|
|
123
|
+
|
|
124
|
+
**Symptom:** `electron_click` or `electron_type_text` has no visible effect.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
# 1. Verify the element exists and is visible
|
|
128
|
+
electron_get_bounding_box selector="{TARGET_SELECTOR}"
|
|
129
|
+
# Check: width/height > 0, coordinates are within viewport
|
|
130
|
+
|
|
131
|
+
# 2. Check if element is obscured by an overlay
|
|
132
|
+
electron_screenshot
|
|
133
|
+
# Look for modals, tooltips, or overlapping elements
|
|
134
|
+
|
|
135
|
+
# 3. Check element attributes
|
|
136
|
+
electron_get_attribute selector="{TARGET_SELECTOR}" attribute="disabled"
|
|
137
|
+
electron_get_attribute selector="{TARGET_SELECTOR}" attribute="readonly"
|
|
138
|
+
|
|
139
|
+
# 4. Try clicking by coordinates instead
|
|
140
|
+
electron_get_bounding_box selector="{TARGET_SELECTOR}"
|
|
141
|
+
# Use returned x + width/2, y + height/2 as click coordinates
|
|
142
|
+
electron_click x=150 y=200
|
|
143
|
+
|
|
144
|
+
# 5. For type_text: ensure element is focused
|
|
145
|
+
electron_click selector="{TARGET_SELECTOR}"
|
|
146
|
+
electron_type_text text="test input"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Problem | Cause | Fix |
|
|
150
|
+
|---------|-------|-----|
|
|
151
|
+
| Click no effect | Overlay blocking | Dismiss the overlay first |
|
|
152
|
+
| Click no effect | Element disabled | Check and resolve disabled state |
|
|
153
|
+
| Click no effect | Wrong coordinates | Use `electron_get_bounding_box` to verify |
|
|
154
|
+
| Type not appearing | Element not focused | Click element first, then type |
|
|
155
|
+
| Type not appearing | Input is readonly | Check `readonly`/`disabled` attributes |
|
|
156
|
+
| Key press ignored | Wrong key name | Supported: `Enter`, `Tab`, `Escape`, `Backspace`, `Delete`, `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Home`, `End`, `Space` |
|
|
157
|
+
|
|
158
|
+
## Wrong Content / State
|
|
159
|
+
|
|
160
|
+
**Symptom:** UI shows incorrect text, values, or layout.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
# 1. Read the actual content
|
|
164
|
+
electron_get_text selector="{TARGET_SELECTOR}"
|
|
165
|
+
electron_get_value selector="{INPUT_SELECTOR}"
|
|
166
|
+
|
|
167
|
+
# 2. Screenshot for visual comparison
|
|
168
|
+
electron_screenshot
|
|
169
|
+
|
|
170
|
+
# 3. Check the accessibility tree for the full component context
|
|
171
|
+
electron_get_accessibility_tree maxDepth=5
|
|
172
|
+
|
|
173
|
+
# 4. Highlight the problematic element
|
|
174
|
+
electron_highlight_element selector="{TARGET_SELECTOR}"
|
|
175
|
+
electron_screenshot
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Recovery Steps
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
# 1. Screenshot current state
|
|
182
|
+
electron_screenshot
|
|
183
|
+
|
|
184
|
+
# 2. Reconnect if stale
|
|
185
|
+
electron_connect
|
|
186
|
+
|
|
187
|
+
# 3. Check URL
|
|
188
|
+
electron_get_url
|
|
189
|
+
|
|
190
|
+
# 4. If app is in bad state, restart
|
|
191
|
+
electron_launch appPath="/path/to/{YOUR_APP}"
|
|
192
|
+
electron_wait_for_selector selector="{YOUR_APP_ROOT}" timeout=15000
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Common Error Patterns
|
|
196
|
+
|
|
197
|
+
| Error | Cause | Fix |
|
|
198
|
+
|-------|-------|-----|
|
|
199
|
+
| "No target found" | No renderer connected | `electron_connect` |
|
|
200
|
+
| "Selector not found" | Bad CSS selector | Use `electron_get_accessibility_tree` |
|
|
201
|
+
| "Timeout waiting" | Element didn't appear | Increase timeout or check conditional rendering |
|
|
202
|
+
| "Cannot find context" | CDP session expired | `electron_connect` again |
|
|
203
|
+
| "Execution context destroyed" | Page navigated | Wait for new page, retry |
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electron-e2e-testing
|
|
3
|
+
description: >
|
|
4
|
+
End-to-end testing workflows for Electron apps via electron-dev-bridge.
|
|
5
|
+
Trigger on: test, e2e, end-to-end, regression, form testing,
|
|
6
|
+
UI verification, test flow, smoke test, integration test,
|
|
7
|
+
visual regression, form fill, submit, assertion.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Electron E2E Testing with electron-dev-bridge
|
|
11
|
+
|
|
12
|
+
Structured test patterns for verifying Electron app behavior using the MCP bridge tools.
|
|
13
|
+
|
|
14
|
+
## Test Pattern: Launch, Wait, Act, Assert, Screenshot
|
|
15
|
+
|
|
16
|
+
Every test follows this structure:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
1. electron_launch / electron_connect -- establish connection
|
|
20
|
+
2. electron_wait_for_selector -- wait for ready state
|
|
21
|
+
3. electron_click / electron_type_text -- perform actions
|
|
22
|
+
4. electron_wait_for_selector -- wait for result
|
|
23
|
+
5. electron_get_text / electron_get_value -- assert expected state
|
|
24
|
+
6. electron_screenshot -- capture evidence
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Playbook: Basic Interaction Test
|
|
28
|
+
|
|
29
|
+
**Goal:** Verify a button click produces the expected result.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
# 1. Connect
|
|
33
|
+
electron_connect
|
|
34
|
+
|
|
35
|
+
# 2. Wait for the target element
|
|
36
|
+
electron_wait_for_selector selector="[data-testid='submit-btn']" timeout=5000
|
|
37
|
+
|
|
38
|
+
# 3. Click
|
|
39
|
+
electron_click selector="[data-testid='submit-btn']"
|
|
40
|
+
|
|
41
|
+
# 4. Wait for the result
|
|
42
|
+
electron_wait_for_selector selector="[data-testid='result-message']" timeout=5000
|
|
43
|
+
|
|
44
|
+
# 5. Assert
|
|
45
|
+
electron_get_text selector="[data-testid='result-message']"
|
|
46
|
+
# Expected: "Success" or similar
|
|
47
|
+
|
|
48
|
+
# 6. Evidence
|
|
49
|
+
electron_screenshot
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Pass criteria:** `electron_get_text` returns the expected string. Screenshot shows correct UI state.
|
|
53
|
+
|
|
54
|
+
## Playbook: Form Fill & Submit
|
|
55
|
+
|
|
56
|
+
**Goal:** Complete a form and verify submission.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
# 1. Connect and wait for form
|
|
60
|
+
electron_connect
|
|
61
|
+
electron_wait_for_selector selector="form"
|
|
62
|
+
|
|
63
|
+
# 2. Discover fields
|
|
64
|
+
electron_get_accessibility_tree maxDepth=5
|
|
65
|
+
|
|
66
|
+
# 3. Fill text inputs
|
|
67
|
+
electron_type_text selector="#name" text="Jane Doe"
|
|
68
|
+
electron_type_text selector="#email" text="jane@example.com"
|
|
69
|
+
|
|
70
|
+
# 4. Fill dropdown
|
|
71
|
+
electron_select_option selector="#role" value="admin"
|
|
72
|
+
|
|
73
|
+
# 5. Screenshot before submit (evidence of filled state)
|
|
74
|
+
electron_screenshot
|
|
75
|
+
|
|
76
|
+
# 6. Submit
|
|
77
|
+
electron_click selector="[type='submit']"
|
|
78
|
+
|
|
79
|
+
# 7. Wait for result
|
|
80
|
+
electron_wait_for_selector selector=".success-message" timeout=10000
|
|
81
|
+
|
|
82
|
+
# 8. Assert
|
|
83
|
+
electron_get_text selector=".success-message"
|
|
84
|
+
# Expected: contains "submitted" or "saved"
|
|
85
|
+
|
|
86
|
+
# 9. Screenshot after submit
|
|
87
|
+
electron_screenshot
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Pass criteria:** Success message appears. Both before/after screenshots look correct.
|
|
91
|
+
|
|
92
|
+
## Playbook: Visual Regression
|
|
93
|
+
|
|
94
|
+
**Goal:** Detect unintended UI changes after a code modification.
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
# Phase 1: Capture baseline (before changes)
|
|
98
|
+
electron_connect
|
|
99
|
+
electron_wait_for_selector selector="{YOUR_APP_ROOT}"
|
|
100
|
+
electron_screenshot
|
|
101
|
+
# Save as baseline -- note the returned file path
|
|
102
|
+
|
|
103
|
+
# Phase 2: After making code changes, restart app
|
|
104
|
+
electron_launch appPath="/path/to/{YOUR_APP}"
|
|
105
|
+
electron_wait_for_selector selector="{YOUR_APP_ROOT}"
|
|
106
|
+
electron_screenshot
|
|
107
|
+
# Save as current -- note the returned file path
|
|
108
|
+
|
|
109
|
+
# Phase 3: Compare
|
|
110
|
+
electron_compare_screenshots pathA="baseline.png" pathB="current.png"
|
|
111
|
+
# Returns: { identical: false, diffPercent: 0.5, totalBytes: 120000, diffBytes: 600 }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Thresholds** (note: this is a byte-level diff, not pixel-aware):
|
|
115
|
+
- `< 1%` diff: likely acceptable (compression variance, anti-aliasing)
|
|
116
|
+
- `1-5%` diff: review the screenshot -- may be intentional
|
|
117
|
+
- `> 5%` diff: likely a regression, investigate
|
|
118
|
+
|
|
119
|
+
## Playbook: Multi-Page Flow
|
|
120
|
+
|
|
121
|
+
**Goal:** Test a workflow spanning multiple views/pages.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
# Step 1: Login page
|
|
125
|
+
electron_connect
|
|
126
|
+
electron_wait_for_selector selector="#login-form"
|
|
127
|
+
electron_type_text selector="#username" text="testuser"
|
|
128
|
+
electron_type_text selector="#password" text="testpass"
|
|
129
|
+
electron_click selector="[data-testid='login-btn']"
|
|
130
|
+
electron_screenshot
|
|
131
|
+
|
|
132
|
+
# Step 2: Dashboard (after login)
|
|
133
|
+
electron_wait_for_selector selector="[data-testid='dashboard']" timeout=10000
|
|
134
|
+
electron_get_text selector="[data-testid='welcome-msg']"
|
|
135
|
+
# Assert: contains "testuser"
|
|
136
|
+
electron_screenshot
|
|
137
|
+
|
|
138
|
+
# Step 3: Navigate to settings
|
|
139
|
+
electron_click selector="[data-testid='settings-link']"
|
|
140
|
+
electron_wait_for_selector selector="[data-testid='settings-page']"
|
|
141
|
+
electron_screenshot
|
|
142
|
+
|
|
143
|
+
# Step 4: Verify and return
|
|
144
|
+
electron_get_url
|
|
145
|
+
# Assert: URL contains "/settings"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Pass criteria:** Each step transitions correctly. No errors. URLs and text match expectations.
|
|
149
|
+
|
|
150
|
+
## Key Practices
|
|
151
|
+
|
|
152
|
+
### Always wait, never sleep
|
|
153
|
+
Use `electron_wait_for_selector` between every action that changes the UI. This eliminates race conditions and makes tests deterministic.
|
|
154
|
+
|
|
155
|
+
### Screenshot at checkpoints
|
|
156
|
+
Capture screenshots at key moments: before actions, after actions, on errors. These serve as test evidence.
|
|
157
|
+
|
|
158
|
+
### Use data-testid selectors
|
|
159
|
+
Prefer `[data-testid="..."]` selectors for test stability. They survive refactors and style changes.
|
|
160
|
+
|
|
161
|
+
### Assert with get_text / get_value
|
|
162
|
+
Use `electron_get_text` and `electron_get_value` to verify expected content, not just visual inspection.
|
|
163
|
+
|
|
164
|
+
### Handle timeouts as failures
|
|
165
|
+
If `electron_wait_for_selector` times out, the element didn't appear. This is a test failure -- report it with the last screenshot for debugging context.
|
|
166
|
+
|
|
167
|
+
## IPC-Based Assertions
|
|
168
|
+
|
|
169
|
+
When the app has IPC tools configured, use them for deeper assertions. Tool names depend on your app's config — these are examples:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
# After a form submit, verify via IPC (example tool names)
|
|
173
|
+
profiles_query query="Jane Doe"
|
|
174
|
+
# Assert: returned array contains the submitted profile
|
|
175
|
+
|
|
176
|
+
# Check app state directly (example tool name)
|
|
177
|
+
session_getStatus
|
|
178
|
+
# Assert: status is "authenticated"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
IPC tools give you backend verification alongside UI assertions.
|