git:20260708.586577e to git:20260725.6c1b23d

71 added, 169 removed. Audit A to A.

---
name: electron-playwright-validator
description: >-
- Validate Electron desktop app UI using Playwright automation via the e-cli tool.
- Use when testing Electron app UI, validating after code changes, checking if tabs render,
- clicking through UI flows, taking screenshots for visual review, or debugging runtime
- import errors that typecheck doesn't catch. Works with any Electron project that has
- @playwright/test and electron in devDependencies. Use when the user asks "validate the
- electron app", "check the UI", "click through the app", "take a screenshot", "does the
- app render", "test the electron UI", "launch the app and check", "verify the app works",
- "is the app broken", or "debug a runtime error". NOT for native macOS
- (SwiftUI/AppKit) apps — use the peekaboo macOS validator — and NOT for
- mobile apps (use the Maestro validator).
+ This skill should be used when a user asks to launch, inspect, automate, test,
+ validate, or debug an Electron desktop UI through Playwright/CDP, including
+ blank renderers, runtime import failures, accessibility snapshots, layout
+ defects, click-through flows, or post-change checks. Not for native macOS or
+ mobile apps, browser-only pages, or unit-level IPC tests. The target project
+ must provide Electron and Playwright.
---
# Electron Playwright Validator
- Validate Electron desktop apps by launching them with Chrome DevTools Protocol (CDP) and automating the UI via Playwright. The `e-cli` tool provides a persistent session model: launch the app once (~5s startup), then run fast CDP-connected commands (~200ms each) to inspect, click, screenshot, and validate.
-
- ## Setup — resolve the tool path first
-
- `e-cli` ships inside this plugin and is NOT on PATH. Define this once per session and use it for every invocation:
-
- ```bash
- E_CLI="${CLAUDE_PLUGIN_ROOT}/bin/e-cli"
- "$E_CLI" --help
- ```
-
- Every `e-cli <cmd>` in this document means `"$E_CLI" <cmd>`. The tool resolves `electron` and `playwright` from the **project's** node_modules — run it from the project root; nothing is installed globally.
-
- ## Core Workflow
-
- Follow this sequence for every validation session:
-
- 1. **Launch** — `e-cli launch` starts the Electron app with CDP enabled. Auto-builds if `out/main/index.js` is missing.
- 2. **Snapshot** — `e-cli snapshot` dumps the full accessibility tree. This is how you "see" the UI.
- 3. **Interact** — Use `e-cli click`, `e-cli fill`, `e-cli press` to navigate and interact.
- 4. **Validate** — After each interaction, snapshot again to verify the UI updated correctly. Use `e-cli screenshot` + `Read` tool for visual confirmation.
- 5. **Close** — `e-cli close` terminates the app and cleans up state.
-
- Always close the app when done. A lingering Electron process blocks subsequent launches.
-
- ## Reading the Accessibility Tree
-
- The `e-cli snapshot` output is your primary tool for understanding the UI. Each line represents a node:
-
- ```
- WebArea "MyApp"
- navigation "Main"
- tab "Library" pressed=true
- tab "Search"
- tab "Settings"
- main
- heading "Library" level=1
- list "Item list"
- listitem "first-item"
- listitem "second-item"
- ```
-
- Use this tree to:
- - **Find elements** — scan for the role and name of what you want to interact with
- - **Build selectors** — translate tree nodes into Playwright selectors
- - **Verify state** — check `pressed`, `expanded`, `checked`, `disabled` attributes
- - **Confirm navigation** — after clicking a tab, snapshot to see the new view content
-
- ## Selector Strategy
-
- Prefer selectors in this order (most robust to least):
-
- 1. **Role selectors** — `role=tab[name="Sessions"]`, `role=button[name="New"]`
- 2. **Text selectors** — `text=Sessions`, `text=Create new session`
- 3. **Test ID selectors** — `[data-testid=session-list]`
- 4. **CSS selectors** — `.sidebar-nav button`, `#main-content h1`
-
- Role selectors are best because they match the accessibility tree directly and survive CSS refactors. CSS selectors are fragile — use only as a last resort.
-
- > *Consult [accessibility selectors reference](references/accessibility-selectors.md) for full selector syntax and patterns.*
-
- ## Multimodal Validation
-
- Combine accessibility snapshots with screenshots for thorough validation:
-
- ```bash
- "$E_CLI" snapshot # structural check — are the right elements present?
- "$E_CLI" screenshot # visual check — does it look right?
- ```
-
- After `e-cli screenshot`, use the `Read` tool on the PNG file to visually inspect the result. This catches issues that the accessibility tree cannot: broken layouts, missing styles, overlapping elements, blank screens.
-
- ## Timing and Async Content
+ Use the bundled `e-cli` as the interface. It keeps one Electron process alive
+ and connects subsequent commands through CDP, avoiding repeated startup cost.
- Electron apps load content asynchronously. Handle this with:
+ ## Resolve the bundled tool
- - **`e-cli wait <selector>`** — wait for an element to become visible before interacting
- - **Sequential snapshot-then-act** — always snapshot before clicking to confirm the target exists
- - **Post-interaction delay** — if a click triggers an async operation (API call, animation), wait for the result element before snapshotting
+ The executable is `scripts/e-cli` relative to this skill directory. Resolve that
+ path from the host's skill context. In a full plugin install the equivalent path
+ is:
```bash
- "$E_CLI" wait "role=tab[name=Library]" # wait for nav to render
- "$E_CLI" click "role=tab[name=Settings]" # switch tab
- "$E_CLI" wait "role=heading[name=Settings]" # wait for view to load
- "$E_CLI" snapshot # verify the new view
+ E_CLI="${CLAUDE_PLUGIN_ROOT}/skills/electron-playwright-validator/scripts/e-cli"
```
- > *Consult [electron gotchas reference](references/electron-gotchas.md) for timing issues, xterm quirks, and lazy loading.*
-
- ## When to Use e-cli vs pnpm test:e2e
-
- | Scenario | Tool |
- |----------|------|
- | Exploring the UI after code changes | `e-cli` |
- | Debugging a runtime import error | `e-cli` |
- | Validating a specific view renders | `e-cli` |
- | Interactive click-through of a flow | `e-cli` |
- | Deterministic regression suite for CI | `pnpm test:e2e` |
- | Testing IPC handler responses | `pnpm test:e2e` |
-
- Use `e-cli` for **exploratory validation** — quick checks, visual inspection, debugging. Use `pnpm test:e2e` for **deterministic tests** that run in CI.
-
- ## Common Patterns
-
- ### Validate all tabs render
-
- ```bash
- "$E_CLI" launch
- "$E_CLI" snapshot # check initial state; read the tab names from it
- for tab in Library Search Settings; do # substitute the app's actual top-level tabs
- "$E_CLI" click "role=tab[name=$tab]"
- "$E_CLI" snapshot # verify view content
- done
- "$E_CLI" close
- ```
+ Verify `"$E_CLI" --help`, then run from the project root. The tool resolves
+ Electron and Playwright from the project's dependencies; do not install global
+ copies or silently change the project's toolchain.
- ### Check if an error screen shows
+ Direct skill installs can resolve `scripts/e-cli` from the skill directory. Use
+ `node "$E_CLI"` when a distribution loses executable mode.
- ```bash
- "$E_CLI" launch
- "$E_CLI" snapshot # look for error roles/text
- "$E_CLI" screenshot # visual confirmation
- "$E_CLI" close
- ```
+ ## Drive one observable transaction at a time
- ### Evaluate renderer state
+ 1. Launch the app.
+ 2. Read an accessibility snapshot.
+ 3. Resolve one target from current state.
+ 4. Act.
+ 5. Wait for a product postcondition, then snapshot again.
+ 6. Capture pixels only when they can reveal a rendering or layout defect.
+ 7. Close the session when validation finishes.
- ```bash
- "$E_CLI" eval "Object.keys(window.api ?? {})" # check preload bridge (name varies per app)
- "$E_CLI" eval "document.title" # check page title
- "$E_CLI" eval "document.querySelectorAll('.error').length" # count error elements
- ```
+ Treat launch, interaction, and product success as separate claims. A successful
+ click does not prove the view changed correctly.
- ### Debug broken imports
+ ## Prefer semantic state
- If `pnpm typecheck` passes but the app shows a blank screen:
+ Use role and accessible-name selectors before text, test IDs, or CSS. The
+ snapshot is both the discovery surface and the primary behavioral assertion.
+ Load `references/accessibility-selectors.md` only when selector construction is
+ non-obvious.
- ```bash
- "$E_CLI" launch
- "$E_CLI" eval "document.querySelector('#root')?.innerHTML?.substring(0, 200)"
- "$E_CLI" screenshot
- # Check the terminal output / DevTools console for import errors
- "$E_CLI" close
- ```
+ Electron rendering is asynchronous. Wait for the resulting element or state
+ instead of relying on an arbitrary sleep. Snapshot again after navigation,
+ modal changes, or asynchronous content. Read
+ `references/electron-gotchas.md` for lazy rendering, terminal surfaces, and
+ timing failures.
- ## Validation Mindset
+ For multi-window apps, run `e-cli pages` and select the intended renderer rather
+ than assuming the first window is the product surface.
- Running e-cli commands is not enough — you must think critically about what you see.
+ ## Bound visual context
- ### UI Appearance
- After every screenshot, evaluate it with a designer's eye. Do layouts, spacing, colors, and typography look correct? Does this screen feel consistent with the rest of the app? Would a real user notice something off — misalignment, clipped text, wrong font weight, broken dark-mode contrast? If something looks wrong, it is wrong.
+ Save screenshots to disk. When the host retains and resends image inputs, use a
+ bounded isolated visual task and return only its compact text finding to the
+ driver. A small before/after pair may share one visual task when comparison is
+ the decision. If isolation is unavailable, inspect the smallest necessary image
+ or crop and avoid accumulating screenshots in a long-running context.
- ### User Experience
- Don't just verify elements exist. Click through the flow as a user would. Does the interaction sequence make sense? Are transitions smooth? Does the app respond where you expect it to? If a button exists but the flow around it is confusing, that's a bug.
+ Use pixels for blank surfaces, broken styles, clipping, overlap, contrast, and
+ layout. Do not take a screenshot merely because the command exists.
- ### Test Depth
- Happy-path validation is insufficient. Consider what a real user would encounter:
- - Empty states — what happens with no data?
- - Error states — what if something fails?
- - Edge cases — rapid clicks, resize, long text, many items
- - Navigation — can you get back? Does browser-back work?
+ ## Diagnose runtime failures
- If your validation only covers the obvious path, go deeper.
+ A typecheck can pass while the packaged renderer fails at runtime. On a blank
+ or error screen, inspect:
- ### Coherence
- A feature can be technically correct but feel wrong in context. After validating, ask: does this change fit the existing app? Does it match the design language, information density, and interaction patterns of surrounding views? Flag anything that looks out of place, even if it "works."
+ - launch stderr and renderer console output;
+ - the root element and document title;
+ - preload bridge availability;
+ - dynamic import and packaging errors;
+ - the fresh accessibility snapshot and screenshot.
- ## DO
+ Use `e-cli logs` for captured process/renderer diagnostics. `e-cli eval` runs
+ arbitrary JavaScript with renderer and preload privileges; prefer read-only
+ expressions and do not call mutating bridge methods unless the user requested
+ that effect. The full contract lives in `references/e-cli-reference.md`; prefer
+ live `"$E_CLI" --help` when they differ.
- - Always `e-cli snapshot` before interacting — confirms the element exists
- - Always `e-cli close` when done — prevents port conflicts and zombie processes
- - Use role selectors when possible — they match the accessibility tree directly
- - Combine snapshot + screenshot for thorough validation
- - Check `e-cli status` if launch says "Already running" unexpectedly
+ ## Choose the durable test boundary
- ## DON'T
+ Use `e-cli` for interactive exploration, reproducing runtime failures, and
+ checking a specific rendered state. Use the project's existing Playwright E2E
+ suite for deterministic regression and CI. Convert a discovered regression
+ into a durable test when the behavior is important enough to prevent from
+ returning.
- - Don't skip the snapshot step — clicking blind leads to flaky results
- - Don't forget to close — a lingering process blocks the next launch
- - Don't use CSS selectors for elements that have accessible names — prefer role selectors
- - Don't assume instant rendering — use `e-cli wait` for async content
- - Don't run `e-cli` in parallel — one session at a time per port
+ Always close the session, including after failure, and surface cleanup errors
+ rather than leaving a process that blocks the next run.
- > *Consult [e-cli command reference](references/e-cli-reference.md) for full command documentation and examples.*
+ Keep `.e-cli-state.json`, `.e-cli-launch.lock`, and screenshot artifacts out of
+ version control.