Menu

Test Listeners and Event Handling

Relevant source files

Purpose and Scope

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.

Listener Architecture Overview

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.

TestListener Class Structure

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:

InterfacePurposeKey Methods
ITestListenerTest method lifecycleonTestStart, onTestSuccess, onTestFailure, onTestSkipped
ISuiteListenerSuite lifecycleonStart, onFinish
IInvokedMethodListenerAll method invocationsbeforeInvocation, afterInvocation

Listener Registration

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 Lifecycle Management

Suite-level events trigger framework-wide initialization and cleanup operations, including configuration loading, report initialization, and artifact distribution.

Suite Start Process

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:

  1. Configuration Loading: Calls PropertiesHelpers.loadAllFiles() src/test/java/com/anhtester/listeners/TestListener.java78 to load runtime settings from config.properties
  2. Allure Environment Setup: Invokes AllureManager.setAllureEnvironmentInformation() src/test/java/com/anhtester/listeners/TestListener.java79 to write environment metadata
  3. ExtentReports Initialization: Calls ExtentReportManager.initReports() src/test/java/com/anhtester/listeners/TestListener.java80 to prepare HTML/PDF report generation

Sources: src/test/java/com/anhtester/listeners/TestListener.java68-83

Suite Finish Process

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:

  1. Report Finalization: Flushes ExtentReports using ExtentReportManager.flushReports() src/test/java/com/anhtester/listeners/TestListener.java90
  2. Report Archiving: Compresses reports via ZipUtils.zipReportFolder() src/test/java/com/anhtester/listeners/TestListener.java92 if ZIP_FOLDER is enabled
  3. Telegram Notification: Sends report path through TelegramManager.sendReportPath() src/test/java/com/anhtester/listeners/TestListener.java94
  4. Email Notification: Dispatches email summary with test counters using EmailSendUtils.sendEmail() src/test/java/com/anhtester/listeners/TestListener.java96
  5. Allure Metadata: Writes environment properties using AllureEnvironmentWriter src/test/java/com/anhtester/listeners/TestListener.java99 with execution statistics
  6. Allure Configuration: Copies categories.json and executor.json to target/allure-results/ src/test/java/com/anhtester/listeners/TestListener.java102-103

The method writes comprehensive execution metadata to Allure environment properties, including:

  • TARGET (local/remote execution)
  • WAIT_DEFAULT, WAIT_PAGE_LOADED (timeout configurations)
  • HEADLESS mode
  • Browser type
  • Remote URL and port
  • Test counters: count_totalTCs, count_passedTCs, count_skippedTCs, count_failedTCs

Sources: src/test/java/com/anhtester/listeners/TestListener.java86-113

Test Lifecycle Event Handling

The framework tracks four test outcomes (start, success, failure, skip) with distinct handling for each state, including conditional screenshot capture and video recording.

Test State Counters

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:

These 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

Test Start Event

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:

  1. Counter Update: Increments count_totalTCs src/test/java/com/anhtester/listeners/TestListener.java192
  2. ExtentReport Test Creation: Creates a new ExtentTest instance via ExtentReportManager.createTest() src/test/java/com/anhtester/listeners/TestListener.java194
  3. Metadata Extraction: Retrieves @FrameworkAnnotation metadata:
  4. Device Information: Logs device and OS info src/test/java/com/anhtester/listeners/TestListener.java197-198
  5. Video Recording: Starts recording if VIDEO_RECORD equals YES src/test/java/com/anhtester/listeners/TestListener.java200-202

Sources: src/test/java/com/anhtester/listeners/TestListener.java190-204

Test Success Event

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:

  1. Counter Update: Increments count_passedTCs src/test/java/com/anhtester/listeners/TestListener.java209
  2. Conditional Screenshot: If SCREENSHOT_PASSED_TCS equals YES src/test/java/com/anhtester/listeners/TestListener.java211:
  3. Report Logging: Logs success message with Status.PASS src/test/java/com/anhtester/listeners/TestListener.java216
  4. Video Stop: Stops recording with 2-second delay if enabled src/test/java/com/anhtester/listeners/TestListener.java218-221

