Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external dependencies.
.claude/skills/alirezarezvani-full-page-screenshot/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 1% | 0% |
| case-13 | ✗→✓ | ▲ Improved | -22% | 0% |
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
WebSocket)Check environment readiness:
bashnode "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check
If Chrome check fails, instruct user to open chrome://inspect/#remote-debugging and enable "Allow remote debugging for this browser instance".
bashnode "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list
bashnode "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1
bashnode "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000
> Note: --url mode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.
| Parameter | Description | Default | |-----------|-------------|---------| | output | Output PNG file path | /tmp/screenshot.png | | --width | Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 | | --dpr | Device pixel ratio (2 = Retina, but 4x file size) | 1 | | --wait | Page load timeout in ms (--url mode only) | 15000 | | --css | Custom CSS to inject before capture (e.g., hide elements) | — |
bash# macOS sips -g pixelWidth -g pixelHeight /tmp/screenshot.png # Linux file /tmp/screenshot.png
overflow-y: auto/scroll containers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind h-[calc(...)]) so all content renders in a single pass.readyState=complete, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.IntersectionObserver callbacks, then waits for all <img> elements to complete loading.DevToolsActivePort file to find the debugging port. Falls back to probing ports 9222, 9229, 9333./eval, /screenshot, /scroll) for capture.1. Discover Chrome debugging port
2. Connect via WebSocket (CDP)
3. Attach to target / create background tab
4. Set viewport width via Emulation domain
5. Wait: readyState + DOM stability
6. Detect & expand scroll containers
7. Scroll through page (trigger lazy-load)
8. Wait for images to complete
9. Measure final content height
10. Page.captureScreenshot (or tiled capture)
11. Stitch tiles if needed (PIL)
12. Restore viewport, detach, clean up| Do NOT | Do instead | |--------|-----------| | Use --dpr 2 on pages > 10,000px tall | Use --dpr 1 to avoid Chrome memory issues | | Use --url for authenticated/SSO pages | Use --list + targetId on a tab where user is logged in | | Set --wait below 5000 for SPAs | SPAs need time to fetch data and render; use 10000-15000 | | Capture without checking --check first | Always verify Chrome debugging is available | | Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards/tables | | Skip output verification | Always verify with sips or file command after capture |
| Symptom | Cause | Fix | |---------|-------|-----| | "Cannot find Chrome debugging port" | Remote debugging not enabled | Open chrome://inspect/#remote-debugging, enable it | | "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API | | Blank/white screenshot | Page not loaded yet | Increase --wait value | | Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists | | Out of memory | Very tall page + high DPR | Reduce --dpr to 1 and/or reduce --width | | "PIL not available for stitching" | Python Pillow not installed | Install with pip3 install Pillow or accept separate tile files |
engineering/browser-automation — General browser automation patterns via CDP/Playwrightengineering/performance-profiler — Performance analysis that may complement visual captures| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 10,611 | 4,214 | -60% | 1 | 1 | 0% | 2,341 | 1,609 | -31% | 0 | 0 | — |
case-02 | fail→fail | 11,215 | 6,074 | -46% | 1 | 1 | 0% | 2,024 | 1,786 | -12% | 0 | 0 | — |
case-03 | fail→fail | 10,356 | 6,847 | -34% | 1 | 1 | 0% | 1,299 | 1,628 | +25% | 0 | 0 | — |
case-04 | fail→pass | 6,385 | 1,890 | -70% | 1 | 1 | 0% | 1,134 | 1,588 | +40% | 0 | 0 | — |
case-09 | pass→pass | 4,694 | 2,773 | -41% | 1 | 1 | 0% | 861 | 1,882 | +119% | 0 | 0 | — |
case-05 | pass→pass | 11,380 | 5,584 | -51% | 1 | 1 | 0% | 2,063 | 2,430 | +18% | 0 | 0 | — |
case-06 | fail→pass | 19,631 | 2,803 | -86% | 1 | 1 | 0% | 957 | 1,780 | +86% | 0 | 0 | — |
case-07 | fail→pass | 11,955 | 4,395 | -63% | 1 | 1 | 0% | 1,973 | 2,127 | +8% | 0 | 0 | — |
case-08 | pass→pass | 5,587 | 1,995 | -64% | 1 | 1 | 0% | 1,068 | 1,716 | +61% | 0 | 0 | — |
case-10 | fail→pass | 9,501 | 2,142 | -77% | 1 | 1 | 0% | 1,727 | 1,741 | +1% | 0 | 0 | — |
case-11 | pass→pass | 12,371 | 2,667 | -78% | 1 | 1 | 0% | 2,253 | 1,795 | -20% | 0 | 0 | — |
case-12 | pass→pass | 3,617 | 1,636 | -55% | 1 | 1 | 0% | 648 | 1,621 | +150% | 0 | 0 | — |
case-13 | fail→pass | 28,930 | 1,484 | -95% | 1 | 1 | 0% | 2,065 | 1,619 | -22% | 0 | 0 | — |
case-14 | fail→pass | 14,747 | 3,397 | -77% | 1 | 1 | 0% | 2,393 | 1,918 | -20% | 0 | 0 | — |
case-15 | fail→pass | 14,104 | 3,341 | -76% | 1 | 1 | 0% | 2,735 | 2,041 | -25% | 0 | 0 | — |
case-16 | fail→pass | 11,985 | 1,681 | -86% | 1 | 1 | 0% | 2,061 | 1,698 | -18% | 0 | 0 | — |
case-17 | fail→pass | 10,280 | 1,256 | -88% | 1 | 1 | 0% | 2,044 | 1,623 | -21% | 0 | 0 | — |
case-18 | pass→pass | 10,895 | 4,138 | -62% | 1 | 1 | 0% | 2,209 | 2,221 | +1% | 0 | 0 | — |
case-19 | pass→pass | 9,431 | 6,567 | -30% | 1 | 1 | 0% | 1,896 | 2,708 | +43% | 0 | 0 | — |
case-20 | pass→pass | 6,870 | 3,357 | -51% | 1 | 1 | 0% | 1,420 | 2,080 | +46% | 0 | 0 | — |
case-21 | pass→pass | 2,264 | 3,240 | +43% | 1 | 1 | 0% | 409 | 2,056 | +403% | 0 | 0 | — |
case-22 | fail→pass | 10,561 | 1,268 | -88% | 1 | 1 | 0% | 1,951 | 1,552 | -20% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.