How to Run Scheduled Website Screenshot Tests with Jenkins
Schedule Playwright screenshot tests in Jenkins, compare pages with approved baselines, and keep reports and screenshots available after each run.
Use a Jenkins Declarative Pipeline triggers { cron('...') } block to run website screenshot tests on a schedule, then run Playwright in a stable browser environment. For visual regression tests, Playwright’s toHaveScreenshot() compares the rendered page with an approved baseline. Archive screenshots and reports in a post { always { ... } } block so failed comparisons still leave evidence to inspect.
A “screenshot test” can mean either capturing an image for a person to review or automatically comparing it with a baseline and failing when it changes. This guide covers both, with the automated Playwright workflow as the main example.
1. Choose a schedule and test goal
First decide what the job should do and when it should run:
- Capture for review: save screenshots and publish them as Jenkins build artifacts. The job need not fail when pixels change.
- Visual regression: compare each run against reviewed reference images. A difference beyond the assertion’s configured tolerance fails the test.
- Periodic check: use Jenkins
cronfor a recurring run, whether or not source code changed. - Change-driven check: use an SCM webhook or
pollSCMif the intent is to run when repository changes are detected. That is different from a periodic schedule.
Jenkins cron expressions have five fields: minute (0–59), hour (0–23), day of month (1–31), month (1–12), and day of week (0–7, with 0 and 7 representing Sunday).
| Expression | Meaning |
|---|---|
H H * * * |
Once daily, at a job-specific hashed minute and hour. The exact wall-clock time is not guaranteed. |
H/15 * * * * |
About every 15 minutes, using a hash offset within each interval. |
30 2 * * 1-5 |
At 02:30, Monday through Friday, in the schedule’s time zone. |
0 9 * * 1 |
At 09:00 every Monday, in the schedule’s time zone. |
Jenkins recommends the H hash symbol where possible to spread periodic work across jobs. That helps avoid making every job fire at the same minute. Schedules use the Jenkins controller’s time zone by default. If the job requires another time zone, the trigger syntax can include a leading line such as TZ=Europe/London; check the Jenkins version and configuration in use.
triggers {
cron('H H * * *')
}
For a fixed run time, use explicit minute and hour fields, and account for the controller time zone and the load created when multiple jobs start together. For a spread-out recurring check, prefer a hash-based expression.
2. Add a Playwright screenshot assertion
Install Playwright Test in the repository and create a test that visits the target page. The first approved run generates a reference screenshot; review and commit that baseline. Later runs compare against it. Use Playwright’s documented snapshot update option only after reviewing an intentional design change.
npm install --save-dev @playwright/test
npx playwright install
Example test in tests/homepage.spec.js:
const { test, expect } = require('@playwright/test');
test('homepage matches the approved visual baseline', async ({ page }) => {
await page.goto(process.env.TARGET_URL || 'https://example.com', {
waitUntil: 'networkidle',
});
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
});
});
Configure the test output locations in playwright.config.js so Jenkins can archive them predictably:
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests',
reporter: [['html', { outputFolder: 'playwright-report', open: 'never' }]],
outputDir: 'test-results',
use: {
browserName: 'chromium',
headless: true,
viewport: { width: 1440, height: 900 },
screenshot: 'only-on-failure',
},
});
The test’s toHaveScreenshot() assertion writes and compares the named baseline. Keep baseline updates deliberate: generate them in the agreed environment, inspect the visual difference, and commit only approved changes. To capture images for inspection without asserting a baseline, use await page.screenshot({ path: 'test-results/homepage.png', fullPage: true }) in a test and archive that file.
3. Schedule it in a Jenkinsfile
Commit a Jenkinsfile to source control and configure a Jenkins Pipeline job to load it. Playwright’s CI guidance documents a Jenkins Docker-agent pattern. Pin a Playwright image version that matches the project’s Playwright dependency and browser setup; the version below is the illustrative version in the consulted CI documentation, not a claim that it is the newest.
pipeline {
agent {
docker {
image 'mcr.microsoft.com/playwright:v1.63.0-noble'
}
}
triggers {
cron('H H * * *')
}
environment {
TARGET_URL = 'https://example.com'
}
stages {
stage('Install dependencies') {
steps {
sh 'npm ci'
}
}
stage('Website screenshot tests') {
steps {
sh 'npx playwright test'
}
}
}
post {
always {
archiveArtifacts artifacts: 'test-results/**/*,playwright-report/**/*', allowEmptyArchive: true
}
}
}
Replace the example target, schedule, and image tag with project values. npm ci installs from the lockfile, which makes dependency installation repeatable. The Playwright package and the browser image should stay aligned; when upgrading, update the dependency and image together, then review any baseline changes.
allowEmptyArchive: true lets a build continue when an output path is absent, but it can conceal a mistaken artifact pattern. Check the first build’s workspace and confirm the report and screenshots appear under the Jenkins build’s artifacts. Jenkins archives workspace files matching the configured patterns, making them downloadable from the build page.
4. Keep visual comparisons repeatable
Pixel output can vary with the operating system, browser version, browser settings, hardware, power source, and headless mode. Generate baselines and scheduled comparisons in the same environment. Playwright’s guidance is to run tests in the same environment where the baseline screenshots were generated. If the project supports multiple browsers or platforms, maintain baselines appropriate to those environments instead of comparing unlike renders.
- Pin the Playwright container image and dependency versions.
- Keep viewport size, browser engine, locale, and other rendering settings consistent.
- Wait for the page state your test actually needs before capturing. Network idle may be unsuitable for sites with long-lived connections; use a suitable load condition or an explicit readiness locator for that application.
- Reduce nondeterminism in the page under test, such as rotating content or time-sensitive values, when those are not the subject of the check.
- Review visual diffs before changing baselines. A pixel difference is evidence to inspect, not automatically a product defect.
5. Preserve results and investigate failures
The Declarative Pipeline post section supports conditions such as always, success, and failure. Use always for screenshots, test output, and reports that help explain either a pass or a failure. Archive only known workspace paths. Jenkins artifact retention follows build retention settings; for long-term audit or sharing needs, evaluate separately managed artifact storage and retention.
When a run fails, inspect the Jenkins console log, the Playwright HTML report, the actual screenshot, and the expected baseline. This distinguishes a real page change from a browser environment mismatch, a navigation failure, or a missing artifact.
Or skip the browser setup
If you need a clean capture rather than a Playwright baseline assertion, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns an image or PDF. See the API documentation for parameters and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month, with no card.
Options and tradeoffs
| Decision | Use this when | Keep in mind |
|---|---|---|
Hashed cron schedule |
Runs should be spread across time and an exact start time is unnecessary. | H is job-specific, so do not present it as a guaranteed clock time. |
| Fixed cron fields | A particular wall-clock time matters. | Account for controller time zone and simultaneous job load. |
| Docker browser agent | You want a versioned browser environment on Jenkins agents. | Keep the image and Playwright package aligned. |
| Maintained agent installation | Your Jenkins environment already manages browser dependencies. | Keep OS, browser, and package versions stable for comparable images. |
| Screenshot capture only | A human reviews visual output without automated pass/fail comparison. | Save the image to a known workspace directory and archive it. |
| Baseline assertion | A visual change should fail the job for review. | Review diffs and baseline updates rather than accepting every change automatically. |
| Jenkins build artifacts | Build-level download and retention are sufficient. | Retention follows Jenkins build retention configuration. |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The job never runs on schedule | The Pipeline trigger was not loaded, or the schedule/time zone was misunderstood. | Confirm the job loads the committed Jenkinsfile and its trigger. Check the controller time zone and any TZ= setting. A hashed schedule does not promise a specific hour. |
| The job runs at an unexpected time | H selects a job-specific time, or the controller time zone differs from expectations. |
Use explicit minute and hour fields for a fixed time and confirm the controller’s configured time zone. |
| Playwright cannot launch its browser | The installed browser dependencies do not match the agent environment or Playwright package. | Use the documented Playwright container pattern or install the browsers and operating-system dependencies required by the project’s Playwright version. Align the image tag and package version. |
| A baseline assertion fails after a harmless-looking change | Rendering environment, browser version, viewport, or page state changed. | Compare actual and expected images and inspect environment changes. Regenerate and commit a baseline only after confirming the page change is intended. |
| The page screenshot is blank or incomplete | Navigation did not reach the required page state, or capture occurred before content was ready. | Inspect navigation errors and the report. Wait for an application-specific locator or readiness condition before taking the screenshot. |
| Artifacts are missing from the build | The archive pattern does not match files in the workspace, or output paths differ from configuration. | Check the workspace after a build, align outputDir and report output with archiveArtifacts, and verify the artifact links on the build page. |
| Build fails when no report was generated | The archive pattern matched no files and empty archives are disallowed. | Use allowEmptyArchive: true if an empty output is expected, then verify the path so a typo does not go unnoticed. |
| Scheduled checks miss source changes | A periodic trigger was expected to behave like change-driven CI. | Use SCM webhooks or pollSCM for change detection, and retain cron for periodic checks. |
Performance, reliability, and cost
A scheduled browser test consumes an agent and browser time for each run. The research sources provide no benchmark for a particular site or Jenkins installation, so measure the duration and resource use in the target environment. Keep schedules appropriate to the feedback interval you need, spread work with H when an exact time is unnecessary, and avoid running redundant browser jobs more often than the team can act on their results.
Reliability comes from stable dependencies, repeatable rendering conditions, meaningful readiness checks, and preserving diagnostic output even on failure. Jenkins and Playwright setup costs depend on the infrastructure and retention choices already in place; no fixed infrastructure price applies to this workflow. Jenkins build retention controls how long archived files remain available. For ScreenshotNeo API pricing, the free allowance is 1,000 shots monthly with no card; paid plans start at $5 for 3,000 shots, with every feature on every plan.
Frequently asked questions
How do I schedule a Jenkins Pipeline with cron?
Add a Declarative Pipeline triggers { cron('...') } block. The expression has five fields; use Jenkins’ H symbol when spreading periodic jobs is preferable to choosing an exact time.
How can I compare website screenshots in Playwright?
Use await expect(page).toHaveScreenshot() in a Playwright Test. Review and commit the initial baseline, then compare scheduled runs in the same browser environment.
Should screenshot differences fail the build?
Use a baseline assertion when an unexpected visual change should require review. For monitoring or manual review, capture and archive images without treating every difference as a failed test.
Where can I download a Jenkins screenshot?
Archive its workspace file with archiveArtifacts. Jenkins exposes archived files from the build page according to the job’s retention settings.


