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

Call ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE), create the destination directory, and copy the returned temporary file to your chosen path. OutputType.FILE is not a permanent archive: Selenium may delete it when the JVM exits.

Save a WebDriver screenshot to a folder

This complete example follows Selenium’s documented Java workflow. It captures the current browsing context, creates the parent directory when necessary, and copies the temporary screenshot to a durable path.

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public final class ScreenshotExample {
    private ScreenshotExample() {
    }

    public static void saveScreenshot(WebDriver driver, String destination)
            throws IOException {
        File temporaryScreenshot =
                ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);

        Path destinationPath = Paths.get(destination);
        Path parent = destinationPath.getParent();
        if (parent != null) {
            Files.createDirectories(parent);
        }

        FileUtils.copyFile(temporaryScreenshot, destinationPath.toFile());
    }
}

Call it after the page is in the state you want to record:

saveScreenshot(driver, "screenshots/result.png");

The method declares IOException because directory creation and file copying are filesystem operations. In a test, you can let the test framework report that exception; in an application, catch it where you can log the destination and decide whether to retry or fail the operation.

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

What the capture call actually returns

TakesScreenshot indicates that a driver can capture screenshots in different representations. Selenium documents implementations including ChromeDriver, EdgeDriver, FirefoxDriver, SafariDriver, and RemoteWebDriver. The representation is selected with OutputType.

Output type Returned value Use it when
OutputType.FILE A temporary File You want to copy the image directly to a path, as in Selenium’s Java example.
OutputType.BYTES Raw screenshot bytes You need to write to a stream, object store, database, or Java NIO path.
OutputType.BASE64 A Base64-encoded string You must transport encoded image data, for example in a JSON payload.

The file returned for OutputType.FILE is temporary and is deleted when the JVM exits. Copy it before the method returns if the image must survive the test process. Do not treat the temporary filename as your report or artifact location.

A version without Apache Commons IO

Selenium’s published example uses Apache Commons IO’s FileUtils.copyFile. If you do not want that additional library, the same operation can be performed with Java NIO:

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public final class NativeScreenshotExample {
    private NativeScreenshotExample() {
    }

    public static void saveScreenshot(WebDriver driver, String destination)
            throws IOException {
        Path source = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE)
                .toPath();
        Path target = Paths.get(destination);
        Path parent = target.getParent();
        if (parent != null) {
            Files.createDirectories(parent);
        }
        Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
    }
}

This variant overwrites an existing file with the same name. Remove REPLACE_EXISTING if an existing artifact should cause an error instead. If you use Commons IO, keep its version consistent with the rest of your project’s dependency management; Selenium’s example establishes the API call and copy operation, not a required Commons IO version.

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

Create useful filenames and folders

A relative path such as screenshots/result.png is resolved from the process working directory, which may differ between an IDE, Maven, Gradle, and a CI runner. Use an explicit project or artifact directory when reproducibility matters.

  • Create the parent first: Files.createDirectories is safe when the directory already exists and also creates missing intermediate directories.
  • Keep the extension meaningful: use the image extension your reporting tools expect, commonly .png.
  • Avoid collisions: include a test name, timestamp, or an incrementing identifier when several screenshots can be produced in one run.
  • Sanitize test data: replace slashes, colons, and other platform-specific filename characters before using a URL or test title in a filename.
  • Preserve artifacts in CI: configure the CI job to upload the folder after tests finish; copying to a local path alone does not publish it.

For a unique name generated by Java, create the directory and then resolve a generated path:

Path directory = Paths.get("build", "screenshots");
Files.createDirectories(directory);
Path target = Files.createTempFile(directory, "checkout-", ".png");
Files.copy(
        ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE).toPath(),
        target,
        StandardCopyOption.REPLACE_EXISTING
);

Capture an element instead of the whole browsing context

A driver screenshot captures the current browsing context according to the driver’s WebDriver implementation. Selenium also exposes screenshot capture on a supported WebElement. That is useful for a logo, chart, form, or assertion target:

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public static void saveElementScreenshot(WebDriver driver,
                                         String cssSelector,
                                         String destination)
        throws IOException {
    WebElement element = driver.findElement(By.cssSelector(cssSelector));
    File temporaryElementScreenshot =
            element.getScreenshotAs(OutputType.FILE);

    Path target = Paths.get(destination);
    Path parent = target.getParent();
    if (parent != null) {
        Files.createDirectories(parent);
    }
    FileUtils.copyFile(temporaryElementScreenshot, target.toFile());
}

Element capture is different from a page capture: it targets the element’s rendered bounds. The element must be present and supported by the driver, so locate it after the page has loaded and after any required waits.

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

Timing, viewport, and driver differences

Wait for the state you intend to document

A screenshot records the browser state at the instant the capture call runs. Wait for a heading, table, or other application condition rather than relying only on a fixed sleep. If an animation is still running, capture can show an intermediate frame; disable or wait for the animation when visual consistency matters.

