cancel
Showing results for 
Search instead for 
Did you mean: 

Using Xpath in TestComplete

SOLVED
Occasional Contributor

Using Xpath in TestComplete

Hello Everyone, 

 

As we're getting deeper into using TestComplete we noticed through the name mapping that TestComplete doesn't really pull information that we would want it to so it can identify objects. For example,for our sign out button it pulled ObjectType, href, and ObjectIdentifier.

 

To me, that doesn't seem like concrete evidence that is going to be the sign out button and especially down the line it will be horrendous to try and maintain, as the hierarchy is already getting messy and confusing.

 

So our solution was to create scripts to house all of the buttons we would use and their xpaths to call them. Easily maintened, easily navigated. 

 

But the problem I'm facing right now is (the code will be wrong) I'm trying to do something like this:

 

Script: Buttons

SignOut_Button = //*[@id='signout']/div[1]

 

Script:ClickTheButton

page.Buttons.SignOut_Button.Click();

 

I haven't been able to find any documentation on how we would be able to make this work. Is anyone able to point me in the right direction? Or is the name mapping part of the program going to be impossible to circumvent? 

2 ACCEPTED SOLUTIONS

Accepted Solutions
Community Hero

Re: Using Xpath in TestComplete

NameMapping is not impossible to circumvent... but something to keep in mind is that the properties that TestComplete uses automatically are not fixed in stone.  You can edit, add, remove, adjust, etc. the properties used to identify objects to meet what you're looking for.  As I've mentioned many times, I rarely stick with what TestComplete gives me automatically and usually end up doing some sort of modification.

 

Keep in mind that TestComplete's identification criteria is two-fold.

 

1) Find the parent object... at the Root, that's NameMapping.Sys.  For additional layers, like your application, it starts with NameMapping.Sys and then looks at the children.  So, the first criteria is "Does the parent have a child..."

2) Second criteria "...with properties that match this set."  So, you may have multiple objects that have the exact same properties... but if they are children of different parent objects, TestComplete sees them as distinct objects.  But the properties themselves are key to making sure that the CORRECT child object is identified.  

 

So, for example, you have objectidentifier which COULD be something ugly like MainContent_divMain_divSubMain_btnSignOut.  Which, really, is ugly because, if the page changes in hierarchy, that could change.  Howerver, you can wild card it... I'd assume that, for the specific parent of the signout button, there would only be one object that would match "*btnSignOut".  Likewise your href...  test domains shift and change so the root URL may be different... but the rest of the path, if developer properly, should be the same... so, you're href could be edited to "*/signout.aspx" or whatever it is.

 

But you are not limited to using only ObjectType, href, or ObjectIdentifier... ALL the properties of the object are available to you for identification so, if there are properties that you would prefer to use, feel free to use them instead.

 

Now, if you're going to use XPath, you will want to us FindChildByXPath (https://support.smartbear.com/testcomplete/docs/reference/test-objects/members/web-objects/findchild...  In this case, your code would be something more on the lines of

 

browser = Sys.Browser(*);

page = browser.Page('myURL');

SignOut_Button = page.Buttons.FindChildByXPath('/*[@id='signout']/div[1]')

if (SignOut_Button.Exists) {

    SignOut_Button.Click();

}

 

 

This pretty much completely by passes the NameMapping.  Now, you can organize things into code units and so forth to build your own object identification structure, but, in your example, "Buttons" is not a child of the page... Button is a code unit that you are using to bring in the SignOut_Button object... so, you just simply need to click on the object.

 

One thing of note... FindChildByXPath is slower than NameMapping in object identification because it does need to look at the whole page.  NameMapping, once an object is found, it remains in cache until the cache is refreshed or until it needs to be found again.  I would highly suggest that you look into using NameMapping for your project... but as mentioned above, work with the properties exposed by TestComplete.  If you need help in figuring out unique identification, please feel free to ask and we'll help as best we can.  


Robert Martin
[Community Expert Group]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available

View solution in original post

Community Hero

Re: Using Xpath in TestComplete

One other note:

 

Under Tools | Options | Engines | NameMapping there's an option to "Use extended find when possible" that, by default, is checked.  Extended find is a POWERFUL way of collapsing unnecessary identification hierarchy in your NameMapping tree... but it can cause a mess if it's left to it's own devices.  I prefer to turn that option OFF and, if I need to use Extended Find, I can apply it to the objects I need it to manually.  It sounds like, with "the hierarchy is getting messy" comment from you that it could be that Extended Find is collapsing a bunch of stuff making it hard to make heads or tales out of what objects belong to which parents.  Turn the option off and try remapping some of your stuff.  The hierarchy will make more sense then....

 

... and then do any "collapsing" you need to do using the Aliases part of NameMapping to compress long object chains into shorter identifiers.


Robert Martin
[Community Expert Group]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available

View solution in original post

4 REPLIES 4
Community Hero

Re: Using Xpath in TestComplete

