How to Take Screenshots in Selenium: Classes and Interfaces Explained
Learn Selenium’s TakesScreenshot interface, OutputType options, driver and element captures, durable file saves, errors, and practical Java examples.
Use Selenium’s TakesScreenshot interface and call getScreenshotAs(OutputType.X). The interface works with supported WebDriver and WebElement implementations. Choose OutputType.FILE for a temporary PNG file, OutputType.BYTES for raw PNG bytes, or OutputType.BASE64 for encoded text. If you use FILE, copy the returned file to a permanent location before the JVM exits.
1. Minimal Java driver screenshot
This example captures the current browser target and copies the temporary result to artifacts/home.png.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class DriverScreenshot {
public static void main(String[] args) throws Exception {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
Path output = Path.of("artifacts/home.png");
Files.createDirectories(output.getParent());
Path temporary = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE)
.toPath();
Files.copy(temporary, output, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Saved " + output.toAbsolutePath());
} finally {
driver.quit();
}
}
}
TakesScreenshot is an interface, not a standalone utility class. Selenium lists browser drivers such as Chrome, Edge, Firefox, Internet Explorer, Safari and remote drivers among its implementations. See the Java TakesScreenshot API.
2. What the Selenium screenshot classes and interfaces do
| Type | Purpose | Typical Java use |
|---|---|---|
TakesScreenshot |
Declares that a driver or element can capture an image. | ((TakesScreenshot) driver).getScreenshotAs(...) |
OutputType<T> |
Selects the representation returned by the generic method. | FILE, BYTES, or BASE64 |
WebDriver |
Controls the browser and can be the screenshot target. | Capture the current driver target. |
WebElement |
Represents one DOM element and can be the target when supported. | Capture a component, image, or form. |
RemoteWebDriver/RemoteWebElement |
Remote implementations used by Selenium Grid and cloud browsers. | Use the same interface-based call. |
The API method is generic: getScreenshotAs(OutputType<X> target). The value passed as target determines the Java return type. Selenium documents this contract in the OutputType API.
3. Choosing an OutputType
OutputType.FILE: temporary file
FILE returns a temporary file. Selenium’s Java documentation states that this file is deleted when the JVM exits, so treat it as an intermediate artifact and copy it immediately.
Path destination = Path.of("artifacts/failure.png");
Files.createDirectories(destination.getParent());
Path temporary = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE)
.toPath();
Files.copy(temporary, destination, StandardCopyOption.REPLACE_EXISTING);
OutputType.BYTES: raw PNG bytes
Use bytes when uploading directly to object storage, attaching a test report, or processing the image in memory.
byte[] png = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
Files.write(Path.of("artifacts/in-memory.png"), png);
OutputType.BASE64: encoded text
Base64 is useful when a reporting system accepts text or when you need a data URI. It increases payload size compared with raw bytes.
String base64Png = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BASE64);
String dataUri = "data:image/png;base64," + base64Png;
4. Capturing a WebElement
Driver and element screenshots are separate targets. Locate the element first, then cast it to TakesScreenshot.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class ElementScreenshot {
public static void main(String[] args) throws Exception {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
WebElement heading = driver.findElement(By.cssSelector("h1"));
Path destination = Path.of("artifacts/heading.png");
Files.createDirectories(destination.getParent());
Path temporary = ((TakesScreenshot) heading)
.getScreenshotAs(OutputType.FILE)
.toPath();
Files.copy(temporary, destination, StandardCopyOption.REPLACE_EXISTING);
} finally {
driver.quit();
}
}
}
Element capture depends on the element implementation supporting the screenshot interface. A conformant WebDriver/WebElement follows the W3C WebDriver behavior; non-conformant implementations use browser-dependent best effort.
5. What area is actually captured?
Do not assume every driver returns a full, stitched page. For conformant implementations, behavior follows the W3C WebDriver specification. For non-conformant implementations Selenium describes a preference order that may include the entire page, the current window, the visible portion of the current frame, or the display containing the browser. Element implementations may return the element’s full content or only its visible portion. The exact result can therefore vary by browser, driver and remote provider.
- Viewport screenshot: commonly captures what is visible in the current browsing context.
- Full-page screenshot: is implementation-dependent; verify it with the browser and driver versions you deploy.
- Frame screenshot: switch into the frame before capturing if the desired content is inside it.
- Element screenshot: targets one element, but clipping and visibility rules remain implementation-dependent.
6. Reliable capture sequence
- Start the driver with the browser options required by your environment.
- Navigate to the URL.
- Wait for the page state or target element you need.
- Capture using the driver or element as the target.
- Persist the result immediately if you requested
FILE. - Close the driver in a
finallyblock.
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
WebElement target = new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.visibilityOfElementLocated(By.id("content")));
byte[] png = ((TakesScreenshot) target).getScreenshotAs(OutputType.BYTES);
Files.write(Path.of("artifacts/content.png"), png);
} finally {
driver.quit();
}
Use explicit waits for a meaningful page condition instead of an arbitrary sleep. If content is animated, wait for the animation to finish or apply test-specific CSS before capture.
7. Other Selenium language bindings
The Java names do not carry across every binding. Python exposes convenience methods such as driver.save_screenshot(); JavaScript uses takeScreenshot(); C# uses ITakesScreenshot and a Screenshot object. Consult the binding-specific Selenium documentation rather than assuming the Java interface exists unchanged.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
ClassCastException |
The driver or element does not implement TakesScreenshot. |
Use a supported implementation, update the driver, or check the remote provider’s capabilities. |
UnsupportedOperationException |
The underlying implementation does not support screenshots. | Run against a driver/provider that implements screenshot capture. |
WebDriverException |
Capture failed at the browser or transport layer. | Check browser-driver compatibility, session health, logs and available disk or memory. |
| File disappears | OutputType.FILE is temporary. |
Copy it to a durable path before JVM shutdown. |
| Blank or incomplete image | Capture happened before navigation, rendering or lazy content finished. | Wait for a selector, document state, network completion or the application’s ready signal. |
| Element capture fails | Element is detached, invisible, outside the current context or unsupported. | Relocate it after navigation, switch to the correct frame, wait for visibility and try a driver capture for diagnosis. |
| Only part of a long page appears | Full-page capture is not guaranteed by every implementation. | Check the driver’s documented behavior or use a capture service designed for full-page output. |
9. Performance, reliability and cost considerations
- Use bytes for pipelines: avoid temporary-file I/O when the next step is an upload or report attachment.
- Use files for inspection: copying a temporary file gives a simple artifact for local debugging and CI retention.
- Control browser lifetime: create one driver per suitable test scope and always call
quit()to avoid orphaned processes. - Reduce unnecessary captures: screenshots consume browser, memory and storage resources, especially at large viewport sizes.
- Make waits deterministic: a stable readiness condition improves repeatability more than increasing a fixed sleep.
- Remote sessions add failure points: network interruptions and provider limits can surface as
WebDriverException; retain logs and retry only when the operation is safe to repeat.
Selenium itself does not define a screenshot price. Your cost comes from browser execution, infrastructure, storage and any remote-browser provider you use.
10. Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF. Cookie and consent banners, newsletter popups and chat widgets are removed before the shot; bot checks, blank pages and failed loads are never billed. Responses identify the page verdict and billing status with X-Page-Verdict and X-Billed headers. An MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf.
See the ScreenshotNeo API documentation for all options.
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}`);
Plans include 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
11. Frequently asked questions
Is TakesScreenshot a class?
No. It is a Java interface implemented by supported driver and element objects.
Does OutputType.FILE save directly to my chosen filename?
No. It returns a temporary file. Copy it to your destination path.
Can Selenium screenshot a WebElement?
Yes, when that element implementation supports TakesScreenshot. Cast the element and call getScreenshotAs.
Which output type is best for CI?
BYTES is convenient for report APIs; FILE is convenient when your CI archives filesystem artifacts.
Does Selenium guarantee a full-page image?
No. The result depends on W3C conformance and the browser-driver implementation. Verify the behavior of your target environment.


