Advance Selenium | Video & Screenshot Capture
Advance Selenium screen shot capture of test execution can be done by using different methods as –
- captureScreenshot –
- It captures a PNG screenshot to the specified file and syntax is: public void captureScreenshot(java.lang.String filename)
- Parameters
filename – the absolute path to the file to be written, e.g. “c:\blah\screenshot.png” - captureScreenshotToString – It capture a PNG screenshot. It then returns the file as a base 64 encoded string and it’s syntax is public java.lang.String captureScreenshotToString()Selenium
- Returns:
- The base 64 encoded string of the screen shot (PNG file)
- captureEntirePageScreenshotToString –
- It downloads a screenshot of the browser current window canvas to a based 64 encoded PNG file. The entire windows canvas is captured, including parts rendered outside of the current view port. Currently this only works in Mozilla and when running in chrome mode.
- It returns the base 64 encoded string of the page screenshot (PNG file) and it’s syntax is
- public java.lang.String captureEntirePageScreenshotToString(java.lang.String kwargs)
Parameters:
kwargs – A kwargs string that modifies the way the screenshot is captured. Example: “background=#CCFFDD”. This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed (possibly obscuring black text).
WebDriver natively having built in video capture of test execution, only screenshots when test fails. If you want this you’ll have to rely on third party tools integrated with WebDriver.
- Selenium – Capture Screenshot using TestNG
- . Reduce the screen capture code redundancy.
As we write test in different methods, in-order to capture the screen shot on error, we need to wrap every test method in the following way
1 try {
2 // test here
3 } catch (Throwable e) {
4 // capture screenshot here
5 }
TestNG provide Listeners and Reporters through which we can generate custom reports. In this example I am extending TestListenerAdapter, which implements ITestListener with empty methods, so that I don’t have to override other methods of the interface that I am not interested. Use the onTestFailure method to capture the screen shot as it is invoked once test fails.
- File naming convention
It is better to name the file using time stamp, so that we can easily understand when this error occurred.
Apart from this I also append the file name with IP address that can help me in identifying on which system this error occurred, assuming you are working on different browser combinations from different locations. - 26_Mar_2011__02_51_33PM_171.22.0.111.png
- Where to store the file
Store all the files in separate folder inside the working directory. I use separate folder called “ScreenShots”.
C:\eclipse\MyWorkSpace\Implements23\ScreenShots\26_Mar_2011__02_51_33PM_132.22.0.111.png
How to view the files
I am directly inserting the file names in the test reporter, so that screen shot appear as hyper link.
01 package package1;
02
03 import java.awt.AWTException;
04 import java.awt.Dimension;
05 import java.awt.Rectangle;
06 import java.awt.Robot;
07 import java.awt.Toolkit;
08 import java.awt.image.BufferedImage;
09 import java.io.File;
10 import java.io.IOException;
11 import javax.imageio.ImageIO;
12 import org.testng.ITestResult;
13 import org.testng.Reporter;
14 import org.testng.*;
15 import org.testng.TestListenerAdapter;
16 import java.io.*;
17 import java.util.Date;
18 import java.text.DateFormat;
19 import java.text.SimpleDateFormat;
20 import java.util.*;
21 import java.lang.*;
22 import java.net.*;
23
24 public class TestNGCustom extends TestListenerAdapter {
25 private int Count = 0;
26
27 //Take screen shot only for failed test case
28 @Override
29 public void onTestFailure(ITestResult tr) {
30 ScreenShot();
31 }
32
33 @Override
34 public void onTestSkipped(ITestResult tr) {
35 //ScreenShot();
36 }
37
38 @Override
39 public void onTestSuccess(ITestResult tr) {
40 //ScreenShot();
41 }
42
43 private void ScreenShot() {
44 try {
45
46 String NewFileNamePath;
47
48 /*
49 //Code to get screen resolution
50 //Get the default toolkit
51 Toolkit toolkit = Toolkit.getDefaultToolkit();
52 //Get the current screen size
53 Dimension scrnsize = toolkit.getScreenSize();
54 //Print the screen size
55 System.out.println (“Screen size : ” + scrnsize);
56 */
57
58 //Get the dir path
59 File directory = new File (“.”);
60 //System.out.println(directory.getCanonicalPath());
61
62 //get current date time with Date() to create unique file name
63 DateFormat dateFormat = new SimpleDateFormat(“dd_MMM_yyyy__hh_mm_ssaa”);
64 //get current date time with Date()
65 Date date = new Date();
66 //System.out.println(dateFormat.format(date));
67
68 //To identify the system
69 InetAddress ownIP=InetAddress.getLocalHost();
70 //System.out.println(“IP of my system is := “+ownIP.getHostAddress());
71
72 NewFileNamePath = directory.getCanonicalPath()+ “\\ScreenShots\\”+ dateFormat.format(date)+”_”+ownIP.getHostAddress()+ “.png”;
73 System.out.println(NewFileNamePath);
74
75 //Capture the screen shot of the area of the screen defined by the rectangle
76 Robot robot = new Robot();
77 BufferedImage bi=robot.createScreenCapture(new Rectangle(1280,1024));
78 ImageIO.write(bi, “png”, new File(NewFileNamePath));
79 Count++;//Assign each screen shot a number
80 NewFileNamePath = “ScreenShot”+ Count + ““;
81 //Place the reference in TestNG web report
82 Reporter.log(NewFileNamePath);
83
84
85 }
86 catch (AWTException e) {
87 e.printStackTrace();
88 }
89 catch (IOException e) {
90 e.printStackTrace();
91 }
92 }
93 }
Video capture uses 3rd party tools in python or Java as also explained below with JUnit.
JUnit for capture
In the world of JUnit, a “runner” is the thing responsible for executing test cases. If your class doesn’t specify a runner (and most do not), the default BlockJUnit4ClassRuner is used, which looks for methods with the @Test annotation that you’re likely already familiar with. Our custom runner extends this class:
public class SeleniumJUnitRunner extends BlockJUnit4ClassRunner {
public SeleniumJUnitRunner(Class<?> c) throws InitializationError {
super(c);
}
protected Statement methodInvoker(FrameworkMethod m, Object test) {
if (!(test instanceof SeleniumTest)) {
throw new RuntimeException(“Only works with SeleniumTest”);
}
final SeleniumTest stc = ((SeleniumTest) test);
stc.setDescription(describeChild(m));
return new InvokeMethod(m, test) {
@Override
public void evaluate() throws Throwable {
try {
super.evaluate();
} catch (Throwable throwable) {
stc.takeScreenshot(“FAILURE”);
throw throwable;
} finally {
stc.captureNetworkTraffic();
}
}
};
}
}
What is happening here is that we’re overriding the way JUnit invokes a method in our test case. We’re still letting it go through, but we’re also catching and re-throwing any exception, with the addition of capturing a screenshot in between. We’re also capturing the network traffic that ran from the browser.
Both of these methods are part of the SeleniumTest that our test cases extend, and both use standard commands built in to Selenium. Screenshots are taken with a selenium.captureScreenshotToString() command, which returns the screenshot as a Base64 encoded string. The network log is retrieved using the selenium.captureNetworkTraffic(), which returns the network traffic in XML, JSON, or plain text format. Note: in order for the captureNetworkTraffic() command to work, you must start Selenium like so:
selenium.start(“captureNetworkTraffic=true”);
This tells Selenium to route all browser traffic through its local proxy, which allows it to see the network traffic and capture it for retrieval later.