The idea of the Page Object Model (POM) in UI Automation framework development is that Pages or Sections of pages are represented by classes. Public methods in these classes expose functions as user interactions on specific part of the page. This helps solve problem with brittle tests as a result of manipulating web elements directly. An important point here is that even though it is called Page Object Model, classes need not represent entire page.
- Modelling Out the AUT
- Locating Relevant Elements
- Our first Page Object class
- Our Second Page Object class Using Page Factory
- Visual Studio 2015 (Community Edition should be fine)
- Selenium Webdriver
- Chrome driver
- Previous Posts
- Basic C# knowledge/ OOP concept (classes, Methods, Properties)
- Basic Knowledge of Unit Test frameworks (Nunit)
- Basic Knowledge of DOM, Html and CSS
- The Application Under Test on Instant WordPress
POM makes it a lot easier to separate Test Scripts from the code we are using to program the selenium API. For more on the Page Object Model please refer to the selenium wiki
Modelling out the AUT:
We are going to start with an initial goal of smoke testing our application. Then we will build on it and then Refactor, Refactor, Refactor. This could be pre-existing smoke test cases from the manual testers. If working in an agile environment and the AUT is not ready yet, then you can analyse the requirement to get an idea of the core and minimum functionality of the AUT.
- Start-up the AUT by running Instant WordPress.
- Select WordPress FrontPage or alternatively copy the URL and paste into browser of your choice (preferably google chrome)
- You should have the default page back up.
The Home Page
I will start by dividing the page into different sections. As shown in the figure below.
|Page Objects||Class Name||Notes||Functions|
|Header Page Object||HeaderPObject.cs||Displays the Logo
Displays the Tagline
|Menu Page Object||MenuPObject.cs||Displays Menu Items
Navigate to other pages
Holds the header Image
|Post Section Page Object||PostSectionPObject.cs||Consists of multiple
posts with the same properties and functions
|Side Widget Page Object||SideWidgetPObject,cs||Multiple sections with similar functions||Search blog
Display recent posts
Display recent comments
|Side Meta Page Object||SideMetaPObject.cs||WordPress opens in a new tab
Switch window function required.
More page objects to be returned needs to be created.
|Access to login page
Access to rss feed
Link to WordPress.org
On a high Level, the above table gives us a picture of the public methods we might want in our classes. Also we have noted down some things that might aid us when developing our functions. Note more functions and requirements will be discovered as we start coding.
Let’s start with the header.
Some smoke test cases related to the header:
- Verify the logo is displayed
- Verify Tagline shows the correct text
(Note to verify an image is displayed requires a bit more than getting the display property of the web element however for simplicity we will use it for now)
Locating Relevant Elements:
Our elements of focus will be the Logo and the Tagline. Some common strategies of locating Elements in Selenium Web-driver include;
ID, Name, Link Text, Partial Link text, Tag name, Class Name, CssSelector, Xpath. Usually, My order of preference of locating elements are; Id > Name > CssSelector. In fact these 3 strategies are enough most of the time when locating web elements. Later on, I will cover advanced locating techniques using Css selectors and Xpath, and you will see you can locate any element as long as it exists in the DOM. Even though we have this power, the ideal scenario when no ID, Name or Unique class Name is present for an element, will be to ask the the web developer to put it there.
Hopefully you are using chrome.
- Right click and inspect element to view the properties.
As you can see the Text representing the logo has an ID “site-title” (well we’ll assume it as our logo for now)
For the Tagline, the ID is ”site-description”
Our first Page Object class:
Let’s flip to visual studio and open our project. if you haven’t got the project setup yet please refer to previous post on framework Setup here.
Add a new class to the ‘. Web’ Project and name it HeaderPObject.cs
- The first thing in the class is to import the relevant namespace, OpenQA.Selenium.
- I have also declared 2 properties of type IWebElement, Logo and TagLine
- There are 2 methods named to describe the actions we are trying to perform based on the data.
- In the methods we have set the properties by using the web-driver instance from our Test Base class and calling the findElement method, which takes a ‘By’ type as parameter with different methods to locate and initialize element.
- Ensure the URL in the TestBase reflects the AUT URL in my case it is “http://127.0.0.1:4001/WordPress”;
- First add a class into the ‘. Test’ Project and name it anything for now (HeaderTests)
- Then we want to include the relevant namespace, NUnit unit testing framework for our assertions etc., the .Web project namespace, and namespace containing our page Objects.
- If you are not able to reference these namespaces, then you might need to reference the project in your test project by right clicking, adding reference.
- Next we Extend the Test Base class, to reuse the setup and Teardown steps.
- Then we declare methods, decorated with the [Test] attribute from NUnit.Framework namespace. Name the method to reflect what we are intending to test.
- In our test method, we create an instance of the Page Object classes we need so that we can call the public methods (Our Api)
- We call the method and usually on the last line, we make assertions on our expected results.
- Ensure Instant WordPress is running and start the Test
Our Second Page Object class Using Page factory:
- Firstly for this class, we import the relevant namespaces, OpenQA.Selenium, OpenQA.Selenium.Support.PageObjects; Under the latter namespace is where we have the Pagefactory class and other classes that will help to initialize our Page Elements declared in the class.
- In the constructor of the page object class I have called the static method from the Pagefactory class, InitElement, it takes an instance of the Webdriver and the class representing the page as parameter.
- There are also 2 properties of type IWebElement declared, decorated with the Findsby Attribute.
- We set the How property of the FindsBy Attribute class to enum id, and the Using to the string to be used to locate the id of the element.
- Two methods named to describe the actions we are trying to perform based on the data were also declared
- In the methods we simply return the value of the IWebElement Display property for the IsLogoDisplayed Method, and we return the value in the Text property.
- Declare another method in our HeaderFunctionTests.cs class, decorated with the [Test] attribute.
- In our test method, we create an instance of the Page Object class
- We call the relevant method on the instance and we leverage NUnit to make assertions on our expected results.
- Ensure Instant WordPress is running and start the Test
If you get an Error as shown below, a reason will be because your elements are not initialized, you might be missing Step 2.
So we have covered The FindsByAttribute, and the Page factory class.
We have used 2 public methods as an interface for the QA engineer to interact with the framework, which in turn drives the Webpage, and he does not need to know anything about selenium.
Next we will refactor our code such that the responsibility of initializing our Web Elements, will be given to a separate class. This means we do not have to put that line of code in every single page object constructor hence, we create Less responsibility for the class and code looks cleaner.
We will also see how we can have some sort of factory class to create instances of our page object. This is because, whoever is going to write the script need not know about the classes that needs to be instantiated to write the script. It is hard to remember class names, imagine a QA engineer who needs to script about 700 test cases, you will see the new keyword all over the scripts and he will need to know the names of the classes he needs to instantiate. This could be very frustrating, (why are we creating objects when we say we are scripting anyway?). Also remember, we want to hide every complexity within the framework.
Click Here to Download the Complete Working Solution.
Be the first to be notified when the next tutorial is published.