Page 1 of 2

Access to repository from user code collection

Posted: Fri Dec 01, 2017 9:17 am
by EugeneMkv
Hi!
Is there a way to access a repo in user code collection (namespace Ranorex_Automation_Helpers)?
I tried a lot of things, but unfortunately had no luck.
I can easily use Report or Validate classes, but can't use repository.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 1:07 pm
by odklizec
Hi,

You have to instantiate the repository in given code collection, e.g. like this:

Code: Select all

private static NameOfSolution.NameOfSolutionRepository repo = NameOfSolution.NameOfSolutionRepository.Instance;
This line of code should be added at start of your collection. Then you should be able to access the repository via "repo" keyword. Hope this helps?

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 1:21 pm
by Vaughan.Douglas
First of all, I wouldn't do this. You really want the code in a usercode collection to be generic, and you can edit the signature of the method to only accept specific object types if you really want to get down to it. This community would be more than willing to help you generalize a code sample to fit this ideal.

To answer your question, this is all just .Net so yes there is a way. You just need to instantiate a static/shared instance of the repository so it's accessible just like you have to with each usercode method on the collection. It's different for VB.Net and C# (shared versus static), but I'm fairly certain that's where your solution lies.

I skipped over Lesson 7 in the user guide because I'm assuming you're familiar with accessing the repository in user code that is NOT in a code collection.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 1:40 pm
by EugeneMkv
I'm not a newbee in .NET world. Sure it was a first idea to instantiate a static repo field.
But the studio returns error: The type or namespace name 'my_solution' could not be found (are you missing a using directive or an assembly reference?)

the line - private static my_solution.my_solution.repository repo = my_solution.my_solution.repository.Instance;
goes right after the:

public class UserCodeCollection1
{

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 1:53 pm
by EugeneMkv
Vaughan.Douglas wrote:First of all, I wouldn't do this. You really want the code in a usercode collection to be generic, and you can edit the signature of the method to only accept specific object types if you really want to get down to it. This community would be more than willing to help you generalize a code sample to fit this ideal.
...
Suppose I need a method for getting some text value from wpf-based GUI. Then the text is parsed to DateTime for some comparisons. And this method could be used in different test-cases and recordings. Now the only way to do this is via inheritance of common class for every recording. And this is inconvenient way.
That's why I need an access to my repo from User Code Library. Would be nice to have such feature.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:34 pm
by Vaughan.Douglas
Your approach should work, so maybe there is an issue with your namespaces? How many projects do you have in your solution?

As for a more generalized means of accomplishing the same thing, you could split it up between multiple actions in the recorded module.
  • Perform a get on your WPF object and store it in a module variable/parameter
  • Create a usercode method that does everything else ie convert from string to date and compare the value
Or in this example: I just pass the ReporItemInfo into my method and deal with it all in my UserCodeMethod.

Code: Select all

<UserCodeMethod> _
     Public Shared Sub ValidateDate(myAttribute As String, myExpected As String, myObjectInfo As Ranorex.Core.Repository.RepoItemInfo)
			
     Report.Log(ReportLevel.Info, String.Format("Attempting to convert the '{2}' attribute of '{3}'; '{0}' and the expected value '{1}' to valid dates for comparison", Host.Current.FindSingle(myObjectInfo.AbsolutePath).Item(myAttribute).ToString(), myExpected, myAttribute, myObjectInfo.Name))

     Validate.AreEqual(StringToDate(Host.Current.FindSingle(myObjectInfo.AbsolutePath).Item(myAttribute).ToString()), StringToDate(myExpected), "Expect '{0}' to match '{1}'", False)
			
End Sub
which also calls

Code: Select all

