qtp

QTP – Testing Multiple Browser Applications

Web applications due to their dynamic nature, make script development quite challenging. I am writing this article in an attempt to simplify one of the aspects that automation developers face while working with Web applications. We will see how QTP can be used to automate multiple browsers with the use of a Dictionary object, to which we can add Browsers, remove them, change the way we reference them, and much more. 

You will notice in the examples at the end of this article that, regardless of how many pages we navigate, we would never have to keep a track of changing properties. In other words, regardless of browser navigation and actions performed on each browser, this concept will help use the name we give them to work with them, instead of following their ever-changing properties.

Let’s begin by creating a global variable, that will hold the Browser Collection to be accessed by our class:

'Public Variable: Holds Browser Collection
Public colBrowser

Another reason to create a global variable is that as long as it is an object, it can be used as a reference by (local) class variables, thus being over-written as many times as we want.

To ensure that we are not creating a new object each time our class initiates, we must create a Singleton, which will be stored in the initialization procedure of our class. It will also assure us that our code is highly efficient and our global variable is created only once, and not destroyed unless required.

' Purpose: Initializes the Scripting.Dictionary Singleton
Private Sub Class_Initialize
    Dim bInit: bInit = False        
 
    ' If colBrowser has already been instantiated, then Init = True
    If IsObject(colBrowser) Then
        If Not colBrowser Is Nothing Then
            bInit = True
        End If
    End If
 
    ' If colBrowser was destroyed or has not yet instantiated, then create it
    If bInit = False Then Set colBrowser = CreateObject("Scripting.Dictionary")
 
    ' colObject (local) acts as a reference to colBrowser
    colObject = colBrowser
End Sub

Above, colObject is a reference to our Global Collection object colBrowser.

Instead of creating a new object each time, we will reuse the same reference to add all the necessary Browsers. To add browsers to our collection, let’s create a simple method called “AddBrowser” and a public property “HWND”, that will store the Windows Handle of the Browser:

' Purpose: Adds Browsers and their HWNDs to a Collection
Sub AddBrowser(sName)
    ' If the Name already exists in the collection, then remove it so it can be re-added
    If colObject.Exists(sName) Then
        colObject.Remove sName
        colObject.Remove sName & "-HWND"
    End If
 
    ' Add the Browser with its corresponding handle
    ' Store the Handle Property
    With colObject            
        .Add sName, Browser("hwnd:=" & Me.HWND)
        .Add sName & "-HWND", Me.HWND
    End With
End Sub
 
Private Handle
 
' Purpose: Stores the Browser Handle
Public Property Let HWND(ByVal Val)
    Handle = val   
End Property
Public Property Get HWND()
    HWND = Handle   
End Property

AddUsingCreationTime

To provide ourselves with more options to add browsers, let’s create 3 more methods: AddUsingCreationTime, AddUsingTitle, and AddLastOpen. As the name suggests, AddUsingCreationTime will enable us to add the browser in our collection object using its creationtime:

' Purpose: Uses the "AddBrowser" method to add browsers to the collection 
' using their CreationTime Property
Public Sub AddUsingCreationTime(sName, intCreationTime)
    Dim oBrowser, oCol
 
    ' Description object for Browser Class
    Set oBrowser = Description.Create
    oBrowser("micclass").Value = "Browser"        
 
    ' ChildObjects of Browser Class Description
    Set oCol = Desktop.ChildObjects(oBrowser)
 
    'If the supplied CreationTime is greater than the total number of open browsers, 
        'then Report Err.
    If intVal > oCol.Count Then
        Reporter.ReportEvent micWarning, "Add Browser Using CreationTime", "Browser " & _
                "with CreationTime " &intCreationTime& " was not found."
        Exit Sub
    End If
 
    ' Store the Browser Handle
    Me.HWND = Browser("creationtime:=" & intCreationTime).GetROProperty("HWND")
 
    ' Add the browser to the collection
    AddBrowser sName
End Sub

AddUsingTitle

Similarly, AddUsingTitle will enable us to store a Browser if we prefer using Browser’s Title:

' Purpose: Uses the "AddBrowser" method to add browsers to the collection 
' using their Title Property
Public Sub AddUsingTitle(sName, sTitle)
    ' Verify if the browser with the supplied title exists
    If Not Browser("title:=" & sTitle).Exist(1) Then
        Reporter.ReportEvent micWarning, "Add Browser Using Title", "Browser " & _
                "with Title " &sTitle& " was not found."
        Exit Sub
    End If
 
    ' Store the Browser Handle
    Me.HWND = Browser("title:=" & sTitle).GetROProperty("HWND")
 
    ' Add the browser to the collection
    AddBrowser sName
End Sub

AddLastOpen

Lastly, for greater flexibility, we will create another method, AddLastOpen, which as the name suggests, will add only the most current browser to our collection:

