How to Set Up Extent Reports with ExtentReportManager for HTML Test Reports in anhtester/automationframeworkselenium
The anhtester/automationframeworkselenium repository provides a ready-to-use ExtentReportManager that integrates ExtentReports with TestNG via a custom listener to generate thread-safe HTML test reports with screenshots and metadata.
The anhtester/automationframeworkselenium framework ships with a built-in reporting architecture that simplifies setting up Extent Reports with ExtentReportManager for HTML test reports. This implementation abstracts the ExtentReports API into manageable components that handle initialization, thread-safe test logging, and automatic HTML generation without requiring boilerplate code in your test classes.
Core Architecture Components
The framework implements a three-layer architecture to manage ExtentReports lifecycle and thread safety.
ExtentReportManager
The ExtentReportManager class in src/main/java/com/anhtester/reports/ExtentReportManager.java serves as the central utility that creates the singleton ExtentReports instance. It configures the Spark HTML reporter, sets document titles, captures screenshots as Base64, assigns authors and categories, and handles the final flush operation that writes the HTML file to disk.
ExtentTestManager
The ExtentTestManager class in src/main/java/com/anhtester/reports/ExtentTestManager.java maintains a ThreadLocal<ExtentTest> variable. This design ensures that each test method running in parallel execution receives its own isolated ExtentTest object, preventing race conditions when multiple threads log simultaneously.
TestListener
The TestListener class in src/test/java/com/anhtester/listeners/TestListener.java implements TestNG's ITestListener interface. This listener wires the manager into the test lifecycle by triggering initialization on suite start, creating test entries when methods begin, logging results after execution, and flushing reports when the suite finishes.
Maven Dependency Configuration
The project declares the ExtentReports dependency in pom.xml using version 5.1.2. No additional configuration is required unless upgrading the library.
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>${extentreports.version}</version>
</dependency>
The property extentreports.version is defined in the properties section of pom.xml. Update this value to upgrade to newer ExtentReports releases.
Configuring Report Paths and Behavior
All report configuration resides in FrameworkConstants (src/main/java/com/anhtester/constants/FrameworkConstants.java), which reads values from config.properties at startup. Modify these settings in src/main/resources/config.properties:
EXTENT_REPORT_FOLDER– Directory where HTML reports are written (e.g.,reports/ExtentReports/)EXTENT_REPORT_NAME– Base filename without extension (e.g.,ExtentReport)OVERRIDE_REPORTS– Set to"yes"to overwrite the same file on each run, or"no"to generate timestamped filesOPEN_REPORTS_AFTER_EXECUTION– Set to"yes"to automatically open the HTML report in the default browser after test completionSCREENSHOT_PASSED_TCS,SCREENSHOT_FAILED_TCS,SCREENSHOT_SKIPPED_TCS– Enable screenshots for specific test statuses by setting to"yes"
Initializing the Extent Report
The framework initializes the report automatically when the TestListener triggers. The onStart() method invokes:
ExtentReportManager.initReports();
This method creates the ExtentReports instance, instantiates an ExtentSparkReporter with the configured theme and document title, attaches system information (framework name, author, environment), and stores the output file path in a private static variable for later flushing.
Creating Thread-Safe Test Entries
When each test method begins execution, the listener's onTestStart() method creates a dedicated test entry:
ExtentReportManager.createTest(iTestResult.getName());
You can enrich test metadata immediately after creation:
ExtentReportManager.addAuthors(getAuthorType(iTestResult));
ExtentReportManager.addCategories(getCategoryType(iTestResult));
ExtentReportManager.addDevices();
ExtentReportManager.info(BrowserInfoUtils.getOSInfo());
These calls delegate to ExtentTestManager.setExtentTest(), which stores the ExtentTest object in a thread-local variable, ensuring isolated logging for parallel test execution.
Logging Steps and Capturing Screenshots
Use the static helper methods from ExtentReportManager anywhere in your test code to append log entries and visual evidence:
| Method | Usage |
|---|---|
logMessage(String msg) |
General informational logging |
logMessage(Status status, String msg) |
Log with explicit status (PASS, FAIL, WARNING) |
pass(String msg) / fail(String msg) / skip(String msg) |
Shorthand for status-specific logging |
addScreenShot(Status status, String name) |
Captures Base64 screenshot from the Selenium WebDriver and attaches it to the current step |
addScreenShot(String name) |
Captures screenshot with INFO status |
info(Markup markup) |
Adds rich HTML content like tables or code blocks |
Screenshot capture respects the configuration flags set in config.properties. When enabled, the framework automatically captures the browser state and embeds it directly into the HTML report using Base64 encoding to ensure portability.
Flushing and Opening the Final Report
When the test suite completes, the listener's onFinish() method finalizes the report:
ExtentReportManager.flushReports();
ReportUtils.openReports(link);
The flushReports() method writes all accumulated data to the HTML file, closes the ExtentReports instance, and calls ExtentTestManager.unload() to clear thread-local storage. If OPEN_REPORTS_AFTER_EXECUTION is enabled, the generated HTML file opens automatically in the system default browser.
Complete Working Example
The following minimal test class demonstrates the integration. Because TestListener handles the lifecycle automatically, you only write logging statements:
import com.anhtester.reports.ExtentReportManager;
import com.aventstack.extentreports.Status;
import org.testng.annotations.Test;
public class LoginTest {
@Test
public void verifyValidLogin() {
// Log navigation step
ExtentReportManager.logMessage("Navigating to login URL");
// Perform login actions here...
// Attach screenshot after login
ExtentReportManager.addScreenShot(Status.PASS, "Post-login dashboard");
// Log verification
ExtentReportManager.pass("Login successful with valid credentials");
}
}
Ensure your testng.xml registers the listener:
<suite name="Automation Suite">
<listeners>
<listener class-name="com.anhtester.listeners.TestListener"/>
</listeners>
<test name="Regression Tests">
<classes>
<class name="LoginTest"/>
</classes>
</test>
</suite>
Summary
- ExtentReportManager in
src/main/java/com/anhtester/reports/ExtentReportManager.javahandles singleton instance creation, Spark reporter configuration, and HTML generation. - ExtentTestManager maintains thread-local storage via
ThreadLocal<ExtentTest>to support parallel test execution safely. - TestListener automates the entire lifecycle from initialization through flushing without requiring manual setup in test classes.
- Configuration is centralized in
FrameworkConstantsand driven byconfig.propertiesvalues for report paths, naming conventions, and screenshot behavior. - Screenshots are captured as Base64 and embedded directly into the HTML report to ensure single-file portability.
- The framework supports automatic report opening post-execution via the
OPEN_REPORTS_AFTER_EXECUTIONproperty.
Frequently Asked Questions
How do I enable screenshots only for failed test cases?
Set the property SCREENSHOT_FAILED_TCS=yes in src/main/resources/config.properties, and ensure SCREENSHOT_PASSED_TCS and SCREENSHOT_SKIPPED_TCS are set to no. The ExtentReportManager checks these flags before invoking the screenshot capture logic in addScreenShot().
Can I run tests in parallel without mixing log entries?
Yes. The ExtentTestManager class uses a ThreadLocal<ExtentTest> variable to isolate each thread's ExtentTest instance. When createTest() is called, the manager stores the test object in thread-local storage, ensuring that parallel test methods write to their respective report nodes without interference.
Where is the final HTML report file located?
The report writes to the directory specified by EXTENT_REPORT_FOLDER in config.properties, typically under reports/ExtentReports/. If OVERRIDE_REPORTS is set to no, the filename includes a timestamp prefix (e.g., 20240115_143022_ExtentReport.html). The exact path is constructed in ExtentReportManager.initReports() using FrameworkConstants.EXTENT_REPORT_FOLDER_PATH.
How do I add custom system information to the report header?
Modify the initReports() method in ExtentReportManager.java or extend the manager to call extentReports.setSystemInfo(key, value) before the suite starts. Common additions include build numbers, test environments, or browser versions captured via BrowserInfoUtils.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →