Make Selenium Easy

Where Does PageFactory Suck – Selenium WebDriver – Java

Implementation of Page Object Model using PageFactory is popular while creating automated test scripts using Selenium WebDriver – Java. But it sucks at many places as it limits usage in a way and behaves differently.

To use PageFcatory we need to declare fields with types as WebElement and List<WebElement> in Page Objects class using annotations like @FindBy , @FindBys and @FindAll. We need to initialize Page Object class using any overloaded initElements() method of PageFactory.

The good point about PageFactory is that declared web elements in Page Object class are lazily initialized. That means if we do not use a WebElement of a Page Object class, that web element will never be searched for. This is the reason that when we initialize a Page Object class, we do not get NoSuchElementException instantly for declared web elements which are not present at web page currently.

Another good point of PageFactory is that it searches for WebElement every time when a method is called on it which lowers chances of getting StaleElementReferenceException. However we can override this behavior using @CacheLookup.

Where does PageFactory suck?

Starting point of pain is Type of field which must be a WebElement or a List<WebElement>. It restricts the usage where you need to use By type. When an web element is found then it is stored in a variable of type WebElement. Because of limitations of PageFactory , every web elements need to have type as WebElemen or List<WebElement>. If PageFactory does not find element, it throws NoSuchElementException.

There is difference between Presence of an element and Display of an element. If an element is not present then it will not be displayed but if an element is present then it may or may not be displayed.

That is the reason you see all presence related methods accept By type not a WebElement type like visibility related methods.

In above image, you can see some visibility methods accepting By type but those methods actually checking presence followed by visibility.

You may need to work on already found element. For example – Checking enable status of element or if element is displayed. At these places PageFactory sucks.

Let’s see a scenario :-

I want to search something on Google. Enter search keyword and hit enter on Search button. I need to verify that Search button should not be visible on web page.

I will create two scripts – With and without PageFactory and to verify invisibility of search button, I will use invisibilityOf() of ExpectedConditions class.

Output

Did you observe that test without PageFactory works perfectly fine whereas test with PageFactory gave NoSuchElementException. Reason behind is that PageFactory searched for a element every time whenever a method is called on it. So when invisibilityOf() method was called on Search element, it did not find that and throws exception instead of visibility status. If we use @CatchLookup annotation with element, we will get same result in both test methods.

In first test, when we check for invisibility of element then it gives true. What actually happened that after sending enter key on search button, element became stale and it throws StaleElementReferenceException which could be considered as invisibility of element. Same logic is followed by invisibilityOf() method. See actual implementation of method below :-

But in second test which is with PageFactory, it started searching for an element instead of checking invisibility status and throws NoSuchElementExcepion which we were not expecting.

PageFactory with WebDriverWait & FluentWait

If you use WebDriverWait in above examples then you see that test without PageFactory completed quickly but test with PageFactory will wait till timeout and throws TimeoutExeption at end. Reason behind is this that by default WebDriverWait will ignore NoSuchElementExcepion. In first test again StaleElementReferenceException will be throws which is not ignored by default.

If you use FluentWait in above examples then behavior will be same as without using explicit wait because no exception is ignored by default in FluentWait.

Output

Like above there may be multiple scenarios where behavior differs and it creates problem while writing assertions or creating common methods. Our automation framework should support both pattern. You may need to handle different scenarios for that.

One example of solving above problem is as below :-

We will create our own custom expected conditions and will handle those conditions which are ignored by default implementation.

MyExpectedConditions

Usage

Output

So the PageFactory has mixed advantages and disadvantages which we need to keep in mind.

You can download/clone above sample project from here.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning

Find all Selenium related post here, all API manual and automation related posts here and find frequently asked Java Programs here.

Many other topics you can navigate through menu.

Author: Amod Mahajan

A software Tester who is paid to judge products developed by others. Currently getting paid in American Dollars. Writing technical posts and creating YouTube videos are my hobbies.

1 thought on “Where Does PageFactory Suck – Selenium WebDriver – Java

  1. Hi Amod,
    So what is the solution for the By.. since im using pagefactory im unable to use explicit wait with expectedconditions(presenceofelement(by)) . Is there a way to use both the PageFactory and normal locating method(like By = by.xpath();)

    or is there another way.

Leave a Reply

Please wait...

Subscribe to new posts to become automation expert

Want to be notified when my new post is published? Get my posts in your inbox.