DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to Capture Screenshot Evidence in GitHub Actions CI/CD Pipelines

How to Capture Screenshot Evidence in GitHub Actions CI/CD Pipelines

Your GitHub Actions workflow just ran your test suite. 50 tests passed. 2 failed. Your CI logs show:

FAIL: spec/login-flow.test.js
  ✓ User loads login page (150ms)
  ✓ User enters credentials (45ms)
  ✗ User sees dashboard after login (5000ms timeout)
Enter fullscreen mode Exit fullscreen mode

But here's what you actually don't know:

  • Did the login form really fill out?
  • What was on the screen when the test timed out?
  • Did a modal appear that blocked the dashboard?
  • Was the page loading, or did it break?
  • Can you see what changed between test runs?

GitHub Actions executes — but doesn't see.

Your workflow runs tests in a headless environment. No browser window. No screenshots. Your logs show pass/fail status. They don't show what the user actually saw on screen.

If a test fails, you manually re-run it locally to debug. That's wasted CI time.

If you need to prove your visual changes work correctly for compliance or audit purposes, you have no evidence.

The Gap: GitHub Actions Lacks Visual Context

GitHub Actions gives you:

  • Test execution logs
  • Pass/fail status
  • Error stack traces
  • Code coverage reports

But it doesn't give you:

  • Screenshots of the page during test execution
  • Before/after visual comparison
  • Evidence of what the browser actually rendered
  • Proof that UI changes are correct

Your CI logs are text. Reviewers and auditors need proof.

The Solution: Add PageBolt Screenshots to Your Workflow

PageBolt's screenshot API captures full-page visuals. Embed it directly into your GitHub Actions workflow using curl in your YAML configuration.

Why this works:

  • ✅ Captures what the test actually sees
  • ✅ Stores visual evidence as workflow artifacts
  • ✅ Makes debugging obvious (screenshot diff shows exactly what broke)
  • ✅ Works with any web app your tests can access
  • ✅ Integrates with your existing GitHub workflow

Real Example: Screenshot Evidence Workflow

Here's a GitHub Actions workflow that runs tests and captures before/after screenshots for proof:

Setup:

  1. Get a free PageBolt API key at pagebolt.dev
  2. Store your key as a GitHub secret: PAGEBOLT_API_KEY
  3. Add screenshot steps to your workflow YAML

.github/workflows/screenshot-evidence.yml:

name: Test with Screenshot Evidence

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install dependencies
        run: npm ci

      - name: Capture page before tests
        run: |
          curl -X POST https://pagebolt.dev/api/v1/screenshot \
            -H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "url": "http://localhost:3000/login",
              "width": 1280,
              "height": 720
            }' \
            -o before-screenshot.json
          cat before-screenshot.json | jq '.url' > before-url.txt

      - name: Start dev server
        run: npm run dev &
        env:
          PORT: 3000

      - name: Wait for server
        run: sleep 5

      - name: Run tests
        run: npm test -- --ci

      - name: Capture page after tests
        if: always()
        run: |
          curl -X POST https://pagebolt.dev/api/v1/screenshot \
            -H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "url": "http://localhost:3000/dashboard",
              "width": 1280,
              "height": 720
            }' \
            -o after-screenshot.json
          cat after-screenshot.json | jq '.url' > after-url.txt

      - name: Store screenshot evidence
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: screenshot-evidence
          path: |
            before-screenshot.json
            after-screenshot.json
            before-url.txt
            after-url.txt

      - name: Comment with screenshot links
        if: always() && github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const before = JSON.parse(fs.readFileSync('before-screenshot.json'));
            const after = JSON.parse(fs.readFileSync('after-screenshot.json'));
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Screenshot Evidence\n\n**Before:** [View](${before.url})\n\n**After:** [View](${after.url})`
            });
Enter fullscreen mode Exit fullscreen mode

This workflow:

  1. Captures a screenshot of the login page before tests run
  2. Starts your dev server
  3. Runs your test suite
  4. Captures a screenshot of the dashboard after tests complete
  5. Uploads both screenshots as workflow artifacts
  6. Comments on the PR with links to the visual proof

Now reviewers can see before/after screenshots directly in the pull request.

Scaling to Complex Workflows

For multi-stage CI/CD pipelines, capture at each critical checkpoint:

  1. Before unit testsAfter unit tests (prove visual baseline)
  2. Before integration testsAfter integration tests (verify multi-component interaction)
  3. Before deploymentAfter deployment (visual proof in staging)
  4. Before accessibility auditAfter audit (capture accessibility improvements)

Store all screenshots as artifacts, indexed by stage and timestamp:

- name: Capture at each stage
  run: |
    for stage in unit integration deployment; do
      curl -X POST https://pagebolt.dev/api/v1/screenshot \
        -H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
        -H "Content-Type: application/json" \
        -d "{
          \"url\": \"http://localhost:3000/$stage-checkpoint\",
          \"width\": 1280,
          \"height\": 720
        }" \
        -o "screenshot-$stage.json"
    done

- name: Upload all screenshots
  uses: actions/upload-artifact@v3
  with:
    name: ci-screenshots
    path: screenshot-*.json
Enter fullscreen mode Exit fullscreen mode

Each screenshot is timestamped, URL-verified, and stored as evidence. Your CI/CD pipeline goes from text logs to visual proof.

Cost & Rate Limits

  • Free tier: 100 requests/month (perfect for testing workflows)
  • Starter: 5,000 requests/month ($29) — handles 500+ CI runs
  • Growth: 25,000+ requests/month ($79) — enterprise CI/CD pipelines
  • Scale: 100,000+ requests/month ($199) — high-volume multi-stage workflows

A typical CI workflow that captures 2-3 screenshots per run uses ~50-75 requests/month on Starter tier.

Why This Matters

GitHub Actions runs tests in isolation. Tests execute headlessly. Your logs show pass/fail. They don't show proof.

Visual audit trails solve three problems:

  1. Debugging — compare before/after screenshots, see exactly what broke
  2. Proof — auditors and reviewers see visual evidence, not just logs
  3. Confidence — know your UI changes actually work as intended

Get Started

  1. Sign up free at pagebolt.dev (100 requests/month, no credit card)
  2. Create a GitHub secret: PAGEBOLT_API_KEY
  3. Add screenshot steps to your .github/workflows/*.yml
  4. Push to trigger the workflow
  5. Check the PR comments for screenshot evidence links

Your GitHub Actions workflows will finally have eyes.


Try PageBolt free — 100 API requests/month, no credit card required. Start capturing visual proof of your GitHub Actions CI/CD pipelines today.

Top comments (0)