Let’s say that you want to automate test scenarios for the login page of a web site.
The login page has 3 elements:
– username textbox
– password textbox
– sign in button
Some of the test cases to be automated for this page are
- user can sign in with correct username and password
- user cannot sign in if username or password are incorrect
- password is masked
- user can create a new account
In this article, we will focus on the first test case only.
Since the test cases uses 2 pages (login page and the page the user sees after a successful sign in), we will need 2 page object classes:
- LoginPage class
- MainPage class
One way of implementing the LoginPage.java class is
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
private By userNameLocator = By.id("userNameId");
private By passwordLocator = By.id("passwordId");
private By signInLocator = By.id("signInId");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, 30);
}
public void clickUserName() {
WebElement userName = findElement(userNameLocator);
userName.click();
}
public void clickPassword() {
WebElement password = findElement(passwordLocator);
password.click();
}
public void clickSignIn() {
WebElement signIn = findElement(signInLocator);
signIn.click();
}
public void typeUserName(String value) {
WebElement userName = findElement(userNameLocator);
userName.sendKeys(value);
}
public void typePassword(String value) {
WebElement password = findElement
(passwordLocator);
password.sendKeys(value);
}
private WebElement findElement(By locator) {
return
wait.until(visibilityOfElementLocated(locator));
}
The LoginPage class has multiple methods for clicking elements and typing text into them.
Using this LoginPage class, we can now build a test script (JUNIT):
@Test
public void testSuccessfullLogin() {
LoginPage loginPage = new LoginPage(driver);
loginPage.clickUserName();
loginPage.typeUserName("admin");
loginPage.clickPassword();
loginPage.typePassword("abcdef");
loginPage.clickSignIn();
MainPage mainPage = new MainPage(driver);
assertTrue(mainPage.isDisplayed() == true);
}
Building a page object class like this is not correct.
It is not correct because what we do is creating an API that interacts with HTML elements.
For a page that has only 3 elements, we have 5 methods.
Imagine how many methods you will need for a page with 100 elements.
The correct approach for page object classes is explained in the following link:
https://martinfowler.com/bliki/PageObject.html
We should not create page object classes and APIs that interact with HTML elements.
Instead, we should create page classes and APIs that interacts with the site similar with how a user does it.
See below the LoginPage class changed to interact with the site:
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
private By userNameLocator = By.id("userNameId");
private By passwordLocator = By.id("passwordId");
private By signInLocator = By.id("signInId");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, 30);
}
public void signInWith(String userName, String password) {
WebElement userName = findElement(userNameLocator);
userName.click();
userName.sendKeys(value);
WebElement password = findElement(passwordLocator);
password.click();
password.sendKeys(value);
WebElement signIn = findElement(signInLocator);
signIn.click();
}
private WebElement findElement(By locator) {
return
wait.until(visibilityOfElementLocated(locator));
}
}
The class has now 1 method only instead of 5.
This method is about interacting with the site like a user by signing in.
Using the LoginPage class, the test script becomes
@Test
public void testSuccessfullLogin() {
LoginPage loginPage = new LoginPage(driver);
loginPage.signInWith("admin", "abcdef");
MainPage mainPage = new MainPage(driver);
assertTrue(mainPage.isDisplayed() == true);
}
The test script is significantly shorter now.
It also looks like English and is similar to a test case.
We should always aim to
- making the test scripts as short as possible
- moving code from the test script to the page object class
- not using any webdriver object or method in the test scripts
- use only page objects and page methods in the test scripts
- not creating any methods that interact with an element in the page object classes
- keep page object classes short (less than 250 lines of code)
- do not create methods that include in their names the following words: click, type, getText, etc as these are most probably interacting with single elements
[…] Correct and incorrect ways of creating page object classes – Alex Siminuic – https://seleniumjava.com/2017/05/20/correct-and-incorrect-ways-of-creating-page-object-classes/ […]
LikeLike
driver.findElement(” “); //driver is missing.. am i correct?
LikeLike