Page Object Model
Page Object Model
separation of test logic from the user interface (UI) elements. It helps in maintaining the test
scripts by creating Page Objects—separate classes that represent web pages or components
of the application under test.
1. Test Case Separation: Each web page or section of the application has its own class,
which contains methods representing actions on that page, such as logging in,
searching, etc.
2. Locator Management: Web elements (locators) for interacting with the page are
stored in these separate classes, keeping the test cases clean and easier to maintain.
3. Reusability: Test cases can reuse methods from these page objects, making the code
more modular and reducing redundancy.
4. Maintainability: When the UI changes (e.g., if a locator changes), only the page
object needs to be updated, not every test case that uses that page.
When we do not follow POM, test cases are written directly with locators and actions. Here's
an example of how test cases can become repetitive:
In each test case, you are directly writing the steps to locate and interact with the Login
page elements (like username, password, and login button).
• Each test case (Test Case 1, Test Case 2, Test Case 3) needs to locate and perform the
login operation separately. This results in duplicate code in each of the test cases.
For example:
• When the UI changes (like if the login button's ID changes), you'll need to go and
update the locator in each test case.
o If you miss updating one test case, it will fail due to the outdated locator.
For example:
• Now, you need to manually go into Test Case 1, Test Case 2, and Test Case 3 to
update the locator.
• If you forget to update the locator in one of the test cases, it will cause that test to
fail.
Problem 2: Upgradation
If the login page changes (e.g., the login button's ID or class is updated), you must update
every test case that uses that locator. This creates a high maintenance burden. The code
duplication means that every time there’s a change, you have to check each test case to
ensure the locators are updated correctly.
driver.findElement(By.xpath("//input[@placeholder='Username']")).sendKeys("username");
driver.findElement(By.xpath("//input[@placeholder='Password']")).sendKeys("password");
driver.findElement(By.xpath("//button[@type='submit']")).click();
driver.findElement(By.xpath("//input[@placeholder='Username']")).sendKeys("username");
driver.findElement(By.xpath("//input[@placeholder='Password']")).sendKeys("password");
driver.findElement(By.xpath("//button[@type='submit']")).click();
driver.findElement(By.xpath("//input[@placeholder='Search']")).sendKeys("item");
driver.findElement(By.xpath("//button[@type='submit']")).click();
driver.findElement(By.xpath("//input[@placeholder='Username']")).sendKeys("username");
driver.findElement(By.xpath("//input[@placeholder='Password']")).sendKeys("password");
driver.findElement(By.xpath("//button[@type='submit']")).click();
driver.findElement(By.xpath("//input[@placeholder='Search']")).sendKeys("item");
driver.findElement(By.xpath("//button[@type='submit']")).click();
driver.findElement(By.xpath("//button[@type='advancedSearch']")).click();
• Each page has its own class, and test cases call methods from these page classes.
• The login actions, for example, are encapsulated in the LoginPage class.
2. Locator Management:
• The locators for UI elements are stored within the page class (e.g., LoginPage), not
within the test cases.
• Test cases simply call the methods defined in the page object to perform actions.
3. Reusability:
• Once the login logic is defined in the LoginPage class, it can be reused across all test
cases that require login.
• This avoids the need to repeat the same code in each test case.
4. Maintainability:
• If a UI element changes (e.g., the login button's locator changes), we only need to
update it in the LoginPage class.
• The LoginPage class defines locators using By (for username, password, and login
button).
The PageFactory class in Selenium simplifies the process of initializing web elements using
annotations. It reduces boilerplate code and automatically initializes elements when the
page object is created, making the code cleaner and more maintainable.
package tests;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import pages.LoginPage;
driver.get("https://yourwebsite.com/login");
loginPage.setUsername("username");
loginPage.setPassword("password");
loginPage.clickLoginButton();
driver.quit();
Both approaches help in applying the Page Object Model design pattern effectively in
Selenium, but PageFactory provides a more streamlined and automated approach for
element initialization, reducing the amount of code needed to interact with web elements.
package pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
public class loginpage {
private WebDriver driver;
private FluentWait<WebDriver> wait;
// Constructor
public loginpage(WebDriver driver, FluentWait<WebDriver> wait) {
this.driver = driver;
this.wait = wait;
}
// Locators
private By txt_username_loc = By.xpath("//input[@placeholder='Username']");
private By txt_password_loc = By.xpath("//input[@placeholder='Password']");
private By btn_login_loc = By.xpath("//button[@type='submit']");
// Methods
public void setUsername(String username) {
wait.until(ExpectedConditions.visibilityOfElementLocated(txt_username_loc)).sendKeys(user
name);
}
public void setPassword(String password) {
wait.until(ExpectedConditions.visibilityOfElementLocated(txt_password_loc)).sendKeys(pass
word);
}
public void clickLoginButton() {
wait.until(ExpectedConditions.elementToBeClickable(btn_login_loc)).click();
}
}
Test
package pages;
import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.testng.Assert;
public class LoginTest {
public static void main(String[] args) {
WebDriver driver=null ;
try {
driver.manage().window().maximize();
.withTimeout(Duration.ofSeconds(20))
.pollingEvery(Duration.ofMillis(1000))
.ignoring(Exception.class);
driver.get("https://opensourcedemo.orangehrmlive.com/web/index.php/auth/login");
// Step 6: Check if the login was successful by verifying the page title
Assert.assertEquals(driver.getTitle(), "OrangeHRM");
} catch (Exception e) {
} finally {
if (driver != null) {
driver.quit();
}}