July 28, 2015

The-Internet: Page Object Model examples

Writing automated test code to test against Dave Haeffner's mock site, The-Internet: Login Page.
    This post is fifth in a series of six. Need to go back to the beginning?

    Part Five: What is the Page Object Model?  

    According to the original Selenium Wiki

    The Page Object Model appeared as early as March of 2013, on the wiki for Selenium WebDriver. https://code.google.com/p/selenium/wiki/PageObjects

    Imagine modelling a Java class on a Login page. 

    Welcome to The-Internet!

    There are two major actions you can do on a Login page: 
    • Create a successful login
    • Create an unsuccessful login. 
    One could create one method for each action one could perform in a page. 

    With their early example, they have methods to type a username and password, click a submit button, methods that handle a login success and a login failure, and a method called "loginAs" which accepts the strings for a Username and Password and wraps up all the methods that typeUsername(username), typePassword(password), and returns the submitLogin().  

    They advise, in general, not to make assertions on the page. Those are for the tests, themselves. 

    For more information you can go to Selenium Wiki: Page Objects on Google.Code.Com 

    Originally, the concept encapsulating objects of a page dealt with the window of a user interface, not a web browser. See Window Driver by Martin Fowler, 8/26/2004, also from ThoughtWorks, the company that brought you Selenium 1 and Selenium 2: WebDriver.  

    Note: The Selenium Wiki information is out of date. For archival purposes, you can browse the wiki which has been in existence since Selenium WebDriver first came out. The new home for the documentation is at https://seleniumhq.github.io/docs/

    According to the new Selenium Wiki

    With the new wiki, the Page Object model is now referred to as a "Page Object Design Pattern". Instead of informal language of the earlier wiki, it speaks in the language of a software professional. 

    Why use Page Objects?

    • "Readable: Business stake holders can understand it.
    • "Writable: Easy to write, avoids unnecessary duplication.
    • "Extensible: Functionality can (reasonably) be added without breaking contracts and existing functionality.
    • "Maintainable: By leaving the implementation details out of test cases, you are well-insulated against changes to the [automated test]
    "[...] This method completely abstracts the concepts of input fields, buttons, clicking, and even pages from your test code. Using this approach, all your tester has to do is call this method. This gives you a maintenance advantage: if the login fields ever changed, you would only ever have to change this method--not your tests".

    Page Object Example

    We could write a Page Object for the Login page of The-Internet as such:

    With this example, we have three main methods of the LoginPage class:

    • enterUserName: Pass a username as a String, and this method will send the username into the textbox. 
    • enterPassword: Likewise, pass a password as a String, and this method will send the password into the textbox. 
    • logIntoPage: Send the username and password, such as the test user data stored in an enum fashion for this example, and it will call the above methods to enter the username and password, and click the Login button. 
    But what are those odd lines of code that is not exactly Selenium?
    • waitForElementToBeVisible(LoginPageEnum.PASSWORD.selector());
    • sendKeys(LoginPageEnum.USERNAME.selector(), user);
    • click(LoginPageEnum.LOGIN_BUTTON.selector());
    Just as we do at my workplace, I encapsulated some of the code:


    • Locators on the LoginPage are being stored as Enums: Since locators could be in either By.id or By.cssSelector, I created an interface, ISelector and implemented it in the enum class. Adding the name of the enum in the method and ".selector()" after it is an easy way to make the code more readable. To see the full code, you can scroll to the bottom of the LoginPage I have listed on GitHub.


    • Commonly used WebDriver functionality is stored in a class, CommonUtils: Need to handle syncing? Logging functionality? The methods in the CommonUtils class act as a wrapper. To see the full code, you can go to the CommonUtils page I have listed on GitHub.

    The working code for the PageObjects LoginPage and SecureArea along with CommonUtils, and the enum class UserEnum.java can be found in my GitHub repository, WebDriver_TheInternet_Advanced.

    Now that we have done all this work, in the next blog post, we can write out our test...

    NEXT: Writing the Automated Test

    -T.J. Maher
     Sr. QA Engineer, Fitbit
     Boston, MA

    // Automated tester for [ 4 ] month and counting!

    Please note: 'Adventures in Automation' is a personal blog about automated testing. It is not an official blog of Fitbit.com

No comments: