An Overview of Selenium Framework Architecture

Table of contents
- Overview of the Framework Flow
- 1. Test Cases: The Heart of Execution
- 2. Page Objects: Source of Locators
- 3. Abstract Component: Reusable Methods for Pages
- 4. Base Test: Reusable Setup Code for Test Cases
- 5. Test Data: Provided from JSON Files
- 6. Reporting and Screenshots: Handled by Listeners
- 7. Retry Mechanism: Retry Listener
- 8. XML Files: The Test Runners
- 9. POM.xml and Maven: The Entry Point
- 10. Execution Flow: Bringing it All Together
- 11. Advanced Concepts
- Final Thoughts

If you want to deeply understand how a real-world Selenium framework works, this guide is for you. We’re going to walk through a complete framework architecture and explain every part of it clearly, step-by-step.
This architecture is based on a modular, maintainable, and scalable design pattern that many real-time projects follow. It's also perfect to draw and explain during interviews!
Overview of the Framework Flow
At a high level, this is how the framework works:
Test cases execute test steps.
Test steps interact with web elements via locators.
Locators are stored in Page Objects.
Reusable methods are centralized in an Abstract Component.
Test cases are managed and configured via XML files.
Data for test execution comes from JSON files.
Reporting and screenshots are handled via Listeners.
The entire setup is executed via Maven commands using the
pom.xml
.
Let’s break down each part one by one.
1. Test Cases: The Heart of Execution
At the center of your framework are the test cases. Each test case contains the steps needed to validate specific scenarios in your application.
Example test cases:
TestCase1
TestCase2
TestCase3
But these test steps need locators. So, where do the locators come from?
2. Page Objects: Source of Locators
All the locators (like buttons, inputs, links, etc.) that your test cases use are stored in Page Object classes.
If your application has 10 pages, you will have 10 corresponding page object classes - one for each page.
Example:
LoginPage.java
ProductPage.java
CartPage.java
Each page class holds the element locators and page-level methods. The test cases access elements through these classes, following the Page Object Model (POM) design pattern.
3. Abstract Component: Reusable Methods for Pages
Some methods are common across multiple pages - for example:
Waiting for elements
Navigating to the cart
Handling headers/footers
Instead of duplicating these methods in every page class, we create a common abstract class, usually named something like AbstractComponent.java
.
How it works:
All Page Object classes extend this abstract class.
Shared utilities (e.g., waits, navigations) live in
AbstractComponent
.This promotes code reusability and keeps the code DRY (Don’t Repeat Yourself).
4. Base Test: Reusable Setup Code for Test Cases
Just like page objects have reusable utilities, test cases also need common code, such as:
Opening the browser
Closing the browser
Choosing which browser to run
All this setup and teardown logic is moved into a Base Test class (e.g., BaseTest.java
).
Key point:
All test classes extend the BaseTest
class to inherit browser and environment setup code.
So,
Page Object classes ⟶ extend
AbstractComponent
Test classes ⟶ extend
BaseTest
5. Test Data: Provided from JSON Files
Your test cases need input data. Instead of hardcoding this, we externalize it using JSON files.
How it works:
JSON files hold test data (like usernames, product names, etc.).
In the
BaseTest
, a parser method (likegetDataToJson()
) reads the JSON file.This method converts the data into a HashMap.
A DataProvider uses this HashMap to supply data to each test.
This way, your data is separated from your tests, supporting data-driven testing.
6. Reporting and Screenshots: Handled by Listeners
For tracking results and failures, we use TestNG Listeners.
Listeners perform actions before and after each test:
Create entries in the Extent HTML Report
Take screenshots on failure
Log test status (pass/fail)
Flow:
Test starts → Listener creates an Extent Report entry.
Test executes.
Test ends → Listener updates the report with pass/fail status and screenshot.
This improves visibility and debugging by generating beautiful HTML reports.
7. Retry Mechanism: Retry Listener
Sometimes tests fail due to flakiness (like timing issues). To handle this, we use a Retry Listener.
It automatically reruns failed tests based on configuration, improving reliability in CI pipelines.
This is also part of the listener setup and helps reduce false negatives in reports.
8. XML Files: The Test Runners
The execution of tests is triggered through TestNG XML files. These XML files decide:
Which test classes to run
In what order
With what groups or parameters
Example:
testng-smoke.xml
testng-regression.xml
9. POM.xml and Maven: The Entry Point
Tests are triggered using Maven commands via the terminal.
Flow:
You run a Maven command.
It reads the
pom.xml
file.Inside
pom.xml
, we define profiles for different TestNG XMLs.Based on the profile, the corresponding TestNG XML is triggered.
That XML file runs the listed test cases.
10. Execution Flow: Bringing it All Together
Let’s visualize how everything flows:
You run a Maven command.
Maven checks
pom.xml
and chooses the correct TestNG XML.TestNG XML specifies the test cases to run.
Test cases:
Use BaseTest to set up browser
Get data from JSON via
getDataToJson()
parserUse Page Objects for UI interaction
Page Objects access AbstractComponent for reusable actions.
Listeners capture reports/screenshots.
Final Extent HTML Report is generated.
11. Advanced Concepts
To further strengthen your framework, mention the following advanced features:
Inheritance and Interfaces
Page classes extend
AbstractComponent
Test classes extend
BaseTest
Interface implementations are used for abstraction and modularity
Thread Local Group for Parallel Execution
Inside listeners, we use ThreadLocal to maintain thread safety.
This allows parallel test execution without conflict.
Cucumber Integration (Optional Layer)
If you're using Cucumber, your framework may also have:
Feature files
Step Definitions
These can act as a wrapper over the test cases for BDD-style scenarios.
Final Thoughts
This framework (check out the previous blogs for complete framework design) is designed using best practices in test automation:
Follows the Page Object Model
Promotes code reuse with inheritance
Supports data-driven testing with JSON
Generates professional HTML reports
Handles failures with retry and screenshots
Enables parallel execution with
ThreadLocal
Subscribe to my newsletter
Read articles from Samiksha Kute directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Samiksha Kute
Samiksha Kute
Passionate Learner!