Using Selenium Webdriver For Full Page Screenshots
A tutorial for using the Selenium Webdriver to take screenshots.
Join the DZone community and get the full member experience.
Join For FreeOne of the most performed actions of any webpage tester is taking a screenshot of the webpage. Whenever a tester finds and reports a bug, that bug would not be taken seriously without supporting screenshots or even videos of the issue. This is equally true no matter the type of testing you are doing and that includes selenium automation testing.
In automation testing, especially where a typical test run may involve hundreds of commands and test cases, automated screenshots taken at critical assertions are important for developers and testers in making sure that every test case executed as it should. These proofs are, in turn, used for debugging to find out what went wrong and the reason for failure. For automation testing with selenium, these screenshots help to distinguish whether the failures are due to application failure or due to script failure.
Now with that said, when we say screenshot we could mean capturing an image of any part of the screen including the image of an element in question or even a screenshot of the whole page. Therefore in this post, we would be looking at how you can take automated screenshots of web pages for different purposes using Selenium WebDriver automation scripts. To start, there are four major ways of capturing screenshot images using Selenium Webdriver. Such as:
- Screenshot of Viewable area.
- Screenshot of the entire screen i.e. capturing screenshot of the full webpage.
- Screenshot of the desired webElement.
- The cloud-based platform supporting screenshots of AUT.
Automated Selenium Test Scripts for Taking Screenshots of Viewable Area
This is the most used approach of taking screenshots of applications under automation and the easiest one as well. Selenium provides an out-of-the-box capability called TakeScreenShot interface that can be used for taking screenshots of the viewable area.
You can check the detail of the interface here.
This interface provides a method known as getScreenshotAs
which helps to capture the screenshot and store it in the desired location.
Here’s the syntax to capture the screenshot:
File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
To store the taken screenshot into a file, the below statement is used:FileUtils.copyFile(screenshotFile, new File("path of the file you want to save the screenshot to"));
This is it! Just two statements and you will be able to take the screenshot. Let’s incorporate this step into a code snippet. The below example showcases Airbnb stay details page example where we are taking a screenshot of the viewable screen:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class ViewableScreenshotExample {
WebDriver driver;
@BeforeTest public void setupUrl() {
System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://www.airbnb.co.in/s/India/");
}
@Test public void performAction() throws InterruptedException { //Scroll down the page
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,250)", ""); //open the stay details page
driver.findElement(By.xpath("//div[contains(text(), 'Sea Hut Homestay with Aircon')]")).click();
Thread.sleep(1500); //Switch to the required tab
ArrayList<String> ta = new ArrayList<String> (driver.getWindowHandles());
int i=ta.size(); System.out.println(i);
driver.switchTo().window(ta.get(1)); }
@AfterTest public void takeScreenshot() {
//take screenshot of the page
File src= ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(src, new File("path of the file"));
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace();
} } }
The code snippet above will take the viewable screen screenshot as below:
This is all good and awesome if you have to take a screenshot of the view that your code is testing; however, if I want to take a screenshot of the entire webpage, the above-mentioned code is not enough. We have a solution.
Capturing Full Webpage Screenshot Using Automated Selenium Test Scripts
A need may arise to take screenshots of the entire screen rather than just the viewport of the browsers. Some browsers take a screenshot of the viewable port only whereas others take a screenshot of the entire screen. Earlier versions of Firefox used to take screenshots of the entire screen, unlike chrome and IE, but eventually even the latest versions of Firefox now only take viewport screenshots. So to capture screenshots of the entire screen using selenium web driver scripts, we can make use of AShot()
.
AShot()
is a web driver webdriver screenshot utility to capture the entire page screenshot and is natively supported from Selenium 3 onwards. It provides the following features:
- It helps capture the entire screen and web element.
- Beautify screenshot.
- Provides screenshot comparison.
For more details on the utility, you can refer here.
To take a screenshot of the entire screen, you need to add the jar into your project. You can download the jar from here http://central.maven.org/maven2/ru/yandex/qatools/ashot/ashot/1.5.3/ashot-1.5.3.jar
Once the jars are added into the project, all you need to do is mention the below lines of code when you intend to take the full-screen screenshot:
Screenshot screenshot=new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
ImageIO.write(screenshot.getImage(),"PNG",new File("path of the file"));
In the code below, the Ashot method shooting strategy is used by setting the viewport to full screen and taking screenshots. This code snippet below goes to Airbnb India Stays and Tours page and takes a screenshot of the full view.
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
public class EntireScreenshot {
public static void main(String[] args) { // TODO Auto-generated method stub
WebDriver driver;
System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://www.airbnb.co.in/s/India/");
//take screenshot of the entire page
Screenshot screenshot=new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
try {
ImageIO.write(screenshot.getImage(),"PNG",new File("path of the file"));
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); }
driver.quit();
} }
As you run this code, note how the code automatically scrolls down the page and takes the screenshot of the entire page. Below is the example of the taken screenshot.
Taking full pages screenshots is great, but you may encounter a use case where you are concerned with the screenshot of the desired webElement only. Your only concern will be to take a screenshot of the desired element and not the whole screen. Also, if you wish to take screenshots of the logo image or other UI specific elements to check its pixilation or UI issues, all you care about is taking the webElement image rather than the whole screen image. Let dig into how to take a screenshot of a web Element.
Taking Screenshot of Desired Web Element Using Selenium WebDriver
Taking a screenshot of the desired element is also pretty easy. The main concept is to crop the full screenshot to the desired location of the webElement based on its coordinates and height-width. Here’s a code snippet below highlighting how you can take a screenshot of just the logo of the Amazon.com website.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.server.handler.FullscreenWindow;
public class LogoScreenShotExample {
public static void main(String[] args) throws IOException { // TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://www.amazon.in/"); //locating amazon logo
WebElement logo = driver.findElement(By.id("nav-logo")); // Get entire page screenshot
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullScreen = ImageIO.read(screenshot); //Find location of the webelement logo on the page
Point location = logo.getLocation(); //Find width and height of the located element logo
int width = logo.getSize().getWidth();
int height = logo.getSize().getHeight();
//Now the main point, which is cropping the full image to get only the logo screenshot
BufferedImage logoImage = fullScreen.getSubimage(location.getX(), location.getY(),
width, height);
ImageIO.write(logoImage, "png", screenshot); //copy the file to the desired location
FileUtils.copyFile(screenshot, new File("path of file"));
}
}
Here’s the image was taken by the above code snippet of the webElement:
This is it. Isn’t it cool guys. Just find out what your test scenario wants and take the required screenshot. Nowadays we do not need to take screenshots because of so many upcoming cloud-based platforms providing support to all those screenshots and videos to your automation scripts execution.
This brings me to my last approach of taking a screenshot which eventually means not taking one and the tool doing its job. Well, you heard it right. Let’s look into its details.
Taking Full Page Automated Screenshots On Cloud
Running tests locally is important however if you want to make sure that your website works on all browsers, even those you don’t have access to locally, you would need service like LambdaTest. LambdaTest is a cloud-based selenium grid that you can use to run all your automated selenium test scripts online. The best part about the LambdaTest grid, however, is that it takes automated screenshots of your webpage after the execution of each selenium command. Also, the LambdaTest platform takes a complete video of the test execution as well. All you need to do is run your scripts on this platform which provides you features like screenshots, videos, network logs, console logs and so on. Few points of consideration or pre-conditions to make your script running on the platform is:
- LambdaTest account
- LambdaTest Username, access key and URL to connect to
- Setting up the required properties to gain access to the features you need.
This is it. Now let’s run our same above-mentioned code of Airbnb Stays detail page without the need of providing the screenshot method since it captures the whole video of the execution. In the below code snippet I will be using LambdaTest username, access key, and LambdaTest Selenium Grid URL to connect to the required browser and perform actions. Notice that changing the above code into LambdaTest compatible code required only to call remote webdriver instead of local chrome webdriver, and passing on a desired-capabilities object to define which browser you need to run tests on:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Platform;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.net.URL;
public class LambdatestWithoutScreenShotMethod {
public static final String username = "sadhvisingh24";
public static final String auth_key = "X1PLnv28q0eSqWoqaqv9STD4gPRfWnVOisEUcmlW0zg9HO3GYi";
public RemoteWebDriver driver;
public static final String URL = "@hub.lambdatest.com/wd/hub";
@BeforeTest public void setupUrl() {
DesiredCapabilities capability = new DesiredCapabilities();
capability.setPlatform(Platform.WIN8);
capability.setBrowserName("chrome");
capability.setVersion("75.0");
capability.setCapability("build", "cross_browser");
capability.setCapability("name", "cross_browser");
capability.setCapability("network", true); //to enable network logs
capability.setCapability("visual", true); //to enable screenshots
capability.setCapability("video", true); //to enable video
capability.setCapability("console", true); //to enable console logs
try {
driver = new RemoteWebDriver(new URL("https://" + username + ":" + auth_key + URL), capability);
} catch (Exception e) {
System.out.println("Invalid grid URL" + e.getMessage());
}
try {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://www.airbnb.co.in/s/India/");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
@Test public void performAction() throws InterruptedException { //Scroll down the page
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.scrollBy(0,250)", ""); //open the stay details page
driver.findElement(By.xpath("//div[contains(text(), 'Sea Hut Homestay with Aircon')]")).click();
Thread.sleep(1500); //Switch to the required tab
ArrayList < String > ta = new ArrayList < String > (driver.getWindowHandles());
int i = ta.size();
System.out.println(i);
driver.switchTo().window(ta.get(1));
}
@AfterTest public void closeSetup() {
driver.quit();
}
}
The referenced screenshot below:
In the screenshot above, LambdaTest provides support of video where you can view the whole execution flow of your web app.
Apart from this LambdaTest also provides a standalone full paged automated screenshot feature, that can help you to take screenshot across browsers of your designated application and even compare them. LambdaTest calls this feature as ‘Screenshot testing’. You can access these screenshots as and when required and even share them with the required stakeholders and mail them as per needs. This feature comes in handy when you got to test your application across multiple browsers and versions and perform
- Navigate to the LambdaTest ‘Visual UI testing’ menu header and navigate to its sub-header ‘Screenshot’ as below
- Once you reach this page, all you need to do is place the URL you intend to test in the URL placeholder. Select the required browser and version you wish to take a screenshot on and just click on the button ‘capture’. Bingo, that’s it.
- The images to be captured will be added in the queue. Once it’s completed, you can access those images, as below:
As you saw above, we focused on all possible ways of taking screenshots in detail, so next time when you are stuck on how to take a screenshot, this article will come in handy. You can also refer to my other articles as part of this series. Happy testing!
Published at DZone with permission of Sadhvi Singh. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments