Attach Screen Shots to ReportNG reports using Maven

2,407 views
Skip to first unread message

Deepa Kiran Bagepalli

unread,
Dec 17, 2013, 3:25:17 AM12/17/13
to testng...@googlegroups.com
Hi All,
I am using TestNG + Maven and using ReportNG for reports.
Below is my POM.xml where i added listeners to surefire plugin for generating ReportNG reports.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<!-- testng xml suite file to be used for test execution -->
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
<testFailureIgnore>true</testFailureIgnore>
<properties>
<!-- Setting ReportNG listeners -->
<property>
<name>listener</name>
<value>org.uncommons.reportng.HTMLReporter, org.uncommons.reportng.JUnitXMLReporter</value>
</property>
</properties>
</configuration>
</plugin>

The ReportNG reports are saved in /target/surefire-reports/html folder of the project

Now, I am trying to take screen shots at time of test failure and attach it to reportNG report. I tried by adding Report.Log to @AfterMethod class but it did not work. I haven't found any changes to be made in POM to attach screen shots to reportNG report

Can some one please suggest the modifications (if any) to be done to POM and test scripts.

Thanks & Regards
Deepa Kiran

Krishnan Mahadevan

unread,
Dec 17, 2013, 3:42:15 AM12/17/13
to testng...@googlegroups.com
What did you log using Reporter.log() ? What do you mean it didn't work ? You would need to elaborate a bit more here.

Reporter.log() dumps messages into the a corresponding Test method's ITestResult object. I dont know how was ReportNG built, but am guessing it should be reading the messages from every test method's ITestResult object to render reports.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to testng...@googlegroups.com.
Visit this group at http://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/groups/opt_out.

Deepa Kiran Bagepalli

unread,
Dec 17, 2013, 7:57:03 AM12/17/13
to testng...@googlegroups.com
Thanks Krishnan for the reply

While i have a png file in the /screenshots folder, i have added below code to @AfterMethod class

@AfterMethod
public void vewResult(ITestResult result)
{
String fileName = System.getProperty("user.dir") + File.separator + "screenshots" + File.separator + "Step3.png";
Reporter.setCurrentTestResult(result);
Reporter.log("<a href=\""+fileName+"\"> Clickhere </a>");
//Reporter.log("<img src=\"file:///" + fileName + "\" alt=\"\"/><br/>");

}

I read on forums that this approach mostly works for TestNG but I still tried it though i am not sure if it works for ReportNG or not.

Please suggest.

Thanks & Regards
Deepa

Shawn McCarthy

unread,
Dec 17, 2013, 9:09:59 AM12/17/13
to testng...@googlegroups.com
I don't use ReporterNG, but I do use TestNG. With TestNG, you can not (that I know of) use Reporter.log in a BeforeMethod or AfterMethod. What I did was override the onFailure and onSuccess methods and use Reporter.log in those. I am not saying this is the best way, but just one way I did it. I am interested to see how other people handled this as well.

Thanks !

Manoj Hans

unread,
Dec 17, 2013, 11:31:40 AM12/17/13
to testng...@googlegroups.com
Hi Deepa, 

Try below code--

@AfterMethod
public void vewResult(ITestResult result)
{
private static final String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
System.setProperty(ESCAPE_PROPERTY, "false");

String fileName = System.getProperty("user.dir") + File.separator + "screenshots" + File.separator + "Step3.png";
Reporter.setCurrentTestResult(result);
Reporter.log("<a href=\""+fileName+"\"> Clickhere </a>");
//Reporter.log("<img src=\"file:///" + fileName + "\" alt=\"\"/><br/>");
}


--Manoj Hans

Sergey Kuts

unread,
Dec 17, 2013, 2:24:45 PM12/17/13
to testng...@googlegroups.com
You're welcome.

public class ReportUtils extends ReportNGUtils {

    public List<String> getTestOutput(ITestResult result) {

        List<String> output = super.getTestOutput(result);

        String screenshot = (String)result.getAttribute("screenshot");
        if (screenshot != null) {
            output.add("<a href=\"../" + screenshot + "\">Screenshot</a>");
        }

        return output;
    }
}

