What Is Page Object Model (POM)
Page Object Model (POM) is a design pattern, nowadays the POM becomes more popular in automation testing area. As it helps to create Object repository for web User Interface(UI) elements and it eliminates the code duplication to increase the maintainability of the code. Parallely, it also acts as an interface to a page of our Application under test.
We can create separate Page Object Class for each page of our application, that contains the methods that represent the services available on the page and this will also help us to find the HTML elements of that page. Usually, the test code will never access the browser instance and HTML elements directly whereas it will only access through the Page object class.
The main advantage of POM is, that we can change or rewrite any web page on which we no need to change any test. So, we need to change the code only within the page object class which needs to be changed. Alongside, POM supports both Selenium and Watir Webdriver.
Why We Should Use POM
Handling one test file is easy to maintain! But how about maintaining 100+ test files at same time? Can you imagine handling it? No right?! Of course, it sounds bad! That’s why we’re going to use POM here.
For example, Let’s consider that one of our application contains 10+ pages. Let’s assume that each page has to display its username after the login. In this scenario, we must test whether the username is present or not. One of the simple yet the toughest problem with test script maintenance is that we will use the same page element in all our 10+ test scripts. So, If any changes occurs in that element then the test will be completely failed in all the 10+ test scripts. As a result, we should update the change in all the 10+ test scripts. Now you guys come to know how time consumable it is. On the other hand, it’s not easy to maintain also. For avoiding this we can use Page Object Model (POM).
In this tutorial, we are going to integrate POM with Watir Webdriver and cucumber.
In case, If you are new to cucumber and don’t have any idea of where to start then you can follow this guide, where i have explained completely about the Cucumber & it’s web automation testing.
A Guide for Web Automation Testing With Ruby Cucumber And Watir
Implementing Page Object Model (POM) With Ruby Cucumber
To implement POM, we need to create a project cucumber-test first and you can use the following code to create it,
$ mkdir cucumber-test $ cd cucumber-test/
Then create a file named with ‘Gemfile’ and then add the following lines into Gemfile.
source 'https://rubygems.org' gem 'watir' gem 'cucumber' gem 'page-object'
Run the below code to install gems for our testing.
bundle install
Now we can initialize the cucumber for our project using cucumber –init comment, as it will help us to create the cucumber project structure,
$ cucumber --init create features create features/step_definitions create features/support create features/support/env.rb
Add the following lines in features/support/env.rb file
require 'watir' require 'page-object' Before do @browser = Watir::Browser.new :chrome @browser.window.maximize end
Now we’re ready to implement the Page Object model for Amazon search functionality with the below code.
Note: To give you the simplified solution here i have implemented POM on my previous code of cucumber blog. Similarly, you can implement it with any of your cucumber projects.
Create a file amazonsearch.feature under features/ directory and add the following lines.
amazonsearch.feature
Feature: Amazon Search functionality Scenario: searching mobile phones on Amazon Given a user goes to Amazon home page When a user search for "mobile phones." Then amazon should return result for "mobile phones."
Now you can create ‘pages’ directory under ’features’ directory. Normally page object file has two parts, one is Declaration part and another one is the implementation part. Therefore, if we try to integrate it with cucumber then the declaration part of the page class will be page object file and implementation part will be step definition file.
Now create search_page.rb file under features/pages directory, then add the following code
class SearchPage include PageObject text_field(:search_box, id: "twotabsearchtextbox") button(:search, value: "Go") div(:search_results, id: "search") def visit_amazon_site @browser.goto 'http://www.amazon.com' end def enter_search_keyword(search_key) self.search_box = search_key end def click_search_button search end def search_results_present?(search_key) search_results.include?(search_key) end def close @browser.close end end
Create a file named “amazon_search_step.rb” under features/step_definitions directory and add the following lines.
require_relative '../pages/search_page.rb' Given(/^a user goes to Amazon home page$/) do @amazon_page = SearchPage.new(@browser) @amazon_page.visit_amazon_site end When(/^a user search for "([^"]*)"$/) do |keyword| @amazon_page.search_box_element.wait_until(&:present?) @amazon_page.enter_search_keyword(keyword) @amazon_page.click_search_button end Then(/^amazon should return result for "([^"]*)"$/) do |arg| expect(@amazon_page.search_results_present?(arg)).to eql(true) @amazon_page.close end
As you can see in the step definition file, that we accessed all the elements from the page object class. So, if any changes occurs in UI then we don’t need to change the step definition file. Instead, we need to change the code only within the Page Object class file.
Now you can run the cucumber test using the following command.
$ cucumber features/amazonsearch.feature
Advantages of Using Page Object Model (POM)
Reduces Code Duplication -> As it has non-brittle test code which will not allow us to give duplicate name so it helps us to avoid code duplications.
Provides More Readability -> We can define the page using Page Object, also these methods provide access to the page dynamically, which will work on all pages.
Improves Maintainability -> If you want to change the locator name, you can change it in the definition part of the page. And this will reflect in all the tests so we no need to change the step definitions and feature files too.
Supports Code Reusability -> Basically, Page object class will not depend on test case. We can use the same Page object repository to integrate with different testing frameworks like JUnit, Cucumber, Capybara, etc.
Disadvantages Of Using POM
Takes time -> It takes time to define all locators in a class
High setup -> It requires more manual efforts to set up.
[contact-form-7 404 "Not Found"]