Configuring XPath to automatically use REGEX value

Ask general questions here.
jlowder
Posts: 55
Joined: Wed Dec 30, 2009 2:56 pm

Configuring XPath to automatically use REGEX value

Post by jlowder » Thu Dec 31, 2009 3:40 pm

Hello,

I was wondering if it was possible to have Ranorex automatically replace certain Xpath values with a regular expression?

For example, everytime an object has "element" or "element[#]" in it's Xpath, could that be replaced with an * instead? I want to keep the elements with actual values attached to them (like element[@type=''] etc). I'm spending a significant amount of time working on the object repository instead of my scripts. This ability would greatly help reduce those tedius tasks.

Thanks,

Jason

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Re: Configuring XPath to automatically use REGEX value

Post by Ciege » Thu Dec 31, 2009 3:43 pm

Well you could write your own little method that you call that will convert a passed in XPath to use a regular expression. You could add quite a bit of intelligence to treat different types of elements different and behave differently based on input parameters.
If this or any response has helped you, please reply to the thread stating that it worked so other people with a similar issue will know how you fixed your issue!

Ciege...

jlowder
Posts: 55
Joined: Wed Dec 30, 2009 2:56 pm

Re: Configuring XPath to automatically use REGEX value

Post by jlowder » Thu Dec 31, 2009 4:26 pm

I'm not even sure where I would begin to do such a thing. It seems to me that what you suggest may be an even larger undertaking than actually modifying the repository directly. To be useful I would need a method that would take in all repository items and modify them on the fly before they are used. Granted, I'm new to C# but I just don't see how that would be feasable. Can you provide a little more detail of how your suggestion would work?

Thanks

Jason

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Re: Configuring XPath to automatically use REGEX value

Post by Ciege » Thu Dec 31, 2009 4:36 pm

Unfortunately I do not use the repository so I do not have code on hand to give you that will take information out of the repository and manipulate it. I do all my object finding real time based on variables. I.e. I have a clickButton method that takes in a form variable and a button name variable. That method automatically searches the form for the button and either clicks on it or returns an error to the caller that the button could not be found.

The way I do things is not "typical" for a Ranorex user but works very well for the way I write my automation code.

So that I can expand on my suggestion for you a bit. Can you give me an example of an XPath from your repo and then how you would expect that XPath to look after you "REGEX'd" it? Then I can expand a little on how I would write a method to do this.

Second question (since I don't use the repo I don't know the answer to this) why do you need to change XPaths in your repo? I thought that they were put there to specify a specific object and that each was unique for each object. What is the need to continue modifying XPaths in the repo?
If this or any response has helped you, please reply to the thread stating that it worked so other people with a similar issue will know how you fixed your issue!

Ciege...

jlowder
Posts: 55
Joined: Wed Dec 30, 2009 2:56 pm

Re: Configuring XPath to automatically use REGEX value

Post by jlowder » Thu Dec 31, 2009 5:13 pm

What you are doing is exactly something I was considering with my previous post about using FindSingle.

Our web application is using Flash and each time the page loads the locations of certain objects sometimes change. There is virtually nothing static with our object XPaths, yet certain elements will remain the same (caption, text, id etc.). Because of those specific items that don't change, I was hoping to simply "find" the object on the fly based on this information and then create an object specifically for it.

Would you be willing to share the code you use to locate objects or provide some pointers on where to start looking to create such methods? My first attempt with the Find/FindSingle methods for our flash app have been returning errors that have put me at an impasse.

One of the XPaths that gives me grief looks like:

element[@type='BvSprite']/element[1]/element[@type='BvWizard']/element[2]/element[3]/element[@type='BvXMLInterface']/element/element[1]/element[@id='nextBtn2']/text[@caption='Next']

