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
Java
Python
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.
Java
Python
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.
Thanks for helpful tip again!
Forgot to tell you in your previous posts that there is a problem sometimes in your posts that they don't fit the width of the textbox, please see following example – https://www.dropbox.com/s/pgobud4i7resd8k/notfitting.jpg
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..
Thanks a lot Alexey for letting me know… I'll fix it this weekend.
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
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
Hi Alexey… It is fixed now.
Yeap, much better now, thanks!
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
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.
It was very nice tutorial precise and accurate but please explain little more by adding different examples ..Thanks
Thanks Jay for you feedback. Will take it into account for new posts.