		<UserCodeMethod> _
		Public Shared Function StringToDate(ByVal dateAsString As String) As Date
			Dim myDate As Date
			Date.TryParse(dateAsString, myDate)
			Return myDate
		End Function

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:39 pm
by odklizec
Are you sure about the bold part?...
private static my_solution.my_solution.repository repo = my_solution.my_solution.repository.Instance;

Typically, the repository autogenerated repository name is my_solutionrepository so unless you changed repo name, the line should look more like this:
private static my_solution.my_solutionrepository repo = my_solution.my_solutionrepository.Instance;

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:45 pm
by EugeneMkv
Vaughan.Douglas wrote:You're approach should work, so maybe there is an issue with your namespaces? How many projects do you have in your solution?
There are no issues with my namespaces. There are only two of them: one for main solution and another - Ranorex_Automation_Helpers.
I've just started my new project.
As for a more generalized means of accomplishing the same thing, you could split it up between multiple actions in the recorded module.
Thanks. But I prefer to do it in one place.
I will not copy-paste the same a code for getting the text-values from GUI for every recording. This is ridiculous and goes against the OOP paradigm.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:51 pm
by EugeneMkv
odklizec wrote:Are you sure about the bold part?...
oh sorry, I've made a mistake copypasting these parts.

it looks like this (double checked):

private static my_solution.my_solutionRepository repo = my_solution.my_solutionRepository.Instance;

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:52 pm
by Vaughan.Douglas
EugeneMkv wrote: Thanks. But I prefer to do it in one place.
I will not copy-paste the same a code for getting the text-values from GUI for every recording. This is ridiculous and goes against the OOP paradigm.
You'll notice the <UserCodeMethod> tag in the provided code samples. They are part of a UserCode repository that resides in an entirely different project within the same solution. There is no copy/paste involved.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 2:57 pm
by EugeneMkv
Vaughan.Douglas wrote: You'll notice the <UserCodeMethod> tag in the provided code samples. They are part of a UserCode repository that resides in an entirely different project within the same solution. There is no copy/paste involved.
I'm not into VB.NET stuff but into C# instead.
Ok, then, the only one problem for me is to access my repo...

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 3:09 pm
by odklizec
Hi,

I just tried it in my relative new project with user code collection and it works as expected?
repo_instance.png
But the truth is that I did not tried it within the test automation helpers project.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 3:09 pm
by Vaughan.Douglas
EugeneMkv wrote: I'm not into VB.NET stuff but into C# instead.
Ok, then, the only one problem for me is to access my repo...
Sorry, this particular solution happens to be VB. Here it is as run through the code converter over at Telerik.com

Code: Select all

[UserCodeMethod]
public static void ValidateDate(string myAttribute, string myExpected, Ranorex.Core.Repository.RepoItemInfo myObjectInfo)
{
     Report.Log(ReportLevel.Info, string.Format("Attempting to convert the '{2}' attribute of '{3}'; '{0}' and the expected value '{1}' to valid dates for comparison", Host.Current.FindSingle(myObjectInfo.AbsolutePath).Item(myAttribute).ToString(), myExpected, myAttribute, myObjectInfo.Name));
    Validate.AreEqual(StringToDate(Host.Current.FindSingle(myObjectInfo.AbsolutePath).Item(myAttribute).ToString()), StringToDate(myExpected), "Expect '{0}' to match '{1}'", false);
}
It still looks messy, but the key to this method is

Code: Select all

Host.Current.FindSingle(myObjectInfo.AbsolutePath).Item(myAttribute).ToString()
You pass it a RepoItemInfo object as an argument in your calling module. Then the Host.Current.FindSingle takes a RxPath as an argument and it goes out and finds the object so you don't need a reference to your repository. I just daisy-chained all these things together so I wouldn't have to instantiate the repository object separately. Theoretically, you should be able to drop this usercode method into your code and run with it. The "myAttribute" argument is the name of the property you're going after such as "innertext", "value", "text" or whatever.

Re: Access to repository from user code collection

Posted: Fri Dec 01, 2017 4:35 pm
by EugeneMkv
But the truth is that I did not tried it within the test automation helpers project.
But is it possible to create common User Code Library without using namespace Ranorex_Automation_Helpers?
Then the Host.Current.FindSingle takes a RxPath as an argument and it goes out and finds the object so you don't need a reference to your repository.
Thanks, Vaughan Douglas! I get your point and will try this approach!

Re: Access to repository from user code collection

Posted: Mon Dec 04, 2017 1:25 pm
by Vaughan.Douglas
EugeneMkv wrote: But is it possible to create common User Code Library without using namespace Ranorex_Automation_Helpers?
Sure thing!!
Right click on whatever project you want to add the user code collection.
Select 'Add New'

You'll see "User Code Collection" under the "Ranorex" category.
newUCC.png
My approach is to add a Ranorext Test Suite Module Library project to my solution and stick my user code collection(s) in there. That way I can keep all of my general modules and methods in one place and don't end up with circular references.