This is the third article in the Descriptive Programming series, and will outline the concepts of Ordinal Identifiers used in QTP. We will also create a simple test module (step by step) for a login process using only Descriptive Programming (DP).
Ordinal Identifiers – What are they?
Let me quote QTP Reference here:
An ordinal identifier assigns a numerical value to a test object that indicates its order or location relative to other objects with an otherwise identical description (objects that have the same values for all properties). This ordered value provides a backup mechanism that enables QuickTest to create a unique description to recognize an object when the defined properties are not sufficient to do so.
Let’s break the above definition from Mercury/HP into several parts to clarify the concept.
An ordinal identifier assigns a numerical value to a test object
From the quote above, we can conclude that an ordinal identifier is a numerical entity. In other words, its simply a number that is assigned to a test object.
that indicates its order or location relative to other objects with an otherwise identical description (objects that have the same values for all properties)
This means, an Ordinal Identifier works quite differently in relation to the properties we learned in the 1st part of this series. This identifier, or a property if you will, works according to the order or location of test objects. Objects’ order and location are unique characteristics. For example, in a coordinate system, generally only a single object exists on a given ‘x,y’ coordinate. Thus, an ordinal identifier will always be unique. Index defines the order, and location defines location.
This ordered value provides a backup mechanism that enables QuickTest to create a unique description to recognize an object when the defined properties are not sufficient to do so.
The quote above is a good way to conclude this concept of Ordinal Identifiers in QTP. Since it is always unique for an object, it can become extremely useful including these with objects’ mandatory and assisstive properties to prevent falling into object recognition problems. The 3 types of ordinal identifiers are: Location, Index and CreationTime (browser only).
Location Ordinal Identifier
Let’s use an example to understand how the Location Identifier works. Consider the 4 WebEdits below:
| Text Box 1: |
Text Box 2: |
| Text Box 3: |
Text Box 4: |
All the edits above have exactly the same properties. This property works vertically, from top to bottom, and left to right. Thus, ‘Text Box 1‘ will have a location value of 0, ‘Text Box 3‘ will have 1, ‘Text Box 2‘ will have 2, and ‘Text Box 4‘ will have 3. Note that VBScript is zero based, so the location property would start at 0. This can be verified by running the following statements:
'Text Box 1 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=0").Set "1" 'Text Box 3 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=1").Set "2" 'Text Box 2 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=2").Set "3" 'Text Box 4 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=3").Set "4"
Text Box 1: location=0 Text Box 2: location=2 Text Box 3: location=1 Text Box 4: location=3
Index Ordinal Identifier
Index is quite similar to location, but it works pertaining to appearance of objects in the source code1. An object appearing prior in the source code will have a smaller Index value as compared to another object that comes later in the source. Thus, for the same group of edit boxes above: ‘Text Box 1′ will have an index of 0, ‘Text Box 2′ will have 1, ‘Text Box 3′ will have 2 and ‘Text Box 4′ will have 3. Let’s test our statements:
'Text Box 1 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=0").Set "1" 'Text Box 2 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=1").Set "2" 'Text Box 3 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=2").Set "3" 'Text Box 4 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=3").Set "4"
Text Box 1: index=0 Text Box 2: index=1 Text Box 3: index=2 Text Box 4: index=3
That was quite easy, wasn’t it? Now, let’s move on to CreationTime, which is an ordinal identifier strictly reserved for the browser object.
CreationTime Ordinal Identifier
Again, let’s use the description given by HP/Mercury in QTP’s helpfile:
If there are several open browsers, the one with the lowest CreationTime is the first one that was opened and the one with the highest CreationTime is the last one that was opened.
That means, the first browser you open will have a creationtime of 0. The second browser will have a creationtime of 1. The third browser will have a creationtime of 2 and so on.
SystemUtil.Run "iexplore.exe", "http://www.HP.com" 'CreationTime 0 SystemUtil.Run "iexplore.exe", "http://www.AdvancedQTP.com" 'CreationTime 1 SystemUtil.Run "iexplore.exe", "http://www.LinkedIn.com" 'CreationTime 2 Browser( "creationtime:=" ).Highlight 'Highlight HP.com Browser( "creationtime:=1" ).Highlight 'Highlight AdvancedQTP.com Browser( "creationtime:=2" ).Highlight 'Highlight LinkedIn.com
When you run the above code in QTP, you will find that the first browser QTP highlights on is HP.com, the second is AdvancedQTP.com and the third is LinkedIn.com. Even this is quite simple, isn’t it?
As promised, we must create a simple login process using the concepts we have learned so far in the next article.
Descriptive Programming Series
- Descriptive Programming (DP) Concepts – 1
- Descriptive Programming (DP) Concepts – 2 {Regular Expressions}
- Descriptive Programming (DP) Concepts – 3 {Ordinal Identifiers}
- Descriptive Programming (DP) – 4 {Creating a Test Script)
1. Credits go to Harish for finding this error. Thank you Harish!!
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.
{ 68 comments… read them below or add one }
Hi Anshoo,
The decription about Ordinal Identifiers is very simple and Clear.Nicely explained about the basics
Cheers
Suni
Thank you, Suni!
Thank you very much now first time it si pretty clear to me.
Thank you, Kuldeep. I’m glad you found this article useful.
Hello Anshoo,
Can you please me tell me what does CreationTime:=-1 means[Please note it is -1 and not 1]
Example
var=Browser(CreationTime=-1).Exist
Also, I have noticed that this code will always give a “True” value if only a single browser exists.
Hi Shilap,
You’re absolutely correct. However, if you tried the same code with 2 or more browsers open, it would always return false. Call it a feature, or a bug from HP/Mercury, but if you have only 1 browser open, regardless of what creationTime you specify, it will always return true.
When there is only 1 open browser, the maximum creationtime is 0, and I think in QTP’s terms, there is no reason to form a collection to determine the correct browser. Notice how creationtime works, though. The first browser has creationtime 0, the second has creationtime of 1, the third has a creationtime of 2, and so on. Now, when there is only 1 browser open, it doesn’t really matter what value of creationtime you supply because a single browser can be a creationtime of -100 and +100. Any value would be correct.
The real concept of CreationTime comes into picture when there are 2 or more browser open. If QTP has a bug there, then that would be a good cause for concern. :)
Anshoo
Anshoo u r genius…..My assumption is that you people{Anshoo & Tarun} are putting your extra efforts teaching QTP to the people across the globe.
It is people like you who make our world a better place.
Lots of love & thanks
Bibek Khatiwara
Wow, Bibek! Thank you for your kind words. I feel really honored. Thanks.
From the above description ,i came to know that is cent percent sure that the object would be identified using Ordinal identifier,but why dont we use the ordinal identifier property to recognize the test objects?
Let me know if anyone knows the answer
Hi Ragha,
The answer is quite simple. Because an Ordinal Identifier is a numeric property, it becomes very complex to know the index of an object each time you run your regression. That’s why, having other properties helps understand which object you’re working with, it helps to troubleshoot easily, and most of all -> it makes your scripts robust.
Consider an example where there are 100 links on a page. Now, each link will have
Indexordinal identifier from 0 to 99. Now, each link will have its own ordinal identifier. That’s settled. However, if the position of the link changes, the indexes of all object will also change, causing us to lose the object that we need most. That’s why ordinal identifier are coupled with other properties to identify objects.Hi Anshoo, can pls tell me how to use file system object in descriptive programming
eg.
I’ve to create a excel file, write some data in that sheet and close it . how can we do this in descriptive proramming?
pls suggest
Renu
Hi Renu,
What you’re referring to is not a Descriptive Programming concept, but VBScript. Below is a simple snippet that can be used to write data to Excel WorkBook:
Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.WorkBooks.Open("C:\Test.xls") Set xlSheet = xlBook.WorkSheets("Sheet1") 'Write "This is a demo" to Row 2, Column 7 of the Sheet xlSheet.Rows(2).Columns(7).Value = "This is a demo" xlBook.Save xlBook.Close xlApp.Quit Set xlSheet = Nothing Set xlBook = Nothing Set xlApp = NothingHi ,
This site is very help for QTPers.can u plese explain the same code if the excel has ifooter installed i changed the code as
Window(“regexpwndtitle:=TCS iFooter”).WinObject(“regexpwndtitle:=&Cancel”).Click
but it showing the runtime error as not able to find the parent object
Thanks,
Sailaja
Can we implement the same code to wirte in to datatable of QTP
Code for the DataTable would be different. However, you can write data to Excel and Import the Sheet to the desired DataTable.
Hi Anshoo,
what is Automation testing framework, which framework , we can use in QTP?can you give some description about it?
Thanks
Renu
Renu,
Following document shows the types of frameworks: http://www.ibm.com/developerworks/rational/library/591.html and all of them can be easily created in QTP.
Hi Anshoo,
This is the 1st time, I have seen your web site and have been reading your articles since morning
I have n’t even opened any other site since morning.
You are providing a rich knowledge for the begineers and at the advance level too. In small words, GREAT WORK AND KEEP IT UP!!!!
Now one basic question,
I didn’t get the picture what should I choose in between Index and location identifier.
Can you please put some more light on this ?
Thanks,
Harish
Harsh,
Index and Location are both Ordinal Identifiers, they’re both numeric assignments for objects consisting in the AUT.
Index works from left to right, Location works top to down. I use Index 99% of the time when choosing between the two because Location can be a little tricky to work with. I will try to create an HTML example and post it as soon as possible.
Anshoo,
Thanks for your prompt reply.
What I have understood is Index Property is directly proportionaly to Location property.
So, How index is more stable than location and How does it make difference to us whether it’s assigning numeric value from left to right or Top to botton?
-Harish
I think an example would definitely be helpful here. If you observe the footer of Relevant Codes, you will see the following headers: TAGS, RECENT COMMENTS, SUBSCRIBE/SOCIAL MEDIA. If I am working with the links under the Tags heading, I will use Index. For Subscribe and Social Media, I will use Location. Technically, I can use either, but generally one is easier to understand than the other.
Hi,
I have webtable which size 7 column and 4 rows.
Each row i have set of webelements.
I am using checkpoints for checking whether the webelements are there ?
My problem is that , webelement property of one row is similar to other , so it says multiple objects found with the same property.
could you please tell me whether ordianl identifier can use in the checkpoint?
if so please let me konw?
Hi Anshoo,
Thanks a lot for such a wonderful explanation on DP.
I have small doubt, could you please explain me with an example(real time) – how “CreationTime Ordinal Identifier” are useful.
Thank you,
Sophie
Consider the following scenario that opens 2 identical browsers:
How will you work with the first open browser? Here, creationTIme of 0 will be used. How will you work with the second open browser? Here, creationTime of 1 will be used.
In other words, each browser has a numerical identity defined in terms of CreationTime and it always starts with 0. The first browser will have CreationTime of 0, second will have CreationTime of 1, third will have CreationTime of 2 and so on.
Hi, Anshoo,
Thank you for this so thorough guidelines for DP.
I have one requirement which need to complete by DP, maybe also scripting in QTP. Could you kindly help me to investigate in it?
The example is
I want to get the source code of one web page, and then I need to verify the META tag if it is existed.
E.g.,
I need to verify whether the value of content is “text/html;charset=UTF-8″.
I need to verify whether the value of http-equiv is “Content-Type”.
I don’t plan to use this method: Right Click -> View Source -> Get the source code.
How can I get it by DP or scripting in QTP? In other words, how can I get an object which hide in the source code? Maybe I got the misunderstanding of the definition for “Object” in QTP.
Could you advise?
Thank you.
Regards,
Dennis
Dennis,
This can be done through HTML DOM:
Set oRegExp = New RegExp oRegExp.IgnoreCase = True oRegExp.Global = False oRegExp.Pattern = "content=.text/html;.*charset=UTF-8." sOuterHtml = Browser("").Page("").Object.documentElement.outerHtml Set oMatches = oRegExp.Execute(sOuterHtml) If oMatches.Count > 0 Then Reporter.ReportEvent micPass, "Content-Type", oMatches(0) End If oRegExp.Pattern = ".*http-equiv.*Content-Type.*" Set oMatches = oRegExp.Execute(sOuterHtml) If oMatches.Count > 0 Then Reporter.ReportEvent micPass, "http-equiv", oMatches(0) End If Set oMatches = Nothing Set oRegExp = NothingI have used the RegExp object above, but it can also be done through InStr, Left/Right/Mid.
Hi, Anshoo,
I have read this article again today, and I found another question.
How can I simply use the “Object Spy” tool for retrieving the “Location” and “Index”? Is that possible? Do I need to add some customerized properties in “Object Identification”?
In other words, how could I explicitly retrieve the value of “Location” and “Index” ?
Do you have any good idea?
Thank you in advance.
Regards,
Dennis
Hi Dennis,
The Object Spy cannot retrieve either Location or Index identifiers (or CreationTime for Browser) as these are all run-time properties and cannot be determined at design time.
Using QTP methods, the only possible way is to do this through ChildObjects.
QuickTest can assign a value to the test object’s Location property to uniquely identify the object. The first occurrence of the object is 0. Values are assigned in columns from top to bottom, and left to right. Location property values are object-specific.
QuickTest can assign a value to the test object’s Index property to uniquely identify the object. The first occurrence of the object is 0. The value is based on the order in which the object appears within the source code. Index property values are object-specific.
(Reference: Mercury QuickTest Professional User’s Guide > Working with Advanced Testing Features > Configuring Object Identification > Understanding the Object Identification Dialog Box > Selecting an Ordinal Identifier)
Hi Anshoo,
Your are doing great job buddy! I really appreciate it..
I have a question that is out of this box.. but still i have to ask.
I am using Excel sheet in place of Access DB for Input source. and That excel file i m using as a Database (Not as a Excel sheet). But as we know that we can not delete rows from Excel tables.. and in the same time i m not able to set Null value for those particular fields too. So could you please tell me what else i could do just to overcome this problem?
Hi Yogesh,
Please see this article: http://techsupt.winbatch.com/ts/T000001033005F50.html
I hope it will be helpful to you :)
Amazing the best source to learn QTP……Great work Anshooo
Does anyone know if QTP 11 supports Safari browser or MAC OS?
Sorry, this is the confidential information of HP SW Lab. :)
Hi Anshoo
The article is very useful and cleared a lot of concepts of mine. But I have a problem:
I have a table/sheet with 20 records having the field names – id, name, address. I have to fetch the 10th record that will contain only ‘name’ field. How can we do it in DP? Please suggest.
TIA
Anuj Garg
Anuj,
What is the technology of your application?
Hi Ashoo,
Thanks for your efforts..!!!
Can you please help me out in applying text checkpoint in Descriptive programming. I have to put a text checkpoint in the search result.
Thanks,
Dharam
Hi anshu,
While taking the account of ordinal identifies of QTP, we always taking into consideration that location/index number is must present for the desired objects in the application. But suppose we have 4 edit boxes with same properties/values and each object doen’t support any run time objects(3rd part object controls like Ipod software), then in that condition this QTP ordinal identifier mechanism is total failed. Is there is any way we can hadle those objects under the AUT by QTP ?
regards
Niranjan
Niranjan,
Index and Location identifiers are always a runtime property and are assigned each time to EACH object during a run session. Yes, these are generally not the best mechanism for object recognition, and in cases like these, I generally look for WebTables and find the correct row/column combination. In your case then, are these objects embedded within a WebTable?
Is it possible to retrieve the value of Index Ordinal Identifier from Object Repository ,currently I can get all the values under Description properties using GetTOProperties(),but value of index ordinal identifier is not returned.Please advise.
Say for Google page-values of all mandatory properties like name,text,x,y,abs_x,abs_y are returned ,but index value is not retuned.
Bala,
Because index can change depending upon the context of your description or changes in application, it can only be retrieved at run-time.
Thank you for this excellent write-up. Would you have any idea why ordinal identifiers seem to work on some objects but not on others? For example, I have a web app that opens a windows dialog to request authentication. The Browser object is identified but the dialog is not. For example:
If(Browser(“index:=0″).Exist) Then
If(Browser(“index:=0″).Dialog(“index:=0″).Exist) Then
Set x = True
End If
End If
When stepping through with a debugger, the first test is true and the second is false. The Dialog object apparently cannot be referenced with ordinal identifiers.
Try this:
MsgBox Dialog("micclass:=Dialog").Exist(0)Hi Anshoo,
Really I impressed your QTP articles.Anyway I am a beginner in QTP and still learning QTP scripts.I want to do practice and learn QTP real time scripts.Is there any specific link or articles to get learn from you.
Thanks
S kumar.T
Hi Anshoo,
Can you please tell me the method to select valies from a dropdown using index ?
Example : I have a dropdown which contains multiple values and i want to select values from this drop using DP and index property ?
Shubhanshu: “#” can be used before the index value to select it from the List. Example:
Browser("").WebList("").Select "#1" 'selects the 2nd item in the listHey Anshoo,
How to get the “Index” value of any element using DP.
I tried with google.com to get index values for WebEdit fields. There are total 5 WebEdits. But i am not able to print there index values i.e 0, 1, 2, 3, 4
Code is as below:
Set myp = browser(“title:=.*”).page(“title:=.*”)
Set myedit = description.Create()
myedit(“micclass”).value = “WebEdit”
myedit(“html tag”).value = “TEXTAREA”
‘Get all webedit fields
set Noedit = myp.ChildObjects(myedit)
print Noedit.count
If Noedit.count = 0 Then
print “No WebEdit fields were found”
else
For i=0 to Noedit.count-1
print “Webedit # ” & Noedit.count & ” = ” & myp.webedit(myedit).GetROProperty(“name”)
print “~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”
Next
End If
Kindly guide,
Thanks
Radhika
Radhika,
In your For-Loop, all you need to do is to refer the item-index for the collection object (Noedit) to retrieve the ‘name’ property for each Edit. Simply add this to your loop:
Print Noedit(i).GetROProperty("name")I need help on identifying the 2 webedit boxes which are adjacent to each other on a web page using descriptive programming
hi ..
try this code ,ur doubts about index and location properties gets cleared(application used as aut: http://www.google.co.in/intl/en/options/)
Dim a
Set myp=browser(“name:=.*”).page(“title:=.*”)
Set myedit=description.Create
myedit(“micclass”).value=”link”
Set noedit=myp.ChildObjects(myedit)
print noedit.count
If noedit.count=0 Then
print “no links”
else
For i=0 to noedit.count-1
print noedit(i).getroproperty(“index”)
print noedit(i).getroproperty(“name”)
Next
a=browser(“name:=.*”).page(“title:=.*”).link(“index:=1″).getroproperty(“name”)
print a
End If
to use the location property:
Dim a
Set myp=browser(“name:=.*”).page(“title:=.*”)
Set myedit=description.Create
myedit(“micclass”).value=”link”
Set noedit=myp.ChildObjects(myedit)
print noedit.count
If noedit.count=0 Then
print “no links”
else
For i=0 to noedit.count-1
print noedit(i).getroproperty(“index”)
print noedit(i).getroproperty(“name”)
Next
a=browser(“name:=.*”).page(“title:=.*”).link(“location:=1″).getroproperty(“name”)
print a
End If
Hi Anshoo,
How do we identify the index of an object if it the application is not yet developed. Also if the application is developed and there are many objects of the same type having same properties, then how do we know the index without having to go through the source code and doing trying to guess the index.
Murgendra: If the application has not been developed and if you do not have the HTML source (considering its Web), then there is no way you can tell what the index of a given object will be. Also, you must note that indexes depend on other properties. So, adding one property can change the index value and removing another property can again change it.
If the application is ready, you can find out the index using:
1. Loop with Index increments + Highlight
2. ChildObjects
3. HTML DOM length etc.
In some apps, the Index can be dynamic so the above techniques may be required to create robustness.
Thanks for your reply
Thanks a lot Anshoo for such a quick reply, got it now. Thanks once again
Could you please suggest me some other stuff, i am in the learning phase of QTP, done with classroom course, however still need to work on to understand real environment.
Hi, Anshoo,
Yeah, that’s a good solution for this. Thank you for your quick response.
A quick question for your information:
Do you have any concerns about the performance of this method?
Regards,
Dennis
It worked quite well for me Dennis. On which lines do you see a drop in performance? We can surely fix it! :)
Hi,
Firstly, sorry for the delay of this reply.
Yeah, in practice, I’ve tried to do some stress testing in such larger HTML file by this code even use this code in several iterations , but fortunately, it can work well.
Thanks again for your kindness and your help.
Regards,
Dennis
:)
Hi, Anshoo,
Thank you very much. Yeah, I concur with you, maybe that is the only way what I can get it done. Hope it can be implemented by QTP11 :), since I think these properties is very useful.
Regards,
Dennis
QTP 11 Beta 1 is being released tomorrow *fingers crossed*. There have been several improvements/enhancements, but we’ll only know for sure when we try :)
yeah, aha. Perhaps, we cannot see beta version so quickly, and I think alpha version will coming soon. :D
any URL to give a test ?
The app is built on ASP.net with C#.
Hi Anshu
Thanks for your reply
Even I meant to retrieve the value of Index Ordinal Identifier from Object Repository during run time only
We pass ordinal identifier value after referring in object repository right…?
I dont want to refer the object every time in OR and then use during DP.
For Test Object we just use GetROProperties and retrieve the values available in TestObjectDetails area under Description properties …However I cannot use GetROProperties and retrieve the Ordinal identifier value.
Object Repository stores “test” or “design” time values. Index is generated at run-time. A stored Index in OR can change during run-time and you may end up interacting with incorrect object. Btw, do you mean GetTOProperties, or GetROProperties?
Hi Anshoo
I am sorry.I misspelled GetROProperties instead of TestObject.GetTOProperties
Thanks Anshoo.I think I cannot do what I need then.as the index may change anyway during runtime and will not solve the purpose
One more item to check ..
We can retrieve or manipulate Test Objects in Object repository using Objectrepository.util object and GetTOProperties.
However this method is not able to retrieve Checkpoint Test Objects in Object repository and print the checkpoints and its properties.
Reference:Manipulate Object Repositories Using the Object Repository Automation Objects and Methods in QTP Help file It provides reference and example only for Test Object and methods .
MsgBox Dialog(“micclass:=Dialog”).Exist(0)
True
MsgBox Dialog(“index:=0″).Exist(0)
False
MsgBox Browser(“index:=0″).Dialog(“index:=0″).Exist(0)
False
MsgBox Browser(“index:=0″).Dialog(“micclass:=Dialog”).Exist(0)
False
This seems like a bug. Object Spy has no problem placing the Dialog in the context of the Browser.
{ 5 trackbacks }