Reducing Cucumber page object element duplication using mixins

The one thing that quickly happens when you start using a page object pattern to develop your Cucumber acceptance tests is you end up with duplicate page elements in multiple page objects. This happens because usually your pages often have elements common to every page and it doesn’t make sense defining these more than once, enter page mixins.

Page mixins are methods in ruby that you can mix into a class, so that each method in your mixin is then available in the instance of your class. We can use a mixin to define our common elements which are then available for every class we define.

For example, in our Google/Bing search example, the search text fields are conveniently given the same id in each of the search engine pages, therefore it makes sense to define this once and mix it in to each page.

We create a mixin file which is essentially a module with a bunch of methods. In our case, we define initialize to define our elements, and method missing as this is a common method we use for Browser object delegation.

module PageMixIn
  attr_accessor :search_field

  def initialize *args, &block
    @search_field = self.text_field(:name => "q")
  end

  def method_missing sym, *args, &block
    @browser.send sym, *args, &block
  end
end

We then simply include this mixin into our page class, and the methods are mixed in. The super statement in the class's initialize method is needed to ensure the instance variables of the mixin are available in the class.

class GoogleHomePage
  include PageMixIn

  attr_accessor :search_field, :google_search_button

  URLS = { :production => "http://www.google.com/" }

  def initialize(browser)
    @browser = browser
    @google_search_button = @browser.button(:name => "btnG")
    super
  end

  def visit
    @browser.goto URLS[:production]
  end

  def search_for term
    self.search_field.set term
    self.google_search_button.click
    google_results_page = GoogleResultsPage.new(@browser)
    google_results_page.results.wait_until_present if WEBDRIVER
    google_results_page
  end
end

This means we eliminate a lot of duplication of page elements, such as the search field, as well as common methods such as the method_missing.

Summary and a quick tip

I have found using page mixins provides a flexible approach to reducing page object element and method duplication. It makes your pages easy to read and compact. A quick tip though: I thoroughly recommend storing all page objects and page mixins under the support directory in Cucumber, as this ensures they are loaded automatically by Cucumber and are consistently available to reference.

2 thoughts on “Reducing Cucumber page object element duplication using mixins

  1. Is there a reason this would be better than creating an object hierarchy for page objects to inherit from? I’m implementing page objects for the first time and I’m having a hard time figuring out the best practices.

  2. I’m too. I am using a class called AllPages that is a super class and all the pages inherits from AllPages:

    class SomePage < AllPages

    So in this way I define all common elements in AllPages like header and footer.
    What's the difference between both methods?

Comments are closed.