WebShot
A fast command-line tool for taking website screenshots, built in Rust.
Features
- Take full-page or element-specific screenshots
- Scrolling screenshots - capture content beyond viewport
- Generate PDFs from web pages
- Execute JavaScript before capturing
- Batch processing with YAML configs
- Support for PNG, JPEG, WebP, and PDF formats
- Custom viewports and mobile emulation
- Wait for elements or timeouts
- Extract text content from pages
- Multiple comparison algorithms (pixel-diff, SSIM, MSE, PSNR)
- Generate difference images highlighting changes
- Visual regression testing support
- Configurable similarity thresholds
- Works on Windows, macOS, and Linux
Installation
From Source
You'll need Chrome or Chromium installed. The tool will find it automatically.
Quick Start
# Basic screenshot
# Custom size and output
# Screenshot just the header
# Generate a PDF
# Screenshot in WebP format
# Extract text content
# Full page scrolling screenshot
Usage
Basic Options
-o, --output- Output file path-w, --width- Viewport width (default: 1280)-H, --height- Viewport height (default: 800)-s, --selector- CSS selector for element screenshots-j, --javascript- JavaScript to run before screenshot--wait-for- Wait for element to appear-t, --timeout- Timeout in seconds (default: 30)--retina- Enable high-DPI mode-q, --quality- JPEG/WebP quality 1-100-v, --verbose- Verbose logging--full-page- Enable full page scrolling screenshot--max-height- Maximum height for full page screenshots (pixels)--scroll-delay- Scroll delay between captures (milliseconds)-h, --help- Show help (-His used for viewport height)
Subcommands
screenshot
Basic screenshot with full options:
pdf
Generate PDF from webpage:
multi
Process multiple screenshots from YAML config:
text
Extract text content:
compare
Compare two images for differences:
# Basic comparison
# Use different algorithm with threshold
# Generate difference image
# Output results as JSON
# Ignore anti-aliasing differences
Configuration Files
For batch processing, create a YAML file:
# Simple config
screenshots:
- url: "https://example.com"
output: "example.png"
- url: "https://github.com"
output: "github.png"
width: 1920
height: 1080
Advanced config with defaults:
defaults:
width: 1280
height: 800
timeout: 30
output_dir: "screenshots"
screenshots:
- url: "https://github.com"
output: "github-header.png"
selector: ".Header"
- url: "https://example.com"
output: "interactive.png"
javascript: "document.querySelector('button').click();"
- url: "https://spa-app.com"
output: "spa-loaded.png"
wait_for: ".content"
timeout: 15
Configuration Options
url- Target HTTP(S) URL (required)output- Output file path (required)width,height- Viewport dimensionsselector- CSS selector for element screenshotsjavascript- JavaScript code to executewait_for- CSS selector to wait fortimeout- Timeout in secondsretina- Enable retina modequality- JPEG/WebP quality 1-100wait- Wait time before screenshotuser_agent- Custom user agentheaders- Custom HTTP headerscookies- Cookies to setauth- Basic authentication (username/password)scroll_mode- Scrolling mode: "Viewport", "FullPage", or "FullElement"max_height- Maximum height for full page screenshots (pixels)scroll_delay- Scroll delay between captures (milliseconds)
Output Behavior
- Supported output extensions are
.png,.jpg,.jpeg,.webp, and.pdf. - Webshot chooses the runtime output format from the
outputfilename extension. - Relative screenshot
outputpaths are resolved underdefaults.output_dirwhen it is set. - The
multicommand's-o, --output-diroption is prepended at runtime to each loaded output path, including anydefaults.output_dircomponent already applied during config loading. For example,defaults.output_dir: "screenshots",output: "home.png", andwebshot multi config.yaml -o artifactswritesartifacts/screenshots/home.png. - Parent directories for screenshot, PDF, text, diff-image, and JSON comparison outputs are created automatically.
- Existing output files are replaced when a command writes the same path.
Examples
Mobile Screenshots
# iPhone viewport
# iPad viewport
Scrolling Screenshots
# Full page scrolling screenshot
# Scrolling element screenshot (captures entire scrollable content)
# Control scroll timing for slow-loading content
# Mobile full page with height limit
JavaScript Execution
# Click elements and modify page
Custom Chrome Setup
# Use custom Chrome path
# Add Chrome flags
Troubleshooting
Chrome not found: Use --chrome-path to specify location manually
Element not found: Check CSS selector syntax, use --wait-for for dynamic content
Timeouts: Increase with -t flag, check network connection
JavaScript errors: Use -v for verbose logging
Development
# Build
# Run deterministic tests
# Browser/network integration tests are ignored by default and require Chrome or Chromium
CI and release flow
GitHub Actions runs the Rust CI workflow for pushes to master or main, for
pull_request events targeting master or main, and for pushed tags matching v*.
Pull requests run only the Test job; releases are triggered only by v* tags.
The Test job checks out the repository, installs the stable Rust toolchain,
uses the Cargo cache, runs cargo test --verbose --all-features, builds with
cargo build --release --verbose, and uploads the release binary artifact from
target/release/webshot as webshot-binary for seven days.
To publish a release, create and push a version tag such as v0.2.1:
Pushing a v* tag first runs the Test job. If it succeeds, the Create Release job
builds target/release/webshot again and publishes a GitHub Release with
generated release notes (generate_release_notes: true) via
softprops/action-gh-release@v1.
License
MIT License - see LICENSE file for details.
Built with headless_chrome and clap.