--- name: chrome-devtools description: Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging. license: Apache-2.0 --- # Chrome DevTools Agent Skill Browser automation via executable Puppeteer scripts. All scripts output JSON for easy parsing. ## Quick Start **CRITICAL**: Always check `pwd` before running scripts. ### Installation #### Step 1: Install System Dependencies (Linux/WSL only) On Linux/WSL, Chrome requires system libraries. Install them first: ```bash pwd # Should show current working directory cd .claude/skills/chrome-devtools/scripts ./install-deps.sh # Auto-detects OS and installs required libs ``` Supports: Ubuntu, Debian, Fedora, RHEL, CentOS, Arch, Manjaro **macOS/Windows**: Skip this step (dependencies bundled with Chrome) #### Step 2: Install Node Dependencies ```bash npm install # Installs puppeteer, debug, yargs ``` #### Step 3: Install ImageMagick (Optional, Recommended) ImageMagick enables automatic screenshot compression to keep files under 5MB: **macOS:** ```bash brew install imagemagick ``` **Ubuntu/Debian/WSL:** ```bash sudo apt-get install imagemagick ``` **Verify:** ```bash magick -version # or: convert -version ``` Without ImageMagick, screenshots >5MB will not be compressed (may fail to load in Gemini/Claude). ### Test ```bash node navigate.js --url https://example.com # Output: {"success": true, "url": "https://example.com", "title": "Example Domain"} ``` ## Available Scripts All scripts are in `.claude/skills/chrome-devtools/scripts/` **CRITICAL**: Always check `pwd` before running scripts. ### Script Usage - `./scripts/README.md` ### Core Automation - `navigate.js` - Navigate to URLs - `screenshot.js` - Capture screenshots (full page or element) - `click.js` - Click elements - `fill.js` - Fill form fields - `evaluate.js` - Execute JavaScript in page context ### Analysis & Monitoring - `snapshot.js` - Extract interactive elements with metadata - `console.js` - Monitor console messages/errors - `network.js` - Track HTTP requests/responses - `performance.js` - Measure Core Web Vitals + record traces ## Usage Patterns ### Single Command ```bash pwd # Should show current working directory cd .claude/skills/chrome-devtools/scripts node screenshot.js --url https://example.com --output ./docs/screenshots/page.png ``` **Important**: Always save screenshots to `./docs/screenshots` directory. ### Automatic Image Compression Screenshots are **automatically compressed** if they exceed 5MB to ensure compatibility with Gemini API and Claude Code (which have 5MB limits). This uses ImageMagick internally: ```bash # Default: auto-compress if >5MB node screenshot.js --url https://example.com --output page.png # Custom size threshold (e.g., 3MB) node screenshot.js --url https://example.com --output page.png --max-size 3 # Disable compression node screenshot.js --url https://example.com --output page.png --no-compress ``` **Compression behavior:** - PNG: Resizes to 90% + quality 85 (or 75% + quality 70 if still too large) - JPEG: Quality 80 + progressive encoding (or quality 60 if still too large) - Other formats: Converted to JPEG with compression - Requires ImageMagick installed (see imagemagick skill) **Output includes compression info:** ```json { "success": true, "output": "/path/to/page.png", "compressed": true, "originalSize": 8388608, "size": 3145728, "compressionRatio": "62.50%", "url": "https://example.com" } ``` ### Chain Commands (reuse browser) ```bash # Keep browser open with --close false node navigate.js --url https://example.com/login --close false node fill.js --selector "#email" --value "user@example.com" --close false node fill.js --selector "#password" --value "secret" --close false node click.js --selector "button[type=submit]" ``` ### Parse JSON Output ```bash # Extract specific fields with jq node performance.js --url https://example.com | jq '.vitals.LCP' # Save to file node network.js --url https://example.com --output /tmp/requests.json ``` ## Execution Protocol ### Working Directory Verification BEFORE executing any script: 1. Check current working directory with `pwd` 2. Verify in `.claude/skills/chrome-devtools/scripts/` directory 3. If wrong directory, `cd` to correct location 4. Use absolute paths for all output files Example: ```bash pwd # Should show: .../chrome-devtools/scripts # If wrong: cd .claude/skills/chrome-devtools/scripts ``` ### Output Validation AFTER screenshot/capture operations: 1. Verify file created with `ls -lh ` 2. Read screenshot using Read tool to confirm content 3. Check JSON output for success:true 4. Report file size and compression status Example: ```bash node screenshot.js --url https://example.com --output ./docs/screenshots/page.png ls -lh ./docs/screenshots/page.png # Verify file exists # Then use Read tool to visually inspect ``` 5. Restart working directory to the project root. ### Error Recovery If script fails: 1. Check error message for selector issues 2. Use snapshot.js to discover correct selectors 3. Try XPath selector if CSS selector fails 4. Verify element is visible and interactive Example: ```bash # CSS selector fails node click.js --url https://example.com --selector ".btn-submit" # Error: waiting for selector ".btn-submit" failed # Discover correct selector node snapshot.js --url https://example.com | jq '.elements[] | select(.tagName=="BUTTON")' # Try XPath node click.js --url https://example.com --selector "//button[contains(text(),'Submit')]" ``` ### Common Mistakes ❌ Wrong working directory → output files go to wrong location ❌ Skipping output validation → silent failures ❌ Using complex CSS selectors without testing → selector errors ❌ Not checking element visibility → timeout errors ✅ Always verify `pwd` before running scripts ✅ Always validate output after screenshots ✅ Use snapshot.js to discover selectors ✅ Test selectors with simple commands first ## Common Workflows ### Web Scraping ```bash node evaluate.js --url https://example.com --script " Array.from(document.querySelectorAll('.item')).map(el => ({ title: el.querySelector('h2')?.textContent, link: el.querySelector('a')?.href })) " | jq '.result' ``` ### Performance Testing ```bash PERF=$(node performance.js --url https://example.com) LCP=$(echo $PERF | jq '.vitals.LCP') if (( $(echo "$LCP < 2500" | bc -l) )); then echo "✓ LCP passed: ${LCP}ms" else echo "✗ LCP failed: ${LCP}ms" fi ``` ### Form Automation ```bash node fill.js --url https://example.com --selector "#search" --value "query" --close false node click.js --selector "button[type=submit]" ``` ### Error Monitoring ```bash node console.js --url https://example.com --types error,warn --duration 5000 | jq '.messageCount' ``` ## Script Options All scripts support: - `--headless false` - Show browser window - `--close false` - Keep browser open for chaining - `--timeout 30000` - Set timeout (milliseconds) - `--wait-until networkidle2` - Wait strategy See `./scripts/README.md` for complete options. ## Output Format All scripts output JSON to stdout: ```json { "success": true, "url": "https://example.com", ... // script-specific data } ``` Errors go to stderr: ```json { "success": false, "error": "Error message" } ``` ## Finding Elements Use `snapshot.js` to discover selectors: ```bash node snapshot.js --url https://example.com | jq '.elements[] | {tagName, text, selector}' ``` ## Troubleshooting ### Common Errors **"Cannot find package 'puppeteer'"** - Run: `npm install` in the scripts directory **"error while loading shared libraries: libnss3.so"** (Linux/WSL) - Missing system dependencies - Fix: Run `./install-deps.sh` in scripts directory - Manual install: `sudo apt-get install -y libnss3 libnspr4 libasound2t64 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1` **"Failed to launch the browser process"** - Check system dependencies installed (Linux/WSL) - Verify Chrome downloaded: `ls ~/.cache/puppeteer` - Try: `npm rebuild` then `npm install` **Chrome not found** - Puppeteer auto-downloads Chrome during `npm install` - If failed, manually trigger: `npx puppeteer browsers install chrome` ### Script Issues **Element not found** - Get snapshot first to find correct selector: `node snapshot.js --url ` **Script hangs** - Increase timeout: `--timeout 60000` - Change wait strategy: `--wait-until load` or `--wait-until domcontentloaded` **Blank screenshot** - Wait for page load: `--wait-until networkidle2` - Increase timeout: `--timeout 30000` **Permission denied on scripts** - Make executable: `chmod +x *.sh` **Screenshot too large (>5MB)** - Install ImageMagick for automatic compression - Manually set lower threshold: `--max-size 3` - Use JPEG format instead of PNG: `--format jpeg --quality 80` - Capture specific element instead of full page: `--selector .main-content` **Compression not working** - Verify ImageMagick installed: `magick -version` or `convert -version` - Check file was actually compressed in output JSON: `"compressed": true` - For very large pages, use `--selector` to capture only needed area ## Reference Documentation Detailed guides available in `./references/`: - [CDP Domains Reference](./references/cdp-domains.md) - 47 Chrome DevTools Protocol domains - [Puppeteer Quick Reference](./references/puppeteer-reference.md) - Complete Puppeteer API patterns - [Performance Analysis Guide](./references/performance-guide.md) - Core Web Vitals optimization ## Advanced Usage ### Custom Scripts Create custom scripts using shared library: ```javascript import { getBrowser, getPage, closeBrowser, outputJSON } from './lib/browser.js'; // Your automation logic ``` ### Direct CDP Access ```javascript const client = await page.createCDPSession(); await client.send('Emulation.setCPUThrottlingRate', { rate: 4 }); ``` See reference documentation for advanced patterns and complete API coverage. ## External Resources - [Puppeteer Documentation](https://pptr.dev/) - [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) - [Scripts README](./scripts/README.md)