A screenshot gives testers visual proof of what the browser rendered at the time of failure. It helps confirm whether the issue came from the application, test data, browser behavior, page load timing, or the automation script.
As a Selenium automation engineer, I’ve encountered failures that were hard to reproduce across different developer environments. Capturing screenshots during these failures made debugging much easier, especially when issues were tied to specific browser versions, device viewports, or timing issues.
In this article, I will explain how to capture Selenium screenshots and use them better during test debugging.
What are the Prerequisites for taking a Screenshot in Selenium?
Taking screenshots in Selenium requires a few basic tools and steps to be set up properly. Here’s what you will need to get started:
- Selenium WebDriver: The core tool for automating browser actions. It allows you to perform tasks like clicking buttons, filling forms, and of course, capturing screenshots. Without Selenium WebDriver, taking a screenshot in Selenium isn’t possible.
- TakesScreenshot Interface: The TakesScreenshot interface is a special feature in Selenium that enables you to take a screenshot of your current browser window. By using its getScreenshotAs() method, you can capture an image in different formats like a file or base64.
- OutputType Class: To define how the screenshot should be saved, you’ll use the OutputType class. The most common usage is OutputType.FILE, which saves the screenshot as a file, but you can also save it in base64 format if needed.
- Java or Python: Depending on the language you are using for automation, you’ll need either Java or Python bindings for Selenium. Both support capturing screenshots via the TakesScreenshot interface.
- Java File Handling: To save the screenshot, you will need to work with Java’s file handling features. The File class is used to define the screenshot, and FileUtils (from Apache Commons IO) helps in saving it to a specific location.
- Appropriate Browser Driver: Ensure you have the right browser driver, such as ChromeDriver or GeckoDriver, installed for your browser.
How to take Screenshot in Selenium WebDriver?
To capture screenshots in Selenium, one has to utilize the method TakesScreenshot. This notifies WebDriver that it should take a screenshot in Selenium and store it.
Syntax:
File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); String screenshotBase64 = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BASE64);
OutputType defines the output type for the required screenshot in the above snippet.
If the user intends to take a screenshot in Selenium and store it in a designated location, the method is getScreenshotAs.
Here’s an example of this usage method:
<X> X getScreenshotAs(OutputType<X> target) throws WebDriverException
In the above snippet
- X is the return type of the method
- target holds the destination address
- throws WebDriverException is activated if screenshot capturing is not supported.
Depending on the browser being used, the TakesScreenshot method can return the following:
- The entire page
- The current open window
- The visible segment of the current frame
- The whole display containing the browser
- The complete content of the HTML element. This essentially refers to the visible portion of the HTML element.
Advanced Screenshot Use Cases in Selenium
In real testing scenarios, you often need to go beyond basic screenshots to capture specific areas of a page or even the entire page, especially when dealing with large web applications. Selenium gives you the flexibility to do that.
Viewport Screenshot in Selenium
A viewport screenshot captures only the visible part of a web page within the browser window. This is useful when you need to capture the state of the page as seen by the user, including UI issues like layout misalignments, broken images, or missing elements.
To take a viewport screenshot in Selenium, you will use the TakesScreenshot interface in combination with the getScreenshotAs() method. This method captures the browser’s current state and saves it to your specified location.
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("screenshot.png"));This will save the visible part of the browser window as a screenshot in the specified file path. Although capturing only the visible viewport is often enough for quick debugging, it’s important to keep in mind that if the page is scrollable, parts of the content outside the viewport won’t be captured.
Screenshot of the Entire Page
By default, Selenium only captures the visible portion of the browser window (viewport), so if the page content extends beyond the viewport, it will not be included.
To take a full-page screenshot, Selenium does not natively support this functionality across all browsers. However, you can use workarounds or browser-specific capabilities to achieve this.
Here’s an example using Firefox which natively supports full-page screenshots through WebDriver:
File screenshot = ((FirefoxDriver) driver).getFullPageScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("fullpage-screenshot.png"));This will capture the entire page, including elements that are not currently visible in the viewport, and save it as a file.
For Chrome, Selenium alone cannot capture a full-page screenshot. You’ll need to use the Chrome DevTools Protocol (CDP) or an external tool like AShot.
Using AShot for Full-Page Screenshots (for browsers like Chrome):
This code uses the AShot library to capture a full-page screenshot by scrolling through the page and stitching together individual screenshots.
Screenshot screenshot = new
AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
ImageIO.write(screenshot.getImage(), "PNG", new File("fullpage-ashot.png"));Additional Considerations:
- Performance Impact: Full-page screenshots can be slower to capture, especially on long or complex pages. It’s essential to balance testing needs with performance considerations.
- Browser-Specific Limitations: Different browsers have varying levels of support for full-page screenshots. Firefox natively supports it, while Chrome and Edge require additional libraries or workarounds like AShot or CDP.
Screenshot of a Specific Element
Sometimes, you don’t need the entire screen, just a button, image, or input box. Selenium lets you take a screenshot of any specific element using the getScreenshotAs() method on a WebElement.
Here’s a simple example:
WebElement element = driver.findElement(By.id("logo"));
File src = element.getScreenshotAs(OutputType.FILE);This is useful when you want to confirm whether a particular element appears correctly or to highlight where a test is failing.
Additional Considerations:
- Element Visibility: The element must be visible on the screen. If it’s hidden or not rendered yet, Selenium won’t capture it.
- Handling Multiple Elements: If you’re testing multiple elements (like an image gallery or list of buttons), you may need to loop through a collection of elements and capture screenshots for each.
List<WebElement> elements = driver.findElements(By.className("button"));
for (int i = 0; i < elements.size(); i++) {
WebElement element = elements.get(i);
File screenshot = element.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("button-screenshot-" + i + ".png"));
}Both these advanced screenshot methods, capturing the full page and specific elements, can save a lot of time during test reviews in addition to making your test reports easier to understand and more informative.
Screenshot for Test Failure
If a test fails, the ability to take a screenshot in Selenium is especially helpful in understanding what went wrong. An easy way to do this would be to use TestNG annotations.
Here are the steps to capture a screenshot in Selenium in this case:
- Create a class. Implement TestNG ‘ITestListener’.
- Call the method ‘onTestFailure’.
- Add the code to take a screenshot with this method.
- Get the Test method name and take a screenshot with the test name. Then place it in the desired destination folder.
TestNG Example:
public class TestListener implements ITestListener {
public void onTestFailure(ITestResult result) {
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver");
if (driver != null) {
try {
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(
screenshot,
new File("screenshots/failure-screenshot-" + result.getName() + ".png")
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}How To Take Multiple Screenshots in Selenium?
To take multiple screenshots in Selenium, repeat the screenshot process at each required step. Use the TakesScreenshot interface and getScreenshotAs() method to capture the images. Here’s how you can do it:
Step 1: Typecast your WebDriver: Convert your WebDriver instance into TakesScreenshot:
TakesScreenshot screenshot = (TakesScreenshot) driver;
Step 2: Capture the screenshot: Use getScreenshotAs() method to grab the screenshot and save it as a file:
File srcFile = screenshot.getScreenshotAs(OutputType.FILE);
Step 3: Generate a unique file name: Add timestamps, page names, or test step identifiers to make sure each screenshot is saved with a unique name.
Step 4: Save the screenshot: Use Apache Commons IO’s FileUtils.copyFile() method:
FileUtils.copyFile(srcFile, new File("path/to/save/imageName.png"));Step 5: Repeat the steps as needed: Wrap the code in a loop or call it after important actions to capture multiple screenshots throughout your test.
To summarize, using loops or custom methods, you can take multiple screenshots in Selenium.
Taking Screenshots at Different Test Steps
You can capture screenshots after important actions in a test flow. This helps you compare the browser state before and after navigation, form submission, login, checkout, or any other critical step.
Here’s an example of how to take screenshots at multiple steps within a test case:
driver.get("https://www.browserstack.com/");
File screenshot1 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot1, new File("screenshots/homepage.png"));
driver.navigate().to("https://www.browserstack.com/case-study/tui-automates-compliance-and-shifts-left-with-browserstack-accessibility-suite");
File screenshot2 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot2, new File("screenshots/case-study-page.png"));First Step: Screenshot captured after opening the homepage.
Second Step: Screenshot captured after navigating to the case study page.
How to get the driver object in TestListeners using TestNG?
To capture a screenshot in Selenium while using TestNG, it’s important to manage the WebDriver instance properly and name your screenshot files in a way that makes sense for easier debugging. Here’s how you can do it effectively.
Passing WebDriver via ThreadLocal or Base Class
Passing WebDriver through ThreadLocal or a Base Class helps manage individual WebDriver instances for each test. This helps keep tests isolated and makes parallel testing easier.
1. ThreadLocal Approach: ThreadLocal helps to create a separate WebDriver instance for each test. This is especially useful when running multiple tests in parallel because it ensures each test has its own isolated WebDriver.
private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
public static WebDriver getDriver() {
return driver.get();
}2. Base Class Approach: Another way is to use a base class that initializes WebDriver. This allows WebDriver to be shared across different test methods. By doing this, you can create a single point of management for your WebDriver instance.
public class BaseTest {
protected WebDriver driver;
@BeforeMethod
public void setUp() {
driver = new ChromeDriver();
}
}Using ITestResult to Capture Test Name for Screenshot
Once the test execution is complete, you can use ITestResult to capture the test name and save the screenshot with the method name. This makes it easier to trace which test failed and find the corresponding screenshot.
Here’s how you can implement it:
public void onTestFailure(ITestResult result) {
WebDriver driver = getDriver();
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("screenshots/" + result.getName() + ".png"));
}With these steps, you can easily manage WebDriver and capture screenshots for improved debugging in Selenium with TestNG.
Base64 Screenshot in Selenium
In certain scenarios, you may prefer to capture and store Selenium screenshots in Base64 format instead of saving them as image files. This is particularly useful when you need to embed the screenshot in reports, send it over a network, or insert it directly into a database or API response.
To capture a screenshot in Base64 format, you can use the same getScreenshotAs() method but specify the OutputType.BASE64 option. This returns the image as a Base64-encoded string, which you can then process as needed.
String screenshotBase64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);
System.out.println("Screenshot in Base64: " + screenshotBase64);Use Cases for Base64 Screenshots:
- Embedding in HTML reports: Base64-encoded screenshots can be embedded directly into HTML reports, making them viewable without needing separate image files.
- API responses: If you’re building a REST API for automation or test reporting, returning screenshots as Base64 strings is an easy way to share the image without worrying about file paths or hosting.
- Storing in databases: Some databases allow storing images as Base64-encoded strings, so you can save the screenshot directly into the database for further processing.
How to Take Screenshots in Parallel Test Execution in Selenium
Running tests in parallel is essential for speeding up test execution, especially in large test suites. However, when running tests in parallel, managing WebDriver instances and ensuring that each test gets its own unique screenshot can be tricky.
To ensure that each parallel test gets a screenshot without overwriting files or causing conflicts, you can use the ThreadLocal mechanism. This isolates WebDriver instances for each thread, allowing parallel tests to run independently and take screenshots safely.
Using ThreadLocal to Isolate WebDriver Instances
Here’s how you can use ThreadLocal to create a separate WebDriver instance for each parallel test:
public class TestBase {
private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
public static WebDriver getDriver() {
return driver.get();
}
@BeforeMethod
public void setUp() {
WebDriver localDriver = new ChromeDriver();
driver.set(localDriver);
}
@AfterMethod
public void tearDown(ITestResult result) {
WebDriver currentDriver = getDriver();
if (currentDriver != null) {
try {
if (result.getStatus() == ITestResult.FAILURE) {
File screenshot = ((TakesScreenshot) currentDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(
screenshot,
new File("screenshots/" + result.getName() + "-" + Thread.currentThread().getId() + ".png")
);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
currentDriver.quit();
driver.remove();
}
}
}
}Why Use ThreadLocal in Parallel Execution?
- Thread Isolation: Each test runs with its own instance of WebDriver, ensuring that browser states and screenshots do not interfere with each other.
- Unique Filenames: By using the thread ID or other unique identifiers, you can save each screenshot with a unique name, avoiding file overwrites in parallel tests.
Running Tests in Parallel (TestNG Example)
If you’re using TestNG for parallel execution, you can configure parallel test execution in your TestNG XML file. Here’s an example:
<suite name="Parallel Test Suite" parallel="tests" thread-count="4"> <test name="Test1"> <classes> <class name="com.example.TestClass1"/> </classes> </test> <test name="Test2"> <classes> <class name="com.example.TestClass2"/> </classes> </test> </suite>
Additional Considerations:
- Managing Screenshots: With parallel execution, it’s essential to ensure each screenshot is saved in a unique directory or with a unique filename to prevent conflicts. This can be done by including timestamps or test names in the filenames.
- Driver Cleanup: Always ensure that WebDriver instances are properly cleaned up after each test to avoid memory leaks or hanging processes in parallel execution.
Follow-Up Read: How to take Screenshots using Python and Selenium
Integrating Screenshots with Reporting Tools
Reporting integration makes screenshots easier to use during defect triage. Instead of searching a folder manually, the screenshot appears next to the failed test.
Allure Reports
Example:
import io.qameta.allure.Allure;
import java.io.FileInputStream;
public void attachScreenshot(WebDriver driver) {
try {
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Allure.addAttachment("Failure Screenshot", new FileInputStream(src));
} catch (Exception e) {
e.printStackTrace();
}
}Use this inside a TestNG listener or a JUnit extension. For Pytest, use Python-specific Allure APIs instead of this Java example.
ExtentReports
Example:
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
String path = "screenshots/failure.png";
FileUtils.copyFile(src, new File(path));
test.fail("Test failed");
test.addScreenCaptureFromPath(path);Reporting tools add context to screenshots. They help teams see which step failed, what the browser showed, and which test data or environment was used.
Troubleshooting Selenium Screenshots
While capturing screenshots in Selenium is a powerful tool for debugging, there are some common issues testers may face. These issues can arise due to browser configurations, WebDriver settings, or timing problems. Here’s how to troubleshoot and fix common Selenium screenshot issues.
1. Blank Screenshots
Blank screenshots are a common issue, especially in headless mode or when the browser hasn’t rendered the page fully before the screenshot is taken. This can happen due to page load delays or improper timing in your test.
Solution: Ensure that the page has fully loaded before capturing the screenshot. Use explicit waits or synchronization techniques to wait for the page to be ready.
import java.time.Duration;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("someElement")));
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("screenshot.png"));This ensures that Selenium waits for the element to be visible before taking the screenshot.
2. Black Screenshots
In some cases, especially when running tests in headless mode (without a visible browser window), you may encounter black screenshots. This usually happens because the browser’s rendering engine is not fully initialized or is experiencing graphical rendering issues in headless mode.
Solution: Try running the browser in non-headless mode to verify if the issue persists. If it resolves the issue, it’s a sign that the problem is specific to headless mode.
If you need to continue using headless mode, ensure you’re using a stable version of the browser driver and WebDriver. You can also try adding the –disable-gpu flag to the Chrome or Chromium driver:
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu");
WebDriver driver = new ChromeDriver(options);This can resolve rendering issues in headless environments.
3. Element Clipping (Partial Screenshots)
When the browser window is too small or the element being captured is partially off-screen, Selenium may only capture a portion of the element, resulting in clipped screenshots.
Solution: Increase the browser window size or ensure that the element is fully in view before capturing the screenshot. You can use driver.manage().window().maximize() to maximize the window:
driver.manage().window().maximize();
WebElement element = driver.findElement(By.id("someElement"));
File screenshot = element.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("clipped-element.png"));This will maximize the browser window before capturing the screenshot to avoid clipping.
4. Slow Page Loads or Timed Out Elements
If the page is slow to load or elements take time to render, your screenshot might capture an incomplete state of the page.
Solution: Use explicit waits to wait for specific elements to appear or for the page to load before taking the screenshot. This will ensure that all elements are available when the screenshot is captured.
5. Screenshots Not Being Captured in CI/CD Environments
In CI/CD environments, where the tests run in headless mode or on remote machines, sometimes screenshots may fail to be captured or saved due to file path issues or missing dependencies.
Solution: Make sure the CI server has the necessary permissions to save files to the location where screenshots are being stored. Also, check that all required dependencies (like libraries for file handling or image saving) are installed.
Conclusion
Taking screenshots in Selenium is crucial for test automation. It helps capture the browser’s state during testing, making it easier to fix issues and track results. One of the effective ways testers can capture screenshots of entire pages or specific elements is by using the TakesScreenshot interface and the getScreenshotAs() method.
Additionally, they can also use loops or custom utility methods to take multiple screenshots in Selenium at different steps of the test flow. However, to make this process seamless, it’s important to manage the WebDriver instance properly, especially during parallel test execution.






