Part 2: OOPs concepts in Selenium-Java Automation Framework

Sandeep
5 min readJan 30, 2023
Photo by Nick Page on Unsplash

This medium post is the continuation of OOPs concepts in the Selenium-Java Automation Framework. You can find Part 1 here. As we have in the previous post the four pillars of OOPs are below:

  • Abstraction
  • Encapsulation
  • Inheritance
  • Polymorphism

Let us go one by one where the OOPs concept is applied in a Selenium-Java automation framework:

I. Abstraction

Abstraction is a methodology of hiding the implementation of internal details and showing the functionality to the users. In the Selenium Automation framework, the most common thing which you might have seen is the POM(Page Object Model) Design Pattern. In the POM Design pattern, each web page will have its own class and methods so the person who is writing the test script can use the methods but we can’t see the implementation by this we hide implementation details in our main test script. Considering we have a login page below is how we will write the class and utilize it for one of the test script creations:

  • Login page class
package pomPages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {

WebDriver driver;

//Constructor that will be automatically called as soon as the object of the class is created
public LoginPage(WebDriver driver) {
this.driver = driver;
}

//Locator for username field
By userName = By.id("userName");

//Locator for password field
By password = By.id("password");

//Locator for login button
By loginButton = By.id("login");


//Method to enter username
public void enterUsername(String userNameValue) {}

//Method to enter password
public void enterPassword(String passwordValue) {}

//Method to click on Login button
public void clickLoginButton() {}
}
  • Login class implementing the methods
package pomPages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

//Constructor
public class LoginPageMethods {
public LoginPageMethods(WebDriver driver) {
this.driver = driver;
}

//Method to enter username
public void enterUsername(String userNameValue) {
driver.findElement(userName).sendKeys(userNameValue);
}

//Method to enter password
public void enterPassword(String passwordValue) {
driver.findElement(password).sendKeys(passwordValue);
}

//Method to click on Login button
public void clickLoginButton() {
driver.findElement(loginButton).click();
}
}
  • The main class where we will be utilizing it
package testSuite;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import pomPages.LoginPageMethods;

@BeforeTest
// Some code to initialize driver

@Test
public class TC001_LoginTest{

public static void main(String[] args){

System.setProperty("webdriver.chrome.driver", "<Provide the path of the chrome-driver.exe in your system>");
WebDriver driver = new ChromeDriver();
driver.get("https://www.somewebsite.com");

//Creating object of Login page
LoginPageMethods login = new LoginPageMethods(driver);

//Enter username & password
login.enterUsername("<your_userName>");
login.enterPassword("<your_password>");

//Click on login button
login.clickLoginButton();

//Close browser instance
driver.quit();
}

}

II. Encapsulation

Encapsulation is the mechanism that binds together code and data it manipulates. Please take note of access modifiers in java which you can find below:

  • Private: The access is limited to the containing class. For example, a variable or a method declared as private can only be accessed by other members inside the same class.
  • Protected: The access is limited to the containing class and any types derived from this class.
  • Public: There are no restrictions, the member or type can be accessed both from inside and outside the package.

It can be useful, for example, if we want to make the fields of a class read-only or write-only.

Find an example below for encapsulation in selenium-java:

  • Login page class
package pomPages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

// THIS IS LOGIN PAGE CLASS
public class LoginPage {

private String url = "http://somewebsite.com";

@FindBy(css="span.userName")
private WebElement userName;

@FindBy(css="span.password")
private WebElement password;

@FindBy(css="span.loginButton")
private WebElement loginButton;

private WebDriver driver;

public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}

// Class getters
public WebElement getuserName() {
return userName;
}

public WebElement getPassword() {
return password;
}

public WebElement getLoginButton() {
return loginButton;
}

public String getPage() {
driver.get("url");
}

}
  • Main class
package testSuite;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import pomPages.LoginPage;

// THIS IS THE MAIN CLASS
public class TC001_LoginFlow {

private WebDriver driver;

@BeforeTest
// Some code to initialize driver

@Test
public void testLoginPage() {

// Create an instance of LoginPage class and provide the driver
LoginPage seleniumEncapPage = new LoginPage(driver);

// Open the Application Page
LoginPage.getPage();

// Ecapsulation - I am accessing private member using getter method
// Enter user name
seleniumEncapPage.getuserName().sendKeys("someUserName");

//Ecapsulation - I am accessing private member using getter method getter
//Enter password
seleniumEncapPage.getPassword().sendKeys("someUserName");

//Ecapsulation - I am accessing private member using getter method getter
//Click login button
seleniumEncapPage.getLoginButton().click();

//Verify something on HomePage
Assert.assertEquals("actual","expected");
}

@AfterTest
// Some code to close browser
} // End of method - testLoginPage
} // End of class - TC001_LoginFlow

From the above scripts you will understand that the Test script “TC001_LoginFlow” have the access to the web elements only via the methods of the “LoginPage” class.

III.Inheritance

In the previous post we have seen there are different types of inheritance which are below:

  • Single Inheritance
  • Multilevel Inheritance
  • Hierarchical Inheritance
  • Multiple Inheritance
  • Hybrid Inheritance

In the Selenium-Java framework the most common place where we can see the inheritance is in setting up the basic things like below:

  • To initialize the WebDriver interface
  • To access values from the property files

Please find the below code to get more real-time context

  • Base Class
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

public class BaseClass {

WebDriver driver;

@BeforeClass
public void setupApplication() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("<your_website>");
}

@AfterClass
public void closeApplication() {
driver.quit();
}
}
  • The main class which inherits the base class
import org.openqa.selenium.By;
import org.testng.annotations.Test;

public class loginScenario extends BaseClass {

@Test(description = "Valid login scenario")
public void loginToApp() {
driver.findElement(By.name("txtUsername")).sendKeys("admin1");
driver.findElement(By.id("txtPassword")).sendKeys("password@123");
driver.findElement(By.id("btnLogin")).click();
}

}

So here we can see how we can inherit one class into another class in Selenium. One of the main advantages of doing this is we can avoid a good amount of code duplication.

IV. Polymorphism

As we have seen in the previous post there are two types of polymorphism which are as below:

  • Compile-time polymorphism(static polymorphism)
  • Runtime polymorphism(dynamic polymorphism)

Now let us see one real-time implementation of Polymorphism in the Selenium-Java framework. One of the places that it can utilize is the common utility classes where we will be having multiple common methods. Please find one such example where you might have to select an element based on the index or the text of the string:

public class CommonMethods
{
Select list;

public void listDetails(Select listOfElements)
{
this.list = list;
}

//Common method for selecting the element by the index of the WebElement
public void selectByIndex(int indexOfTheElement)
{
this.list.selectByIndex(indexOfTheElement);
}

//Common method for selecting the element by the text of the WebElement
public void select(String textOfTheElement)
{
this.list.selectByVisibleText(textOfTheElement);
}
}

That’s All Folks. Happy coding 😃!!

All references:

  1. https://www.tutorialspoint.com/how-to-use-select-list-in-selenium
  2. https://chercher.tech/java/polymorphism-selenium-java
  3. https://www.javatpoint.com/

--

--