all of those element[#] values will sometimes change from page rendering to page rendering. That's why I was looking to replace them all with *'s. But if I could find an item based on one of the specific element id's that would be nice.

Thanks,

Jason

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Re: Configuring XPath to automatically use REGEX value

Post by Ciege » Thu Dec 31, 2009 5:23 pm

Well, here is the method I wrote for PushButtonClick. Basically it accepts a Ranorex Form object and a string pushbutton name (which could be its controlname or its text value). It will search the form for a button object with that value. If it finds it, it will click the pushbutton. If it does not find it, it will return an error code.

Obviously you can modify this to search for all kinds of objects. I split out many methods from this such as a textboxclick, checkboxclick, tabclick, etc... They could all be the same method (basically) but it is easier to break them out so other, greener automation developers, can just use this as an API to manipulate all the different types of elements within a form.

Make sense?

Code: Select all

        public static int PushButtonClick(Ranorex.Form RanorexFormName, String PushButtonName, bool boolHideNotFoundError)
        {
            /************************************************************************
             * Function         : PushButtonClick(Ranorex.Form RanorexFormName, String PushButtonName)
             *
             * Description      : This function will search for and (if found)  
             *                  :  select a PushButton on the form.
             *                         
             * Parameters       : RanorexFormName   - The form object the the PushButton lives on
             *                  : PushButtonName    - Name of the PushButton to click
             *                  : boolHideNotFoundError - FALSE (default) - reports that the item was not found - returns -1
             *                  :                       - TRUE - Hides the error that the item was not found - Still returns -1
             *                  :                       - This option basically transforms this method into a check if exists method
             *                  
             * Return Type      : Integer
             * 
             * Return Value     : 0 for success, -1 for failure
             * 
             * Revision History
             * Date       : Author                    : Reason/Change
             * ---------- : ------------------------- : ------------------------------
             * 03/05/2009 : Chris Gendreau            : Initial Creation 
             * 12/10/2009 : Chris Gendreau            : Added HideNotFoundError option
            ************************************************************************/

            Ranorex.Button HDbutton;
            int error = 0;

            //Search for the PushButton on the Form
            try
            {
                RanorexFormName.EnsureVisible();
                RanorexFormName.Activate();
                Thread.Sleep(500);
                HDbutton = RanorexFormName.FindSingle(".//button[@controlname='" + PushButtonName + "' or @text='" + PushButtonName + "']", 30000);
            }

            catch (RanorexException e)
            {
                if (boolHideNotFoundError != true)
                {
                    Report.Error("Unable to find PushButton: " + PushButtonName);
                    Report.Error(e.ToString());
                    Report.Screenshot();
                }
                error = -1;
                return error;
            }

            //Click a PushButton
            try
            {
                Report.Debug("Clicking PushButton: " + PushButtonName);
                HDbutton.Focus();
                Thread.Sleep(500);
                HDbutton.Click(Location.Center);
                Report.Debug("  Clicked PushButton: " + PushButtonName);
            }

            catch (RanorexException e)
            {
                Report.Error(e.ToString());
                Report.Screenshot();
                error = -1;
            }
            return error;
        } //End PushButtonClick
If this or any response has helped you, please reply to the thread stating that it worked so other people with a similar issue will know how you fixed your issue!

Ciege...

jlowder
Posts: 55
Joined: Wed Dec 30, 2009 2:56 pm

Re: Configuring XPath to automatically use REGEX value

Post by jlowder » Thu Dec 31, 2009 5:30 pm

Yes, thank you. That is precisely what I had in mind. I just need to get a response from support about my use of the FindSingle method with my Flash objects. Either FlexObject or my base URL is causing grief for the root "form"..

Thanks again,

Jason

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Re: Configuring XPath to automatically use REGEX value

Post by Ciege » Thu Dec 31, 2009 5:40 pm

I have not done any flex testing yet so I can't help out specifically. However...

In your other post. Is the error coming on the first or second line?
Is a flex element a child of the document object?
Maybe first find the document object, then find the flex element, then search from the flex element down.

1) Find the DOM object

Code: Select all

