Interacting with the browser | Taking the screenshot of the page

In the Previous Tutorial, we learned how to do cross-browser execution. In this tutorial, we’ll learn how to take the page screenshot.

In real life Test Automation projects we are generally required to take page screenshot periodically, especially if a step fails. We can use the screenshot as steps to reproduce the failure.

WebDriver code for Taking Screenshot

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

//Cast (convert) WebDriver to type ‘TakesScreenshot’ that is a Java Interface.
//Call its function ‘getScreenshotAs’ and pass output type as ‘FILE’ .
//Please be aware that at this stage the file format won’t be an image type and it won’t saves the file.
File fileScreenshot= ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

//Copy the raw screenshot file to the local file system with the correct extension for image file type,e.g *.png
try {
 FileUtils.copyFile(fileScreenshot, new File("C://MyScreenshot.png"));
} catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}
driver.save_screenshot("C://my_screenshot.png")

Automating a sample test case:

  • Navigate to the URL – https://cosmocode.io/wrong-url.html
  • If the field First Name is not present, take page screenshot and save it in the local machine.
  • If the field First Name is present, type some value to it.
  • Terminate the test.
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
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 ScriptClass {
 public static void main(String[] args) {
	
 System.setProperty("webdriver.chrome.driver", "C:\\teachmeselenium\\chromedriver.exe");
 WebDriver driver = new ChromeDriver();
 driver.manage().window().maximize();
 driver.get("https://cosmocode.io/wrong-url.html");
 //Try to find the element. If it does not exist, 'NoSuchElementException' will be thrown.
 try{
   WebElement eleFirstName = driver.findElement(By.id("firstname"));
   eleFirstName.sendKeys("This line wont be executed.");
 }catch(NoSuchElementException noEleEx){
 //Take screenshot as raw file type
 File fileScreenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
  //Copy screenshot in local file system with *.png extension
  try{
   FileUtils.copyFile(fileScreenshot, new File("C://MyScreenshot.png"));
   }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  driver.quit();
 } 
}
import org.openqa.selenium.NoSuchElementException
from selenium import webdriver
	
driver_path = "C:\\teachmeselenium\\chromedriver.exe")
driver = webdriver.Chrome(driver_path)
driver.get("https://cosmocode.io/wrong-url.html")
#Try to find the element. If it does not exist, 'NoSuchElementException' will be raised.
try:
    eleFirstName = driver.find_element_by_id("firstname")
    eleFirstName.sendKeys("This line wont be executed.");
except NoSuchElementException, e:
    #Take screenshot
    driver.save_screenshot("C://my_screenshot.png")
driver.quit()

In the Next Tutorial, we will learn how to execute JavaScript using WebDriver.

11 thoughts on “Interacting with the browser | Taking the screenshot of the page”

  1. Ok, I have following code:

    package com.googlecode.selenium;

    import org.apache.commons.io.FileUtils;
    import org.openqa.selenium.*;
    import org.openqa.selenium.firefox.FirefoxDriver;

    import java.io.File;
    import java.io.IOException;
    import java.util.NoSuchElementException;

    public class Screenshot {
    public static void main(String[] args) {
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.get("http://www.cosmotechies.com/teachmeselenium/p/wrong-url.html");
    try {
    WebElement eleFirstName = driver.findElement(By.id("firstname"));
    eleFirstName.sendKeys("This line won't be executed as previous line will throw exception");
    } catch (NoSuchElementException noEleEx) {
    File fileScreenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    try {
    FileUtils.copyFile(fileScreenshot, new File("C://MyScreenShot.png"));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    driver.quit();
    }
    }

    But i get following error:

    Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"id","selector":"firstname"}
    Command duration or timeout: 692 milliseconds
    For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
    Build info: version: '2.42.0', revision: '5e82430', time: '2014-05-22 20:18:07'
    System info: host: 'ALEKSEJSA-NB', ip: '192.168.2.95', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0'
    Driver info: org.openqa.selenium.firefox.FirefoxDriver
    Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=30.0, platform=XP, browserConnectionEnabled=true, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
    Session ID: 7d8e8f96-4c65-4d08-8398-703723692312
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:596)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:349)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementById(RemoteWebDriver.java:390)
    at org.openqa.selenium.By$ById.findElement(By.java:214)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:341)
    at com.googlecode.selenium.Screenshot.main(Screenshot.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
    Caused by: org.openqa.selenium.remote.ErrorHandler$UnknownServerException: Unable to locate element: {"method":"id","selector":"firstname"}
    Build info: version: '2.42.0', revision: '5e82430', time: '2014-05-22 20:18:07'
    System info: host: 'ALEKSEJSA-NB', ip: '192.168.2.95', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0'

    And no screenshot file..

    Reply
  2. Hi Alexey

    If you look closely at first line of error – "Exception in thread "main" org.openqa.selenium.NoSuchElementException"

    The package that you have imported is – "import java.util.NoSuchElementException;" which is wrong. You should have imported – "import org.openqa.selenium.NoSuchElementException;"

    This is the reason the catch block is unable to catch the selenium exception. Lesson learned for you- "Import correct package". Lesson learned for me – "Include package imports as well along with code for readers".

    Cheers
    Shadab

    Reply
  3. Yeap, this fixed it.
    Though driver quits with strange message:

    Jun 19, 2014 11:54:21 AM org.openqa.selenium.os.UnixProcess$SeleniumWatchDog destroyHarder
    INFO: Command failed to close cleanly. Destroying forcefully (v2). org.openqa.selenium.os.UnixProcess$SeleniumWatchDog@7b98f307

    Reply
  4. Good to see that it has taken the snapshot of full page, irrespective of the area which was visible

    1) How can we take multiple screenshots when we dont know the count how many we want,, because in that case we may need to create n number of png file in c:

    2) How do we know which driver needs to be imported,, because everytime i see ,eclipse recommend java/selenium drivers. Sometimes we use selenium , sometimes we use java

    Regards
    Gaurav Khurana

    http://www.udzial.com
    Udzial Means Share

    Reply
  5. 1) The good practice is to take System's current date & time and append them with the screenshot file name so that even if you are required to take n number if screenshots for n steps, you will have distinct files. You can also create folder and sub-folders at run time based on date/month to easily manage those files.

    2) It will come naturally with practice buddy. The more you would explore Selenium-Java the more you would understand which packages to import. In general, if the method is related to performing some action on browser you may need 'org.openqa.selenium.SOMETHING' imports. For now, you can Google or go through the official documentation to know about the package structure needs to be imported or try all eclipse suggestions.

    Reply

Leave a Reply