Some tips for creating page object classes for a healthy person

4 min


Hello again. In anticipation of the start of the course “Java QA Engineer” prepared a translation of another useful article.


This is the beginning of the new year, and many people around the world decide to pay more attention to their health. It’s fine! In fact, your tests for the frontend also need such a solution.

The most popular design pattern used in web UI testing codebases is the Page Object Model (POM) pattern. This pattern involves class modeling to represent one page of the system under test. Based on this model, the class will contain properties that represent user interface page elements and methods that interact with these elements.

Taking this login page for our application as an example, let’s discuss tips for creating a class using POM.

CLASS

We create the only class in our automation environment to represent this page. It is recommended that you ensure that the class name matches the page in the application so that other developers can quickly find the class associated with this user interface page.

So, in this example, we will create a class called LoginPage.

public class LoginPage {
    
    private WebDriver driver;
 
    public LoginPage(WebDriver driver){
        this.driver = driver;
    }
}

PROPERTIES

LoginPage should contain properties for each of the elements on the page that will be used in your tests. The values ​​of these properties are pointers to elements on a real page. By defining these locators in one place, you will not need to hardcode them in every place where you use them – thus eliminating duplication.

private By usernameField        = By.id("username");
private By passwordField        = By.id("password");
private By signInButton     	= By.id("log-in");
private By rememberMeCheckbox   = By.id("rememberMe");
private By twitterIcon          = By.id("twitterIcon");
private By facebookIcon     	= By.id("fbIcon");
private By linkedInIcon     	= By.id("linkedInIcon");
private By errorMessage     	= By.id("alert");

METHODS

In addition to properties, the class should also contain methods that allow the test to interact with the application, such as filling in input fields and clicking buttons. Here are some tips for developing these methods for optimal use in your tests.

ADD GETTERS AND SETTERS

The purpose of POM classes is to set (set) and get (get) the state of your application. So you will need the appropriate methods for this.

For example, we definitely need to set the username and password fields, so we need to add setters for them.

public void setUsername(String username) {
    driver.findElement(usernameField).sendKeys(username);
}
 
public void setPassword(String password) {
    driver.findElement(passwordField).sendKeys(password);
}
public String getErrorMessage() {
    return driver.findElement(errorMessage).getText();
}

ADD ONLY WHAT YOU NEED AT THE PRESENT

Please note that we did not add getters and setters for each field, because we do not need them in our tests. Add only what you need at the moment. You can always add more if needed for a new test. This eliminates the need to maintain unused code.

TRANSITIONS SHOULD RETURN NEW OBJECTS

You will also need methods for clicking buttons and links. However, when your click leads to a page change, your method should return a handle to the class that represents the user interface page that you clicked on.

For example, if pressing the login button leads to the main page of your application, then your method should return a handle to the class representing this main page.

public HomePage clickSignInButton() {
    driver.findElement(signInButton).click();
    return new HomePage();
}

Thanks to the support of this recommendation, all calling tests will know that a transition will occur when this method is called, and the test has a handle to the required object to continue interacting with the application.

DO NOT BE AFRAID TO CREATE METHODS FOR COMFORT
Right now, to enter the application you need to call at least three methods (setUsername, setPassword and clickSignInButton) Since they are commonly used together, it makes sense to provide a convenient login method in your class so that your tests can only call one method.

public HomePage login(String username, String password) {
    setUsername(username);
    setPassword(password);
    return clickSignInButton();
}

Note that we did not implement the logic in this method, but instead just called individual methods. It is important that these methods are available separately so that they can be used in negative testing (for example, set a username, but not a password).

LEARN CONDITIONS

For checkbox elements (or other switches), a simple click on them may not correspond to the desired design of the test. For example, what if your test wants the checkbox to be installed, but it is already installed? Calling the click method in this case will give you the opposite result. Instead, make your method more complex by introducing logic that will only check if the user needs this result. To do this, instead of a blind click, accept an argument that indicates the intention (i.e., we need it to be selected or not) and act accordingly.

public boolean isRememberUsernameChecked() {
    return driver.findElement(rememberMeCheckbox).isSelected();
}
 
public void setRememberUsername(boolean checkIt) {
    boolean alreadySelected = isRememberUsernameChecked();
 
    //прожимается, только если цель теста не соответствует текущему состоянию 
    if( (checkIt && !alreadySelected) || (!checkIt && alreadySelected) ) {
        driver.findElement(rememberMeCheckbox).click();
    }
}

KEEP NEUTRALITY POM CLASSES

Your POM class must be a neutral object that interacts and collects information about your application. Try to keep your methods neutral and make sure they are versatile enough to be used in any test that wants to interact with the page. This means that these methods should not include statements.

For example, what if our method, which receives the error message, also fails the test, if the message is visible?

//Так не надо делать. Не используйте это
public String getErrorMessage() {
    String message = driver.findElement(errorMessage).getText();
    if(message.isDisplayed()){
        assert.fail(message);
    }
    return message;
}

I cannot reuse this method for tests in which I want to make sure that an error message is displayed if the username or password is incorrect or not specified. This is because the POM class took on the task of determining that displaying the error message is an error; while in these cases this is not so. Instead, simply return the state and let the test determine what it means.

public String getErrorMessage() {
    return driver.findElement(errorMessage).getText();
}

HEALTHY CODE PRECEDES HEALTHY TESTS

These tips should help you develop good workable classes that implement the Page Object Model design pattern. Using this pattern facilitates the separation of powers (e.g., tests and state management), reduces code duplication, and provides reusable methods. Have a nice test!

We invite everyone to free webinarin which you will learn all the details about the course. We will also take up the practice and collect the plug for the third system from our tools and talk about how to adapt it for testing purposes.


0 Comments

Leave a Reply