← the whole session plugin/skills/agentic-chrome-testing/SKILL.md

Drive the person's own already-open, already-logged-in Chrome window via AppleScript — navigate, click, screenshot, read the DOM. macOS only. Use when verifying UX in the browser identity the person actually uses (their real cookies, their real logged-in state), not a separate automation profile.

Agent Chrome Testing

Control a real, visible Chrome window — the person's own, with their own cookies and logged-in session — via AppleScript. No debug port, no CDP, no Puppeteer. Screenshots are PNGs that Claude can read natively (multimodal).

Why this one instead of a separate automation browser: some UX only shows up when you're really signed in as yourself (personalized state, a real subscription, real history). A separate automation profile (see /alignment-harness:devtools-site-testing, which uses the chrome-devtools MCP and works on every platform) can't see that. This skill drives the browser window the person is actually looking at, at the cost of being macOS-only.

Prerequisites

  1. macOS only. AppleScript has no equivalent on Linux or Windows. On those platforms, or if this isn't macOS, use /alignment-harness:devtools-site-testing instead — say so plainly rather than silently failing.
  2. One-time Chrome setting: Chrome → View → Developer → "Allow JavaScript from Apple Events". Without this, every command below fails with an Apple-Events permission error. If you hit that error, tell the person exactly this menu path — don't guess at another fix.
  3. Your app running locally. This skill needs the URL and start command for whatever you're testing. If you ran /alignment-harness:harness-setup, it recorded these; otherwise ask once and remember the answer for the session (e.g. "what command starts your dev server, and what URL does it serve?" — commonly something like npm start on http://localhost:3000).

There is no separate "debug port" step — this script talks to Chrome directly through AppleScript, not through Chrome's remote-debugging port. If you've read an older doc that mentions a debug script, ignore it; it belongs to a different mechanism than this one.

The script

A ready-to-use driver ships with this skill: scripts/agent-chrome.js (Node, no dependencies beyond what ships with Node itself). Run it with node:

node <path-to-this-skill>/scripts/agent-chrome.js <command> [args...]

If the project already has its own copy of an equivalent script, use that instead — the commands below are the same either way.

Commands

# Navigation — replace with the URL recorded at setup
node agent-chrome.js navigate http://localhost:3000/

# Screenshots (Claude reads these with the Read tool)
node agent-chrome.js screenshot /tmp/page.png

# Interactions
node agent-chrome.js click "#start-btn"
node agent-chrome.js click "text=Start Session"
node agent-chrome.js type "#email" test@example.com

# Inspect page state
node agent-chrome.js eval "document.title"
node agent-chrome.js eval "JSON.stringify([...document.querySelectorAll('button')].map(b => b.textContent.trim()))"

# Wait for element before acting
node agent-chrome.js wait ".loaded" 5000

# Console errors (listens for N ms, prints anything logged via console.error)
node agent-chrome.js console-errors 3000

# Tab management
node agent-chrome.js tabs

Typical Agent Workflow

1. [one-time] Chrome → View → Developer → Allow JavaScript from Apple Events
2. node agent-chrome.js navigate <your-app-url>
3. node agent-chrome.js screenshot /tmp/check.png
4. [Read /tmp/check.png — "see" the page]
5. node agent-chrome.js click "text=Some Button"
6. node agent-chrome.js screenshot /tmp/after.png
7. [Read /tmp/after.png — verify the result]

Using with a user-state simulator

If your app has an admin tool that lets you set up specific user states via URL (logged in, subscribed, a given plan, etc.), navigate to it the same way:

node agent-chrome.js navigate "http://localhost:3000/your-admin-simulator-path?auth=logged_in&subscription=trialing&redirect=/&clear=true"
# Wait for redirect to complete
sleep 2
node agent-chrome.js screenshot /tmp/simulated.png

The exact params depend entirely on your own app — this pattern only applies if you've built (or have) such a tool.

Selectors

Type Example Notes
CSS "#my-id", ".my-class", "button[type=submit]" Standard CSS selectors
Text "text=Start Session" Matches element containing that text

Discover selectors when you don't know what's on the page:

node agent-chrome.js eval "JSON.stringify([...document.querySelectorAll('button')].map(b => b.textContent.trim()))"
node agent-chrome.js eval "JSON.stringify([...document.querySelectorAll('a')].map(a => ({text: a.textContent.trim(), href: a.href})))"
node agent-chrome.js eval "JSON.stringify([...document.querySelectorAll('input')].map(i => ({id: i.id, name: i.name, placeholder: i.placeholder})))"

Troubleshooting

Error Fix
"not allowed" / Apple-Events error Chrome → View → Developer → "Allow JavaScript from Apple Events"
"Element not found" Use screenshot to see the page, or eval to inspect DOM
Navigate does nothing / times out Your dev server may not be running — check its start command
Blank screenshot Page may need more time to render — use wait before screenshot
Any command at all, on Linux/Windows Not supported here — use /alignment-harness:devtools-site-testing

Recording what you found

Before testing, check whether anything is already known about this flow. If memory search is configured (see /alignment-harness:harness-setup), search it. Otherwise grep the project's own docs/notes and git log for the page or feature you're about to test, and say plainly if nothing turned up.

After testing, record findings as a file rather than losing them at the end of the session: alignment-harness records ux-findings prints the folder — write a short markdown or JSON note there (what you tested, what you saw, win/loss/pattern/blocker) and show the person the path.