How to Capture Screenshot Evidence in GitHub Actions CI/CD Pipelines
GitHub Actions runs tests headlessly with zero visual output. Add PageBolt screenshots to your workflows to capture before/after states of UI tests, store visual evidence as artifacts, and debug test failures with proof.
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)
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?
- 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.
The Gap: GitHub Actions Lacks Visual Context
GitHub Actions gives you test execution logs, pass/fail status, error stack traces, and code coverage reports. But it doesn't give you screenshots of the page during test execution, before/after visual comparison, or 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
Store your key as a GitHub secret: PAGEBOLT_API_KEY, then 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: Start dev server
run: npm run dev &
env:
PORT: 3000
- name: Wait for server
run: sleep 5
- 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
- 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
- name: Upload screenshot evidence
if: always()
uses: actions/upload-artifact@v3
with:
name: screenshot-evidence
path: |
before-screenshot.json
after-screenshot.json
- name: Comment on PR with screenshots
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const before = JSON.parse(require('fs').readFileSync('before-screenshot.json'));
const after = JSON.parse(require('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})`
});
This workflow captures before/after screenshots, uploads them as artifacts, and comments on the PR with screenshot links so reviewers see visual proof directly in the pull request.
Scaling to Complex Pipelines
For multi-stage CI/CD pipelines, capture at each critical checkpoint:
- Before unit tests → After unit tests (visual baseline)
- Before integration tests → After integration tests (multi-component proof)
- Before deployment → After deployment (staging verification)
- Before accessibility audit → After audit (capture improvements)
- 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\",\"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
Cost & Rate Limits
| Plan | Requests/month | Price |
|---|---|---|
| Free | 100 | $0 |
| Starter | 5,000 | $29 |
| Growth | 25,000 | $79 |
| Scale | 100,000 | $199 |
A typical CI workflow capturing 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 evidence solves three problems:
- Debugging — compare before/after screenshots, see exactly what broke
- Proof — auditors and reviewers see visual evidence, not just logs
- Confidence — know your UI changes actually work as intended
Give your CI pipeline eyes — free
100 requests/month, no credit card. Add two curl commands to any GitHub Actions workflow and capture visual proof of every test run.
Get API key free →