Do not assume every screenshot has the same extent

The WebDriver API describes conformant screenshots under the W3C WebDriver specification and best-effort fallback behavior for non-conformant implementations. Consequently, viewport size, device-pixel ratio, browser version, and driver implementation can affect the captured extent. Set the window or viewport deliberately when comparing images, and do not promise identical full-page behavior across every driver.

Remote sessions still need artifact handling

RemoteWebDriver can implement TakesScreenshot, but the returned file or bytes must still be copied by the client code. In a remote grid, save to a directory available to the process that runs the test, then upload that directory from the runner. A path on your laptop is not automatically a path on the remote browser host.

Choose FILE, BYTES, or BASE64 for the destination you have

Write bytes directly

byte[] image = ((TakesScreenshot) driver)
        .getScreenshotAs(OutputType.BYTES);
Path target = Paths.get("screenshots", "bytes-result.png");
Files.createDirectories(target.getParent());
Files.write(target, image);

BYTES avoids a separate temporary-file copy and is convenient when your next API accepts a byte array. The bytes still need durable storage if you want to retain them after the test.

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

Decode Base64 when required

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;

String encoded = ((TakesScreenshot) driver)
        .getScreenshotAs(OutputType.BASE64);
byte[] image = Base64.getDecoder().decode(encoded);
Path target = Paths.get("screenshots", "base64-result.png");
Files.createDirectories(target.getParent());
Files.write(target, image);

Base64 is larger than raw bytes because it is an encoding for transport. Use it only when the receiving interface requires text.

Troubleshooting

Symptom Likely cause Fix
ClassCastException at the capture call The driver does not expose TakesScreenshot. Use a WebDriver implementation that supports the screenshot command, or check the driver capability before casting.
FileNotFoundException or “no such file or directory” The destination’s parent folder does not exist, or the process cannot write there. Call Files.createDirectories, use an absolute writable path, and verify CI workspace permissions.
The file disappears after the run The temporary OutputType.FILE was retained instead of copied. Copy it immediately to your destination, or request BYTES and write those bytes yourself.
The screenshot is blank or shows the wrong page Capture occurred before navigation, rendering, or an asynchronous update completed. Wait for a deterministic page condition and confirm the active window, frame, and URL before capture.
An element screenshot fails The selector matched no element, the element is stale, or the implementation does not support element capture. Locate the element after the relevant wait, avoid reusing a stale reference, and fall back to a driver screenshot when appropriate.
Images overwrite one another Every test uses the same destination filename. Include a test identifier or generated filename and isolate parallel workers’ directories.
Different browsers produce different dimensions Viewport, scaling, or implementation behavior differs. Standardize browser window size and driver versions, and compare within the same environment.

Performance and reliability considerations

  • Capture only at diagnostic points; screenshots add browser and filesystem work to every test.
  • For failure evidence, capture in the test framework’s failure hook so ordinary passing tests do not create unnecessary files.
  • Use bytes when sending directly to an artifact service, and use files when humans or CI tools need a conventional folder.
  • Check the returned path or write result and log it with the test name. A successful WebDriver command does not guarantee that a later copy succeeded.
  • Keep screenshots bounded in size by controlling viewport dimensions and avoiding accidental high-resolution settings unless visual fidelity requires them.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a URL image rather than a screenshot tied to an already-running Selenium session, ScreenshotNeo provides a single HTTP request. Its API accepts a URL and returns a PNG, JPEG, WebP, or PDF. Read the parameter details in the ScreenshotNeo documentation.

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)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Before capture, ScreenshotNeo accepts the cookie or consent banner like a visitor 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. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

Plan Included screenshots Price
Free 1,000 per month $0, no card
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Every feature is on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to get 1,000 screenshots a month without entering a card.

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

FAQ

Can I save screenshots outside the project directory?

Yes. Pass an absolute destination such as /var/log/ui-shots/result.png or C:\test-artifacts\result.png, provided the Java process has permission to create and write there.

Should screenshot copying happen before or after quitting the driver?

Capture and copy while the driver session is alive. Put cleanup such as driver.quit() after artifact creation; quitting first can make a later capture impossible.

How can I prevent sensitive data from entering an artifact?

Navigate to a sanitized test account, hide or replace secrets before capture, and restrict access to the output directory. Screenshot files can contain everything visible in the browser, including personal or authentication data.

Frequently Asked Questions

Can I save screenshots outside the project directory?

Yes. Pass an absolute destination, provided the Java process has permission to create and write there.

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

Should screenshot copying happen before or after quitting the driver?

Capture and copy while the driver session is alive; perform driver cleanup afterward.

How can I prevent sensitive data from entering an artifact?

Use sanitized test data, hide secrets before capture, and restrict access to the screenshot directory.

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.