Skip to content

Commit cc086e2

Browse files
Add MCP instructions, and update the sigenergy example based on running through the instructions
1 parent 4dee69a commit cc086e2

File tree

4 files changed

+385
-159
lines changed

4 files changed

+385
-159
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../.github/instructions/playwright-mcp.instructions.md
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
---
2+
applyTo: '**'
3+
description: Playwright MCP browser automation patterns for Home Assistant
4+
globs: ['**']
5+
alwaysApply: false
6+
---
7+
8+
# Playwright MCP Browser Automation
9+
10+
Patterns for browser automation using the Playwright MCP server with Home Assistant.
11+
12+
## Core Concept: Snapshot-Based Interaction
13+
14+
The MCP pattern uses accessibility tree snapshots instead of CSS selectors.
15+
16+
**Workflow:**
17+
18+
1. Capture snapshot with `browser_snapshot()`
19+
2. Parse element refs from YAML output
20+
3. Interact using `browser_click(ref=...)` or `browser_type(ref=..., text=...)`
21+
4. Re-snapshot after each interaction (refs change)
22+
23+
**Snapshot element format:**
24+
25+
```yaml
26+
button "Submit" [ref=e5355] [cursor=pointer]:
27+
- generic [ref=e5356]: Submit
28+
```
29+
30+
The `ref` attribute uniquely identifies elements for the current page state.
31+
32+
## Environment Setup
33+
34+
### Starting Home Assistant
35+
36+
```bash
37+
uv run hass -c config
38+
```
39+
40+
Wait 30-60 seconds for startup. UI available at `http://localhost:8123`.
41+
42+
### Resetting to Clean State
43+
44+
```bash
45+
git clean -fdX config/
46+
```
47+
48+
Removes database, state files, and cached data while preserving tracked sensor packages.
49+
50+
## Element Identification
51+
52+
Identify elements in snapshots by:
53+
54+
| Pattern | Example |
55+
| ---------------- | -------------------------------------- |
56+
| Role and name | `button "Submit" [ref=e5355]` |
57+
| Text content | `generic [ref=e733]: Sigenergy System` |
58+
| Nested structure | Parent-child hierarchy in YAML |
59+
60+
## UI Component Patterns
61+
62+
### Text Input (textbox)
63+
64+
```yaml
65+
textbox "Load Name*" [ref=e5331]:
66+
- text: Load
67+
```
68+
69+
```
70+
browser_type(element="Load Name textbox", ref="e5331", text="My Load")
71+
```
72+
73+
### Button
74+
75+
```yaml
76+
button "Submit" [ref=e5355] [cursor=pointer]:
77+
- generic: Submit
78+
```
79+
80+
```
81+
browser_click(element="Submit button", ref="e5355")
82+
```
83+
84+
### Combobox Dropdown
85+
86+
**Closed state:**
87+
88+
```yaml
89+
combobox "Connection*" [ref=e5337]:
90+
- generic: Switchboard
91+
```
92+
93+
**Pattern:**
94+
95+
1. Click combobox to open
96+
2. Re-snapshot to see options
97+
3. Click option ref
98+
99+
```
100+
browser_click(element="Connection combobox", ref="e5337")
101+
# snapshot shows: option "Inverter" [ref=e5361]
102+
browser_click(element="Inverter option", ref="e5361")
103+
```
104+
105+
### Entity Picker Dialog
106+
107+
Entity pickers open a dialog with search and results.
108+
109+
**Closed state:**
110+
111+
```yaml
112+
listitem [ref=e5348]:
113+
- generic: Select an entity
114+
```
115+
116+
**Pattern:**
117+
118+
1. Click listitem to open picker dialog
119+
2. Type in Search textbox to filter
120+
3. Click matching sensor in results
121+
122+
```
123+
browser_click(element="Entity picker", ref="e5348")
124+
# dialog opens with: textbox "Search" [ref=e5378]
125+
browser_type(element="Search textbox", ref="e5378", text="General Price")
126+
# results show: listitem [ref=e5650]: Home - General Price
127+
browser_click(element="Home - General Price", ref="e5650")
128+
```
129+
130+
**Search behavior:**
131+
132+
- Matches **friendly names**, not entity_ids
133+
- Use distinctive keywords: "General Price", "consumed", "charging"
134+
- Partial matches work: "solar" finds all solar sensors
135+
136+
### Multi-Select Entity Picker
137+
138+
For fields accepting multiple sensors, an "Add entity" button appears after first selection.
139+
140+
```
141+
# Select first
142+
browser_click(element="Forecast picker", ref="e5348")
143+
browser_type(element="Search", ref="e5378", text="East solar")
144+
browser_click(element="East solar sensor", ref="e5650")
145+
146+
# Add more
147+
browser_click(element="Add entity button", ref="e5975")
148+
browser_type(element="Search", ref="e5378", text="North solar")
149+
browser_click(element="North solar sensor", ref="e5651")
150+
```
151+
152+
### Numeric Input (spinbutton)
153+
154+
```yaml
155+
spinbutton "Import Limit" [ref=e5400]
156+
...
157+
```
158+
159+
```
160+
browser_type(element="Import Limit", ref="e5400", text="55")
161+
```
162+
163+
### Alert Dialog
164+
165+
Success dialogs block all other interactions until closed.
166+
167+
```yaml
168+
alertdialog "Success" [ref=e6060]:
169+
- paragraph: Created configuration for Load.
170+
- button "Finish" [ref=e6067]
171+
```
172+
173+
**Always close immediately:**
174+
175+
```
176+
browser_click(element="Finish button", ref="e6067")
177+
```
178+
179+
## Critical Rules
180+
181+
### Re-snapshot After Every Interaction
182+
183+
Element refs change after any interaction.
184+
185+
```
186+
browser_click(element="Submit", ref="e5355")
187+
browser_snapshot() # REQUIRED - get new refs
188+
browser_click(element="Finish", ref="e6067") # New ref from new snapshot
189+
```
190+
191+
### Close Dialogs Before Continuing
192+
193+
Unacknowledged success dialogs block all subsequent interactions.
194+
Look for `alertdialog` in snapshot and click Finish/Close.
195+
196+
### Search by Friendly Name
197+
198+
Entity picker search matches friendly names, not entity_ids.
199+
200+
`"General Price"` → matches "Home - General Price"
201+
`"max active power"` → matches "Sigen Plant Max Active Power"
202+
`"sensor.home_general_price"` → no match
203+
204+
### Descriptive Element Names
205+
206+
Always provide meaningful `element` descriptions.
207+
208+
`browser_click(element="Connection combobox", ref="e5337")`
209+
`browser_click(element="combobox", ref="e5337")`
210+
211+
## Navigation
212+
213+
| Page | URL |
214+
| -------------------- | -------------------------------------------------------------- |
215+
| Home | `http://localhost:8123` |
216+
| Integrations | `http://localhost:8123/config/integrations` |
217+
| Specific integration | `http://localhost:8123/config/integrations/integration/{name}` |
218+
219+
```
220+
browser_navigate(url="http://localhost:8123/config/integrations")
221+
```
222+
223+
## Troubleshooting
224+
225+
### No Search Results
226+
227+
- Try broader search terms
228+
- Search matches friendly names only
229+
- Check available sensors in config/packages/
230+
231+
### Dialog Blocking
232+
233+
Take snapshot, find `alertdialog`, click its Finish/Close button.
234+
235+
### Wrong Element Clicked
236+
237+
Using stale ref from old snapshot. Always re-snapshot after interactions.
238+
239+
### Element Not Found
240+
241+
Element may not be visible. Check if scrolling needed or if it's in a closed dropdown/dialog.
242+
243+
## Common Snapshot Patterns
244+
245+
| Component | Pattern |
246+
| -------------- | ------------------------------------------------------- |
247+
| Text input | `textbox "Field*" [ref=...]` |
248+
| Button | `button "Text" [ref=...]` |
249+
| Dropdown | `combobox "Field*" [ref=...]` |
250+
| Entity picker | `listitem: Select an entity` |
251+
| Success dialog | `alertdialog "Success"` |
252+
| Numeric input | `spinbutton "Field" [ref=...]` |
253+
| Option in list | `option "Name" [ref=...]` or `listitem [ref=...]: Name` |

.vscode/mcp.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"inputs": [],
3+
"servers": {
4+
"microsoft/playwright-mcp": {
5+
"args": ["@playwright/mcp@latest"],
6+
"command": "npx",
7+
"gallery": "https://api.mcp.github.com",
8+
"type": "stdio",
9+
"version": "0.0.1-seed"
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)