' Purpose: Uses the "AddBrowser" method to add the last (most recent) open browser
'    Note: The last open browser always has the greatest CreationTime
Public Sub AddLastOpen(sName)
    Dim oBrowser, oCol
 
    ' Description object for Browser Class
    Set oBrowser = Description.Create
    oBrowser("micclass").Value = "Browser"        
 
    ' ChildObjects of Browser Class Description
    Set oCol = Desktop.ChildObjects(oBrowser)
 
    ' Store the Browser Handle
    Me.HWND = Browser("creationtime:=" & oCol.Count - 1).GetROProperty("HWND")
 
    ' Add the browser to the collection
    AddBrowser sName
End Sub

To simplify calling of objects, we will use the names we give to each browser. Instead of using .item, we can use .Name which is more descriptive. This part can be omitted, but for the sake of completion, let’s create this method anyways:

Public Function Name(Key)
    Dim Keys
 
    Keys = colObject.Keys
 
    If IsNumeric(Key) Then
        Key = Keys(Key)
    End If
 
    If IsObject(colObject.Item(Key)) Then
        Set Name = colObject.Item(Key)
    Else
        Name = colObject.Item(Key)
    End If
End Function

Finally, we must create an instance of the object, that will enable us to call class methods:

' Create a new instance of Class clsBrowser
Set BrowserObject = New clsBrowser

We’re done! You can download the class here, or view the text version here

Demonstration: AddUsingCreationTime

As a demonstration, you can associate (or ExecuteFile) the library and run the following lines of code:

Demonstration: AddUsingTitle

As stated earlier, this method will store any browser with the provided title.

SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com", "", "", 3 : Wait(4)
'Add the First open browser (creationtime=0) to the collection
BrowserObject.AddUsingCreationTime "DemoAUT", 0
 
SystemUtil.Run "iexplore.exe", "http://relevantcodes.com", "", "", 3 : Wait(4)
'Add the Second open browser (creationtime=1) to the collection
BrowserObject.AddUsingCreationTime "RelevantCodes", 1
 
'Use the names we gave the browser, and use the same name regardless of changes in its properties
With BrowserObject.Name("DemoAUT")
    .WebEdit("name:=userName").Set "test"
    .WebEdit("name:=password").Set "test"
    .Image("name:=login").Click
 
    .Sync
 
    If .WebList("name:=fromPort").Exist(10) Then
        .WebList("name:=fromPort").Select "Frankfurt"
        .WebList("name:=fromMonth").Select "December"
        .WebList("name:=toPort").Select "Paris"
        .WebList("name:=toMonth").Select "December"
        .WebRadioGroup("name:=servClass").Select "#1"
        .WebList("name:=airline").Select "Unified Airlines"
        .Image("name:=findFlights").Click
    End If
End with
 
'Use the names we gave the browser, and use the same name regardless of changes in its properties
With BrowserObject.Name("RelevantCodes")
    .Link("text:=Articles", "index:=0").Click
    .Link("text:=Home", "index:=0").Click
    .Link("text:=QTP\/Web", "index:=0").Click
End with
 
With BrowserObject
    .Name("DemoAUT").Close
    .Name("RelevantCodes").Close
End with
 
'Release
BrowserObject.Destroy

Demonstration: AddLastOpen

As stated earlier, this method will add the last open browser to the global browser collection.

SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com", "", "", 3 : Wait(4)
'Add the last open browser to the collection
BrowserObject.AddLastOpen "DemoAUT"
 
SystemUtil.Run "iexplore.exe", "http://relevantcodes.com", "", "", 3 : Wait(4)
'Add the last open browser to the collection
BrowserObject.AddLastOpen "RelevantCodes"
 
'Use the names we gave the browser, and use the same name regardless of changes in its properties
With BrowserObject.Name("DemoAUT")
    .WebEdit("name:=userName").Set "test"
    .WebEdit("name:=password").Set "test"
    .Image("name:=login").Click
 
    .Sync
 
    If .WebList("name:=fromPort").Exist(10) Then
        .WebList("name:=fromPort").Select "Frankfurt"
        .WebList("name:=fromMonth").Select "December"
        .WebList("name:=toPort").Select "Paris"
        .WebList("name:=toMonth").Select "December"
        .WebRadioGroup("name:=servClass").Select "#1"
        .WebList("name:=airline").Select "Unified Airlines"
        .Image("name:=findFlights").Click
    End If
End with
 
'Use the names we gave the browser, and use the same name regardless of changes in its properties
With BrowserObject.Name("RelevantCodes")
    .Link("text:=Articles", "index:=0").Click
    .Link("text:=Home", "index:=0").Click
    .Link("text:=QTP\/Web", "index:=0").Click
End with
 
With BrowserObject
    .Name("DemoAUT").Close
    .Name("RelevantCodes").Close
End with
 
'Release
BrowserObject.Destroy

Notice the demos above. We only have to use the custom name we gave to the browser to perform events on the objects that exist inside of it. Our custom names can be used throughout the automation cycle, but I would recommend you to look into the “ChangeName” method available in the class. This would make object naming easier, and more descriptive, as the titles change the moment we navigate to another page.

1 thought on “QTP – Testing Multiple Browser Applications”

  1. Pingback: Software test pyramid

Leave a Comment

Scroll to Top