Browser verify
Testing-grade browser automation via Chrome DevTools Protocol (CDP). Direct access to the browser's DOM, JS runtime, network layer, cookies, computed styles, and console — without any external dependencies. Complements MCP-based tools by enabling arbitrary JS evaluation in page context and deep inspection that screenshot-only tools miss. Use when you need to: run JS in the page, inspect cookies/localStorage, check computed styles, enumerate third-party scripts, emulate devices, analyze network timing, or interact via real mouse and keyboard events.From its SKILL.md
npx -y skills add arozumenko/wikis --skill browser-verifyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.8 KB, as published. Nobody here has run it
Browser Verify
Testing-grade browser automation using Chrome controlled through the Chrome DevTools
Protocol. All interactions use real CDP Input domain events (mouse coordinates,
key events) — not synthetic JS .click(). Zero external dependencies beyond
Node 22's built-in WebSocket.
Architecture
Scripts live in the scripts/ directory alongside this SKILL.md:
chrome-launcher.sh— Start/stop/status Chrome with remote debuggingcdp.mjs— Full CDP client with 50+ commands
No npm install required. Uses Node 22 built-in WebSocket.
Resolving Script Paths
The scripts are in the scripts/ subdirectory of this skill. Resolve the path
from your .claude/skills/browser-verify/ install location or the octobots
symlink — both work the same way:
# Works for both npx-installed and symlinked:
SCRIPTS=".claude/skills/browser-verify/scripts" # npx skills add
SCRIPTS="octobots/skills/browser-verify/scripts" # symlinked install
bash "$SCRIPTS/chrome-launcher.sh" start --headless
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
Workflow
1. Start Chrome
bash "$SCRIPTS/chrome-launcher.sh" start
# Headless (no window, faster):
bash "$SCRIPTS/chrome-launcher.sh" start --headless
2. Run Commands
node "$SCRIPTS/cdp.mjs" <command> [args] [--flags]
3. Stop Chrome
bash "$SCRIPTS/chrome-launcher.sh" stop
Command Reference
Navigation
| Command | Example | Purpose |
|---|---|---|
navigate <url> | navigate "https://example.com" | Open URL, wait for load |
reload | reload | Reload current page |
back | back | Browser back |
forward | forward | Browser forward |
page-info | page-info | Title, URL, counts, viewport, meta |
list-targets | list-targets | List open tabs |
new-tab [url] | new-tab "https://example.com/about" | Open new tab |
close-tab [id] | close-tab | Close tab |
Visual
| Command | Example | Purpose |
|---|---|---|
screenshot | screenshot --output /tmp/page.png | Full page capture |
screenshot --selector <s> | screenshot --selector ".card" | Element capture |
screenshot --full | screenshot --full --output /tmp/full.png | Beyond viewport |
viewport <w> <h> | viewport 375 812 | Set viewport size |
pdf | pdf --output /tmp/page.pdf | Save as PDF |
emulate <device> | emulate mobile | Device emulation |
Available devices: mobile, iphone, ipad, tablet, android, desktop, laptop
DOM Inspection
| Command | Example | Purpose |
|---|---|---|
evaluate <js> | evaluate "document.title" | Run JS in page context |
get-html [--selector s] | get-html --selector "#app" | Get outerHTML |
get-text [--selector s] | get-text --selector ".message" | Get textContent |
get-attribute <sel> <attr> | get-attribute "a" "href" | Get attribute |
get-value <sel> | get-value "input[name=email]" | Get input value |
get-styles <sel> | get-styles ".btn" --props "color,fontSize" | Computed styles |
query-all <sel> | query-all "li.item" | Info on all matches |
Interaction (Real CDP Input Events)
| Command | Example | Purpose |
|---|---|---|
click <sel> | click "button.submit" | Left click |
click <sel> --button right | click ".menu" --button right | Right click |
click <sel> --count 2 | click ".item" --count 2 | Double click |
hover <sel> | hover ".tooltip-trigger" | Mouse hover |
type <sel> <text> | type "#email" "[email protected]" | Type text |
type <sel> <text> --clear | type "#search" "new query" --clear | Clear then type |
press <key> | press Enter | Press key |
press <key> --modifiers "ctrl" | press a --modifiers "ctrl" | Key combo |
clear <sel> | clear "#search" | Clear input field |
focus <sel> | focus "#input" | Focus element |
blur <sel> | blur "#input" | Blur element |
select <sel> <value> | select "#country" "US" | Select dropdown |
check <sel> | check "#agree" | Check checkbox |
uncheck <sel> | uncheck "#newsletter" | Uncheck checkbox |
scroll <sel> | scroll ".footer" | Scroll to element |
scroll --x 0 --y 500 | scroll --x 0 --y 500 | Scroll to coords |
drag <from> <to> | drag ".item" ".dropzone" | Drag and drop |
upload <sel> <path> | upload "#file" "/tmp/doc.pdf" | File upload |
Waiting
| Command | Example | Purpose |
|---|---|---|
wait <sel> | wait ".loaded" | Wait for DOM element |
wait-visible <sel> | wait-visible ".modal" | Wait until visible |
wait-hidden <sel> | wait-hidden ".spinner" | Wait until hidden |
wait-text <text> | wait-text "Success" | Wait for text on page |
wait-url <pattern> | wait-url "/dashboard" | Wait for URL change |
wait-network-idle | wait-network-idle | Wait for no requests |
sleep <ms> | sleep 1000 | Fixed delay |
All wait commands accept --timeout <ms> (default 10000).
Debugging
| Command | Example | Purpose |
|---|---|---|
get-console | get-console | All console messages |
get-network | get-network | Network requests + timing |
get-network --status 4xx | get-network --status error | Filter by status (4xx, 5xx, error, or exact code) |
get-network --type xhr | get-network --type fetch | Filter by initiator type |
get-cookies | get-cookies | All cookies |
set-cookie <n> <v> | set-cookie "token" "abc" --domain localhost | Set cookie |
clear-cookies | clear-cookies | Clear all cookies |
QA Inspection
| Command | Example | Purpose |
|---|---|---|
get-storage | get-storage | localStorage + sessionStorage combined |
get-performance | get-performance | Timing, resource sizes, LCP/FID/CLS |
get-meta | get-meta | Meta tags, OG, Twitter cards, structured data |
inject-axe | inject-axe | Run axe-core WCAG 2.x audit, returns violations |
inject-axe --selector s | inject-axe --selector "main" | Scope axe to a subtree |
Common Patterns
Login Flow
node "$SCRIPTS/cdp.mjs" navigate "https://app.example.com/login"
node "$SCRIPTS/cdp.mjs" type "#email" "[email protected]" --clear
node "$SCRIPTS/cdp.mjs" type "#password" "pass123" --clear
node "$SCRIPTS/cdp.mjs" click "button[type=submit]"
node "$SCRIPTS/cdp.mjs" wait-url "/dashboard" --timeout 5000
node "$SCRIPTS/cdp.mjs" screenshot --output /tmp/dashboard.png
Responsive Verification
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
node "$SCRIPTS/cdp.mjs" emulate mobile
node "$SCRIPTS/cdp.mjs" screenshot --output /tmp/mobile.png
node "$SCRIPTS/cdp.mjs" emulate desktop
node "$SCRIPTS/cdp.mjs" screenshot --output /tmp/desktop.png
Privacy Inspection
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
node "$SCRIPTS/cdp.mjs" get-cookies
node "$SCRIPTS/cdp.mjs" get-storage
node "$SCRIPTS/cdp.mjs" evaluate "JSON.stringify([...document.querySelectorAll('script[src]')].map(s=>s.src))"
Accessibility Audit (axe-core)
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
node "$SCRIPTS/cdp.mjs" inject-axe
# Scope to main content only:
node "$SCRIPTS/cdp.mjs" inject-axe --selector "main"
Performance Snapshot
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
node "$SCRIPTS/cdp.mjs" get-performance
# Check for failed requests:
node "$SCRIPTS/cdp.mjs" get-network --status error
SEO / Meta Audit
node "$SCRIPTS/cdp.mjs" navigate "https://example.com"
node "$SCRIPTS/cdp.mjs" get-meta
Notes
- Always start Chrome before running commands; stop when done
- Screenshots saved as PNG — use Read tool to view them
- All
click/type/hoveruse real CDP Input events at element coordinates - Elements are automatically scrolled into view before interaction
type --clearuses Select All + Delete before typing (framework-safe)- Console/network capture is per-session (per
navigatecall)
Reference
See references/cdp-commands.md for extended evaluate patterns, QA-specific
inspection scripts, and troubleshooting.