Implementing PageFactory patten and Annotations in TeamMentor

One of the things I’ve been trying to achieve during the creation of a framework for browser automation, is the capability of using best practices and methodologies that make code maintainable across test.

So I’ve been using the PageObject pattern and most recently a good candidate has been the PageFactory pattern, described here  and how its name indicates , it is a factory of a class.

This is how Selenium folks describe it :

The PageFactory relies on using sensible defaults: the name of the field in the Java class is assumed to be the “id” or “name” of the element on the HTML page.

Then they add:

The driver instance that’s used is the one that’s passed to the PageFactory‘s initElements method.

I implemented this pattern and also I was able to use another powerful feature : Annotations. An annotation in this case is an attribute used to identify page elements using different combinations but at the end of the day you will have an IWebElement based on the annotation selected.

In order to explain how the PageFactory and the Annotations works, let’s look at the following  class that performs the SignOn feature (and it is actually reused by several test). By looking at the HTML form, I’ve created an IWebElement for each field in the form and using annotations, I’ve indicated the way the element is going to be found.

Annotations

This class contains a  definition of all the HTML form fields of the SignUp page,therefore when the method PageFactory.InitElements is called, those fields are already initialized and you will have a IWebElement to work with.  I forgot to mention that you can try to find an element using different attributes, please take a look at the following list:

Attributes

The following code explains how an instance is created:

Constructor

It’s important to say that this pattern also allows to take advantage of the Cache mechanism. If there are fields that never changed (are not tied to AJAX events), you can use the Cached version of the element and therefore improve the performance of the application.

By adopting this pattern we can make sure that if there are changes at the UI level (adding new fields or renaming them), there is just a place to look at. Moreover, this approach also allows a unified way to deal with the page elements.

So far I’ve been using it and I’m very optimistic about the results 🙂

Advertisements

About Michael Hidalgo

Michael is a Software Developer Engineer based on San José, Costa Rica. He leads the OWASP Chapter from Costa Rica. You can take a look at my blog at http://blog.michaelhidalgo.info/
This entry was posted in Architecture, Selenium WebDriver, UnitTests, WebDriver and tagged , , , . Bookmark the permalink.

2 Responses to Implementing PageFactory patten and Annotations in TeamMentor

  1. Maciek says:

    I am using That pattern to. but there are to thing that that annoy me:
    U can’t use annotation to wait for element condition (or at least i haven’t found a way yet).

    One more thing I have noticed that you are selecting elements by id. I am not sure if it is good way for dotNet, cause such id have “whole path to element” in them and when developer will move element the id will change.
    Personally I prefer to uses classes I is little more work to do cause i have to make developers add some times classes but it need much less maintaining so far.
    Example:
    private const string Paymant1Locator = “div.payment-type-1 a”;
    [FindsBy(How = How.CssSelector, Using = Paymant1Locator)]
    private IWebElement Paymant1Element;

  2. Michael Hidalgo says:

    Hi, thanks for your comments, yeah I noticed that too. I’ve implemented our own Wait conditions to address this potential problem.

    The problem here is if you have a label in your HTML that is rendered by an AJAX request, in this case you need to implement your own conditions, because the PageFactory pattern would not check that for you during the initialization.

    Regarding your second comment, I would say that the best way to look for a unique element in the DOM is by using the Id. That helps to ensure that the elements are unique. Unfortunately one size does not fit all.
    Using a CSS class can end up with more than an element to deal with.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s