What is Page Factory?

In the previous section on what is page-object, we talked about how to represent a web page into a page-object, initialize the elements using webdriver and then accessing them in step_definitions.

Since we had only one page-object, we really couldn’t see the issues we might face as code grows. In this section, lets see what is the problem when we define page-objects as we did and the code gets larger and larger. Yes sure, it works as is !

KISS principle:

But we do want to follow KISS (keep it simple stupid) right [Anyways, I have my own qualms about this KISS principle and where it doesn’t apply and how it can be masked into too much of abstraction, but that’s for a later discussion]

The Problem:

Let’s say hypothetically that I had 3 cucumber scenarios and each scenario would interact with the home page and do further steps. The scenarios from a high level perspective do the following. We will be using automationpractice website.

  1. Go to home page, click sign in, and further steps
  2. Go to home page, verify phone number is correct, then only click sign in
  3. Go to home page, click contact us and further steps

The home page looks as below [The corresponding html locator information is also posted.

element_html_map

Home page-object:

Cucumber Scenarios:

Step Definitions (partial)

Do we see the issue now ?

Yes I am sure you must have figure it out. It is in the step_definitions code.

  1. We are repeatedly instantiating the SeleniumFrameworkHomePage object because the step definitions are used in different scenarios– as this code grows, we will lose track of which instance of SeleniumFrameworkHomePage we are interacting with [unless we go through Cucumber step by step, which is really a pain]
  2. Also I have getters and setters for each WebElement, so I have to pass the driver object to the getter and then poll the dom at that point to retrieve the Web Element. This seems redundant especially if the html locator for the element is NOT going to change during the session.
  3. As a script writer, instead of being able to write automation scenarios quickly and uncover the defects, I am lost in a maze of objects here and what is instantiated at what time [Of course, I can always dump the current state of object and inspect it and move on, but is it really worth the time when there is page-factory pattern;)]

Page Factory pattern:

The page factory pattern relieves this burden on the user of instantiating the page-object elements and interacting with them in the step definitions.

The google page talks about this in detail, however summarizing, there are two ways in which I can initialize the elements of a page object.

  1. PageFactory.initElements(driver,SeleniumFrameworkHomePage.class)
  2. public class SeleniumFrameworkHomePage { @Findby(className=”address”); private WebElement address; }

 

An implementation:

As you can see in the above step definitions for “I sign in” step, we are first passing the AutomationHomePage through PageFactory i.e. all WebElements inside AutomationHomePage get instantiated at this point. And after that, we an start using the elements of AutomationHomePage without having to worry about polling the DOM once again.
We will be extensively using PageFactory throughout building Hybrid/Page Object framework.

But Dude..

What about asynchronous behavior, where html elements detach from DOM and lose their reference with webdriver, that means my page-object that was used a while ago may have stale html elements right ?

Bingo! (You should feel like Neo in Matrix when he asks that question to Oracle…haha)

Right, so you would come across StaleElementReference exceptions in extremely ajax applications. There are strategies to handle this with page-objects and page-factory too. We will talk about some strategies in the closing pages of this section.

Next:

So we talked about page-factory pattern and how it might be useful to us. The next section is where we would take a concrete workflow on an e-commerce website and implement page-object and page-factory patterns.

Just as a reminder, we will be adhering to the Roadmap and Future section, so would request you to read that once again if you did not already.