Skip to main content

Selenium: Design Patterns

In a previous article I described a set of best practices for designing automated tests. So as I said, in this post I would like to expand our toolbox of two design patterns, that work great with selenium tests. In this post we will dig into Page Object pattern and combine it with Page Factory. As always, whole code for project is available on my github. 

Page Object 

Pattern Page Object is a concept that helps to reduce the number of duplicated code, and helps with test maintenance, resulting from changes in the structure and functionality of the web application. The main idea behind page object is to place the code relating to the functionality of subpages in separate classes. In a very simplified way, if your web application includes pages:

  • home
  • about
  • contact
We should create three separate page object classes: 

  • Home.java 
  • About.java 
  • Contact.java 

Each class should contain only those methods that support functionality for the corresponding subpage, and define selectors only for this subpage. We should also remember, that public methods in page object class are only those, that represents user’s workflow. 

One important point is that each public method in page object class should return object of page that user is on. For example, if a button on the page does not gets you to different subpage, this method should return this. Moreover, if a button is a link to another page, the method should return page object class of this subpage. Here is a code snippet of this approach using an example from previous article, where we wrote tests for Facebook login:


In above example, methods enterUserLogin() and enterUserPassword() don’t transfer user to another subpage, but perform activities on the login page, so return type is object of LoginPage class (this). On the other hand, submitLoginCredentials() method moves user to home page (or to the page informing about the login failure), so it returns home page class object. In real life example, in HomePage.class we would have had methods that perform actions on the home page, but since it’s only an example code demonstrating pattern usage, we have only checkIfLoginSucceed() method here:


…and test looks as follows:


Page Factory pattern 

The main idea behind this pattern is to support page object classes, and to allow better page selectors management. Page Factory provide us with a set of annotations, which work great with selectors and enhance code readability. To understand this, let’s look at a standard initialization webelement through the selector:

private static By email = By.id(“email”); 
WebElement emailBox = driver.findElement(email);

Unfortunately, the readability leaves much to be desired. The problem is also that variable with selector and web element object require a separate initialization. Along with Page Factory, this is greatly simplified:

private WebElement email;

That’s all! Page Factory search page source code for element with id=”email” by default and assigns it to declared webelement. Of course, this minimalism can introduce some confusion, and therefore I recommend the use of @FindBy annotation:

@FindBy(id = “email”) private WebElement userEmailLoginInput;

We can also search selectors by other attributes, such as xpath, name, className, etc. Everything we have to do to use this pattern, is to initialize PageFactory in the page object class constructor:

PageFactory.initElements(driver, this);

Our LoginPage.class with page factory pattern will look like this:


Important thing to notice is that every time we call a method on web element, page factory search for our element all over again through page sources. If page isn’t AJAX-based, we can use page factory cache to search an element only with page factory initialization, and then retrieve it from cache:

@FindBy(id = “email”)
@CacheLookup private
WebElement userEmailLoginInput;

Continue reading 

If you want to continue reading and expand your knowledge in area of Docker and Selenium Grid, I recommend you these books:

  • Selenium WebDriver Practical Guide – there’re not many materials about Selenium Grid, but this books is a great read if you want to master not only Grid, but Selenium in general

Summary 

As in every aspect of software development, design patterns in test automations help us to develop tests faster and more efficient. Page Object and Page Factory are two simple patterns, that significantly improve maintenance and readability of selenium tests. For complete sources of examples in this article please visit my github. If you have any questions, feel free to leave a comment!

Popular posts from this blog

REST-Assured framework overview

In modern software development, REST services becomes most popular choice for implementing distributed and scalable web application. They are light and easy to maintain, which results in faster and more effective implementation and system integration.
I recommend you also my other posts about REST-Assured and building microservice’s test automation frameworks: REST-Assured: going deeperBuilding microservices testing framework
With the increase popularity of RESTful services, there is a need for fast and lightweight tool for REST webservices testing automation. One of the most popular choice is Rest-Assured framework from Jayway. It introduces simplicity of testing web services from dynamic languages like groovy or ruby to java. In this post we will get our hands dirty and write automatic test in Rest-Assured framework.
In order to create complete implementation of automated tests in Rest-Assured framework, we need to write our code against some example API. We’ll use standalone Wiremock m…

Notes after TestingCup 2018

On May 28-29th I attended TestingCup conference in Łódź. Having quite unique perspective: this was my second year in row as a Speaker at this conference I want to share some thoughts on the event. Dust has settled, lets go! 



Championship Originally TestingCup is a software testing championship. Wait, what? Yes, the formula is unique: teams and individuals from all around Poland are competing in finding the most bugs and defects in specially prepared application - Mr. Buggy. I don’t have specific data, but since this year’s conference was all english I guess competitors were not only from Poland. As a spectator, I must say that the whole competition looked very professional. There were team shirts and names, podium and trophies (gold cup and cash). 
Some cons? Testing championship is held at the first day of the conference. So this is already a conference, but if you’re not taking part in the championship… there’s not much to do, since all the talks are in the next day. Organizers are aw…

Testing Asynchronous APIs: Awaitility tutorial

Despite the growing popularity of test automation, most of it is still likely to be done on the frontend side of application. While GUI is a single layer that puts all the pieces together, focusing your automation efforts on the backend side requires dealing with distributed calls, concurrency, handling their diversity and integration.
Backend test automation is especially popular in the microservices architecture, with testing REST API’s. I’ve noticed that dealing with asynchronous events is particularly considered as challenging. In this article I want to cover basic usage of Awaitility – simple java library for testing asynchronous events. All the code examples are written in groovy and our REST client is Rest-Assured.
Synchronous vs Asynchronous In simple words, synchronous communication is when the API calls are dependent and their order matters, while asynchronous communication is when the API calls are independent. Quoting Apigee definition:
Synchronous  If an API call is synchrono…