public class BaseHTMLReporter extends HTMLReporter implements ITestListener {

    private static final String UTILS_KEY ="utils";
    private static final ReportUtils REPORT_UTILS = new ReportUtils();

    protected VelocityContext createContext() {
        VelocityContext context = super.createContext();
        context.put(UTILS_KEY, REPORT_UTILS);
    }

    private void createScreenshot(ITestResult result) {
        // take screenshot and put its path into test result context
        result.setAttribute("screenshot", "your_screenshot_path");
    }

    @Override
    public void onTestStart(ITestResult result) {}

    @Override
    public void onTestSuccess(ITestResult result) {
        createScreenshot(result);
    }

    @Override
    public void onTestFailure(ITestResult result) {
        createScreenshot(result);
    }

    @Override
    public void onTestSkipped(ITestResult result) {}

    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}

    @Override
    public void onStart(ITestContext context) {}

    @Override
    public void onFinish(ITestContext context) {}
}

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.16</version>
                    <configuration>
                        <systemPropertyVariables>
                            <org.uncommons.reportng.escape-output>false</org.uncommons.reportng.escape-output>
                        </systemPropertyVariables>

                        <properties>
                            <property>
                                <name>usedefaultlisteners</name>
                                <value>false</value>
                            </property>

                            <property>
                                <name>listener</name>
                                <value>your.package.BaseHTMLReporter</value>
                            </property>
                        </properties>

                        <suiteXmlFiles>
                            <suiteXmlFile>testng.xml</suiteXmlFile>
                        </suiteXmlFiles>
                    </configuration>
                </plugin>

вторник, 17 декабря 2013 г., 10:25:17 UTC+2 пользователь Deepa Kiran Bagepalli написал:

Deepa Kiran Bagepalli

unread,
Dec 18, 2013, 8:16:37 AM12/18/13
to testng...@googlegroups.com
Thanks all for the replies.
The solution posted by Sergey Kuts worked for me and is wonderful. Thanks so much for that.

Though my problem is resolved, i am curious to understand few things as i haven't completely understood the given code :
1. Why are we writing new custom listener ? Isn't this feature (adding screen shots to reports) provided by ReportNG ? OR we want to achieve some thing else other than the feature provided by ReportNG ?
2. For what action does "VelocityContext" is being used
3. What is "org.uncommons.reportng.escape-output" in POM and why is it set to false ?

Thanks & Regards
Deepa

Krishnan Mahadevan

unread,
Dec 18, 2013, 8:50:02 AM12/18/13
to testng...@googlegroups.com

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/


On Wed, Dec 18, 2013 at 6:46 PM, Deepa Kiran Bagepalli <deepa.k...@gmail.com> wrote:
Thanks all for the replies.
The solution posted by Sergey Kuts worked for me and is wonderful. Thanks so much for that.

Though my problem is resolved, i am curious to understand few things as i haven't completely understood the given code :
1. Why are we writing new custom listener ? Isn't this feature (adding screen shots to reports) provided by ReportNG ? OR we want to achieve some thing else other than the feature provided by ReportNG ?

Depends on the need. For e.g., in my organization we decided to build a totally custom listener which has a different look and feel for the reports.
 
2. For what action does "VelocityContext" is being used
This is part of Velocity Template, which is essentially being used to build html pages with context substitution at runtime [ Imagine something like a JSP programming or servlet programming being done at the client side ] http://www.javaworld.com/article/2075966/core-java/start-up-the-velocity-template-engine.html 

 
3. What is "org.uncommons.reportng.escape-output" in POM and why is it set to false ?
Open http://reportng.uncommons.org/ and refer to "Supported System Properties" section for an explanation.
 

Thanks & Regards
Deepa

Sergey Kuts

