How to Build a Selenium UI Testing Framework
Abubakkar Sithik
Posted on June 12, 2023
Selenium UI Testing Automation Framework
I recently created a Selenium UI testing automation framework for a sample flight/hotel booking website. The framework is based on the PageFactory and Fluent Interface patterns, and it uses Selenium, TestNG, and Extent Reports.
The framework is designed to be easy to use and maintain. It includes a set of page classes that represent the different pages of the website, as well as a set of test classes that exercise the page classes. The test classes are written using the Fluent Interface pattern, which makes them more readable and maintainable.
The framework also includes a report generator that creates interactive and detailed reports for the test results. The reports include information such as the test name, the test status, and the test steps.
This framework can be used for UI automation testing of any web application. I am confident that it will be a valuable tool for other developers as well.
Framework Details
Test Application
For this framework, I used ClearTrip as the sample flight/hotel booking website.
Framework - What and Why?
A framework is a pre-existing codebase that provides common functionalities and solves basic tasks for software requirements. By building on top of a framework, developers can focus on solving specific requirements without reinventing the wheel. The chosen framework serves as the foundation for implementing the software requirements specific to the project.
Project Structure
The project follows a standard directory structure. The page classes and related files are located in the src/main/java/com/cleartrip/casestudy
path, while the test classes and related files can be found in the src/test/java/com/cleartrip/casestudy
path. This separation allows for better organization and maintainability.
Key features of the framework:
- Page classes for each page under test, utilizing the PageFactory model to find and initialize web elements.
- Test classes that create instances of the page classes to access their methods, decoupling tests from the page elements.
- Static instantiation of the WebDriver to ensure only one instance is shared across all test classes.
- Relevant dependencies and plugins defined in the
pom.xml
file.
Packages
Main Package
The
src/main/java/
package contains the core framework code. All the page classes and related files are located in this main package. Detailed documentation can be found in the Javadoc at<working-dir>/doc/index.html
.
Test Package
The
src/test/java/
package contains the actual test classes. The subpackagecom.cleartrip.casestudy.tests
holds all the TestNG test classes related to the ClearTrip application. The Javadoc for these test classes can be found at<working-dir>/doc/com/cleartrip/casestudy/tests/package-summary.html
.
Reports
With the Extent library, we can generate interactive and detailed reports for our UI test results. The test reports can be found at
workingDir/ExtentReports/ExtentReportResults.html
.
Installation
To set up and run the UI automation framework on your local system, follow these steps:
Steps to follow to set up Selenium in the local system:
1. Install Java:
- Check if Java is already installed by running
java -version
andjavac -version
in the terminal. - If Java is not installed or an outdated version is present, install the latest Java Development Kit (JDK).
2. Install Eclipse or any other latest IDE:
- Download the Eclipse installer and run it.
- Select the option to install Eclipse for Java developers.
- Open the Eclipse workbench.
3. Get the Codebase:
- Clone the
selenium-pom-factory-fluent-pattern
repository from GitHub.
4. Set up the Project in Eclipse:
- Open Eclipse and go to
File -> Open Project from File System
. - Browse the cloned project folder and open it.
- Install the TestNG plugin for Eclipse by going to
Help -> Eclipse Marketplace
-> search for TestNG and Install it and Restart Eclipse after the installation. - The Maven plugin should be available by default. To verify, right-click on the project and check if there is an option called "Maven".
Possible issues:
- If there is an error in the
pom.xml
file, try the following steps:- Open the terminal and navigate to
Users/<profile_name>/.m2
. - Run
rm -r repository
. - Right-click on the project and select "Update project".
- Open the terminal and navigate to
- If there are errors in all import statements, try the following steps:
- Click on the
src/main/java
folder, go toBuild Path
, and remove it from the build path. - Click on
src -> main -> java
, right-click, go toBuild Path
, and select "Use as Source Folder". - Refresh the project.
- Click on the
5. Set up verification:
- In the test package, right-click on any Java file and select "Run As TestNG Test".
Simple Example Test
Let's get started with a simple example of creating a test for flight booking using the page factory/fluent interface pattern.
Test Steps:
- Go to www.cleartrip.com.
- Select the trip type (One Way Trip).
- Select the origin (Bangalore).
- Select the destination (Delhi).
- Select a date (Any random date).
- Click on the "Search" button.
Refer to the image below to understand the page classes and test classes for different application pages:
Step 1: Create a Page Class
We need to create page objects for all the implemented pages in the ClearTrip site: HomePage.java
, FlightResultsPage.java
, HotelResultsPage.java
, HotelsPage.java
, and SignInPopup.java
. These page classes will be used in the test classes to perform actions and assertions.
Let's consider the following scenario: On the home page, the user selects the flight booking option, enters valid details, and clicks the search button, which redirects them to the flight results page.
Example page class for the Home page (HomePage.java
):
public class HomePage {
private WebDriver driver;
private WebDriverWait wait;
@FindBy(xpath = "//nav[@class='row fieldRow tripType']")
private WebElement tripType;
@FindBy(id = "FromTag")
private WebElement origin;
// Other web elements and methods...
public HomePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
wait = new WebDriverWait(driver, WaitTimes.TIME_5_SECONDS.getWaitTime());
}
// Methods for interacting with the elements and performing actions on the Home page...
/**
* This method launches the home page
*/
public HomePage launch() {
driver.get("https://www.cleartrip.com/");
return this;
}
/**
* This method selects the trip type
*
* @param tripTypeOption Value of Trip Type
*/
public HomePage selectTripType(String tripTypeOption) {
tripType.findElement(By.xpath("//input[@value='" + tripTypeOption + "']")).click();
return this;
}
/**
* This method selects the place of origin
*
* @param origin Value of Origin
*/
public HomePage selectOrigin(String origin) {
this.origin.clear();
this.origin.sendKeys(origin);
wait.until(ExpectedConditions.visibilityOfAllElements(originOptions));
originOptions.get(Indices.INDEX_0.getIndexValue()).click();
return this;
}
/**
* This method clicks on the search button after
*/
public FlightResultsPage clickSearchButton() {
searchButton.click();
return new FlightResultsPage(driver);
}
/**
* This method clicks on the "Hotels" link in the home page
*/
public HotelsPage clickHotelsLink() {
hotelLink.click();
return new HotelsPage(driver);
}
/**
* This method clicks on the SignIn option which appears after clicking the "Your Trips" options
*/
public SignInPopup clickSignInOption() {
signIn.click();
return new SignInPopup(driver);
}
}
In the above example, we have created a page class for the ClearTrip Home page. It contains the necessary web elements and action methods associated with the Home page, initialized using the PageFactory model.
Please note that this is just an example, and you'll need to create similar page classes for other pages in the application.
Step 2: Create a TestBase Class
Create a Base Test Class which is extended in all the Test Classes. So The WebDriver is instantiated in such a way that it is static and only one instance will be created and shared across all the test classes. The Driver will only quit once all the tests are done.
TestBase.java
/**
* Base Test Class which is extended Test Classes
*/
public abstract class TestBase {
/**
* Static WebDriver Instance
*/
protected static WebDriver driver;
public WebDriver getDriver() {
return driver;
}
/**
* Suite level setup method where the static instance of the WebDriver is instantiated
*/
@BeforeSuite
public static void initDriver() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
ChromeOptions options = new ChromeOptions();
// The following statement sets the argument to disable notification in chrome when executing the tests
options.addArguments("--disable-notifications");
driver = new ChromeDriver(options);
driver.manage().window().maximize();
}
/**
* Suite level tear-down method to quit the WebDriver instance
*/
@AfterSuite
public void quitDriver() {
driver.quit();
}
}
Step 3: Create a Test Class
In test class, instances of the page classes will be created to access methods in the page classes. Thus, tests are decoupled from the pages/ elements under test. This makes the framework more maintainable.
So in this
FlightBookingTest
class we have to create the objects of HomePage, FlightResultsPage to access the methods available in those pages.
FlightBookingTest.java
/**
* Class containing test for validating search-flight results
*/
public class FlightBookingTest extends TestBase {
/**
* Instance of HomePage class
*/
private HomePage homePage;
/**
* Instance of FlightResultsPage class
*/
private FlightResultsPage flightResultsPage;
/**
* Class level test-Setup method that intantiates {@link HomePage} and {@link FlightResultsPage}
*/
@BeforeClass
public void testClasSetup() {
homePage = new HomePage(driver);
flightResultsPage = new FlightResultsPage(driver);
}
/**
* Test method for verifying whether search summary is rightly displayed when searching for flights
*/
@Test
public void testThatResultsAppearForAOneWayJourney(Method method) {
ExtentTestManager.startTest(method.getName(), "Test method for verifying whether search summary is rightly displayed when searching for flights");
ExtentTestManager.getTest().log(LogStatus.INFO, "Launching the browser");
homePage.launch()
.selectTripType(TripTypes.ONE_WAY.getTripType())
.selectOrigin(Cities.BANGALORE.getCity())
.selectDestination(Cities.Delhi.getCity())
.selectDate()
.clickSearchButton();
ExtentTestManager.getTest().log(LogStatus.INFO, "Asserting flight search summary details");
Assert.assertTrue(
flightResultsPage.isSearchSummaryAvailable(),
"Search Summary is not available after clicking the Search Button when searching for flights");
}
}
In the above example, we create a test class FlightBookingTest
that uses the HomePage
page class to perform actions on the ClearTrip website's Home page and then asserts or performs further actions on the Flight Results page.
Step 4: Run the Test
To run the test, right-click on the test class FlightBookingTest
and select "Run As TestNG Test". This will execute the test steps and display the test results in the console.
Extent HTML report
Test Reports can be found in
workingDir/ExtentReports/ExtentReportResults.html
Test Summary
Specific Test details
Conclusion
The framework provides an oranized structure for creating page classes, test classes, and generating interactive test reports using Extent Reports.
By following the installation steps and the provided example, you can set up the framework on your local system and start creating UI automation tests for web applications.
For a more detailed understanding of each component and the complete source code, please refer to the GitHub repository.
Posted on June 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.