Pass repository item as parameter to user code

Ranorex Studio, Spy, Recorder, and Driver.
reiniuny
Posts: 23
Joined: Thu Jul 04, 2013 10:48 am

Pass repository item as parameter to user code

Post by reiniuny » Thu Jul 11, 2013 10:35 am

How is it possible to pass a repository item as parameter to a user code method?

As I see I just can pass strings to user code methods. If I define an other class then string as data type for parameter the user code function doesn't appear in the combobox.

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

Re: Pass repository item as parameter to user code

Post by krstcs » Thu Jul 11, 2013 1:19 pm

Currently you can only pass strings to user code.

I have requested that they add the ability to pass other types besides strings (including repository items). It may be a while before that happens though, if it ever does.
Shortcuts usually aren't...

sergii
Posts: 30
Joined: Fri Jun 07, 2013 11:07 pm

Re: Pass repository item as parameter to user code

Post by sergii » Thu Jul 11, 2013 5:08 pm

Just an idea: Why you cannot pass unique XPath to the repository item and catch it on other end using code:

Code: Select all

var xpath = string.Format("/dom[@domain='"+ EnvLinks.RAMlink +"']/.//a[@innertext~'.*{0}.*{1}']/../../../div[5]/div", LastName, FirstName);
DivTag elem = null;
Host.Local.TryFindSingle(xpath, out elem);
elem with contain your repository item of type Div.
I didn't find a way to make it universal for any type of repository item, but this implementation works quite good for me.

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

Re: Pass repository item as parameter to user code

Post by krstcs » Thu Jul 11, 2013 7:06 pm

The problem with that approach is that you still have to know ahead of time what the XPath is you need. And you will have to hard-code it somewhere, either in the module or in the data. You can't pass the XPath straight from a repository object in a module without getting into user code.

I would like to be able to fully de-couple the repository objects from my code modules.

If they allow us to pass repository objects then we could change the XPath in the repository and be done with it. This would also allow us to make more generic methods that could be used on any repository object.
Shortcuts usually aren't...

reiniuny
Posts: 23
Joined: Thu Jul 04, 2013 10:48 am

Re: Pass repository item as parameter to user code

Post by reiniuny » Fri Jul 12, 2013 6:16 am

The approach krstcs explained was my intent too.

At the moment I've created a repository item using a variable. Before calling the user function I set the variable to the desired value. But this value I've to hardcode on many places, so if the value changes I've to change it many times.

Instead of that I'd like to use a repository item and pass it to the user code, then I just would have to change the value once if it changes.

kmck
Certified Professional
Certified Professional
Posts: 83
Joined: Fri Jul 12, 2013 2:41 pm

Re: Pass repository item as parameter to user code

Post by kmck » Fri Aug 30, 2013 2:57 pm

Being able to pass the repository item to a method via a parameter would be a very helpful addition. I've had the same issue as posters above where I have had to use an xpath passed as a parameter, but this unfortunately makes for fragile code. If the xpath changes on a repository item, you can change the repo item's path and have it automatically update everywhere where that item is called, whereas using an xpath means having to manually go through the code, find the defunct xpaths and change each one by hand should they no longer point to the correct item.

Is there still currently no workaround for this?

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

Re: Pass repository item as parameter to user code

Post by Support Team » Tue Sep 03, 2013 12:25 pm

Hello,

Currently, it's not possible to pass a repository item to a user code action.
A possible workaround in Ranorex 4.1 might be to navigate through repository items using the Children property of the RepoItemInfo class. Please take a look at the code snippet below:
public void GetRepoItems()
{
	var items = repo.VipApp.SelfInfo.Children;
	foreach (var item in items)
	{
		Report.Info(item.ToString());
	}		
}
Regards,
Markus (T)

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 7470
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Pass repository item as parameter to user code

Post by odklizec » Thu Nov 14, 2013 1:40 pm

Hi, sorry for hijacking this thread, but I have a similar problem and I thought about solving it by using string parameter and InvokeMethod.

Basically, I have a recording with the User Code, which uses two string parameters containing the rxPath.
I thought about replacing the hardcoded string parameter (containing the rxpath), with somewhat more flexible Repository.ItemInfo.Path string. Such string (passed via string parameter to user code) does not automatically expand to repository path, because after passing as a sting, it behaves like a string ;) But I found something about InvokeMethod and I think this method should be a way to call the string-based method? Then only problem is, that I'm not quite sure how to implement it (sorry, I'm still a C# noob). Any idea?

Here is how my recording looks like:
RepoItemParam.png
Now the question is, how to use the InvokeMethod to call "repo.LiteBox3d.SceneInitializedInfo.Path" passed via string parameter and get the expanded path? Any idea? I'm sure the string needs to be split. That's the easy part. So let's assume the parameter is already split. How to use the InvokeMethod? Any idea? Thank you in advance!
You do not have the required permissions to view the files attached to this post.
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

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

Re: Pass repository item as parameter to user code

Post by Support Team » Mon Nov 18, 2013 5:37 pm

Hello odklizec,

