7

So i've been working on a Page Object Model framework for a large web application for our current company. It's the first time i've made my own framework and implemented the page object model. Im using Ruby w/Capybara and Selenium-Webdriver for my language/driver of choice.

Currently i've divided each page (or obvious "section of the site") into a class file. This class file has methods for just about everything (or an API of sorts). The problem i've ran into is that I am literally writing a method for every single thing....and i've came across 2 ways people seem to do this:

Lets pretend for a section/page of the site is a widget creation form, the widget has a name/description and some sort of "type" dropdown. Also a save button to save the widget.

Option A (Which is what i've done so far): Make a method for each element (the save button, called save_widget, all the different inputs, etc...)

Option B: Have getter and setter methods for each element, then a larger method which uses these private getter and setter methods.

With Option A my test scripts end up being longer, and honestly not much different than using selenium calls themselves.

Option B would probably call one method (Such as create_widget which would pass in multiple items which that method would call all the smaller getter/setter methods). This would make the test script MUCH shorter and more abstracted. However the getter/setter methods would probably take more actual writing for the page objects themselves (but possibly easier to maintain).

Is there a certain style that favors one over the other? The more I think about it the more Option B seems better...but I wonder if in this case abstraction is a good thing.

2 Answers 2

3

Both of your options listed can work. Though, as you mentioned, option A is only slightly better than not using POM.

Every time I do test automation, it's always been on teams that have no automation, so I'm always creating frameworks from scratch.

In my experience, I favor option B that you have listed. This level of abstraction and encapsulation works best for long term maintenance. And, if there is more than 1 person writing tests, they only need to be concerned with what methods to use and not have to worry about how to use getter/setters. This also allows you to create overloaded methods, when needed, and use the same elements in your getter/setter. Option B allows for more customization and control.

Test specs should be short and contain your data, your asserts, and any class/method calls to implement the test. While your POMs contain your elements and methods on how to use the elements.

Edit: Note, not all languages support method overloads. An example of overloaded method looks like:

public void login () {}
public void login (username, password) {}

Same name is used for both methods, the take different parameters, and may have different logic/steps to perform. In this case, maybe the first method is used to login as a guest, where the second supports login credentials.

3
  • "This also allows you to create overloaded methods, when needed, and use the same elements in your getter/setter". Can you describe an example of this?
    – Mercfh
    Aug 5, 2019 at 17:12
  • @Mercfh I edited my answer with a brief example.
    – Lee Jensen
    Aug 6, 2019 at 15:43
  • Ah apparently ruby doesn't support that type of operator overloading unfortunately. Darn.
    – Mercfh
    Aug 6, 2019 at 19:04
3

I might choose option A and do what is needed when it is needed without the extra abstraction.

One additional option is also to move away from a strict page object model. My reason for doing this is maintainability. The issue I encounter is the knowledge needed (or gained) for the page breakdown. You'll often find components that are:

  • Universal, e.g. a 'logout' button'
  • Repeated on multiple pages, e.g. a attach document to multi-form submission
  • Common to a certain workflow over different pages
  • Updated via ajax

Because of these issues I create Page Objects as:

  • Global. For simple applications I've even just kept them all in that one category.
  • Workflow. Some elements are repeated thru a workflow or multi-form submission
  • Page. The more classic use for objects specific to that page and no other.

In fact I often start with just global and wait until I start meetings conflicts / collisions before doing the mroe detailed breakouts. Depends on the situation.

1
  • I typically do have a folder structure for pages/components that are globally used (such as a dashboard page or something like that)
    – Mercfh
    Aug 5, 2019 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.