Page Object Models(POM) in UFT

In this post, we will create a framework which will implement page object design pattern in UFT.

Setting up page objects will drastically improve test maintenance and will reduce code duplication. I think this is the best approach for test development which is easily available for Selenium, but there is no information available about how to implement the same in UFT.

Design

This will be a small framework which will have two sections

  1. Page object classes
  2. Action1 module which will have the tests.

Each page in your application must have a corresponding page class in UFT framework.

We will use Google search home page for developing the demo.

Page Class

We will create a VBS class for replicating a page object class functionality. Below is the class we will use the for the sample. This is a function library Google_Search.QFL.

Public Function Google_Search()
Set Google_Search = New Google_Search_Page
End Function
Class Google_Search_Page
'''' Initialize the variables here
Private Search_TextBox
Private GlobalLargeTimeOutSeconds

''Constructor Here
Private Sub Class_Initialize()
GlobalLargeTimeOutSeconds = 120
'' Load the application page in the first class
SystemUtil.Run "iexplore.exe", "http://www.google.com"
Browser("CreationTime:=0").Page("title:=*").Sync
''Check if the page is loaded and raise an error if not
if Not isPageLoaded then
Err.Raise 5, "Google Search Page", "Google Search Page not Loaded"
End If
'''Check here if on the correct page
''''Either Use OR or Use Descriptive Programming for Initializing Variables ''''We will use Descriptive Programming
Set Search_TextBox = Browser("title:=Google - Internet Explorer").Page("title:=Google").webEdit("name:=q")
End Sub

''Functions for page functionalities here
Public sub Search(Byval SearchText)
Search_TextBox.Set(SearchText)
Search_TextBox.Submit()
End Sub

''This will return results
Public sub PositiveSearch()
Search("HPE UFT TESTING")
End Sub

'This will return No search results
Public sub NegativeSearch()
Search("dgjhsgfhbsfghgdyyhgfhdf hdhgfhghdsjfghdgfds hdgfjhhdfh")
End Sub

''if we have to do something in destructor
Private Sub Class_Terminate()
Browser("CreationTime:=0").CloseAllTabs
End Sub

''Create a seperate function to check if the page is loaded. Call this function whenever you want to check if
''if you are in the right page
''Make sure that you create it with the same names in all of the classes
Public Function isPageLoaded()
'' Use any control or combination of controls here to make sure that the page is loaded
isPageLoaded = Browser("title:=Google - Internet Explorer").Page("title:=Google").webEdit("name:=q").Exist(GlobalLargeTimeOutSeconds)
End Function
End Class

Now let’s see what we are trying to do above.

Function Google_Search

We have created this function to get the object of the class outside this function library. Classes are not directly accessible outside the function libraries. We can call this function from anywhere in the class to get the object of the class.

Once we have the object of the class, we can then call any functions from class and execute the operations on the page.

Class Google_Search_Page

This class will hold the variables and the functions we can perform on this page. One variable is search text box and another one can be the submit button.

Constructor Class_Initialize

This is the constructor for the class and will be called automatically whenever a class object is created in other words when you will call Google_Search function from the test, that will create the object and this will trigger the Constructor and then this constructor will create open the webpage and navigate it to the google search page.

We should also check if the page is loaded here, that will make sure that we are on the correct page when the object is created, and all other functions can be called after that.

Destructor Class_Terminate

This function will be called automatically just before the termination of UFT test. So you can just write something like close the web page in this function and it will make sure that the browser is closed before execution is terminated and you will not have to worry about it.

Functionalities

We have created two functions here to test the google search functionality. First one is positive search and the second one is negative search. Now you might have already noticed that we are not checking if the results are loaded back or not and that because the results are loaded on the second page. We should create a second-page object to check if the results are loaded or not.

Now let’s create the tests on the top of this class for testing the positive and negative search.

Create Tests

In Action1 add the following code


'''First Test
Set OGSPage = Google_Search()
OGSPage.PositiveSearch()
'Setting Object to nothing will call destructor and will close the web page
Set OGSPage = Nothing

'''Second test
Set OGSPage = Google_Search()
OGSPage.negativeSearch()
'Setting Object to nothing will call destructor and will close the web page
Set OGSPage = Nothing

Now execute the tests and see the results. You should see browser opening twice and executions of both the tests.

Let’s add another page object which will simply validate the if the results are loaded on the results page.

GoogleSearchResults_Page


'Function to access class outside
Public Function GoogleSearchResults()
Set GoogleSearchResults = New GoogleSearchResults_Page
End Function

''Class for google search results page
Class GoogleSearchResults_Page

Private GlobalLargeTimeOutSeconds

''Constructor Here
Private Sub Class_Initialize()
GlobalLargeTimeOutSeconds = 120
''Check if the page is loaded and raise an error if not
if Not isPageLoaded then
Err.Raise 5, "Google Search Results Page", "Google Search results Page not Loaded"
End If
End Sub

'Check if the results are loaded on the screen or not
Public Function ResultsLoaded()
ResultsLoaded = Browser("opentitle:=Google").Page("title:=.*oogl.*").Link("xpath:=(//div[@class='g']//h3[@class='r']//a)[1]").Exist(GlobalLargeTimeOutSeconds)
End Function

'Destructor Here
'We dont have to terminate the browser here
Private Sub Class_Terminate()
End Sub

'Check if we are on the correct page
Public Function isPageLoaded()
Browser("opentitle:=Google").Page("title:=.*oogl.*").Sync
'' Use any control or combination of controls here to make sure that the page is loaded
isPageLoaded = Browser("opentitle:=Google").Page("title:=.*oogl.*").webElement("innertext:=All").Exist(GlobalLargeTimeOutSeconds)
End Function