We provide our InvokeMethod for Ranorex Controls to invoke a specified method on a control as described in our API. In your case, you would need to use .NET Reflection to pass your objects to a User Code method.
Please note that only string objects could be passed from the Recording's actions table to a method.

This article on MSDN describes the usage of MethodBase.InvokeMethod and gives a short example:
http://msdn.microsoft.com/de-de/library ... .110).aspx

On the base of this example I created the following method to pass the RepoItemInfo object to my method using Reflection. Please take a look at it.
public void ReflectionCall() {
	Type myClass = this.GetType();
	var repo = <YourRepository>.Instance;
	var txtBox = repo.FormVipApplication.FirstNameInfo;

	MethodInfo myMethod = myClass.GetMethod("HelloWorld");
	object magicValue = myMethod.Invoke(this, new object[]{txtBox});
}

public void HelloWorld(RepoItemInfo infoObject) {
	Report.Info("Path of RepoItemInfo object: " + infoObject.AbsolutePath);
}
In this way, you could pass any object that you want to your User Code method.
Please let me know if this helped you.

Regards,
Markus (T)

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 7470
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Pass repository item as parameter to user code

Post by odklizec » Tue Nov 19, 2013 9:53 am

Hi Markus,

Thank you for the example! It looks exactly what I'm looking for. I will give it a try and let you know. Thanks again!
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 7470
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Pass repository item as parameter to user code

Post by odklizec » Tue Dec 17, 2013 2:00 pm

Hi Markus,

After some time, I was finally able to return to this problem and I'm afraid, I'm unable to modify your nice sample to achieve my goal.

Here is what I have:
public void Wait_For_Not_Exists(string repoElement)
{
// where repoElement contains string like repo.LiteBox3d.SceneInitializedInfo
    Type myClass = this.GetType();  

    MethodInfo myMethod = myClass.GetMethod("????");  //what should be here if I don't want to use another method, like in your sample?
    object magicValue = myMethod.Invoke(this, new object[]{repoElement});  
    string repoPath = magicValue.AbsolutePath;  //this obviously doesn't work because: 'object' does not contain a definition for 'AbsolutePath' and no extension method 'AbsolutePath' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
    System.Diagnostics.Debug.WriteLine("repoPath: " + repoPath);
}
Any idea how to change the code to make it working (to change repoElement string to repo object)? Thank you for your kind help!
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

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

Re: Pass repository item as parameter to user code

Post by Support Team » Thu Dec 19, 2013 4:34 pm

Hello odklizec,

Your assumption is correct. You would need to use a RepoItemInfo object to work with your example.
A string value with the path to the object is not enough, unfortunately. You could of course change the object type that is passed to your method (e.g. to a RepoItem).

Hint: The following method will get the element based on the path:
// find your element based on your path
var txtBox = Host.Local.FindSingle<Ranorex.Text>(repoElement);
In order to call a method using GetMethod(), you would need to know the method name.
In my example, I created a method HelloWorld() for that purpose.

Regards,
Markus (T)

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 7470
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Pass repository item as parameter to user code

Post by odklizec » Fri Dec 20, 2013 9:35 am

Hi Markus

Thanks for your explanation and a new hint.

In previous version of my code, I passed the repo paths (via parameters). But these "path strings" parameters used to be too long and not resistant to repository path changes. So my idea is to pass the repo item names (instead of paths) and then somehow "convert" the string parameters back to repository items, which are usable in code.

I'm currently using TryFindSingle in this way:
Host.Local.TryFindSingle(repo.LiteBox3d.SceneInitializedInfo.AbsolutePath, out element);

But I consider this way hardcoded and not very flexible. I would rather like to have a method, to which I pass the repo element names (not paths) via string parameters.

OK, I will try to use your "HelloWorld" method approach ;) Thanks again!
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 7470
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Pass repository item as parameter to user code

Post by odklizec » Fri Dec 20, 2013 10:32 am

OK, I tried your sample including the "HelloWorld" sample method and I'm afraid, I'm still unable to achieve what I want.

The problem is, in this line:
var txtBox = repo.FormVipApplication.FirstNameInfo;
Basically, I need txtBox to hold a string variable (passed to user code via string parameter)
Here is the edited sample code...
public void ReflectionCall(string repoElement) {  
        Type myClass = this.GetType();  
//        var txtBox = repo.FormVipApplication.FirstNameInfo;  // your original line  
           var txtBox = repoElement;  //repo element passed by string param  e.g. "repo.LiteBox3d.LoadingDoneInfo"

        MethodInfo myMethod = myClass.GetMethod("HelloWorld");  
        object magicValue = myMethod.Invoke(this, new object[]{txtBox});  
    }  
      
    public void HelloWorld(RepoItemInfo infoObject) {  
        Report.Info("Path of RepoItemInfo object: " + infoObject.AbsolutePath);  
    }
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

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

Re: Pass repository item as parameter to user code

Post by krstcs » Fri Dec 20, 2013 2:45 pm

Add the "Path" attribute:

var txtBox = repo.FormVipApplication.FirstNameInfo.Path;
Shortcuts usually aren't...