NameMapping is not impossible to circumvent... but something to keep in mind is that the properties that TestComplete uses automatically are not fixed in stone.  You can edit, add, remove, adjust, etc. the properties used to identify objects to meet what you're looking for.  As I've mentioned many times, I rarely stick with what TestComplete gives me automatically and usually end up doing some sort of modification.

 

Keep in mind that TestComplete's identification criteria is two-fold.

 

1) Find the parent object... at the Root, that's NameMapping.Sys.  For additional layers, like your application, it starts with NameMapping.Sys and then looks at the children.  So, the first criteria is "Does the parent have a child..."

2) Second criteria "...with properties that match this set."  So, you may have multiple objects that have the exact same properties... but if they are children of different parent objects, TestComplete sees them as distinct objects.  But the properties themselves are key to making sure that the CORRECT child object is identified.  

 

So, for example, you have objectidentifier which COULD be something ugly like MainContent_divMain_divSubMain_btnSignOut.  Which, really, is ugly because, if the page changes in hierarchy, that could change.  Howerver, you can wild card it... I'd assume that, for the specific parent of the signout button, there would only be one object that would match "*btnSignOut".  Likewise your href...  test domains shift and change so the root URL may be different... but the rest of the path, if developer properly, should be the same... so, you're href could be edited to "*/signout.aspx" or whatever it is.

 

But you are not limited to using only ObjectType, href, or ObjectIdentifier... ALL the properties of the object are available to you for identification so, if there are properties that you would prefer to use, feel free to use them instead.

 

Now, if you're going to use XPath, you will want to us FindChildByXPath (https://support.smartbear.com/testcomplete/docs/reference/test-objects/members/web-objects/findchild...  In this case, your code would be something more on the lines of

 

browser = Sys.Browser(*);

page = browser.Page('myURL');

SignOut_Button = page.Buttons.FindChildByXPath('/*[@id='signout']/div[1]')

if (SignOut_Button.Exists) {

    SignOut_Button.Click();

}

 

 

This pretty much completely by passes the NameMapping.  Now, you can organize things into code units and so forth to build your own object identification structure, but, in your example, "Buttons" is not a child of the page... Button is a code unit that you are using to bring in the SignOut_Button object... so, you just simply need to click on the object.

 

One thing of note... FindChildByXPath is slower than NameMapping in object identification because it does need to look at the whole page.  NameMapping, once an object is found, it remains in cache until the cache is refreshed or until it needs to be found again.  I would highly suggest that you look into using NameMapping for your project... but as mentioned above, work with the properties exposed by TestComplete.  If you need help in figuring out unique identification, please feel free to ask and we'll help as best we can.  


Robert Martin
[Community Expert Group]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available

View solution in original post

Community Hero

Re: Using Xpath in TestComplete

One other note:

 

Under Tools | Options | Engines | NameMapping there's an option to "Use extended find when possible" that, by default, is checked.  Extended find is a POWERFUL way of collapsing unnecessary identification hierarchy in your NameMapping tree... but it can cause a mess if it's left to it's own devices.  I prefer to turn that option OFF and, if I need to use Extended Find, I can apply it to the objects I need it to manually.  It sounds like, with "the hierarchy is getting messy" comment from you that it could be that Extended Find is collapsing a bunch of stuff making it hard to make heads or tales out of what objects belong to which parents.  Turn the option off and try remapping some of your stuff.  The hierarchy will make more sense then....

 

... and then do any "collapsing" you need to do using the Aliases part of NameMapping to compress long object chains into shorter identifiers.


Robert Martin
[Community Expert Group]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available

View solution in original post

Community Hero

Re: Using Xpath in TestComplete

How about NameMapping along with Aliases, because those will be some ugly names to deal with and probably easy to mistype?

Community Hero

Re: Using Xpath in TestComplete

Hi,

 

Actually, search by XPath is the worst approach in TestComplete's world and should be used as the last resort only.

Several points of top of my head:

-- According to my direct measurements, search by XPath is usually 3-5 times slower than search via Namemapping/FindChild();

-- XPath is case sensitive (translate() function makes XPath expression hardly readable);

-- XPath does not support regular expressions (try to write an XPath looking for either IMG or CANVAS element on the page);

-- If sought for element has id specified, then, as for me, "//*[@id='signout']" XPath is not better in any area than .FindChild("id", "signout", 1000). And if the sought for object has no unique and stable identification attributes, than "//*[@id='signout']/div[1]" XPath is equally unclear as .FindChild("id", "signout", 1000).Panel(1);

-- XPath may return native DOM object. This object will not have TestComplete-provided methods and properties (like .Exists and other). So the check like soughtForObject.Exists will crash and you will have to check first if the returned object is native DOM or TestComplete one and code accordingly.

Regards,
Alex
[Community Expert Group]
____
[Community Expert Group] members are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Postings made by [Community Expert Group] members
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
[Community Expert Group] signature is used with permission by SmartBear Software.
http://smartbear.com/forums/f83/t86934/community-experts/
================================