This document describes the test listener architecture in the AutomationFrameworkSelenium, focusing on how the framework intercepts and responds to test execution lifecycle events. The framework implements two primary listeners: TestListener for TestNG integration and AllureListener for Allure reporting integration. These listeners coordinate test execution observability, including screenshot capture, video recording, report generation, and multi-channel notifications.
For information about the reporting systems themselves, see Extent Reports Integration and Allure Reports Integration. For notification mechanisms, see Notifications and Communication. For base test infrastructure, see Base Test Infrastructure.
The framework implements a multi-interface listener pattern to intercept different stages of test execution. The primary TestListener class implements three TestNG interfaces to capture suite-level, test-level, and method-level events.
Sources: src/test/java/com/anhtester/listeners/TestListener.java30-265 src/test/java/com/anhtester/listeners/AllureListener.java15-69
The TestListener class src/test/java/com/anhtester/listeners/TestListener.java30 implements three interfaces to intercept all lifecycle events:
| Interface | Purpose | Key Methods |
|---|---|---|
ITestListener | Test method lifecycle | onTestStart, onTestSuccess, onTestFailure, onTestSkipped |
ISuiteListener | Suite lifecycle | onStart, onFinish |
IInvokedMethodListener | All method invocations | beforeInvocation, afterInvocation |
Listeners are registered in TestNG suite XML files using the <listeners> element. The framework supports both TestNG and Allure listeners simultaneously, enabling dual reporting output.
Sources: src/test/java/com/anhtester/listeners/TestListener.java30
Suite-level events trigger framework-wide initialization and cleanup operations, including configuration loading, report initialization, and artifact distribution.
Sources: src/test/java/com/anhtester/listeners/TestListener.java68-83
The onStart method src/test/java/com/anhtester/listeners/TestListener.java68-83 performs critical initialization:
PropertiesHelpers.loadAllFiles() src/test/java/com/anhtester/listeners/TestListener.java78 to load runtime settings from config.propertiesAllureManager.setAllureEnvironmentInformation() src/test/java/com/anhtester/listeners/TestListener.java79 to write environment metadataExtentReportManager.initReports() src/test/java/com/anhtester/listeners/TestListener.java80 to prepare HTML/PDF report generationSources: src/test/java/com/anhtester/listeners/TestListener.java68-83
Sources: src/test/java/com/anhtester/listeners/TestListener.java86-113
The onFinish method src/test/java/com/anhtester/listeners/TestListener.java86-113 orchestrates post-execution activities:
ExtentReportManager.flushReports() src/test/java/com/anhtester/listeners/TestListener.java90ZipUtils.zipReportFolder() src/test/java/com/anhtester/listeners/TestListener.java92 if ZIP_FOLDER is enabledTelegramManager.sendReportPath() src/test/java/com/anhtester/listeners/TestListener.java94EmailSendUtils.sendEmail() src/test/java/com/anhtester/listeners/TestListener.java96AllureEnvironmentWriter src/test/java/com/anhtester/listeners/TestListener.java99 with execution statisticscategories.json and executor.json to target/allure-results/ src/test/java/com/anhtester/listeners/TestListener.java102-103The method writes comprehensive execution metadata to Allure environment properties, including:
TARGET (local/remote execution)WAIT_DEFAULT, WAIT_PAGE_LOADED (timeout configurations)HEADLESS modecount_totalTCs, count_passedTCs, count_skippedTCs, count_failedTCsSources: src/test/java/com/anhtester/listeners/TestListener.java86-113
The framework tracks four test outcomes (start, success, failure, skip) with distinct handling for each state, including conditional screenshot capture and video recording.
Sources: src/test/java/com/anhtester/listeners/TestListener.java32-35 src/test/java/com/anhtester/listeners/TestListener.java190-263
The listener maintains four static counters src/test/java/com/anhtester/listeners/TestListener.java32-35:
count_totalTCs: Incremented on every onTestStart src/test/java/com/anhtester/listeners/TestListener.java192count_passedTCs: Incremented on onTestSuccess src/test/java/com/anhtester/listeners/TestListener.java209count_failedTCs: Incremented on onTestFailure src/test/java/com/anhtester/listeners/TestListener.java229count_skippedTCs: Incremented on onTestSkipped src/test/java/com/anhtester/listeners/TestListener.java247These counters are used in suite finish notifications src/test/java/com/anhtester/listeners/TestListener.java96 and Allure environment properties src/test/java/com/anhtester/listeners/TestListener.java99
Sources: src/test/java/com/anhtester/listeners/TestListener.java32-35 src/test/java/com/anhtester/listeners/TestListener.java190-263
Sources: src/test/java/com/anhtester/listeners/TestListener.java190-204
The onTestStart method src/test/java/com/anhtester/listeners/TestListener.java190-204 initializes test-level reporting:
count_totalTCs src/test/java/com/anhtester/listeners/TestListener.java192ExtentReportManager.createTest() src/test/java/com/anhtester/listeners/TestListener.java194@FrameworkAnnotation metadata: getAuthorType() src/test/java/com/anhtester/listeners/TestListener.java195getCategoryType() src/test/java/com/anhtester/listeners/TestListener.java196VIDEO_RECORD equals YES src/test/java/com/anhtester/listeners/TestListener.java200-202Sources: src/test/java/com/anhtester/listeners/TestListener.java190-204
Sources: src/test/java/com/anhtester/listeners/TestListener.java207-222
The onTestSuccess method src/test/java/com/anhtester/listeners/TestListener.java207-222 handles passed tests:
count_passedTCs src/test/java/com/anhtester/listeners/TestListener.java209SCREENSHOT_PASSED_TCS equals YES src/test/java/com/anhtester/listeners/TestListener.java211: CaptureHelpers.captureScreenshot() src/test/java/com/anhtester/listeners/TestListener.java212Status.PASS src/test/java/com/anhtester/listeners/TestListener.java216Sources: src/test/java/com/anhtester/listeners/TestListener.java207-222
Sources: src/test/java/com/anhtester/listeners/TestListener.java225-242
The onTestFailure method src/test/java/com/anhtester/listeners/TestListener.java225-242 handles failed tests:
count_failedTCs src/test/java/com/anhtester/listeners/TestListener.java229SCREENSHOT_FAILED_TCS equals YES src/test/java/com/anhtester/listeners/TestListener.java231: Status.FAIL src/test/java/com/anhtester/listeners/TestListener.java236Sources: src/test/java/com/anhtester/listeners/TestListener.java225-242
Sources: src/test/java/com/anhtester/listeners/TestListener.java245-258
The onTestSkipped method src/test/java/com/anhtester/listeners/TestListener.java245-258 handles skipped tests:
count_skippedTCs src/test/java/com/anhtester/listeners/TestListener.java247SCREENSHOT_SKIPPED_TCS equals YES, captures screenshot src/test/java/com/anhtester/listeners/TestListener.java249-251 (note: no ExtentReport attachment for skipped screenshots)Status.SKIP src/test/java/com/anhtester/listeners/TestListener.java253Sources: src/test/java/com/anhtester/listeners/TestListener.java245-258
The IInvokedMethodListener interface provides hooks for every method invocation, including @BeforeMethod, @AfterMethod, and @Test methods.
Sources: src/test/java/com/anhtester/listeners/TestListener.java56-65
The framework provides hooks before and after every method invocation:
beforeInvocation src/test/java/com/anhtester/listeners/TestListener.java56-59: Called before any test method or configuration method executesafterInvocation src/test/java/com/anhtester/listeners/TestListener.java62-65: Called after any test method or configuration method completesBoth methods currently contain commented-out implementations but provide extension points for method-level instrumentation. The method name can be accessed via method.getTestMethod().getMethodName().
Sources: src/test/java/com/anhtester/listeners/TestListener.java56-65
The AllureListener class implements TestLifecycleListener to integrate with Allure's reporting system, providing screenshot attachment based on test outcomes.
Sources: src/test/java/com/anhtester/listeners/AllureListener.java42-55
The AllureListener implements test lifecycle hooks src/test/java/com/anhtester/listeners/AllureListener.java15:
The beforeTestStop method src/test/java/com/anhtester/listeners/AllureListener.java42-55 conditionally attaches screenshots:
Passed Test Screenshots: If SCREENSHOT_PASSED_TCS equals YES and test status is Status.PASSED src/test/java/com/anhtester/listeners/AllureListener.java43:
{testName}_Passed_ScreenshotFailed Test Screenshots: If SCREENSHOT_FAILED_TCS equals YES and test status is Status.FAILED src/test/java/com/anhtester/listeners/AllureListener.java48:
{testName}_Failed_ScreenshotThe listener uses OutputType.BYTES to capture screenshots in memory, avoiding disk I/O for Allure attachment. Video attachment capability exists but is commented out src/test/java/com/anhtester/listeners/AllureListener.java54
Sources: src/test/java/com/anhtester/listeners/AllureListener.java42-55
The AllureListener provides stub implementations for other lifecycle events src/test/java/com/anhtester/listeners/AllureListener.java17-67:
| Method | Purpose | Implementation |
|---|---|---|
beforeTestSchedule | Before test scheduling | Empty |
afterTestSchedule | After test scheduling | Empty |
beforeTestUpdate | Before test update | Empty |
afterTestUpdate | After test update | Empty |
beforeTestStart | Before test starts | Empty |
afterTestStart | After test starts | Empty |
afterTestStop | After test stops | Empty |
beforeTestWrite | Before writing results | Empty |
afterTestWrite | After writing results | Empty |
These hooks provide extension points for future Allure integration enhancements.
Sources: src/test/java/com/anhtester/listeners/AllureListener.java17-67
The framework implements conditional screenshot and video capture based on configuration flags and test outcomes.
Sources: src/test/java/com/anhtester/listeners/TestListener.java211-213 src/test/java/com/anhtester/listeners/TestListener.java231-233 src/test/java/com/anhtester/listeners/TestListener.java249-251 src/test/java/com/anhtester/listeners/AllureListener.java43-52
The framework supports three screenshot configuration flags referenced from FrameworkConstants:
| Configuration Flag | Trigger | ExtentReport Attachment | Allure Attachment | Implementation |
|---|---|---|---|---|
SCREENSHOT_PASSED_TCS | onTestSuccess | Yes | Yes | TestListener211-213 AllureListener43-46 |
SCREENSHOT_FAILED_TCS | onTestFailure | Yes | Yes | TestListener231-233 AllureListener48-51 |
SCREENSHOT_SKIPPED_TCS | onTestSkipped | No | No | TestListener249-251 |
All flags are imported via import static com.anhtester.constants.FrameworkConstants.* src/test/java/com/anhtester/listeners/TestListener.java28 src/test/java/com/anhtester/listeners/AllureListener.java13
Sources: src/test/java/com/anhtester/listeners/TestListener.java28 src/test/java/com/anhtester/listeners/TestListener.java211-251 src/test/java/com/anhtester/listeners/AllureListener.java13 src/test/java/com/anhtester/listeners/AllureListener.java43-52
Sources: src/test/java/com/anhtester/listeners/TestListener.java200-202 src/test/java/com/anhtester/listeners/TestListener.java218-221 src/test/java/com/anhtester/listeners/TestListener.java238-241 src/test/java/com/anhtester/listeners/TestListener.java255-257
Video recording follows a start-stop pattern:
Recording Start: Initiated in onTestStart if VIDEO_RECORD equals YES src/test/java/com/anhtester/listeners/TestListener.java200-202
screenRecorder.startRecording(getTestName(iTestResult))ScreenRecorderHelpers instance created in constructor src/test/java/com/anhtester/listeners/TestListener.java39-45Recording Stop: Invoked in all outcome methods if VIDEO_RECORD equals YES:
The 2-second delay (via WebUI.sleep(2)) ensures final test state is captured before recording terminates.
Sources: src/test/java/com/anhtester/listeners/TestListener.java37 src/test/java/com/anhtester/listeners/TestListener.java39-45 src/test/java/com/anhtester/listeners/TestListener.java200-202 src/test/java/com/anhtester/listeners/TestListener.java218-221 src/test/java/com/anhtester/listeners/TestListener.java238-241 src/test/java/com/anhtester/listeners/TestListener.java255-257
The listeners coordinate with multiple reporting systems through manager classes, centralizing report generation logic.
Sources: src/test/java/com/anhtester/listeners/TestListener.java1-265
| Manager Class | Method Calls | Purpose | Invoked From |
|---|---|---|---|
ExtentReportManager | initReports() | Initialize HTML/PDF reports | onStart line 80 |
createTest(String) | Create test entry | onTestStart line 194 | |
addAuthors(AuthorType[]) | Add test authors | onTestStart line 195 | |
addCategories(CategoryType[]) | Add test categories | onTestStart line 196 | |
addDevices() | Add device info | onTestStart line 197 | |
info(String) | Log info message | onTestStart line 198 | |
addScreenShot(Status, String) | Attach screenshot | onTestSuccess line 213 onTestFailure line 233 | |
logMessage(Status, String) | Log test outcome | All outcome methods | |
flushReports() | Write reports to disk | onFinish line 90 | |
AllureManager | setAllureEnvironmentInformation() | Set environment metadata | onStart line 79 |
TelegramManager | sendReportPath() | Send Telegram notification | onFinish line 94 |
EmailSendUtils | sendEmail(int, int, int, int) | Send email summary | onFinish line 96 |
ZipUtils | zipReportFolder() | Compress report directory | onFinish line 92 |
CaptureHelpers | captureScreenshot(WebDriver, String) | Take screenshot | All outcome methods conditionally |
Sources: src/test/java/com/anhtester/listeners/TestListener.java79-80 src/test/java/com/anhtester/listeners/TestListener.java90-96 src/test/java/com/anhtester/listeners/TestListener.java194-198 src/test/java/com/anhtester/listeners/TestListener.java212-213 src/test/java/com/anhtester/listeners/TestListener.java232-233
The framework uses custom @FrameworkAnnotation to enrich reports with author and category metadata.
Sources: src/test/java/com/anhtester/listeners/TestListener.java173-187
The getAuthorType method src/test/java/com/anhtester/listeners/TestListener.java173-179 extracts author metadata:
@FrameworkAnnotation is present src/test/java/com/anhtester/listeners/TestListener.java174-176null if annotation is absentauthor() array from annotation src/test/java/com/anhtester/listeners/TestListener.java177AuthorType[] arrayThe getCategoryType method src/test/java/com/anhtester/listeners/TestListener.java181-187 extracts category metadata:
@FrameworkAnnotation is present src/test/java/com/anhtester/listeners/TestListener.java182-184null if annotation is absentcategory() array from annotation src/test/java/com/anhtester/listeners/TestListener.java185CategoryType[] arrayBoth methods use reflection to access method-level annotations via iTestResult.getMethod().getConstructorOrMethod().getMethod().
Sources: src/test/java/com/anhtester/listeners/TestListener.java173-187
The listeners depend on multiple configuration constants from FrameworkConstants to control behavior.
Sources: src/test/java/com/anhtester/listeners/TestListener.java28 src/test/java/com/anhtester/listeners/AllureListener.java13
Both listener classes import constants via static import src/test/java/com/anhtester/listeners/TestListener.java28:
This allows direct reference to constants without class prefix:
SCREENSHOT_PASSED_TCS, SCREENSHOT_FAILED_TCS, SCREENSHOT_SKIPPED_TCSVIDEO_RECORDYES (string constant for comparison)TARGET, WAIT_DEFAULT, WAIT_PAGE_LOADED, HEADLESS, REMOTE_URL, REMOTE_PORTAll screenshot and video checks compare against the YES constant src/test/java/com/anhtester/listeners/TestListener.java211 src/test/java/com/anhtester/listeners/TestListener.java231 src/test/java/com/anhtester/listeners/TestListener.java249 src/test/java/com/anhtester/listeners/TestListener.java200 src/test/java/com/anhtester/listeners/TestListener.java218 src/test/java/com/anhtester/listeners/TestListener.java238 src/test/java/com/anhtester/listeners/TestListener.java255
The AllureListener imports the same constants src/test/java/com/anhtester/listeners/AllureListener.java13 using SCREENSHOT_PASSED_TCS, SCREENSHOT_FAILED_TCS, and YES for conditional screenshot attachment src/test/java/com/anhtester/listeners/AllureListener.java43 src/test/java/com/anhtester/listeners/AllureListener.java48
Sources: src/test/java/com/anhtester/listeners/TestListener.java28 src/test/java/com/anhtester/listeners/AllureListener.java13
The TestListener provides helper methods to extract test metadata from ITestResult objects.
| Method | Purpose | Logic | Line Reference |
|---|---|---|---|
getTestName(ITestResult) | Extract test name | Returns result.getTestName() if not null, otherwise result.getMethod().getConstructorOrMethod().getName() | 47-49 |
getTestDescription(ITestResult) | Extract test description | Returns result.getMethod().getDescription() if not null, otherwise calls getTestName(result) | 51-53 |
These methods are used throughout the listener for logging and reporting:
LogUtils.info("Test case: " + getTestName(iTestResult) + " is starting...") src/test/java/com/anhtester/listeners/TestListener.java191screenRecorder.startRecording(getTestName(iTestResult)) src/test/java/com/anhtester/listeners/TestListener.java201CaptureHelpers.captureScreenshot(DriverManager.getDriver(), getTestName(iTestResult)) src/test/java/com/anhtester/listeners/TestListener.java212Sources: src/test/java/com/anhtester/listeners/TestListener.java47-53 src/test/java/com/anhtester/listeners/TestListener.java191 src/test/java/com/anhtester/listeners/TestListener.java201 src/test/java/com/anhtester/listeners/TestListener.java212
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.