Screenshot Smart
Boost productivity using this user, explicitly, asks, desktop. Includes structured workflows, validation checks, and reusable patterns for media.
Screenshot Smart
A practical skill for capturing, managing, and organizing screenshots ā covering OS-native screenshot commands, automated captures for testing, screenshot annotation, file naming conventions, and integration into documentation workflows.
When to Use This Skill
Choose Screenshot Smart when you need to:
- Capture screenshots for documentation or bug reports
- Automate screenshot capture for visual regression testing
- Organize and name screenshots consistently
- Annotate screenshots with highlights and callouts
- Integrate screenshots into CI/CD or testing pipelines
Consider alternatives when:
- You need image editing or enhancement (use an image enhancer skill)
- You need screen recording or video (use a screen recording skill)
- You need UI mockups or wireframes (use a design skill)
Quick Start
# macOS ā Capture full screen to desktop screencapture ~/Desktop/screenshot.png # macOS ā Capture a specific window screencapture -w ~/Desktop/window.png # macOS ā Capture selection to clipboard screencapture -sc # Linux ā Capture with scrot scrot ~/Desktop/screenshot.png # Linux ā Capture window with gnome-screenshot gnome-screenshot -w -f ~/Desktop/window.png # Windows ā Capture with PowerShell Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Screen]::PrimaryScreen | Out-Null
# Automated screenshot with Playwright from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page(viewport={"width": 1280, "height": 720}) page.goto("https://example.com") # Full page screenshot page.screenshot(path="screenshots/homepage.png", full_page=True) # Element screenshot page.locator(".hero-section").screenshot(path="screenshots/hero.png") # With device emulation iphone = p.devices["iPhone 13"] mobile = browser.new_context(**iphone) mobile_page = mobile.new_page() mobile_page.goto("https://example.com") mobile_page.screenshot(path="screenshots/mobile.png") browser.close()
Core Concepts
Screenshot Capture Methods
| Method | Platform | Use Case | Command/Tool |
|---|---|---|---|
| OS native | macOS | Quick manual captures | screencapture |
| OS native | Linux | Quick manual captures | scrot, gnome-screenshot |
| Browser automation | Cross-plat | Automated web screenshots | Playwright, Puppeteer |
| Headless browser | CI/CD | Visual regression testing | Playwright, Cypress |
| API-based | Cloud | Bulk URL screenshots | screenshotapi, urlbox |
Naming Convention
## Screenshot File Naming ### Pattern {project}_{page}_{state}_{viewport}_{date}.png ### Examples - myapp_login_default_desktop_20241215.png - myapp_login_error_mobile_20241215.png - myapp_dashboard_loaded_tablet_20241215.png - myapp_settings_dark-mode_desktop_20241215.png ### Directory Structure screenshots/ āāā desktop/ ā āāā login/ ā āāā dashboard/ ā āāā settings/ āāā mobile/ ā āāā login/ ā āāā dashboard/ ā āāā settings/ āāā regression/ āāā baseline/ āāā current/
Visual Regression Testing
# visual_regression.py from PIL import Image, ImageChops import math def compare_screenshots(baseline_path, current_path, diff_path, threshold=0.01): """Compare two screenshots and generate a diff image.""" baseline = Image.open(baseline_path) current = Image.open(current_path) if baseline.size != current.size: print(f"Size mismatch: {baseline.size} vs {current.size}") return False diff = ImageChops.difference(baseline, current) diff_pixels = sum(1 for px in diff.getdata() if sum(px[:3]) > 30) total_pixels = baseline.size[0] * baseline.size[1] diff_pct = diff_pixels / total_pixels if diff_pct > threshold: diff.save(diff_path) print(f"DIFF: {diff_pct:.2%} changed ({diff_path})") return False print(f"PASS: {diff_pct:.4%} difference (below {threshold:.2%} threshold)") return True compare_screenshots( "screenshots/baseline/homepage.png", "screenshots/current/homepage.png", "screenshots/diff/homepage_diff.png" )
Configuration
| Parameter | Description | Example |
|---|---|---|
output_dir | Screenshot save directory | "./screenshots" |
viewport | Browser viewport dimensions | "1280x720" |
format | Image format | "png" / "jpeg" |
full_page | Capture full scrollable page | true |
naming_pattern | File naming convention | "{page}_{state}_{date}" |
diff_threshold | Visual regression change threshold | 0.01 (1%) |
Best Practices
-
Use PNG for screenshots, not JPEG ā Screenshots contain text, UI elements, and sharp edges that JPEG compression artifacts destroy. PNG preserves these details perfectly. Use JPEG only for photographs embedded in the page.
-
Capture at a consistent viewport size ā Different window sizes produce different layouts. Set explicit viewport dimensions (e.g., 1280x720) in automated captures so screenshots are comparable across runs and machines.
-
Wait for page stability before capturing ā Animated elements, loading spinners, and lazy-loaded images cause screenshot inconsistencies. Use
page.waitForLoadState("networkidle")or explicit element selectors before capturing. -
Store baseline screenshots in version control ā For visual regression testing, baselines must be versioned alongside the code. When a UI change is intentional, update the baseline. Unversioned baselines on local machines cause false positives across different developers.
-
Name screenshots descriptively, not sequentially ā
screenshot-001.pngtells you nothing.dashboard_monthly-report_loaded_desktop.pngtells you exactly what you're looking at. Good naming makes manual review and debugging faster.
Common Issues
Screenshots differ across machines due to font rendering ā Different operating systems render fonts differently (ClearType on Windows, FreeType on Linux, Core Text on macOS). For consistent visual regression testing, run captures in a Docker container with fixed fonts and rendering settings.
Full-page screenshots are cut off or have white space ā Some pages have lazy-loaded content or dynamically expanding sections. Scroll the entire page before capturing: in Playwright, set full_page=True or scroll programmatically with page.evaluate("window.scrollTo(0, document.body.scrollHeight)").
Animated elements cause flaky visual regression tests ā CSS animations, GIF images, and video players render differently on each capture. Disable animations before screenshots: inject * { animation: none !important; transition: none !important; } or use Playwright's page.emulate_media(reduced_motion="reduce").
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.