Hello Folks,
In this post we will learn how to take screenshots in Selenium webdriver using selenium provide interface TakesScreenshot .
Why we need to take screenshot?
When we perform manual testing , for each step or important steps, we take screenshot and attach in test result report. Screenshots are proof of test case status. It gives information if test case has passed successfully or reasons if test case has failed.
Taking screenshot of browser by using “TakesScreenshot” interface provided by Selenium:
- Selenium provides an interface named “TakesScreenshot” which helps automaton engineer to take screenshot during execution of automation script.
- “WebElement” interface extends “TakesScreenshot” and all browser driver classes like “ChromeDriver”, “FirefoxDriver”, “InternetExplorerDriver”, “EdgeDriver” etc implements “TakesScreenshot”.
- TakesScreenshot interface has a method named “getScreenshotAs” which can capture a screenshot and store it in different ways in specified locations.
- This method can capture screenshot as below based on implementation provided by browser driver class:
- Entire page
- Current window
- Visible portion of the current frame
- The screenshot of the entire display containing the browser
- I will suggest you to must go throw Hierarchy of Selenium Classes and Interface before proceeding further in this post.
- To use “TakesScreenshot” interface, either we need to do up-casting or down casting depending upon reference of your browser driver class.
- If you write your browser driver class as below:
ChromeDriver driver= new ChromeDriver();
You need to up-cast your driver to TakesScreenshot as below:
TakesScreenshot ts= driver;
- If you write your browser driver class as below:
WebDriver driver= new ChromeDriver();
You need to down cast your driver to TakesScreenshot as shown below:
TakesScreenshot ts= (TakesScreenshot)driver;
Java Code:
Output:
Explanation of above code:
- Since I have upcasted my ChromeDriver object to WebDriver, to capture screenshot I need to downcast my ChromeDriver object to TakesScreenshot interface.
- “OutputType” is an interface which provides you options to take screenshot in different type such as FILE, BASE64, BYTES and class. FILE is mostly used.
- When webdriver tales screenshot, it is stored in temp folder which is cleaned up as soon as execution is over. So we can not find it after execution. This is the reason we need to copy screenshot from temp folder to permanent folder.
- Above code will create a folder within project folder named “ScreenCapturesPNG”. Screenshot will be named by concatenating user provided name and UNIX time stamp.
- I created a reusable method to capture screenshot so that we can use it wherever we need and also you can pass customized name to screenshot.
- I am also returning path of screenshot, which we can use to attach screenshot in to a html report, extent report etc.
Limitation of using TakesScreenshot interface for capturing screenshot:
- Above code will not able to capture screenshot when an alert is present. It will give you an exception stating “org.openqa.selenium.UnhandledAlertException”.
- This is a known defect whose details you can find here.
- I will share another way of taking screenshot which will work always.
I hope you must have learnt something new from this post.
If you have any doubt, feel free to ask here.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappySelenium
Please exlpain this – ((TakesScreenshot) driver)
There is no direct parent-child relation between TakesScreenshot & Webdriver, then why compiler is not complaining the below:
Cannot ‘cast’ from Webdriver to TakesScreenshot.
Hi,
After downcasting the driver object and screenshot functionality is completed. Is it required to upcast the driver object to WebDriver to continue further execution?
No. You are saving in different instance type.
You are really helping us with ur amazing posts…keep doing and thank you ☺
Thanks
You makes other understand the underlying concepts of why, how and when!!.. You idea of picking this topic and explaining selenuim Architecture is an absolute eye Opener for many!. The beauty of Upcasting and Downcasting and its need in real terms!!. I want to take the entire vocabulary avaliable to priase your efforts!!.. Many may not get time to appreciate you however your impact many others understanding!..
Thanks a lot for all kind words.
Yes above code will not be able to handle javascript alert if present while taking screenshot. That is limitation of TakesScreenshit interface. In my next post, I will post alternative ways of taking screenshot.
@Saanvi: Yes. I was about to mention this. This code will just take Screenshot for HTML code only. Selenium not handling the jquery script.
However the below code will solve this problem. (Not sure whether you have come across this)
BufferedImage image = new Robot().createScreenCapture(new Rectangle(tk.getScreenSize()));
ImageIO.write(image, “jpg”, new File(“D:\\” + result.getName() + “” + formatter.format(now.getTime()) + “.jpg”));
But you should keep the window open while using Robo. Else, it will capture the current Screen while getting error in the flow.
is there any way to get screenshot when browser is minimized
Selenium 4 onward we can minimze browser and can take screenshots as well.
Hi Amod,
Selenium is unable to capture screen shots when alert pop up is present in google chrome .Any idea about this issue?
This is the exception we used to get:
org.openqa.selenium.UnhandledAlertException: Unexpected modal dialog