Relevant Codes (by Anshoo Arora)

A Test Development Resource for HP QuickTest Professional.

QTP: Working with Multiple Browser Applications (Revised)

by Anshoo Arora on October 19, 2009

Introduction
Web applications due to their dynamic nature, make script development quite challenging. I am writing this article in an attempt to simplify one of its aspects that automation developers face while working with Web applications. We will see how it can be made extremely easy to work with 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 titles (unless we need to). 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 number of times as we want. Next, we will create a Browser class, that will make use of the global variable (as a reference) we declared above:

Class clsBrowser
 
End Class

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:

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: 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 above open browser using its title
BrowserObject.AddUsingTitle "DemoAUT", ".*Mercury Tours.*"
 
SystemUtil.Run "iexplore.exe", "http://relevantcodes.com", "", "", 3 : Wait(4)
'Add the above open browser using its title
BrowserObject.AddUsingTitle "RelevantCodes", ".*Relevant Codes.*"
 
'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.

Download clsBrowser | View as Plain Text | Download Demo Test QTP9.2 | Download Demo Test QTP9.5

References
1. An Improved Dictionary Object by Yaron Assa (AdvancedQTP, SolmarKN)
2. Singleton Pattern by Yaron Assa (AdvancedQTP, SolmarKN)

If you have any questions, please ask them in the comments section. If your query is confidential, please use the Contact Form to send me an e-mail instead.

{ 28 comments… read them below or add one }

1 Clive Farrington November 6, 2009 at 4:35 pm

Just wanted to let you know that the demo fails because the Categories section at the bottom of the page now has a duplicate of the QTP/Web object – need a index:=0 to uniquely identify it. Thanks for the code though, very interesting.

Reply

2 Anshoo Arora November 6, 2009 at 4:50 pm

Thank you, Clive. I will upload the new file tonight.

3 Puneet Varma February 9, 2010 at 6:24 pm

HI Anshoo,

How can I use DP to scroll down on a window application? I tried the following but it didn’t work.

Set Keyboard = DotNetFactory.CreateInstance( “Microsoft.VisualBasic.Devices.Keyboard”, “Microsoft.VisualBasic” )
SwfWindow(“ePDHA – You are currently”).SwfObject(“panel7″).Click
Wait 1
Call Keyboard.SendKeys( “{PGDN}”, True )

Thanks for you help.
Puneet

Reply

4 Anshoo Arora February 10, 2010 at 12:03 am

Hi Puneet,

Try this:

Sub MoveScrollBar(sDirection, iTimes)
        Dim oWScript, x

        Set oWScript = CreateObject("Wscript.Shell")

        For x = 1 to iTimes
                oWScript.SendKeys "{" & sDirection & "}"
        Next

        Set oWScript = Nothing
End Sub

Usage:

