RanorexPath with descendant predicates

Technology specific object identification, supported applications, web technologies, and 3rd party controls.
Vaughan.Douglas
Posts: 250
Joined: Tue Mar 24, 2015 5:05 pm
Location: Des Moines, Iowa, USA

RanorexPath with descendant predicates

Post by Vaughan.Douglas » Tue Mar 24, 2015 5:34 pm

I'd like to convert the following pure Xpath into RanorexPath:

Code: Select all

.//*[contains(@summary, 'Performance Documents')]/descendant::table[descendant::*[contains(text(), 'Performance Review')] and descendant::*[contains(text(), 'Begin')]]/descendant::*[contains(text(), 'Begin')]
I've been messing around trying to convert it, but I can't get the syntax right. I think it should look something like this:

Code: Select all

descendant::*[@summary~'Performance Documents']/descendant::table[descendant::*[@innertext~'Performance Review'] and descendant::*[@innertext~'Begin']]/descendant::*[@innertext~'Begin']
Ranorex doesn't appear to like the descendant axis in the node predicate. I could write this out by traversing up and down the DOM, but I'd rather use the descendant nodes in the predicate of my target node.

Any suggestions?
Doug Vaughan

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Re: RanorexPath with descendant predicates

Post by Support Team » Fri Mar 27, 2015 9:12 am

Hello Voughan,

May I ask if you could explain your question in more detail, maybe based on another sample? Why is it necessary for you to convert the XPath expression into a RxPath instead of generating the RxPath directly?

Regards,
Robert
.
Image

Vaughan.Douglas
Posts: 250
Joined: Tue Mar 24, 2015 5:05 pm
Location: Des Moines, Iowa, USA

Re: RanorexPath with descendant predicates

Post by Vaughan.Douglas » Thu Apr 02, 2015 1:21 pm

Support Team wrote:Hello Voughan,

May I ask if you could explain your question in more detail, maybe based on another sample? Why is it necessary for you to convert the XPath expression into a RxPath instead of generating the RxPath directly?

Regards,
Robert
I'm attempting to create resilient automation to test our integration with Oracle Fusion. The DOM is particularly complected and ugly and we know from previous experience (using QTP) that attributes like ID, class, etc, will change as patches are applied and versions updated.

The RxPath straight from the spy is

Code: Select all

/dom[@domain='REDACTED']//button[#'pt1:USma:0:MAt2:1:AP1:lv21:1:lv10:0:t2:0:lv2:2:cb1']
While I realize I can adjust how RxSpy identifies and evaluates attributes, as you'll see below there doesn't appear to be a good way to get RxSpy to provide me a resilient RxPath.
Rx Fusion Perf Begin.png
Rx Fusion Perf Begin.png (20.32 KiB) Viewed 1856 times
For 90% of what I'm doing regular expressions are working pretty well. However in this particular case I've got over a dozen "Begin" buttons. Four are visible in the attached image, but there are also 4 other sets with various number of "Begin" buttons.

Furthermore, these scenarios are data-driven and the button ID is NOT consistent between users and sessions. The Xpath I proposed allows me to define a row by its contents, in this case containing "Performance Review" and a "Begin" button. Once my row element is identified I can just grab the first and only "Begin" button that's there.

In other similar situations I've been able to use child/descendant elements that were easier to identify and tracked back to the parent/ancestor element that I desired. In this case there are so many div and table objects between identifiable elements that this method become less resilient.

The Xpath of this object according to FirePath is this:

Code: Select all

html/body/div[2]/form/div[6]/div/div/div/div/div[2]/div/div/div/div[1]/div[2]/div/div/div/div/div/div[1]/div[2]/div/div[3]/div/div/div/div[1]/div[1]/div/div[3]/div/div[2]/div/div/div/div/div[1]/div/div/div[3]/div/div[2]/div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div/div[4]/div/div[1]/div[2]/div/div[2]/div/div/div/div[1]/div/div/div[2]/table/tbody/tr[2]/td/div/div/div/div[1]/div[3]/div/div/table/tbody/tr/td[2]/div/div/div[1]/button
Rx Fusion Begin DOM.png
Rx Fusion Begin DOM.png (94.25 KiB) Viewed 1856 times
I've approached our dev team to see if there was a way to insert our own attributes to these elements, but that is simply not possible.

And the extra wrinkle in this situation is that I'm developing automation that will be supported and used by less technical QA folks. My goal is to do this all without creating any custom user code, and so far I've managed to stick to that requirement.
Doug Vaughan

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Re: RanorexPath with descendant predicates

Post by Support Team » Fri Apr 03, 2015 8:14 am

Hello Voughan,

Thank you for the detailed explanation.

May I ask you to create a Ranorex snapshot of your application under test? This would allow us to get more information about the structure of your application. Either upload the snapshot file to the forum or send it to [email protected] directly.

Thank you in advance.

Regards,
Robert
.
Image

Vaughan.Douglas
Posts: 250
Joined: Tue Mar 24, 2015 5:05 pm
Location: Des Moines, Iowa, USA

Re: RanorexPath with descendant predicates

Post by Vaughan.Douglas » Wed Apr 08, 2015 3:50 pm

I don't think I'll be able to send a Ranorex Snapshot as there is a high likelihood that it would contain confidential information.

I'd like to reassert my initial question. Does RxPath have the capacity to identify and element based on sub-elements it contains.

For example:

element[descendant::*[contains(text(), 'Example Text')] and descendant::*[contains(text(), 'Begin')]]

Or in more practical terms, identify a row object based on the contents of two or more component cells.

tr[descendant::td[contains(text(), 'Cell 1 text') and descendant::td[contains(text(), 'Cell 2 Text')]
Doug Vaughan

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: RanorexPath with descendant predicates

Post by krstcs » Wed Apr 08, 2015 4:54 pm

You can use relationship operators to do what you are wanting.

http://www.ranorex.com/support/user-gui ... html#c5804

Just chain them together to get the path you need.

Vaughan.Douglas
Posts: 250
Joined: Tue Mar 24, 2015 5:05 pm
Location: Des Moines, Iowa, USA

Re: RanorexPath with descendant predicates

Post by Vaughan.Douglas » Thu Apr 09, 2015 6:49 pm

While I agree that it is possible to use relationship axis to perform this task, it is not an ideal solution for my requirement. The distance between any two elements that I can reasonably identify can be ten to twenty or more nodes. The problem is that the text value that appears in a given cell of a row in a data table is actually wrapped inside several other anonymous tables, rows, and DIV tags. The only way I can get this to work is by specifying node indices on the way back up the dom which is leaving me at risk to minor chances in the dom layout.

As you can see in the image I posted earlier, I'm looking for the Begin button that is in the same row as "Performance Review" of a web table. Normally this would be just a means of linking cells by following-sibling. However the objects that contain the text "Performance Review" and the object that appears to be a "Begin" button are not siblings. We can see that there is at least thirteen nodes separating the potential sibling from the object containing the text "Performance Review". Going down the dom is just fine, but coming back up to the correct TD tag for which I can use the following-sibling axis on is dubious at best.

Outside of the normal means I would use to solve this with vanilla xPath, I could try to create a repository object that contained multiple RanorexPath properties. I haven't really taken a look at the underlying repository object classes to see how extensible they are.
Doug Vaughan