Page 1 of 2
Convert String to Repo Element
Posted: Mon Dec 05, 2016 2:06 pm
by xibinki
Hi guys,
I'm trying to create a method which allows me to convert strings to repository elements.
I already have the elements on my repository and I wish to do something like this:
Code: Select all
public void method1 (string WhatIWant)
{
BValid = repo.BO.SincronizacaoDeEntidadesInfo.Exists();
if (BValid == true)
{
string A = "repo.BO.SIGABOClient."+WhatIWant+"Info.WaitForExists(180000)";
//Conversion of string A to repository element:
//repo.BO.SIGABOClient.Products1Info.WaitForExists(180000)
??? How to ???
}
else
{
string B = "repo.BO.SIGABOClient."+WhatIWant+"Info.WaitForExists(180000)";
//Conversion of string B to repository element:
//repo.BO.SIGABOClient.Products2Info.WaitForExists(180000)
??? How to ???
}
}
Just a note, we have 3 different elements identified in the repository:
Code: Select all
repo.BO.SIGABOClient.SincronizacaoDeEntidades
repo.BO.SIGABOClient.Products1
repo.BO.SIGABOClient.Products2
Re: Convert String to Repo Element
Posted: Mon Dec 05, 2016 3:00 pm
by odklizec
Hi,
As far as I know, there is currently no way to convert a plain string to repoitem. The only solution seems to be a workaround suggested here:
http://www.ranorex.com/forum/pass-repos ... tml#p23444
But since it's already possible to pass a repoiteminfo/adapter to method (as a parameter), it's better to go this way. I would personally create a method, with repoiteminfo parameter pointing to an element/folder, which is common to all three requested repo items (sigaboclient). Then search for the element in question using Find method and xpath with variable (starting from the common repo item/folder). But do whatever suits you best
Re: Convert String to Repo Element
Posted: Mon Dec 05, 2016 4:12 pm
by xibinki
Could you exemplify your method:
pass a repoiteminfo/adapter to method (as a parameter), it's better to go this way. I would personally create a method, with repoiteminfo parameter pointing to an element/folder, which is common to all three requested repo items (sigaboclient).
Re: Convert String to Repo Element
Posted: Mon Dec 05, 2016 4:35 pm
by Vaughan.Douglas
If I understand what you're trying to do, I'd go about it like this (in VB)... I'm not as comfortable with LINQ in C#
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is Me.myName
Select things
Dim myObject As RepoItemInfo = myQuery.FirstOrDefault()
myObject.WaitForExists(500)
I'd further stick this method on one of those new user code groups in Ranorex 6.2
public Function SearchRepoItemByName(ByVal repoItemName As string) As RepoItemInfo
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is repoItemName
Select things
SearchRepoItemByName = myQuery.FirstOrDefault()
End Function
or this
Public Sub SearchByNameAndWaitForExist(ByVal repoItemName As String, ByVal timeOut As Duration)
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is repoItemName
Select things
myQuery.First().WaitForExists(timeOut)
End Sub
Re: Convert String to Repo Element
Posted: Tue Dec 06, 2016 2:09 pm
by xibinki
Hummm, interesting...
I've tried creating the same structure on C# but I'm missing something :X
Re: Convert String to Repo Element
Posted: Tue Dec 06, 2016 2:25 pm
by odklizec
If you are not sure about correct conversion of VB .NET code to C#, you can use built-in conversion tool, which can be found in menu Tools >> Convert code to...
Just create a new VB .NET based project, copy the provided VB .Net code into it and then convert it to C#
Re: Convert String to Repo Element
Posted: Tue Dec 06, 2016 4:14 pm
by xibinki
So for example, I have these two elements identified on my repository:
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self
repo.BO.SincronizacaoDeProdutos.Self
I also have this validation method:
Code: Select all
public SearchAndValidate (//element I want to pass//) {
bool BValid = true;
while (BValid) {
if (//element I want to pass//Info.Exists()) {
BValid = true;
}
else {
BValid = false;
}
}
}
By using your method:
Code: Select all
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is Me.myName
Select things
Dim myObject As RepoItemInfo = myQuery.FirstOrDefault()
myObject.WaitForExists(500)
I would only need to call like this:
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self)
and
Code: Select all
myQuery(repo.BO.SincronizacaoDeProdutos.Self)
And it would search for the item in my repository and tell me if it exists after 500ms while the test is running:
Is that it?
Re: Convert String to Repo Element
Posted: Tue Dec 06, 2016 9:54 pm
by Vaughan.Douglas
odklizec wrote:If you are not sure about correct conversion of VB .NET code to C#, you can use built-in conversion tool, which can be found in menu Tools >> Convert code to...
Just create a new VB .NET based project, copy the provided VB .Net code into it and then convert it to C#
I haven't met a conversion tool (including Ranorex) that can convert LINQ flawlessly. I tested out the VB code. I would have written the C# equivalent but didn't have time to test it out.
Re: Convert String to Repo Element
Posted: Tue Dec 06, 2016 10:20 pm
by Vaughan.Douglas
xibinki wrote:So for example, I have these two elements identified on my repository:
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self
repo.BO.SincronizacaoDeProdutos.Self
I also have this validation method:
Code: Select all
public SearchAndValidate (//element I want to pass//) {
bool BValid = true;
while (BValid) {
if (//element I want to pass//Info.Exists()) {
BValid = true;
}
else {
BValid = false;
}
}
}
By using your method:
Code: Select all
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is Me.myName
Select things
Dim myObject As RepoItemInfo = myQuery.FirstOrDefault()
myObject.WaitForExists(500)
I would only need to call like this:
Not So much
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self)
and
Yes, this is more along the lines of what you'd need to do
Code: Select all
myQuery(repo.BO.SincronizacaoDeProdutos.Self)
And it would search for the item in my repository and tell me if it exists after 500ms while the test is running:
Is that it?
I think you've more or less got the idea.
The query is basically iterating through the collection of repo items and looking for a match on the "name" property. you could do exactly the same thing using a for each loop, although I think it would be more costly from a resource/time prospective.
If I'm perfectly honest, this is the point where I crack open my Ranorex solution in Visual Studio because it has much better real time code analysis and IntelliSense. If you want to throw what you've got up in here, I'll take a look and see if I can get it sorted out.
Give either of these a shot
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.SelfInfo.Children where ReferenceEquals(things.Name, repoItemName) select things;
return myQuery.FirstOrDefault();
}
to use the above, you'll need to set a variable equal to the function as it's going to return a RepoItemInfo object back to you and then you'd use the waitforExist on it.
RepoItemInfo myObject = SearchRepoItemByName("you string goes here");
myObject.WaitForExists(5000);
__________________________________________________________________________________________
public void SearchByNameAndWaitForExist(string repoItemName, Duration timeOut)
{
var myQuery = from things in repo.SelfInfo.Children where object.ReferenceEquals(things.Name, repoItemName) select things;
myQuery.First().WaitForExists(timeOut);
}
For this one you're not going to get anything back, so you just call the method and provide the arguments.
SearchByNameAndWaitForExist("Your string goes here", 5000);
I didn't actually run either of these conversions, so I can't promise they'll work as expected. Let me know if you run into issues and I can help you through them.
Re: Convert String to Repo Element
Posted: Wed Dec 07, 2016 9:28 am
by odklizec
Vaughan.Douglas wrote:odklizec wrote:If you are not sure about correct conversion of VB .NET code to C#, you can use built-in conversion tool, which can be found in menu Tools >> Convert code to...
Just create a new VB .NET based project, copy the provided VB .Net code into it and then convert it to C#
I haven't met a conversion tool (including Ranorex) that can convert LINQ flawlessly. I tested out the VB code. I would have written the C# equivalent but didn't have time to test it out.
My bad, I missed the LINQ part in the VB code
Re: Convert String to Repo Element
Posted: Wed Dec 07, 2016 3:00 pm
by Vaughan.Douglas
odklizec wrote:Vaughan.Douglas wrote:odklizec wrote:If you are not sure about correct conversion of VB .NET code to C#, you can use built-in conversion tool, which can be found in menu Tools >> Convert code to...
Just create a new VB .NET based project, copy the provided VB .Net code into it and then convert it to C#
I haven't met a conversion tool (including Ranorex) that can convert LINQ flawlessly. I tested out the VB code. I would have written the C# equivalent but didn't have time to test it out.
My bad, I missed the LINQ part in the VB code
It's all good. I like to use LINQ and there are a lot of resources that discuss LINQ in C# and many fewer for VB. I have to say things have gotten MUCH better. It used to be that these converters just threw up all over LINQ, but now VB to C# works pretty well and C# to VB gets you in the right neighborhood just depending on how fancy things got in the original code. I think that is because C# had more robust support out of the gate.
Re: Convert String to Repo Element
Posted: Fri Dec 09, 2016 5:07 pm
by xibinki
Vaughan.Douglas wrote:xibinki wrote:So for example, I have these two elements identified on my repository:
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self
repo.BO.SincronizacaoDeProdutos.Self
I also have this validation method:
Code: Select all
public SearchAndValidate (//element I want to pass//) {
bool BValid = true;
while (BValid) {
if (//element I want to pass//Info.Exists()) {
BValid = true;
}
else {
BValid = false;
}
}
}
By using your method:
Code: Select all
Dim myQuery As IEnumerable(Of RepoItemInfo) = From things In repo.SelfInfo.Children
Where things.Name Is Me.myName
Select things
Dim myObject As RepoItemInfo = myQuery.FirstOrDefault()
myObject.WaitForExists(500)
I would only need to call like this:
Not So much
Code: Select all
repo.BO.SincronizacaoDeEntidades.Self)
and
Yes, this is more along the lines of what you'd need to do
Code: Select all
myQuery(repo.BO.SincronizacaoDeProdutos.Self)
And it would search for the item in my repository and tell me if it exists after 500ms while the test is running:
Is that it?
I think you've more or less got the idea.
The query is basically iterating through the collection of repo items and looking for a match on the "name" property. you could do exactly the same thing using a for each loop, although I think it would be more costly from a resource/time prospective.
If I'm perfectly honest, this is the point where I crack open my Ranorex solution in Visual Studio because it has much better real time code analysis and IntelliSense. If you want to throw what you've got up in here, I'll take a look and see if I can get it sorted out.
Give either of these a shot
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.SelfInfo.Children where ReferenceEquals(things.Name, repoItemName) select things;
return myQuery.FirstOrDefault();
}
to use the above, you'll need to set a variable equal to the function as it's going to return a RepoItemInfo object back to you and then you'd use the waitforExist on it.
RepoItemInfo myObject = SearchRepoItemByName("you string goes here");
myObject.WaitForExists(5000);
__________________________________________________________________________________________
public void SearchByNameAndWaitForExist(string repoItemName, Duration timeOut)
{
var myQuery = from things in repo.SelfInfo.Children where object.ReferenceEquals(things.Name, repoItemName) select things;
myQuery.First().WaitForExists(timeOut);
}
For this one you're not going to get anything back, so you just call the method and provide the arguments.
SearchByNameAndWaitForExist("Your string goes here", 5000);
I didn't actually run either of these conversions, so I can't promise they'll work as expected. Let me know if you run into issues and I can help you through them.
When I use the first method:
Code: Select all
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.SelfInfo.Children where ReferenceEquals(things.Name, repoItemName) select things;
return myQuery.FirstOrDefault();
}
And then:
Code: Select all
RepoItemInfo myObject = SearchRepoItemByName("you string goes here");
myObject.WaitForExists(5000);
I get the following error at the code line with "myObject.WaitForExists(5000);":
Code: Select all
Object reference not set to an instance of an object.
When I use the second method:
Code: Select all
public void validacao(string repoItemName, Duration timeOut)
{
var myQuery = from things in repo.SelfInfo.Children where object.ReferenceEquals(things.Name, repoItemName) select things;
myQuery.First().WaitForExists(timeOut);
}
I get this error at the code line with "myQuery.First().WaitForExists(timeOut);":
------------------------------------------------------------------------------------------------
It seems like the 1st method isn't returning anything, but I'm passing the string of my xpath element, example:
Code: Select all
string repoItemName = "repo.BO.SincronizacaoDeEntidades.Self"
For the 2nd method, it's the exact same thing, it looks like it isn't getting anything into "myQuery" variable and I'm passing the same xpath element string.
A little help here, please
I'm not quite sure why it isn't getting the repo item into the "vars".
Re: Convert String to Repo Element
Posted: Mon Dec 12, 2016 3:36 pm
by Vaughan.Douglas
There is clearly a problem with the code. Like I said my C# isn't all that great. I'll see if I can't get a working version of the C# up here sometime today.
--EDIT--
As with most things, it's a simple problem and totally my fault.
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
I omitted the base object from the query.
repo.selfinfo.children is wrong it should be
repo.myBaseObject.selfinfo.children
baseObject.png
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.myBaseObject.SelfInfo.Children
where _ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
The same issue is present in the rest of my examples. I apologize for any additional frustration this might have caused.
To make up for it, here's the full working c# code
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using WinForms = System.Windows.Forms;
using Microsoft.VisualBasic;
using Ranorex;
using Ranorex.Core;
using Ranorex.Core.Repository;
using Ranorex.Core.Testing;
namespace moreJunk
{
public partial class Recording1
{
/// <summary>
/// This method gets called right after the recording has been started.
/// It can be used to execute recording specific initialization code.
/// </summary>
private void Init()
{
//Dim myName As string = repo.InsidePrincipalHomePage.AnotherItemInfo.name
string myName = "AnotherItem";
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, myName)
select things;
RepoItemInfo myObject = myQuery.FirstOrDefault();
Report.Log(ReportLevel.Success, "CSharp", myObject.Name);
Report.Log(ReportLevel.Success, myObject.FullName);
Report.Log(ReportLevel.Success, "From CSharp version of SearchRepoItemByName", SearchRepoItemByName(myName).Name);
}
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
/// <summary>
/// This won't work because the object doesn't exist.
/// </summary>
/// <param name="repoItemName"></param>
/// <param name="timeOut"></param>
public void SearchByNameAndWaitForExist(string repoItemName, Duration timeOut)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
myQuery.First().WaitForExists(timeOut);
}
}
}
Re: Convert String to Repo Element
Posted: Tue Dec 13, 2016 1:40 pm
by xibinki
Vaughan.Douglas wrote:There is clearly a problem with the code. Like I said my C# isn't all that great. I'll see if I can't get a working version of the C# up here sometime today.
--EDIT--
As with most things, it's a simple problem and totally my fault.
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
I omitted the base object from the query.
repo.selfinfo.children is wrong it should be
repo.myBaseObject.selfinfo.children
baseObject.png
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
var myQuery = from things in repo.myBaseObject.SelfInfo.Children
where _ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
The same issue is present in the rest of my examples. I apologize for any additional frustration this might have caused.
To make up for it, here's the full working c# code
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using WinForms = System.Windows.Forms;
using Microsoft.VisualBasic;
using Ranorex;
using Ranorex.Core;
using Ranorex.Core.Repository;
using Ranorex.Core.Testing;
namespace moreJunk
{
public partial class Recording1
{
/// <summary>
/// This method gets called right after the recording has been started.
/// It can be used to execute recording specific initialization code.
/// </summary>
private void Init()
{
//Dim myName As string = repo.InsidePrincipalHomePage.AnotherItemInfo.name
string myName = "AnotherItem";
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, myName)
select things;
RepoItemInfo myObject = myQuery.FirstOrDefault();
Report.Log(ReportLevel.Success, "CSharp", myObject.Name);
Report.Log(ReportLevel.Success, myObject.FullName);
Report.Log(ReportLevel.Success, "From CSharp version of SearchRepoItemByName", SearchRepoItemByName(myName).Name);
}
public RepoItemInfo SearchRepoItemByName(string repoItemName)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
return myQuery.FirstOrDefault();
}
/// <summary>
/// This won't work because the object doesn't exist.
/// </summary>
/// <param name="repoItemName"></param>
/// <param name="timeOut"></param>
public void SearchByNameAndWaitForExist(string repoItemName, Duration timeOut)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.myBaseObject.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
myQuery.First().WaitForExists(timeOut);
}
}
}
So when I try to use the following code:
Code: Select all
public void v(string repoItemName, Duration timeOut)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.BO.SIGABOClient.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
myQuery.First().WaitForExists(timeOut);
}
I still get the "Sequence contains no element" on the "myQuery.First().WaitForExists(timeOut);", it seems that doesn't find anything on the xpath I just gave to myBaseObject (repo.BO.SIGABOClient) which is where the element I want to search is (repo.BO.SIGABOClient.Importacao.SincronizacaoDeProdutosInfo).
What now?
---Edit 1---
Ok, so I managed to put it to work with the following code:
Code: Select all
public void v(string repoItemName, Duration timeOut)
{
IEnumerable<RepoItemInfo> myQuery = from things in repo.BO.SIGABOClient.Importacao.SelfInfo.Children
where ReferenceEquals(things.Name, repoItemName)
select things;
myQuery.First().Exists(timeOut);
}
But now I have another question, I noticed that in order to successfully search for an element, I had to give the full xPath where the element actually is. My question is, isn't possible to make the method have a wider range, what I'm trying to say is, is it possible to give the root of the repository (ex: repo.BO.SelfInfo.Children) and make the method search deeper through the tree of paths/folders? Because I tried to give the root of the repository and the method presented didn't work (Sequence contains no element). I'm suspecting it's because he's only searching on the "SelfInfo.
Children", isn't there an instruction in Ranorex that allows to search on the entire tree of elements?
Re: Convert String to Repo Element
Posted: Tue Dec 13, 2016 4:34 pm
by Vaughan.Douglas
But now I have another question, I noticed that in order to successfully search for an element, I had to give the full xPath where the element actually is. My question is, isn't possible to make the method have a wider range, what I'm trying to say is, is it possible to give the root of the repository (ex: repo.BO.SelfInfo.Children) and make the method search deeper through the tree of paths/folders? Because I tried to give the root of the repository and the method presented didn't work (Sequence contains no element). I'm suspecting it's because he's only searching on the "SelfInfo.Children", isn't there an instruction in Ranorex that allows to search on the entire tree of elements?
The code sample I provided only works for that first order of children. As written it won't find element in both
repo.BO.SelfInfo.Children and
repo.BO.SomeRootedFolder.SelfInfo.Children
To answer your question, I would think it should be possible but I don't know of a canned Ranorex method to recursively search through the object repository. Also, since it is possible to have multiple elements with the same name in different branches it'll need to search with the FullName property. My code didn't allow for that when I just gave it a go here this morning.
I'll let this spin for a while, but we may need someone with more advanced skills to help us out at this point. Here are some examples I pulled for stackocerflow:
http://stackoverflow.com/questions/2126 ... ubchildren
http://stackoverflow.com/questions/1025 ... -recursion