Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
CI/CD

How to Capture Selenium Screenshots on a Jenkins Agent (and Archive Failures)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run the Selenium test on the Jenkins agent, write each PNG inside that agent’s workspace, then archive the matching files with archiveArtifacts. Put archiving in Declarative Pipeline’s post { always { ... } } block when screenshots must survive failed builds. A screenshot saved on another machine, or outside the workspace, is invisible to Jenkins until your test process copies it into the workspace.

The workflow in one view

  1. Jenkins allocates a workspace on the agent running the stage.
  2. Selenium drives a local or remote WebDriver session and captures the current browsing context (or a selected element).
  3. Your test process writes the returned PNG bytes under a workspace-relative directory such as screenshots/.
  4. Jenkins scans that directory with an Ant-style include pattern and archives matching files.

Use post { always { ... } } so collection runs after success, failure, or an unstable result. The screenshot itself must already have been written before the post block starts.

A minimal Declarative Pipeline

pipeline {
    agent any

    stages {
        stage('Browser tests') {
            steps {
                sh 'pytest'
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: 'screenshots/**/*.png'
        }
    }
}

The test code in this example must create files below screenshots/ in the process working directory. Jenkins archive patterns are workspace-relative and case-sensitive by default. If the directory is outside the workspace, the archive step cannot find it.

When an empty archive is acceptable

If screenshots are conditional, use:

archiveArtifacts artifacts: 'screenshots/**/*.png', allowEmptyArchive: true

This keeps a build from failing when no screenshot is expected, but it can also hide a broken capture path. Omit allowEmptyArchive when every run is supposed to produce an image; a zero-match result should then expose the problem.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture a screenshot in Python

Selenium’s Python binding exposes save_screenshot, which writes a PNG directly. Create the directory first and use a path rooted in the Jenkins workspace.

from pathlib import Path
from selenium import webdriver

out = Path("screenshots")
out.mkdir(parents=True, exist_ok=True)

driver = webdriver.Chrome()
try:
    driver.get("https://example.com")
    driver.save_screenshot(str(out / "home.png"))
finally:
    driver.quit()

For a failure-oriented test, put the save operation in the framework’s failure hook or an exception handler, then let Jenkins archive the directory in post { always { ... } }. The exact hook name varies by test framework; the required handoff is always the same: write the file before Pipeline completion.

Python with an exception capture

from pathlib import Path
from selenium import webdriver

out = Path("screenshots")
out.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
    driver.get("https://example.com")
    # assertions and test actions go here
except Exception:
    driver.save_screenshot(str(out / "failure.png"))
    raise
finally:
    driver.quit()

This preserves the original test failure while leaving the diagnostic image for Jenkins.

Capture and save in JavaScript

The JavaScript WebDriver API returns a Base64-encoded PNG. Decode it when writing the file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const fs = require('node:fs/promises');
const { Builder } = require('selenium-webdriver');

await fs.mkdir('screenshots', { recursive: true });
const driver = await new Builder().forBrowser('chrome').build();
try {
  await driver.get('https://example.com');
  const encoded = await driver.takeScreenshot();
  await fs.writeFile('screenshots/home.png', encoded, 'base64');
} finally {
  await driver.quit();
}

For failure capture, call takeScreenshot() in your test runner’s error hook, create the directory before writing, and rethrow the error so Jenkins still reports the test as failed.

Java and other bindings

Java uses the TakesScreenshot interface. The returned file or bytes must be copied to a location below the workspace before archiving:

WebDriver driver = new ChromeDriver();
try {
    driver.get("https://example.com");
    File source = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    Files.createDirectories(Paths.get("screenshots"));
    Files.copy(source.toPath(), Paths.get("screenshots/home.png"),
               StandardCopyOption.REPLACE_EXISTING);
} finally {
    driver.quit();
}

Every language binding follows the same contract: capture the current browsing context, obtain PNG data, and write it where the Pipeline can see it. Element screenshots are a separate option when a focused component is more useful than the whole viewport; confirm the portion returned by your selected browser and driver.

Full-page, viewport, and element scope

Scope Use it when What to verify
Browsing-context screenshot You need surrounding layout, navigation, and page state for diagnosis. Whether the browser/driver returns the viewport or a taller page image.
Element screenshot A component, modal, or assertion target is the only relevant evidence. That the element is present, displayed, and captured after the required state change.

Choose one deliberately. A narrow element image is easier to inspect, while a full context image explains failures caused by overlays, redirects, or layout shifts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Jenkins agent, container, and remote-browser details

Local browser on the agent

When Chrome, Firefox, or another browser runs on the same agent as the test process, write directly to a workspace-relative path. The archive step can then collect it without transfer work.

Container agents

The file must exist in the workspace visible to the Pipeline step. Container and workspace mount arrangements differ by deployment, so verify that the directory where Selenium writes is mounted or otherwise preserved until archiving.

Selenium Grid or another remote WebDriver

The WebDriver screenshot API returns image data to the test process, but a file written on a remote browser host is not automatically a Jenkins artifact. Keep the capture and file-write operations in the process running on the agent, or explicitly transfer the bytes into the agent workspace before the archive step.

Make failure screenshots dependable

  1. Use a deterministic directory such as screenshots/.
  2. Create it before the first possible failure.
  3. Capture in the test framework’s failure hook or an exception handler.
  4. Do not delete the directory during cleanup until after artifact collection.
  5. Archive in post { always { ... } }.

If multiple tests run in parallel, give files unique names (for example, include the test name) or isolate each branch’s directory, then archive the combined tree.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting missing artifacts

Symptom Likely cause Fix
No files archived Capture code never ran or failed before writing. Log the capture result and place it in a failure hook/exception handler.
Archive pattern matches nothing Filename, extension, capitalization, or directory differs from the glob. Compare the real path with screenshots/**/*.png; remember matching is case-sensitive by default.
File exists in a remote host or container Jenkins cannot see that filesystem. Write returned screenshot data into the agent workspace or transfer it there.
Screenshot disappears Cleanup runs before archiving. Move deletion after artifact collection or preserve the directory.
Build fails while archiving No file matched and empty archives are not allowed. Fix the path, or intentionally set allowEmptyArchive: true for conditional captures.

Performance, reliability, and retention choices

  • Capture only useful states. One failure image per test or assertion is usually more actionable than images after every command.
  • Keep names stable and unique. Stable paths simplify globbing; unique names prevent parallel tests from overwriting one another.
  • Archive after all tests finish. The always post condition provides one collection point regardless of the result.
  • Watch workspace size. Large suites can create many PNGs; configure Jenkins retention separately from capture logic if long-term storage is unnecessary.
  • Record the browser context. A screenshot reflects the current window, tab, and state. Capture after navigation or interaction has completed, not immediately after starting an asynchronous action.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. It accepts a URL in one request and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo documentation for authentication and options. A direct call looks like this:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

It also supports full-page lazy-image loading, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF controls, custom CSS/JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed image links, asynchronous signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs are accepted to ease migration.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan. Create a free ScreenshotNeo account.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Does Jenkins take the screenshot for me?

No. Selenium captures it; Jenkins stores the file only after it exists in the workspace and matches the archive pattern.

Can I archive JPEG or WebP files?

Yes. Change the glob to the extension your test writes, such as screenshots/**/*.jpg; Selenium’s standard examples return or save PNG data.

Why use always instead of a success condition?

Because diagnostics are most valuable when a test fails. The always post condition runs regardless of the completed build result.

Frequently Asked Questions

Does Jenkins take the screenshot for me?

No. Selenium captures it; Jenkins stores the file only after it exists in the workspace and matches the archive pattern.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I archive JPEG or WebP files?

Yes. Change the glob to the extension your test writes, such as screenshots/**/*.jpg; Selenium’s standard examples return or save PNG data.

Why use always instead of a success condition?

Because diagnostics are most valuable when a test fails. The always post condition runs regardless of the completed build result.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.