hwnd = SwfWindow("ePDHA – You are currently").SwfObject("panel7″).GetROProperty("hwnd")
Window("hwnd:=" & hwnd).Activate
MoveScrollBar "Down", 5

5 Puneet Varma February 15, 2010 at 5:28 pm

Hello,

The above code did not work, but I try doing the following:
Window(“HA”).WinObject(“frmAssessment2″).VScroll micPageNext, 2

This code worked once, but then it doesn’t work any more. This is a window application.

Thanks

Reply

6 Anshoo Arora February 17, 2010 at 8:42 am

Puneet,

Did you try the above code? It generally works as its a simple mechanism to perform automated scrolls.

7 Anonymous May 5, 2010 at 6:23 am

Can anyone explain what is Me. in the following code.

With colObject
.Add sName, Browser(“hwnd:=” & Me.HWND)
.Add sName & “-HWND”, Me.HWND
End With

Reply

8 Anshoo Arora May 5, 2010 at 8:06 am

Me is the region (Class) object that helps differentiate between local (function) and region level variables. Example:

Class TestClass
	Public TestName 'Region Variable

	Public Function TestFunction()
		Dim TestName 'Local Variable

		TestName = "Test 001" 'Local Variable defined
		Me.TestName = "Test 002" 'Region variable defined

		MsgBox TestName
		MsgBox Me.TestName
	End Function
End Class

Set NewTestClass = New TestClass
NewTestClass.TestFunction

9 Aruna June 10, 2010 at 7:08 am

Hi Anshoo,
I tried the above code for child objects of browser.
Set oCol = Desktop.ChildObjects(oBrowser)
I got an error like object required.
Please check the code and guide me.

Reply

10 Anshoo Arora June 10, 2010 at 2:12 pm

Aruna,

In your code, what is oBrowser?

11 Aruna June 10, 2010 at 7:13 am

Thank You Anshoo.
You hava done a great job by providing guidance for QTP beginners n experienced as well.
Keep it up.
My request is to give syntax explanation so that will ne more helpful for ewbees .

Thanks onceagain Anshoo

Reply

12 Vishal July 6, 2010 at 6:42 pm

Hey Anshoo,

First of all thanks for the beautiful code.
But I am having trouble running it. It keeps giving me ‘object required’ error at line ‘BrowserObject.AddUsingCreationTime “DemoAUT”, 0. Could you please help me?

Reply

13 Anshoo Arora July 8, 2010 at 12:28 pm

Hi Vishal,

Have you associated the function library with the test before executing the statement?

14 Gurdev September 27, 2010 at 1:39 pm

Hi,

is there a way to handle multiple browsers using Object Repository?

I have two different applications that I have to use to login, I have the objects and properties in the same shared OR.
with 2 browser class.
ex.
Browser(“abc1″) – creationtime for this is 0 (in OR)
Browser(“abc2″) – creationtime for this is 1 (in OR)
I have to go back and forth on the applications.

I’m having problem detecting one after another, most of the time I have to close one of the browser to recognize the object.
the reason is CreationTime on the classes are in OR.
I tried various methods and i got my script working, but then the other scripts fail.

I tried using location, so i had to modify the shared OR and changed the creationtime to location. Not so useful.
Is there another way using OR?

Thanks,

Gurdev

Reply

15 Suhas October 7, 2010 at 1:25 am

If GMail is Opened is 2 browser and How can we detect original application through QTP. Please anyone tell me

Thank you,

Regards,

Suhas.A

Reply

16 Anshoo Arora November 14, 2010 at 5:02 pm

The first GMail browser will have a lower creationTime value as compared to the GMail browser that was opened after wards..

17 Anonymous October 10, 2010 at 12:52 pm

use creation time 0 for firstbrowser and second is creation time1

Reply

18 Sevenup February 22, 2011 at 12:00 pm

Hi,
where does the intVal come from in Sub AddUsingCreationTime?
Regards,
Sevenup

Reply

19 Anshoo Arora February 23, 2011 at 2:20 am

Good question. I just saw it too, and it seems like a bug in the code. I will investigate this in the morning and update you. Thanks!

20 Pavneet Singh February 23, 2011 at 6:27 am

Hi Anshoo

I want to create and add objects to OR during runtime , is this method possible ? Please update

Regards,
Pavneet Singh Bhatia

Reply

21 Louis June 2, 2011 at 6:06 am

Function function_IdentifyNewBrowser2 (objBrowser)

Dim objFindBrowser, objBrowserChild, strHwnd

‘ Description object for Browser Class
Set objFindBrowser = Description.Create
objFindBrowser(“micclass”).Value = “Browser”

‘ ChildObjects of Browser Class Description
Set objBrowserChild = Desktop.ChildObjects(objFindBrowser)

‘ Store the Browser Handle
objBrowser.SetTOProperty “hwnd”, Browser(“creationtime:=” & objBrowserChild.Count – 1).GetROProperty(“HWND”)

End Function ‘ function_IdentifyNewBrowser2

Reply

22 Radhika June 23, 2011 at 9:44 am

Hey Anshoo,

I am trying to navigate from one browser to another but it is not happening.
systemutil.Run “iexplore.exe”, “yahoo.com”
browser(“IE”).Navigate “google.com”

It opens “yahoo.com” successfully but does not navigate to google in next step.

I have qtp 10 and IE 8

Thanks,
Radhika

Reply

23 Anshoo Arora June 24, 2011 at 11:17 am

Radhika: It may not work correctly because the properties for the Browser object may not be correct, or because the script runs faster than it takes to open the browser. Try this:

SystemUtil.Run "iexplore.exe", "yahoo.com"

If Browser("title:=Yahoo!").Exist(15) Then
	Browser("title:=Yahoo!").Navigate "google.com"
End If

24 Anonymous August 11, 2011 at 5:05 pm

i am having the same problem Qtp is not recognising the browsers, please help

Reply

25 ankita suhaney November 2, 2011 at 3:21 am

I am trying this line of code:
Window(“DEMO2301.spm”).Window(“Window”).WinObject(“F3 Server 60000000″).VScroll micScrollStart

but it is giving me runtime error:
This operation cannot be performed.

Can anybody tell me the probable reasons for it?
My WinObject is having vertical scrolldown

Reply

26 Vishal July 12, 2010 at 1:34 am

Hi Anshoo,

Thanks for reponding to my request.
Before running the script, I downloaded the library file, saved as qfl and associated with the ‘Demonstration: AddUsingCreationTime’. Second time I tried with ‘Demonstration: AddUsingTitle’ , but got same error both the times. I repeated the steps with saving the library as vbs but still got same error.

Regards.

Reply

27 Anshoo Arora July 14, 2010 at 3:16 pm

Vishal,

I’m not exactly sure what’s causing this issue, but please download this test and see how’s its been implemented there. You can use the concepts in the test to make your existing code work.

Reply

28 Radhika June 24, 2011 at 1:54 pm

Still not working for me. I tried cross checking all the properties of the browser and also with the “If…loop” but not working. :(

If browser(“opentitle:=Yahoo!”).Exist(25) Then
browser(“opentitle:=Yahoo!”, “name:=Yahoo!”).Navigate “www.gmail.com”
End if

Radhika

Reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post: