DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to Automate Screenshots in Your CI/CD Pipeline

How to Automate Screenshots in Your CI/CD Pipeline

Every deploy is a visual change. Buttons move. Colors shift. Layouts break. You can't catch all of it manually.

What if your CI/CD pipeline automatically captured screenshots after each deploy? Stored them. Compared them. Surfaced visual regressions before they hit production?

That's what this tutorial covers. We'll add screenshot automation to GitHub Actions using PageBolt's API.

The Setup

What you'll need:

  • A GitHub repository with GitHub Actions enabled
  • A staging environment (or production)
  • A PageBolt API key (free tier: 100 screenshots/month)
  • 15 minutes

What you'll get:

  • Screenshots captured after every deploy
  • Before/after comparison storage
  • Visual regression detection (manual review)
  • Artifact logs for debugging

Step 1: Store Your API Key as a Secret

In GitHub: Settings → Secrets and variables → Actions → New repository secret

Name: PAGEBOLT_API_KEY
Value: your-actual-api-key-here
Enter fullscreen mode Exit fullscreen mode

Your workflow will access it as ${{ secrets.PAGEBOLT_API_KEY }}.

Step 2: Create the GitHub Actions Workflow

Create .github/workflows/screenshot-deploy.yml:

name: Capture Deploy Screenshots

on:
  deployment_status

jobs:
  screenshot:
    runs-on: ubuntu-latest
    if: github.event.deployment_status.state == 'success'

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Create screenshots directory
        run: mkdir -p screenshots

      - name: Capture deployment screenshot
        env:
          PAGEBOLT_API_KEY: ${{ secrets.PAGEBOLT_API_KEY }}
          DEPLOYMENT_URL: ${{ github.event.deployment_status.environment_url }}
        run: node scripts/capture-screenshot.js

      - name: Upload screenshots as artifact
        uses: actions/upload-artifact@v4
        with:
          name: deployment-screenshots
          path: screenshots/
          retention-days: 30

      - name: Comment on PR with screenshot
        if: github.event.pull_request
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '📸 Deployment screenshot captured. Check artifacts tab.'
            })
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Screenshot Capture Script

Create scripts/capture-screenshot.js:

const fs = require('fs');
const path = require('path');

async function captureScreenshot() {
  const apiKey = process.env.PAGEBOLT_API_KEY;
  const deploymentUrl = process.env.DEPLOYMENT_URL;
  const timestamp = new Date().toISOString().split('T')[0];

  if (!apiKey || !deploymentUrl) {
    console.error('❌ Missing PAGEBOLT_API_KEY or DEPLOYMENT_URL');
    process.exit(1);
  }

  console.log(`📸 Capturing screenshot of: ${deploymentUrl}`);

  try {
    const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        url: deploymentUrl,
        format: 'png',
        width: 1280,
        height: 720
      })
    });

    if (!response.ok) {
      throw new Error(`API error: ${response.status} ${response.statusText}`);
    }

    // Response is binary PNG data
    const buffer = await response.arrayBuffer();
    const screenshotPath = path.join('screenshots', `${timestamp}-deployment.png`);

    fs.writeFileSync(screenshotPath, Buffer.from(buffer));
    console.log(`✅ Screenshot saved: ${screenshotPath}`);
    console.log(`📊 Size: ${buffer.byteLength} bytes`);

  } catch (error) {
    console.error(`❌ Screenshot failed: ${error.message}`);
    process.exit(1);
  }
}

captureScreenshot();
Enter fullscreen mode Exit fullscreen mode

Step 4: Test It

Push to your repo. Trigger a deployment. Watch the workflow run:

  1. GitHub Actions captures a screenshot of your staging URL
  2. Screenshot saves to screenshots/ directory
  3. Artifact is stored in the workflow run
  4. Comment posted on PR (if applicable)

Before/After Comparison

To compare screenshots between commits, store them by date:

// Modify the script to save with commit SHA
const commitSha = process.env.GITHUB_SHA.slice(0, 7);
const screenshotPath = path.join('screenshots', `${commitSha}-screenshot.png`);
Enter fullscreen mode Exit fullscreen mode

Then manually compare by downloading both artifacts:

  1. Current deployment screenshot
  2. Previous deployment screenshot
  3. Open in a visual diff tool (macOS Preview, ImageMagick, etc.)

Real-World Example: E-commerce Site

After every deploy to staging, capture a screenshot of:

  • Homepage
  • Product page
  • Checkout flow

Store all three. Review manually. Catch layout shifts before they reach production.

// Capture multiple URLs
const urls = [
  `${deploymentUrl}/`,
  `${deploymentUrl}/products/sample-product`,
  `${deploymentUrl}/checkout`
];

for (const url of urls) {
  await captureScreenshot(url, `${path.basename(url) || 'home'}`);
}
Enter fullscreen mode Exit fullscreen mode

Pricing

Free tier: 100 screenshots/month (covers most CI/CD pipelines)
Starter: $29/month for 5,000 screenshots (high-frequency deploys)
Growth: $79/month for 25,000 screenshots (large teams)
Scale: $199/month for 100,000 screenshots (enterprise)

For most projects, the free tier is enough. One screenshot per deploy = ~30 screenshots/month (if you deploy daily).

Next Steps

  1. Copy the workflow and script above
  2. Add your PageBolt API key to GitHub Secrets
  3. Deploy to staging
  4. Watch the artifact appear in your workflow run
  5. Compare screenshots manually or integrate with a visual regression tool

Start PageBolt free — 100 screenshots/month, no credit card.

Top comments (0)