Sources: src/test/java/com/anhtester/listeners/TestListener.java207-222

Test Failure Event

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:

  1. Error Logging: Logs failure message and throwable src/test/java/com/anhtester/listeners/TestListener.java226-227
  2. Counter Update: Increments count_failedTCs src/test/java/com/anhtester/listeners/TestListener.java229
  3. Conditional Screenshot: If SCREENSHOT_FAILED_TCS equals YES src/test/java/com/anhtester/listeners/TestListener.java231:
  4. Failure Details: Logs throwable to ExtentReport with Status.FAIL src/test/java/com/anhtester/listeners/TestListener.java236
  5. Video Stop: Stops recording if enabled src/test/java/com/anhtester/listeners/TestListener.java238-241

Sources: src/test/java/com/anhtester/listeners/TestListener.java225-242

Test Skip Event

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:

  1. Warning Log: Logs skip warning src/test/java/com/anhtester/listeners/TestListener.java246
  2. Counter Update: Increments count_skippedTCs src/test/java/com/anhtester/listeners/TestListener.java247
  3. Conditional Screenshot: If SCREENSHOT_SKIPPED_TCS equals YES, captures screenshot src/test/java/com/anhtester/listeners/TestListener.java249-251 (note: no ExtentReport attachment for skipped screenshots)
  4. Report Logging: Logs skip message with Status.SKIP src/test/java/com/anhtester/listeners/TestListener.java253
  5. Video Stop: Stops recording if enabled src/test/java/com/anhtester/listeners/TestListener.java255-257

Sources: src/test/java/com/anhtester/listeners/TestListener.java245-258

Method Invocation Hooks

The IInvokedMethodListener interface provides hooks for every method invocation, including @BeforeMethod, @AfterMethod, and @Test methods.

Invocation Lifecycle

Sources: src/test/java/com/anhtester/listeners/TestListener.java56-65

The framework provides hooks before and after every method invocation:

Both 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

Allure Listener Integration

The AllureListener class implements TestLifecycleListener to integrate with Allure's reporting system, providing screenshot attachment based on test outcomes.

Allure Lifecycle Events

Sources: src/test/java/com/anhtester/listeners/AllureListener.java42-55

The AllureListener implements test lifecycle hooks src/test/java/com/anhtester/listeners/AllureListener.java15:

Screenshot Attachment Logic

The beforeTestStop method src/test/java/com/anhtester/listeners/AllureListener.java42-55 conditionally attaches screenshots:

  1. Passed Test Screenshots: If SCREENSHOT_PASSED_TCS equals YES and test status is Status.PASSED src/test/java/com/anhtester/listeners/AllureListener.java43:

  2. Failed Test Screenshots: If SCREENSHOT_FAILED_TCS equals YES and test status is Status.FAILED src/test/java/com/anhtester/listeners/AllureListener.java48:

The 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

Unused Lifecycle Hooks

The AllureListener provides stub implementations for other lifecycle events src/test/java/com/anhtester/listeners/AllureListener.java17-67:

MethodPurposeImplementation
beforeTestScheduleBefore test schedulingEmpty
afterTestScheduleAfter test schedulingEmpty
beforeTestUpdateBefore test updateEmpty
afterTestUpdateAfter test updateEmpty
beforeTestStartBefore test startsEmpty
afterTestStartAfter test startsEmpty
afterTestStopAfter test stopsEmpty
beforeTestWriteBefore writing resultsEmpty
afterTestWriteAfter writing resultsEmpty

These hooks provide extension points for future Allure integration enhancements.

Sources: src/test/java/com/anhtester/listeners/AllureListener.java17-67

Capture Strategy and Configuration

The framework implements conditional screenshot and video capture based on configuration flags and test outcomes.

Screenshot Capture Configuration

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 FlagTriggerExtentReport AttachmentAllure AttachmentImplementation
SCREENSHOT_PASSED_TCSonTestSuccessYesYesTestListener211-213 AllureListener43-46
SCREENSHOT_FAILED_TCSonTestFailureYesYesTestListener231-233 AllureListener48-51
SCREENSHOT_SKIPPED_TCSonTestSkippedNoNoTestListener249-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

