A self-hosted visual regression testing tool built with Node.js that allows you to set baselines and compare screenshots of your website across different URLs and selectors.
- πΈ Screenshot capture with Puppeteer
 - π Pixel-level image comparison with Pixelmatch
 - π Console and HTML reporting
 - βοΈ Flexible configuration for multiple URLs and selectors
 - π― Support for different viewport sizes
 - π Baseline management system
 - π Easy-to-use CLI interface
 
- Clone or download this project
 - Install dependencies:
 
npm install- Initialize configuration:
 
node index.js init- Edit the configuration file (
config/visual-regression.config.json) to match your website: 
{
  "baseUrl": "http://localhost:3000",
  "targets": [
    {
      "name": "homepage",
      "url": "/",
      "selector": "body",
      "viewport": { "width": 1200, "height": 800 }
    },
    {
      "name": "header",
      "url": "/",
      "selector": "header",
      "viewport": { "width": 1200, "height": 200 }
    }
  ],
  "options": {
    "waitTime": 3000,
    "threshold": 0.1,
    "includeAA": false,
    "diffMask": [255, 0, 255]
  }
}- Set baseline screenshots:
 
node index.js baseline- Run visual regression tests:
 
node index.js test --htmlInitialize a sample configuration file.
node index.js init [--force]--force: Overwrite existing configuration
Set baseline screenshots for comparison.
node index.js baseline [--config <path>] [--target <name>]--config: Configuration file path (default: config/visual-regression.config.json)--target: Set baseline for specific target only
Run visual regression tests.
node index.js test [--config <path>] [--output <dir>] [--html]--config: Configuration file path (default: config/visual-regression.config.json)--output: Output directory for results (default: results)--html: Generate HTML report
List all baseline screenshots.
node index.js listClear all baseline screenshots.
node index.js clear [--yes]--yes: Skip confirmation prompt
The configuration file (config/visual-regression.config.json) supports the following options:
The base URL for your website (e.g., http://localhost:3000).
Array of targets to test. Each target can have:
name: Unique identifier for the targeturl: URL path relative to baseUrlselector: CSS selector to capture (e.g.,body,#main,.header)viewport: Object withwidthandheightfor browser viewport
Comparison and capture options:
waitTime: Time to wait after page load before screenshot (ms)threshold: Difference threshold (0-1, lower = stricter)includeAA: Include anti-aliased pixels in comparisondiffMask: RGB color for highlighting differences
- Setup: Configure your targets in the config file
 - Baseline: Capture initial screenshots as the "golden" baseline
 - Develop: Make changes to your website
 - Test: Run regression tests to compare against baseline
 - Review: Check console output and HTML report for differences
 - Update: If changes are expected, update the baseline
 
results/
βββ current-YYYY-MM-DDTHH-MM-SS-SSSZ/    # Current screenshots
βββ diff-YYYY-MM-DDTHH-MM-SS-SSSZ/       # Difference images
βββ report-YYYY-MM-DDTHH-MM-SS-SSSZ.html # HTML report
baseline/                                 # Baseline screenshots
{
  "targets": [
    {
      "name": "homepage-desktop",
      "url": "/",
      "selector": "body",
      "viewport": { "width": 1200, "height": 800 }
    },
    {
      "name": "homepage-mobile",
      "url": "/",
      "selector": "body",
      "viewport": { "width": 375, "height": 667 }
    }
  ]
}{
  "targets": [
    {
      "name": "navigation",
      "url": "/",
      "selector": "nav",
      "viewport": { "width": 1200, "height": 100 }
    },
    {
      "name": "footer",
      "url": "/",
      "selector": "footer",
      "viewport": { "width": 1200, "height": 200 }
    }
  ]
}{
  "targets": [
    {
      "name": "home",
      "url": "/",
      "selector": "body",
      "viewport": { "width": 1200, "height": 800 }
    },
    {
      "name": "about",
      "url": "/about",
      "selector": "body",
      "viewport": { "width": 1200, "height": 800 }
    }
  ]
}This tool can be easily integrated into CI/CD pipelines:
# Set baseline (run once or when updating)
node index.js baseline
# Run tests in CI
node index.js test --html
# The tool will exit with code 1 if any tests fail- Screenshots are blank: Increase 
waitTimein configuration - Element not found: Check that the selector exists and the page is fully loaded
 - Connection refused: Ensure your website is running on the specified baseUrl
 - Permission denied: Check file permissions for the project directory
 
For debugging, you can modify the screenshot-capture.js to enable headful mode:
await puppeteer.launch({
  headless: false, // Set to false for debugging
  // ... other options
});- puppeteer: Browser automation for screenshot capture
 - pixelmatch: Pixel-level image comparison
 - fs-extra: Enhanced file system operations
 - commander: CLI framework
 - chalk: Terminal colors and formatting
 
MIT License - feel free to use this in your projects!