QTP: Creating Object Descriptions “On The Fly”

by Anshoo Arora ON September 27, 2009 · Posted In All, QTP, QTP/DP · 12 comments

This article is a follow-up to the Descriptive Programming Series and will discuss a simple way of creating Object Descriptions on the fly. There are several reasons for using this approach, such as overcoming the need to write extra code and having the ability to make the change in only a single place while performing maintenance. This article includes the concepts and working examples of how and when we can must use this approach.

There are instances where object descriptions are incremented in a numerical context. In other words, a part of the object description stays the same, but these descriptions increment starting at a number, generally 0.

To illustrate, consider the below HTML_IDs for 4 list boxes in a Web Application:

List Box 1 HTML ID -> lstBox0
List Box 1 HTML ID -> lstBox1
List Box 1 HTML ID -> lstBox2
List Box 1 HTML ID -> lstBox3

Notice how the descriptions above increment. lstBox is common in all 4 descriptions, but there is a numerical increment after each, starting at 0. When creating an object description in such a scenario, you may tend to do the following:

Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstBox0").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstBox1").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstBox2").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstBox3").Select "Item"

The above is a common usage, and completely acceptable. But in practice, we may have more than 4 Objects with such descriptions and creating the same line of code over and over again, and maintaining everything can be quite a task. In such situations, the concept in this article can be quite beneficial. For example, the above code snippet can be condensed into:

'use a variable to increment from 0 to 3
For x = 0 to 3
	Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstBox" & x).Select "Item"
Next

Now, if the HTML_ID of this object changes, we have to make the change only once as opposed to several times. For example, if the HTML_ID of the list box above was to change from lstBox to lstObject, we would simply update our code like this:

For x = 1 to 4
	'lstBox becomes lstObject
	Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstObject" & x).Select "Item"
Next

Instead of updating it 4 times:

Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstObject0").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstObject1").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstObject2").Select "Item"
Browser("SomeBrowser").Page("SomePage").WebList("html id:=lstObject3").Select "Item"

Numeric Increments

Let’s see a working example. Please open a new IE browser and navigate to the following Page: Demo 1. You can simply set values in all of the text boxes using the following snippet:

With Browser("name:=SimpleDemo1.*").Page("micclass:=Page")
	For x = 1 to 6
		.WebEdit("html id:=txtDemo" & x ).Set "Text Box " & x
	Next
End With

Alphabetic Increments

Now imagine a similar situation where numeric increments are replaced with alphabets. There are several ways of working with such scenarios, but what I generally do is create an array with all the alphabets and increment elements of that array to work with runtime objects:

Dim arrAlphabets: ReDim arrAlphabets(25)
 
arrAlphabets = Array("a", "b", "c", "d", "e", "f", "g", "h", _
		"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", _
		"s", "t", "u", "v", "w", "x", "y", "z")

Now, we can use the array of alphabets using the exact same approach we used for numeric descriptions on Demo Page 2.

With Browser("name:=SimpleDemo2.*").Page("micclass:=Page")
    For x = 1 to 6
        .WebEdit("html id:=txtDemo_" & arrAlphabets(x-1)).Set "Text Box " & UCase(arrAlphabets(x-1))
    Next
End With

If you are starting off with Descriptive Programming and VBScript Arrays, and would like to learn how the above approach works, please ask your questions in the comments section and I will try my best to help you.

Complex Increments

The above 2 uses of this technique are quite basic, and chances are that in your environment, you may not see such simple instances. Let’s create another scenario then, with a little complex description. Please open a new browser, and navigate to Demo Page 3.

When you spy on the WebEdits on this page, you will see a long description for the ‘name’ property. The name property of the six WebEdits are:

txt_applicant[0]BuyProductBox_answerString_A
txt_applicant[1]BuyProductItem_answerString_B
txt_applicant[2]BuyProductBall_answerString_C
txt_applicant[3]BuyProductBat_answerString_D
txt_applicant[4]BuyProductSpoon_answerString_E
txt_applicant[5]BuyProductFork_answerString_F