Ranorex.WebDocument HDWebForm = Host.Local.FindSingle<Ranorex.WebDocument>("/dom[@pageurl='" + DOMURL + "']");
Once you have the DOM object, then find the flex element. Then under the flex element find the object you want to interact with.
If this or any response has helped you, please reply to the thread stating that it worked so other people with a similar issue will know how you fixed your issue!

Ciege...

jlowder
Posts: 55
Joined: Wed Dec 30, 2009 2:56 pm

Re: Configuring XPath to automatically use REGEX value

Post by jlowder » Thu Dec 31, 2009 8:32 pm

After modifying my initial FindSingle command to find the dom object, that passes. I am then running into failures trying to find the elements, but I noticed you included a middle step of finding the FlexElement first. I have a flex object off of the base DOM:

body/flexobject[@movie='http://jlowder/RanorexLoader.swf?rxtarget=RenderVue.swf']

All of my repository objects are listed off the base as well, not the flex object, but they all start off as "body/flexobject/".

So are you saying that I need to find some middle element even though the objects I'm looking at in the repository are not directly based on them, but the top DOM element?

Maybe I'll hear back from Ranorex staff next year on this.. :-)

Jason

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Re: Configuring XPath to automatically use REGEX value

Post by Ciege » Thu Dec 31, 2009 10:08 pm

If I understand it correctly, everything in the repo is based off of a root.

However, the way I do things at finding them at run time, if I always search from root I may not find the correct objects within timeout or there may be multiple objects that can fit the parameters and it finds the first one only...

For example, If you get the DOM object and the use FindSingle from the DOM object the find will start at that object and below. If you then find the flex object and use FindSingle from the flex object you can be assured that all object you find are children or descendants of that flex object.

Think of it this way, say you have an app that has two separate control panels but have the same objects in it (i.e. text box, OK button, etc...). If I want to find one of the OK buttons but I start from the root (host.local) I will find the first one it encounters but I cannot be assured that is the one I want without some extra coding. However, if I first find the panel element that I want to work with and then find the button that is a child of that panel element I can be assured that is the one I want to work with.


Based on your XPath:
element[@type='BvSprite']/element[1]/element[@type='BvWizard']/element[2]/element[3]/element[@type='BvXMLInterface']/element/element[1]/element[@id='nextBtn2']/text[@caption='Next']
If I just looked for a text with the caption Next from the root, I may or may not find the one listed here because there may or may not be other texts also with the caption next. However, If I find the element 'BvXMLInterface' first use that as my root, I should be (relatively) assured that the text with caption Next is the one I want and not one that lives under another element.
If this or any response has helped you, please reply to the thread stating that it worked so other people with a similar issue will know how you fixed your issue!

Ciege...

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Re: Configuring XPath to automatically use REGEX value

Post by Support Team » Sat Jan 02, 2010 11:18 pm

Ciege wrote:If I understand it correctly, everything in the repo is based off of a root.
Actually, the repository works very similar to the way your code works if you use application/rooted folders in your repository (like the Ranorex Recorder does by default). A repository can have a structure (see http://www.ranorex.com/support/user-gui ... x-spy.html), e.g. you can have severa application folders (roots), inside each application foler you can put elements and (rooted) folders, and inside the folders you can as well put elements and folders.
When you use a repository item, Ranorex first searches the application folder element absolutely, then relatively searches the folder element that the item is located in, and then relatively searches for the item inside the folder. Basically, whenever you want a relative search, create a "Rooted Folder" (that has a common partly path for several elements) and place your elements inside it.

To the inital issue: As I explained above, you could create a "Rooted Folder" that does not use indices in the path for the flex root element and then put all you flex items in there (or in sub folders of that folder). However, currently that needs manual editing of the item paths, it's not possible to configure Ranorex to omit the index. That's because the Ranorex path generation algorithm always tries to make paths unique for every level in the element hierarchy, since it does not know that e.g. there will be only one element that has a 'type' value of 'BvXMLInterface'.

We already have a feature request in our wanted-features database to provide a way to customize/configure the RanoreXPath generation, but there is no roadmap, yet, when that feature will be included in a release.

Regards,
Alex
Ranorex Support Team