Blog

All articles

PageObjects Pattern in Automated Testing

PageObjects Pattern in Automated Testing

Let’s talk about automated tests or, to be more exact, about аutomated testing frameworks.  And to be even more exact, let’s discuss one of the most widely known automated testing approaches applied in automated GUI testing: PageObjects pattern.

About the Pattern

There exist an abstract superclass Page, implementing a set of principal methods similar for all the pages of the tested application (for example, logout), as well as abstract initialization and data collection methods, applied when important data are collected from а page and the appropriate method is called from inside the constructor.

public abstract class Page {

protected Page() {

   init();

   parsePage();

}

protected abstract void init();

protected abstract void parsePage();

// ....

// service methods...

// ....

}

Further on, all the classes of real pages inherit the superclass Page, implement abstract methods and add their own ones for the functions performed on the page in question. Herein methods of interaction with illogical control elements are described as private void, whereas methods performing the actions of the user, opening a new or updating an existing page are described as public with the return of the expected object (public HomePage).

As a result, when creating a page object the page is initialized and parsed to make sure that all the necessary data are collected and the currently opened page is the correct one, in other words, that the object may be used.

Example:

The Login Portal page includes a Login button and two entry fields, the User field and the Password field.

How will the PageObject look like?

public class LoginPortalPage extends Page {

protected LoginPortalPage() {

   super();

}

private void setUserName(String userName) {

  // Entry field code (Username)

}

private void setPassword(String password) {

  // Entry field code (Password)

}

private void pushLoginButton() {

  // Button push code (Login)

}

protected void parsePage() {

  // Page elements parse

  // Enter relevant values using the data from the page

}

protected void init() {

  // Page initialization

  // Check if the upload has been correct

}

}

As follows from the above-mentioned example, the methods applied within the class in question (LoginPortalPage) match with the actions the user is able to perform on the given page: to set a user name (setUserName), a password (setPassword), to push the Login button (pushLogin).

However, that’s not all. The example hereinabove doesn’t explain in what way we proceed to the next page having pushed the Login button. Here are some other service methods applied exclusively within this class:

private void loginAs(String userName, String password) {

setUserName(userName);

setPassword(password);

pushLoginButton();

}

public HomePage login(String userName, String password) {

loginAs(userName, password);

return new HomePage();

}

public ErrorLoginPage loginInvalid(String userName, String password) {

loginAs(userName, password);

return new ErrorLoginPage();

}

That is why the final version of the LoginPortalPage class will look as follows:

public class LoginPortalPage extends Page {

protected LoginPortalPage() {

   super();

}

private void setUserName(String userName) {

  // Entry field code (Username)

}

private void setPassword(String password) {

  // Entry field code (Password)

}

private void pushLoginButton() {

  // Button push code (Login)

}

protected void parsePage() {

  // Page elements parse

  // Enter relevant values using the data from the page

}

protected void init() {

  // Page initialization

  // Check if the upload has been correct

}

private void loginAs(String userName, String password) {

setUserName(userName);

setPassword(password);

pushLoginButton();

}

public HomePage login(String userName, String password) {

loginAs(userName, password);

return new HomePage();

}

public ErrorLoginPage loginInvalid(String userName, String password) {

loginAs(userName, password);

return new ErrorLoginPage();

}

}

There exist many different ways of implementation of page objects depending on the preferences of the developer. I have just described a reliable variant proved by practice. Hopefully, I will find the courage to continue describing practical recommendations for the use of the PageObject pattern.