How can the description for this object be created such that, we can get our work done through a single line of code, instead of creating 6 different statements to set a value in each text box? Notice the descriptions closely, not only are the applicant numbers incrementing in numerical and alphabetical context, but the product lines are changing as well (Box, Item, Ball etc).

The trick here is to use RegularExpressions/WildCards to make the description generic so it becomes available to all 6 WebEdits. There are several ways this generic description can be created, and if you solved this using a different description, please feel free to share it.

Below is one possible solution for our complex scenario:

Dim arrAlphabets: ReDim arrAlphabets(25)
Dim sName
 
arrAlphabets = Array("a", "b", "c", "d", "e", "f", "g", "h", _
		"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", _
		"s", "t", "u", "v", "w", "x", "y", "z")
 
With Browser("name:=SimpleDemo3.*").Page("micclass:=Page")
    For x = 0 to 5
        sName = "txt_applicant\[" & x & "\].*_" & arrAlphabets(x)
        .WebEdit("name:=" & sName).Set "Text Box " & UCase(arrAlphabets(x))
    Next
End With

Summary

This article summarized how working with objects with similar descriptions can be achieved in a simple manner. This approach may not be feasible for all environments, and should only be used when possible. You’re most likely to see Approach#3 in this article used most often, and at times, it does get a little tricky to write descriptions to work with all objects having similar properties.

This article is the last in the Introductory DP series, and future articles will cover advanced concepts and techniques of working with real-life applications.

I hope you guys find this article useful. Thanks for reading :)

Subscribe to Relevant Codes (by Anshoo Arora)

Hello! We're always posting interesting articles on Relevant Codes. Why not subscribe so you don't miss out?

Leave a Comment

{ 12 comments… read them below or add one }

Ganesh October 27, 2009 at 1:55 pm

why dont u share your QTP learning experience with us??? It wud be great motivation for others too..like how you started learning QTP, what you did, how you became the moderator of AdvancedQTP. What say Anshoo?? I think your readers will know you better..

Reply

Anshoo Arora October 27, 2009 at 5:53 pm

I’m really not that good at QTP. What you read on this site is just some bits and pieces of knowledge I have collected over the years. AdvancedQTP happened because of Dani’s and Meir’s kindness.

But, you’re absolutely correct, and I will try my best to update the About Me page with more information about myself, my work and also try to answer all your questions at the best of my ability.

Thank you, Ganesh.

:)

Reply

Ganesh October 27, 2009 at 1:43 pm

what a solution Anshooo…. it worked.. Thank u so much ;)

Reply

Anshoo Arora October 27, 2009 at 1:51 pm

Great!! You’re most welcome :)

Reply

Ganesh October 25, 2009 at 4:06 am

Hello Anshoo,

I have a doubt with Descriptive Programming. Please see the following code:

Set chkbox=Description.Create
chkbox ("html tag").value="INPUT"
chkbox("type").value="checkbox"

Set allchkboxes=Browser("orkut - friends").Page("orkut - friends").ChildObjects(chkbox)

For i=0 to allchkboxes.Count -1
    allchkboxes(i).Set "ON"
Next

Now this code is running fine on this page: –> http://www.google.co.in/preferences?hl=en but it is giving “General Run Error” on the following page :–> http://www.orkut.co.in/Main#ShowFriends?rl=t

Can you please explain me why? I am using QTP 9.2 and Internet Explorer 6.0

regards,
Ganesh

Reply

Anshoo Arora October 26, 2009 at 8:25 am

Hi ,

I think one of the Checkboxes in the website you are testing may be disabled, or hidden. I can think of only these 2 reasons that will cause the error that you experienced.

Try using this code and see if the error persists:

Set chkbox = Description.Create
chkbox ("html tag").value= "Input"
chkbox("type").value= "CheckBox"