unread,
Dec 18, 2013, 5:46:42 PM12/18/13
to testng...@googlegroups.com
1) ReportNG uses TestNG results and Velocity templates to create custom reports. If you look at its source code, you'll see that it's only a TestNG wrapper that implements generateReport method (TestNG IReporter interface) with fancy output. And it doesn't care about screenshots as this is out of its scope. When we set our custom ReportNG listener that implements generateReport method and disable default listeners, we say to TestNG - "hey, use my own reporter". And when TestNG reaches the place where it should create a report, it will find an appropriate generateReport implementation that is included into ReportNG library. I've added ITestListener only for providing an opportunity to create screenshot after success / fail tests. If you want to do it elsewhere, you can remove it, but anyway you should take care about setting screenshot path to some global context (like ITestResult). This will give you a chance to set it into ReportNG test output.
2) As you've seen, we have overriden getTestOutput from ReportNGUtils to set our screenshot link into report's output. Our BaseHTMLReporter extends (at the end of inheritance chain) AbstractReporter that included createContext method. This method sets ReportNGUtils object into VelocityContext the same way as we do in our implementation. The only difference is that we override this object with our custom (including a link on a screenshot). And all the objects that we put into Velocity Context will be available inside Velocity Templates that are defined inside ReportNG library. Our final report is based on these templates. You can put anything you want into velocity context and parse it inside these templates.
3) This option is intended to disable characters escaping inside results output. If you turn it on, you'll see raw html code instead of a link on a screenshot.

Regards,
Sergey        

среда, 18 декабря 2013 г., 15:16:37 UTC+2 пользователь Deepa Kiran написал:

Deepa Kiran

unread,
Dec 19, 2013, 6:33:48 AM12/19/13
to testng...@googlegroups.com
Thanks so much Sergey 

shikhars

unread,
Jan 14, 2014, 6:34:01 AM1/14/14
to testng...@googlegroups.com
Hi Sergey,

I was trying the code provided here but got an error for
"ReportNGUtils cannot be resolved to a type"

And same for error for VelocityContext.

Please help me resolve this.



--
View this message in context: http://testng.1065351.n5.nabble.com/Attach-Screen-Shots-to-ReportNG-reports-using-Maven-tp19171p19302.html
Sent from the testng-users mailing list archive at Nabble.com.

Sergey Kuts

unread,
Jan 14, 2014, 5:18:17 PM1/14/14
to testng...@googlegroups.com
Hi,

I guess you forgot to include reportng and velocity dependencies into your pom.xml.

Regards,
Sergey

вторник, 14 января 2014 г., 13:34:01 UTC+2 пользователь shikhar srivastava написал:

kiran p

unread,
Jan 16, 2014, 12:37:01 PM1/16/14
to testng...@googlegroups.com
Hi Deepa ,
 

Its easy to attach the screent shot for the test case failure . You dont need any pom changes you need to just add a class which extends TestListenerAdapter and override onTestFailure .
And use the @Listener annotation in the main test classs suite .which contains all the test cases .

Example of the listener



public class CaptureFailedTests extends TestListenerAdapter {

@Override
public void onTestFailure(ITestResult tr) {

WebDriver driver = //Current driver instance of the test case 
File scrFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
DateFormat dateFormat = new SimpleDateFormat("dd_MMM_yyyy__hh_mm_ssaa");
String destDir = "./reports/screenshots/";
new File(destDir).mkdirs();
String destFile = dateFormat.format(new Date()) + ".png";

try {
FileUtils.copyFile(scrFile, new File(destDir + "/" + destFile));
} catch (IOException e) {
e.printStackTrace();
}
Reporter.setEscapeHtml(false);
String screenPath = "Saved <a href=../reports/screenshots/ + destFile + ">Screenshot</a>";
Reporter.log(screenPath);
}


Add the above  class example to your project and  just initialise the variable driver with the current webdriver instance of the test suite .


For your main class which contains testNG test cases add the annotation (@Listener=CaptureFailedTests .class)

The captured screen shots will be part of report html generated 

Regards
Kiran

Abbas ALI

unread,
May 17, 2017, 2:05:23 AM5/17/17
to testng-users
Hi Sergey ,

I tried the way u mention but screenshot not getting generated only screenshot link is available in report when i click it saying 404 , what to do , do i need to do more around it

Logesh Kumar Vb

unread,
Mar 29, 2018, 6:52:04 AM3/29/18
to testng-users
Deepa :

Can you please paste the piece of lines which you used in pom.xml to attach the screenshot in the email notification.

Thanks,
Logesh
Reply all
Reply to author
Forward
0 new messages