Part II – One step deeper into Page Object Model.

As we have already discussed in my last post on page object model, why we need design patterns while coding. In this post, lets see what all pre-requisites are required to get a quick start so that we can get a better understanding of POM aka Page Object Model:

  1. The functionality classes (PageObjects) represent a reasoned common lineage between the pages of the application.
  2. The Page Object pattern act for the screens of your web app as a sequence of objects.
  3. It encapsulates the characteristics represented by a page.
  4. It permit us to mock-up the UI in our tests.
  5. A page object is an object-oriented class that work as an interface to a page of your AUT.

So what the term ‘Design Pattern’ means? Design patterns are defined as the time tested solutions to recurring design problems. There are multiple Design patterns which are available in market now a days. Some people think implementing Design Patterns are tedious to apply , some find them good for long term, But ideally design patterns are considered as the best practises and each developer while designing any new framework should apply them.

Today I will be going to talk about page objects and how we can use them to write automated tests. So in this post I will cover

what page objects are and

– how they relate to webdriver.

– why we would or should use page objects when writing automated tests.

So, first things first, What is Page Object Model

Lets take an example of wordpress.com only. Each web page has many links, text body text headings.. if we go to another page we see a form some buttons… so another way to summarize it is that each page has various kind of elements on it and these elements are as far as webdriver is concerned are referred to as web elements. And the page object pattern is used to represent these WEB elements as a whole object. And to use these we use page object. For example, on the home page, we can have a java class which can be used to click on the links, get the heading if we want to, we can say click on this link which will take us to another page object that will give us another page object. That new page object will give us more information to test that particular page.

It might sound a little confusing at this moment but it will become clearer as we go on. Page-Object pattern is one of the most effective approaches for creating a Test Automation Framework. This pattern maps a GUI page to a page class and the functionality to interact about the page is captured within the Page class (i.e., a new page class created for each new web page). So, you are calling the page class methods that perform action on the web page in your tests.

Test maintenance becomes easier by creating a Base Page class as it contains most common functions that need to be performed on any web page. For example: If need to navigate to a webpage in many of my tests, I may define this in my Base Page Class and then my Page Class must inherit this.

The first step we have to take in implementing the page object model is that we have to model the user experience. This means that all page specific elements has to be extracted to separate classes. This will guarantee that all functionality will be scripted only once.

WHAT’S THE PROBLEM?

First lets have a look at a test that I wrote. This is a test that does not use any page objects. At the moment, its just creating an instance of webdriver, creating a firefox browser, navigating to a website and clicking on various links using various locators.


package com.Wordpress;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TestAddNewPost {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
// Login to Admin Portal
driver.get("https://khyatisehgal.wordpress.com/wp-admin/");
WebElement email = driver.findElement(By.id("user_login"));
WebElement pwd = driver.findElement(By.id("user_pass"));
WebElement submit = driver.findElement(By.id("wp-submit"));
email.sendKeys(new String[] { "email@gmail.com" });
pwd.sendKeys(new String[] { "password" });
System.out.println("Going to click on submit");
submit.click();
System.out.println("clicked on submit");
// Go to All Posts page
driver.get("https:/khyatisehgal.wordpress.com/wp-admin/edit.php");
// Add new Post
WebElement addNewPost = driver.findElement(By.linkText("Add New"));
addNewPost.click();
// Add New Post's Content
driver.switchTo().frame("content_ifr");
WebElement postBody = driver.findElement(By.id("tinymce"));
postBody.sendKeys(new String[] { "This is description" });
driver.switchTo().defaultContent();
WebElement title = driver.findElement(By.id("title"));
title.click();
title.sendKeys(new String[] { "My First Post" });
// Publish the post
WebElement publish = driver.findElement(By.id("publish"));
publish.click();
}
}

So, When we actually take a deeper look at this, you can see that the instance of webdriver is being used many times and it does not look very clean. Also notice that we are using we are using the direct code that is found in the HTML page in our test and this also isn’t very good.

For instance, if our id for the login link has to change, and at the moment it would just matter that you come to this single test, you come here and change it in one place. Lets say we have got a gigantic web application, and we are writing various different tests. And we have tests in tens or hundreds and in some cases even thousands for long running application, and you need to change the value of this locator in each and every test. Thats not very meaningful. Through page objects we can do this in a very easy way and we can only do it in one place. So page objects help us to make more sense of what our tests are going to do and also help us maintain our tests better as well.

Why not give it a go.
There are differences of opinion on whether page objects should include assertions themselves, or just provide data for test scripts to do the assertions. Advocates of including assertions in page objects say that this helps avoid duplication of assertions in test scripts, makes it easier to provide better error messages, and supports a more TellDontAsk style API. In addition, including assertions mixes the responsibilities of providing access to page data with assertion logic, and leads to a bloated page object.

Capabilities of Page Object Model

  • Helps to implement OOP concepts like Abstraction and Encapsulation 
  1. Hides the details of telling the browser how to do those things.
  2. Hide all the internal details of the page (locators,elements ids,Urls) in Page Object.
  • Makes tests more readable
    In comparison to above commands of selenium , where in you need to add all the commands in the tests scripts . in page object model you need to put method names. The methods which you have created according to your understanding of application so these methods name are more readable and easy to understand.
  • Simple and clear page classes with sensible method names
    You can actually give the customize names to your methods. You need not to keep anything in mind, just looking into the method name gives you all idea about the capabilities of the method. For example: public ContactUsPage goToContactUsPage() .
  • Improves the maintainability of tests
    In page object , Whenever there is a ui change then we need to change the code at single location and not in the test scripts. Changing in page class will update all the concerned test cases. This is useful particularly when there are frequent change in the AUT. (Useful in Agile methodology based projects)
  • Easy creation of new tests.
    In fact, tests can be created by a person not knowing the features of automation tools like selenium. Once the methods creation is done then we only need to call these methods whenever and wherever required. This will make our test script writing more fast and easy.
  • Reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place. By using the page object model we can make non-brittle test code and reduce or eliminate duplicate test code. Beside of that it improves the readability and allow us to create interactive documentation. Last but not least, we can create tests with less keystrokes. An implementation of the
    page object model can be achieved by separating the abstraction of the test object and the test scripts.
  • Stay DRY

Page object model believes in the principle of Do not repeat yourself. Suppose you have a log in class then you need to add this login functionality code every time you want to access any page of website. But with Page Object Model , you can reduce the line of code by calling log-in method.

When you’re simulating having the user enter a new URL into the URL bar of the browser, then it’s the responsibility of the test class to create the page object it needs. Some operation on the page that would cause the browser to point to another page — for example, clicking a link or submitting a form — then it’s the responsibility of that page object to return the next page object.

Why to use it?

Creating Selenium test cases can result in a cluttered project. One of the reasons is that too many duplicated code is used. Duplicated code could be caused by duplicated functionality and this will result in duplicated usage of locators. The disadvantage of duplicated code is that the project is less maintainable.

If some locator will change, you have to walk through the whole test code to adjust locators where necessary. By using the page object model we can make non-brittle test code and reduce or eliminate duplicate test code. Beside of that it improves the readability and allow us to create interactive documentation. Last but not least, we can create tests with less keystrokes. An implementation of the page object model can be achieved by separating the abstraction of the test object and the test scripts.

Advertisements

One thought on “Part II – One step deeper into Page Object Model.

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