I am looking for a way to attach a screenshot to Results section of TestNG Report for the failed methods.
So far I was able to attache my screenshots to Reporter Output by implementing this:
Reporter.log("<br> <img src=.\\screenshots\\" + fileName + " /> <br>");
but still struggling with adding them to Test Results section of failed methods.
I was able to implement Listener and intercept onTestFailure actions which was originally suggested here:
How can I include a failure screenshot to the testNG report
Here is an example of that:
#Override
public void onTestFailure(ITestResult result) {
Reporter.setCurrentTestResult(result);
Reporter.log("<br> <img src=.\\screenshots\\Untitled.png /> <br>");
Reporter.setCurrentTestResult(null);
}
But Reporter.log function still pushes my information in the Reporter output log but not in the Results->Failed methods->Failed method log.
Update (03/14/14): I've attached screenshot to clarify my question. The problem is not in capturing screenshot and attaching it to Report. That part works fine. The problem is that screenshot is attached to Test Output part of the report but I want to see it in Results -> Failed Methods.
I have also implemented the same extending Testng TestListenerAdapter. By capturing the screenshot then attach it to the Testng Report with the image of size height=100 and width=100 with onTestFailure. Please see below if this helps solve your problem
File scrFile = ((TakesScreenshot) WebdriverManager.globalDriverInstance).getScreenshotAs(OutputType.FILE);
//Needs Commons IO library
try {
FileUtils.copyFile(scrFile, new File(file.getAbsolutePath()+ "/selenium-reports/html/" + result.getName() + ".jpg"));
Reporter.log("<a href='"+ file.getAbsolutePath()+"/selenium-reports/html/" + result.getName() + ".jpg'> <img src='"+ file.getAbsolutePath()+"/selenium-reports/html/"+ result.getName() + ".jpg' height='100' width='100'/> </a>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Reporter.setCurrentTestResult(null);
In addition to above don't forget to add following lines to your testng suite xml
<listeners>
<listener class-name="com.tests.DotTestListener" />
</listeners>
OR
passing as listner parameter if you are executing it from command line
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -listener com.tests.DotTestListener test\testng.xml
Reference : http://testng.org/doc/documentation-main.html#logging-listeners
I've had same problem but it solved. By implementing SuitePanel you will be able to add screenshot as you want
https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/reporters/jq/SuitePanel.java
I almost don't change the original code except
...
// Description?
String description = tr.getMethod().getDescription();
if (! Strings.isNullOrEmpty(description)) {
xsb.push("em");
xsb.addString("(" + description + ")");
xsb.pop("em");
}
// Add screen shot here
xsb.push(“img”,”src”,imagePath);
xsb.pop(“img”);
xsb.pop(D);
xsb.pop(D);
If you want to show the screen shot on the failed method then you will have to capture the exception and modify its message content and add img html to that and then it will appear. Let me know if you need example
I had same issue but its fixed now. I made a method to catcher screenshot in base class. this method return full path of screenshot.
public String getScreenshot (String screenshotName, WebDriver driver) throws IOException{
DateFormat dateformate = new SimpleDateFormat("dd-mm-yy-hh-mm-ss");
Date date = new Date();
String currentdate = dateformate.format(date);
String imageName =screenshotName+currentdate;
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
String location =System.getProperty("user.dir")+"\\testOutput\\screenshot\\"+imageName+".png";
File screenshotLocation =new File (location);
FileUtils.copyFile(source, screenshotLocation);
return location;
}
Add use this path to add screenshot in testng report as well as report log by updating testng TestNgListener-
public void onTestFailure(ITestResult arg0) {
Object currentClass = arg0.getInstance();
WebDriver driver = ((BrowserSetup) currentClass).getDriver();
String name = arg0.getName();
System.out.println(name);
try {
String screenshotPath =getScreenshot(name, driver);
System.out.println("Screenshot taken");
String path = "<img src=\"file://" + screenshotPath + "\" alt=\"\"/>";
System.out.println(screenshotPath+" and path - "+path);
Reporter.log("Capcher screenshot path is "+path);
} catch (Exception e) {
System.out.println("Exception while takescreenshot "+e.getMessage());
}
printTestResults(arg0);
}
I suggest you to use ReportNG instead of the primitive TestNG reports.
If the problem only with getting screenshots, you can try to get it like this:
private static byte[] GetCropImg(IWebDriver targetChrome, IWebElement targetElement)
{
var screenshot = ((ITakesScreenshot)targetChrome).GetScreenshot();
var location = targetElement.Location;
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
{
var rect = new Rectangle(location.X, location.Y, targetElement.Size.Width, targetElement.Size.Height);
using (Bitmap bmpImage = new Bitmap(stream))
{
using (Bitmap cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat))
{
using (MemoryStream ms = new MemoryStream())
{
cropedImag.Save(ms, ImageFormat.Jpeg);
byte[] byteImage = ms.ToArray();
return byteImage;
}
}
}
}
}
and then you can save file or save sting64
var imgString64 = Convert.ToBase64String(byteImage); //Get Base64
PS: on JAVA it should be almost the same)
you can get failed test cases screen shots with name of failed test class by using #After method.
Use below code segment
Related
I am using onTestFailure method to display error screenshot in TestNG results. I am using Jenkins to run my test but image is not getting displayed in TestNG results however it is showing it as a link and nothing is happening on clicking this scattered image link. When I copy image link using mouse and trying open it in a browser then image is getting displayed correctly which means path to image is correct.
public class ScreenshotListener extends TestListenerAdapter {
#Override
public void onTestFailure(ITestResult result) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
String methodName = result.getName();
//String pathToScreen;
if(!result.isSuccess()){
File scrFile = ((TakesScreenshot)GlobalVar.wDriver).getScreenshotAs(OutputType.FILE);
try {
String reportDirectory = new File(System.getProperty("user.dir")).getAbsolutePath() + "/target/surefire-reports";
File destFile = new File((String) reportDirectory+"/failure_screenshots/"+methodName+"_"+formater.format(calendar.getTime())+".png");
FileUtils.copyFile(scrFile, destFile);
Reporter.log("<a href='"+ destFile.getAbsolutePath() + "'> <img src='"+ destFile.getAbsolutePath() + "' height='100' width='100'/> </a><br />");
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
I expect image link should display proper screenshot of error but it is showing blank screenshot. I have attached the screenshot of TestNGResults
FURTHER INVESTIGATION RESULT:
I investigated it further and found the reason of not displaying the screenshot. Actually screenshot path is coming as **C:\SelWrokspaceLuna 18 May\RDTest\target\surefire-reports\failure_screenshots\ but jenkin workspace path is **http://localhost:8080/job/firstjob/ws/target/surefire-reports/failure_screenshots/
Can anyone suggest how to get path of Jenkin workspace in selenium script? so that i can give jenkin workspace path in my HTML. Basically how to know this path http://localhost:8080/job/firstjob/ws in selenium script
Base64 image in selenium extent report is not displayed correctly after clicking the image in the report.
Searched various sources to get the issue resolution but did not find the answer anywhere
//dependency in POM.xml Code:-
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
</dependency>
//ExtentReporterListener Code :-
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail("Test failed due to below error");
try {
test.get().fail(result.getThrowable(), MediaEntityBuilder.createScreenCaptureFromPath(TestUtil.getScreenshotExtent()).build());
} catch(IOException e) {
System.err.
println("Exception thrown while updating test fail status " + Arrays.toString(e.getStackTrace()));
}
test.get().getModel().setEndTime(getTime(result.getEndMillis()));
}
//Capture screenshots code:-
public class TestUtil {
public static String getScreenshotExtent() {
String Base64StringofScreenshot = "";
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
byte[] fileContent;
try {
fileContent = FileUtils.readFileToByteArray(src);
Base64StringofScreenshot = "data:image/png;base64," + Base64.getEncoder().encodeToString(fileContent);
} catch(IOException e) {
e.printStackTrace();
}
return Base64StringofScreenshot;
}
}
Can someone please help how to resolve this issue and correctly display the image in extent report after clicking it?
can you please let me know in which browser you are running this Automation suite?
for e.g: You are using Chrome browser in windows OS 64 bit, then you need to check the chromedriver.exe which you have downloaded, that is for 32 bit or 64 bit.If you are using the driver for 32 bit then this type of issue comes.
If you are still not finding any solution then let me know.
I am unable to add the screenshot of failed case to the extent report in Cucumber (java).
//Runner class to generate extent report
#AfterClass
public static void Report() {
Reporter.loadXMLConfig(new File("/Users/chetan/Documents/workspace/Packages/extent-config.xml"));
Properties p = new Properties();
p.list(System.out);
}
//Main class contains step definitions
#After("#browser")
public void teardown(WebDriver driver, Scenario scenario, String screenshotName) throws IOException {
if (scenario.isFailed()) {
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
driver.quit();
}
}
You need to define Extent Report Object at class Level or wherever you like. And then you can use it on Failure.
For the Report location: Create New Folder with name Report in your project directory at root location
For the Screenshot location: Create New Folder with name Screenshots in your project directory at root location
Code:
//Report Initialization
ExtentHtmlReporter htmlreport = new ExtentHtmlReporter(".\\Report\\Extent Report with Screenshot.html");
ExtentReports reports = new ExtentReports();
reports.attachReporter(htmlreport);
ExtentTest testlog;
//Capture and save screenshot
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage img = ImageIO.read(screen);
File filetest = Paths.get(".").toAbsolutePath().normalize().toFile();
ImageIO.write(img, "png", new File(filetest + "\\Screenshots\\" + "Test.png"));
//Log Screenshot in Report
testlog.info("Details of " + "Test screenshot", MediaEntityBuilder
.createScreenCaptureFromPath(System.getProperty("user.dir") + "\\Screenshots\\" + "Test.png").build());
//Flush Report-Mandatory, Else report will not generate.
reports.flush();
You can refer my example from Github (Click here), for ease of Use.
You didn't add the screenshot to the report
ExtentTest test = extent.createTest("TestName");
test.fail("details").addScreenCaptureFromPath("pathToScreenshot");
// or
test.fail("details", MediaEntityBuilder.createScreenCaptureFromPath("pathToScreenshot").build());
This is question for extent reports cucumber adapter but answers are for extent reports.
Please open report and see in console the link to the screenshot path and check if images are there.
It is known issue that extent adapters save screenshots in test-output folder for some reason, you may need to do put screenshot folder in extent.properties or use SystemSet
The problem was apparently solved in new snapshot but I have to check that
How do i identify download is not completed /in progress ? because i want to close web driver after download finished.
WebDriver: Chrome
sample code like this ,assume chrome driver setup is ready.
#Test
public void testDownloadPdf(){
// here is the selenium java code to download pdf.
// when do i perform driver.close();
}
In general, better close the driver in #AfterClass.
If you know the exact file name and expected location, you can use Paths
String file_path_full = "C:\\users\\username\\downloads\\yourpdffile.pdf";
while(Files.notExists(Paths.get(file_path_full))) {Thread.sleep(10000);}
I found this... it work in my case
here i'm using FileUtils.sizeOfDirectory(downloadfolder) it will return size of directory and will check after every 5 sec is the size is equal or not.if file size is equal then download is completed .
private void waitForDownloadFinished() throws Exception {
try {
String path = "/Download/path/";
if (path != null) {
File folder = new File(path);
long size, reSize;
do {
size = FileUtils.sizeOfDirectory(folder);
Thread.sleep(5000);
reSize = FileUtils.sizeOfDirectory(folder);
} while (size != reSize);
System.out.println("Download completed");
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
getWebBrowser().quit();
}
}
If anyone know how to take screenshot of failed test/methods in selenium webdriver using reportNG then please help.
If you provide code then its helpfull or provide some ideas to solve this problem.
Thanks in advance.
Yes, It is possible.
WebDriver firfoxDriver = new FirefoxDriver();
firfoxDriver.get("https://stackoverflow.com/");
File file = ((TakesScreenshot)firfoxDriver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(file, new File("E:\\Data\\ss.png"));
Or You can use this:
#AfterMethod(alwaysRun=true)
public void catchExceptions(ITestResult result){
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
String methodName = result.getName();
if(!result.isSuccess()){
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File((String) PathConverter.convert("failure_screenshots/"+methodName+"_"+formater.format(calendar.getTime())+".png")));
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Well It's depend on your framework that where the control is going after failing the method.
Suppose in your case it is going in catch exception block then copy that code in catch block.
File file = ((TakesScreenshot)firfoxDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file, new File("YOUR PATH"+Filename+.JPG));
You can use Itestlistener in testng to take screenshot. testng has an in built function by which you can take screenshot when it fails.
Just create a seperate listerner class and paste this code:
public class listeners implements ITestListener{
//This "Base " is the main class where you can pass the result of test case and write the //code for screenshot
//I cam creating an object so I can access the method that I created for screenshot in this base class.
//I am also getting the result name so I can identify which test case it got failed
Base b = new Base();
public void onTestFailure(ITestResult result) {
try {
//Getting the result name by result.getName() method
b.getScreenshot( result.getName());
System.out.println("The Failed test is=="+result.getName());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I created this getScreenshot method in the base class and passing the result name
public class Base {
public WebDriver InitializeDr() throws IOException {
//Creating the method to take screenshot in the Base class
public void getScreenshot(String result) throws IOException
{
File dest=new File("D:\\Work\\KT\\Scr Shot\\"+result+"test.png");
File src=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, dest);
}
}
}