End Class

Now the above class uses all of the features of the first-page class except two. It’s not initializing a new browser and navigating it to a URL and closing the browser.

Now let’s update the Action1 code to check if the results are loaded on the page or not


'''First Test
Set OGSPage = Google_Search()
OGSPage.PositiveSearch()
Set OGSRPage = GoogleSearchResults()
if OGSRPage.ResultsLoaded() then
Reporter.ReportEvent micPass, "Check if the google search results are loaded", "Google search results are loaded"
Else
Reporter.ReportEvent micFail, "Check if the google search results are loaded", "Google search results are Not loaded"
End If
Set OGSPage = Nothing

'''Second test
Set OGSPage = Google_Search()
OGSPage.negativeSearch()
Set OGSRPage = GoogleSearchResults()
if Not OGSRPage.ResultsLoaded() then
Reporter.ReportEvent micPass, "Check if the google search results are not loaded", "Google search results are not loaded"
Else
Reporter.ReportEvent micFail, "Check if the google search results are not loaded", "Google search results are loaded"
End If
Set OGSPage = Nothing

Now we are simply checking if the search results are loaded in the first test and we are checking that search results should not load for the second test.

Getter and Setter methods

We can also use getter and setter methods for better handling of the objects and values if required. Now we will update our first-page object to use the setter method for setting the value in the text box. This is not an ideal use but I am just showing what you can do and I am sure that you can figure it out on your own.

We will create the below properties


     ''Creating a property for the class and then using it for setting the values to the search textbox
Public Property Let Search_TB(Byval value)
Search_TextBox.Set(value)
End Property

''Creating a property for the class and then using it for getting the value from the search textbox
Public Property Get Search_TB()
Search_TB = Search_TextBox.GetROProperty("text")
End Property

Now this will create a property for the class and you can simply write Object.Search_TB = “This is UFT ” and UFT will then write it directly in the text box. Why this is important is that now you are restricting anyone from making unintended changes and testers who will write the test on this class will only be able to either set the text or read the text. This is because they don’t have direct access to this object.

This will be extremely helpful because once you have the requirements you will exactly know whats allowed and whats not on the page and you can create those restrictions on the pages by using access modifiers and the properties. So when the testers will write the tests they will not be able to perform any illegal operations.

Updated class Google_Search_Page

Below is the updated code with property usage


Public Function Google_Search()
Set Google_Search = New Google_Search_Page
End Function
Class Google_Search_Page
'''' Initialize the variables here
Private Search_TextBox
Private GoogleSearch_Button
Private GlobalLargeTimeOutSeconds

''Constructor Here
Private Sub Class_Initialize()
GlobalLargeTimeOutSeconds = 120
'' Load the application page in the first class
SystemUtil.Run "iexplore.exe", "http://www.google.com"
Browser("CreationTime:=0").Page("title:=*").Sync
''Check if the page is loaded and raise an error if not
if Not isPageLoaded then
Err.Raise 5, "Google Search Page", "Google Search Page not Loaded"
End If
'''Check here if on the correct page
''''Either Use OR or Use Descriptive Programming for Initializing Variables ''''We will use Descriptive Programming
Set Search_TextBox = Browser("title:=Google - Internet Explorer").Page("title:=Google").webEdit("name:=q")
Set GoogleSearch_Button = Browser("title:=Google - Internet Explorer").Page("title:=Google").webButton("name:=Google Search")
End Sub

''Creating a property for the class and then using it for setting the values to the search textbox
Public Property Let Search_TB(Byval value)
Search_TextBox.Set(value)
End Property

''Creating a property for the class and then using it for getting the value from the search textbox
Public Property Get Search_TB()
Search_TB = Search_TextBox.GetROProperty("text")
End Property

''Functions for page functionalities here
Public sub Search(Byval SearchText)
Search_TB = SearchText
GoogleSearch_Button.Click()
End Sub

''This will return results
Public sub PositiveSearch()
Search("HPE UFT TESTING")
End Sub

'This will return No search results
Public sub NegativeSearch()
Search("dgjhsgfhbsfghgdyyhgfhdf hdhgfhghdsjfghdgfds hdgfjhhdfh")
End Sub

''if we have to do something in destructor
Private Sub Class_Terminate()
Browser("CreationTime:=0").CloseAllTabs
End Sub

''Create a separate function to check if the page is loaded. Call this function whenever you want to check if
''if you are on the right page
''Make sure that you create it with the same names in all of the classes
Public Function isPageLoaded()
'' Use any control or combination of controls here to make sure that the page is loaded
isPageLoaded = Browser("title:=Google - Internet Explorer").Page("title:=Google").webEdit("name:=q").Exist(GlobalLargeTimeOutSeconds)
End Function
End Class

You don’t have to update anything in the Action1 to run this code. One another important thing is that now you don’t have to worry about opening and closing application in each of your test. Now your page classes are aware of when to open a browser and when to use the existing browser.

That’s it, now you have two page classes and two tests written on top of them. Now with this knowledge, you can create your own UFT framework with the page objects.

Let me know in comments if you have any questions.

 

 

Advertisements

3 responses to “Page Object Models(POM) in UFT

  1. This looks nice and I’m doing this in UFT now, just to see it in action 🙂 I just wonder: what would be an advance of using this way instead of using the built in Object Repository?

    Like

  2. This looks nice, and I’m trying this in UFT now 🙂 but what’s the advantage over using UFT’s own Object Repositiory?

    Like

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