Video Recording Strategy

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:

  1. Recording Start: Initiated in onTestStart if VIDEO_RECORD equals YES src/test/java/com/anhtester/listeners/TestListener.java200-202

  2. Recording 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

Report Manager Coordination

The listeners coordinate with multiple reporting systems through manager classes, centralizing report generation logic.

Reporting System Integration

Sources: src/test/java/com/anhtester/listeners/TestListener.java1-265

Manager Method Invocations

Manager ClassMethod CallsPurposeInvoked From
ExtentReportManagerinitReports()Initialize HTML/PDF reportsonStart line 80
createTest(String)Create test entryonTestStart line 194
addAuthors(AuthorType[])Add test authorsonTestStart line 195
addCategories(CategoryType[])Add test categoriesonTestStart line 196
addDevices()Add device infoonTestStart line 197
info(String)Log info messageonTestStart line 198
addScreenShot(Status, String)Attach screenshotonTestSuccess line 213 onTestFailure line 233
logMessage(Status, String)Log test outcomeAll outcome methods
flushReports()Write reports to diskonFinish line 90
AllureManagersetAllureEnvironmentInformation()Set environment metadataonStart line 79
TelegramManagersendReportPath()Send Telegram notificationonFinish line 94
EmailSendUtilssendEmail(int, int, int, int)Send email summaryonFinish line 96
ZipUtilszipReportFolder()Compress report directoryonFinish line 92
CaptureHelperscaptureScreenshot(WebDriver, String)Take screenshotAll 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

Annotation-Based Metadata Extraction

The framework uses custom @FrameworkAnnotation to enrich reports with author and category metadata.

Metadata Extraction Methods

Sources: src/test/java/com/anhtester/listeners/TestListener.java173-187

Author Type Extraction

The getAuthorType method src/test/java/com/anhtester/listeners/TestListener.java173-179 extracts author metadata:

  1. Checks if @FrameworkAnnotation is present src/test/java/com/anhtester/listeners/TestListener.java174-176
  2. Returns null if annotation is absent
  3. Extracts author() array from annotation src/test/java/com/anhtester/listeners/TestListener.java177
  4. Returns AuthorType[] array

Category Type Extraction

The getCategoryType method src/test/java/com/anhtester/listeners/TestListener.java181-187 extracts category metadata:

  1. Checks if @FrameworkAnnotation is present src/test/java/com/anhtester/listeners/TestListener.java182-184
  2. Returns null if annotation is absent
  3. Extracts category() array from annotation src/test/java/com/anhtester/listeners/TestListener.java185
  4. Returns CategoryType[] array

Both methods use reflection to access method-level annotations via iTestResult.getMethod().getConstructorOrMethod().getMethod().

Sources: src/test/java/com/anhtester/listeners/TestListener.java173-187

Configuration Dependencies

The listeners depend on multiple configuration constants from FrameworkConstants to control behavior.

Configuration Constant Usage

Sources: src/test/java/com/anhtester/listeners/TestListener.java28 src/test/java/com/anhtester/listeners/AllureListener.java13

Constant Import and Usage

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_TCS
  • VIDEO_RECORD
  • YES (string constant for comparison)
  • TARGET, WAIT_DEFAULT, WAIT_PAGE_LOADED, HEADLESS, REMOTE_URL, REMOTE_PORT

All 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

Utility Method Helpers

The TestListener provides helper methods to extract test metadata from ITestResult objects.

Test Name and Description Extraction

MethodPurposeLogicLine Reference
getTestName(ITestResult)Extract test nameReturns result.getTestName() if not null, otherwise result.getMethod().getConstructorOrMethod().getName()47-49
getTestDescription(ITestResult)Extract test descriptionReturns result.getMethod().getDescription() if not null, otherwise calls getTestName(result)51-53

These methods are used throughout the listener for logging and reporting:

Sources: 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