Selenium Page Object Model
Writing locators directly inside every test method creates duplicate code. When a website changes one button's ID, a tester must fix that locator in twenty different test files. Page Object Model, known as POM, stores each page's locators and actions in one dedicated class, so updates happen in a single place.
Diagram: Test Files Versus Page Classes
Without POM: Test1 -> [locator A][locator B] Test2 -> [locator A][locator B] Test3 -> [locator A][locator B] (locator A repeated everywhere) With POM: LoginPage class -> [locator A][locator B] Test1 -> uses LoginPage Test2 -> uses LoginPage Test3 -> uses LoginPage (locator A defined once)
Creating A Page Class
public class LoginPage {
WebDriver driver;
By emailField = By.id("email");
By passwordField = By.id("password");
By loginButton = By.id("login-btn");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void enterEmail(String email) {
driver.findElement(emailField).sendKeys(email);
}
public void enterPassword(String password) {
driver.findElement(passwordField).sendKeys(password);
}
public void clickLogin() {
driver.findElement(loginButton).click();
}
}
This class holds every locator and action related to the login page in one organized file.
Using The Page Class Inside A Test
@Test
public void testLogin() {
driver.get("https://www.estudy247.com/login");
LoginPage loginPage = new LoginPage(driver);
loginPage.enterEmail("student@estudy247.com");
loginPage.enterPassword("mypassword");
loginPage.clickLogin();
}
The test method reads like plain instructions, hiding the technical locator details inside the LoginPage class.
PageFactory And @FindBy
Selenium offers PageFactory, an alternate way to build page classes using annotations instead of manual findElement() calls.
public class LoginPage {
WebDriver driver;
@FindBy(id = "email")
WebElement emailField;
@FindBy(id = "password")
WebElement passwordField;
@FindBy(id = "login-btn")
WebElement loginButton;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void login(String email, String password) {
emailField.sendKeys(email);
passwordField.sendKeys(password);
loginButton.click();
}
}
PageFactory.initElements() connects each @FindBy annotation to its matching WebElement automatically when the class loads.
Benefits Of Page Object Model
- One locator change fixes every test that touches that page.
- Test methods stay short and read like plain business steps.
- New team members understand test logic faster since technical details stay separate.
Practical Example
A course website has Login, Checkout, and Dashboard pages. Building three page classes, one per page, lets a team write CheckoutPage.addCourseToCart() and DashboardPage.verifyEnrollment() as simple method calls, keeping the actual test scripts focused purely on business flow.