Set allchkboxes=Browser("creationtime:=").Page("micclass:=Page").ChildObjects(chkbox)

For i=0 to allchkboxes.Count -1
	If allChkBoxes(i).GetROProperty("disabled") = 0 Then
		If allChkBoxes(i).GetROProperty("x") > 0 Then
			allchkboxes(i).Set"ON"
		End If
	End If
Next

Reply

Vijendra October 24, 2009 at 3:49 am
'Opening Calc applicaiton
SystemUtil.Run "calc.exe"

Set Calc=Description.Create()
Calc("micclass").Value= "Window"
Calc("text").Value="Calculator"
Set Button1=Description.Create()
Button1("micclass").value= "WinButton"
Button1("text").Value="1"

Anshoo, I need to describe for 2,3,4,5,6,7,8,9,0,+,-, = and also for divide(/) and multiply(*) {There will be regualr exp issue here I guess}
I do not want to copy the code above, paste it and make modifications to describe other Descriptive objects
I know I need to use array and looping constructs to reduce my burden, but I unable to name it uniquely for every pass I tired, but I guess I am going seriously wrong somewhere
Can you give me idea on how to propramatically do this ?

Reply

Anshoo Arora October 26, 2009 at 8:14 am

Hi Vijendra,

You can do this:

'12 * 10 = 120
With Window("nativeclass:=SciCalc", "index:=")
	.WinButton("text:=1").Click
	.WinButton("text:=2").Click
	.WinButton("text:=\*").Click
	.WinButton("text:=1").Click
	.WinButton("text:=0").Click
	.WinButton("text:==").Click
End With

But, a simpler way would be to create a function to get rid of the redundancy:

Sub TypeKey(vKey)
 	Select Case vKey
		Case "*"
			vKey = "\*"
	End Select
	With Window("nativeclass:=SciCalc", "index:=")
		.WinButton("text:=" & vKey).Click
	End With
End Sub

TypeKey 1
TypeKey 2
TypeKey "*"
TypeKey 1
TypeKey 0
TypeKey "="

There are several other ways of doing the same, and you can also include verification for the keys you are entering so there is no user error. I will try my best to share some more techniques with you. In the meantime, if you have any questions, please feel free to ask :)

Reply

Anshoo Arora October 28, 2009 at 6:21 pm

Hi Vijendra,

There is also an article out on automating Windows Calculator, which can be found here. I hope you like it. :)

Reply

SEOshnik September 29, 2009 at 10:04 pm

Спасибо аффтару за хороший пост. Полностью прочел, почерпнул много ценного для себя.

Reply

Ganesh October 27, 2009 at 12:54 pm

Can you pls explain this code which you have added:

If allChkBoxes(i).GetROProperty(“disabled”) = 0 Then
If allChkBoxes(i).GetROProperty(“x”) > 0 Then
allchkboxes(i).Set”ON”
End If
End If

Why you are equating it to 0? Also in the second line you r using Getroproperty(“x”) which means Getroproperty(“0″), Getroproperty(“1″) and so on.. Now what does this means?

Reply

Anshoo Arora October 27, 2009 at 1:03 pm

Hi Ganesh,

Excellent questions!

If allChkBoxes(i).GetROProperty("disabled") = 0 Then

This above line checks whether the CheckBox item you are working with is enabled. Equating it to “0″ means, we’re negating the statement. Therefore, equating “disabled” with 0 means, it should not be disabled.

If allChkBoxes(i).GetROProperty("x") > 0 Then

The above line checks whether the object has its “x” coordinate greater than 0. If its 0 or less than 0, it will be outside the scope of the screen. Thus, for the object to be visible to the human eye, it should have “x” greater than 0. Please do not confuse this with .GetROProperty(0) because, “x” is a property of any Web object, and denotes the “x” axis on a coordinate system.

I hope this helps :)

Reply

Previous post:

Next post: