Answer
ExtentReports Integration with Selenium + TestNG
ExtentReports produces rich, interactive HTML reports with pass/fail/skip charts, screenshots, and logs — far better than TestNG''s default reports.
Maven Dependency
XML
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>5.1.1</version>
</dependency>
Step 1 — ExtentReportManager (Singleton)
Java
public class ExtentReportManager {
private static ExtentReports extent;
private static ThreadLocal<ExtentTest> extentTest = new ThreadLocal<>();
public static ExtentReports getInstance() {
if (extent == null) {
String reportPath = System.getProperty("user.dir") +
"/test-output/ExtentReport.html";
ExtentSparkReporter spark = new ExtentSparkReporter(reportPath);
spark.config().setDocumentTitle("AutomateQA Test Report");
spark.config().setReportName("Regression Suite");
spark.config().setTheme(Theme.DARK);
extent = new ExtentReports();
extent.attachReporter(spark);
extent.setSystemInfo("OS", System.getProperty("os.name"));
extent.setSystemInfo("Environment", "Staging");
extent.setSystemInfo("Tester", "AutomateQA Team");
}
return extent;
}
public static void setTest(ExtentTest test) { extentTest.set(test); }
public static ExtentTest getTest() { return extentTest.get(); }
}
Step 2 — TestNG Listener
Java
public class ExtentReportListener implements ITestListener {
@Override
public void onStart(ITestContext context) {
ExtentReportManager.getInstance();
}
@Override
public void onTestStart(ITestResult result) {
ExtentTest test = ExtentReportManager.getInstance()
.createTest(result.getMethod().getMethodName());
ExtentReportManager.setTest(test);
ExtentReportManager.getTest().info("Test started: " + result.getMethod().getMethodName());
}
@Override
public void onTestSuccess(ITestResult result) {
ExtentReportManager.getTest().pass("Test PASSED");
}
@Override
public void onTestFailure(ITestResult result) {
ExtentReportManager.getTest().fail(result.getThrowable());
// Attach screenshot on failure
try {
WebDriver driver = DriverManager.getDriver();
String base64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);
ExtentReportManager.getTest()
.addScreenCaptureFromBase64String(base64, "Failure Screenshot");
} catch (Exception e) {
ExtentReportManager.getTest().warning("Could not capture screenshot: " + e.getMessage());
}
}
@Override
public void onTestSkipped(ITestResult result) {
ExtentReportManager.getTest().skip(result.getThrowable());
}
@Override
public void onFinish(ITestContext context) {
ExtentReportManager.getInstance().flush(); // CRITICAL — writes report to disk
}
}
Step 3 — Register in testng.xml
XML
<suite name="Regression">
<listeners>
<listener class-name="listeners.ExtentReportListener"/>
</listeners>
<test name="AllTests">
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
Step 4 — Add Logs in Tests
Java
@Test
public void loginTest() {
ExtentReportManager.getTest().info("Navigating to login page");
driver.findElement(By.id("username")).sendKeys("admin");
ExtentReportManager.getTest().info("Entering credentials");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.id("loginBtn")).click();
Assert.assertTrue(driver.getTitle().contains("Dashboard"));
ExtentReportManager.getTest().pass("Login successful — dashboard loaded");
}
Report Output Features
- ✓Interactive pie chart of pass/fail/skip counts
- ✓Timeline view of test execution
- ✓Embedded screenshots on failures
- ✓System info panel
- ✓Dark/light theme support
- ✓Collapsible test step logs
