Convert String to Repo Element

Class library usage, coding and language questions.
Vaughan.Douglas
Posts: 250
Joined: Tue Mar 24, 2015 5:05 pm
Location: Des Moines, Iowa, USA

Re: Convert String to Repo Element

Post by Vaughan.Douglas » Tue Dec 13, 2016 7:41 pm

Ok, I still haven't figured out how to search by the object's full name, but I found what can only be considered black magic over at stackoverflow that seems to work for us.

I just straight up lifted their code and I only have the vaguest idea how it works (as designated by the class name 'Idontevenknow'). The C# notation here is beyond my experience, so I'm not going to really walk you through the lambda stuff.

Rather than trying to explain any of this I've just attached my sample solution.
StringToRepoItem.zip
(21.91 KiB) Downloaded 51 times
I think this type of thing could be useful to a lot of people. Hopefully others from the community might be able to expand upon this or streamline it somehow.

Good luck and let me know if this solves your problem.
Doug Vaughan

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Wed Dec 28, 2016 1:21 pm

Vaughan.Douglas wrote:Ok, I still haven't figured out how to search by the object's full name, but I found what can only be considered black magic over at stackoverflow that seems to work for us.

I just straight up lifted their code and I only have the vaguest idea how it works (as designated by the class name 'Idontevenknow'). The C# notation here is beyond my experience, so I'm not going to really walk you through the lambda stuff.

Rather than trying to explain any of this I've just attached my sample solution.
StringToRepoItem.zip
I think this type of thing could be useful to a lot of people. Hopefully others from the community might be able to expand upon this or streamline it somehow.

Good luck and let me know if this solves your problem.
Thanks for helping me in this quest, Vaughn :)
Now I'm trying to do something different, based on the method we already discussed here:

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 want to be able to find the repoitem and use .Click() action, so basically what I'm trying to code is something like this:

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().Click();
}
So on the repo.BO.SIGABOClient.Importacao tree, I have the repo.BO.SIGABOClient.Importacao.Reception. I would pass the string repoItemName = repo.BO.SIGABOClient.Importacao.Reception and what I want to do is for myQuery.Click(), which would supposedly be the same as repo.BO.SIGABOClient.Importacao.Reception.Click(). Although when I try to do this, Ranorex tells me that:
'System.Collections.Generic.IEnumerable<Ranorex.Core.Repository.RepoItemInfo>' does not contain a definition for 'Click' and no extension method 'Click' accepting a first argument of type 'System.Collections.Generic.IEnumerable<Ranorex.Core.Repository.RepoItemInfo>' could be found (are you missing a using directive or an assembly reference?) (CS1061) - D:\Repositories\Flow2TestAuto\RanorexStudio Projects\Flow2TestProject\Flow2TestProject\CodeTestProject\FO\FO.cs:140,13
Is there a way to be able to use our "v" method to perform clicks with the repository items found?
Thanks.

User avatar
RobinHood42
Posts: 239
Joined: Fri Jan 09, 2015 3:24 pm

Re: Convert String to Repo Element

Post by RobinHood42 » Thu Dec 29, 2016 1:05 pm

Hi,

The error message tells you what the problem is ;-)
You are using the RepoItemInfo object which has no definition for a click method.

You can try to search for the repository items and not their info objects.
For example: repo.BO.SIGABOClient.Importacao.Children

Cheers,
Robin

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Mon Jan 02, 2017 1:59 pm

RobinHood42 wrote:Hi,

The error message tells you what the problem is ;-)
You are using the RepoItemInfo object which has no definition for a click method.

You can try to search for the repository items and not their info objects.
For example: repo.BO.SIGABOClient.Importacao.Children

Cheers,
Robin
I've tried what you suggested "repo.FO.FLOW2FO.Container2.Children" but I get an error telling me that Ican't use "Children" on my repo-item and if i use "Self.Children" I get a different error. My code is something like this:

Code: Select all

for (int i = 0; i < length; i++)
{
string repoItemName = "Button" + arrayOfCharacters[i].ToString();
IEnumerable<RepoItemInfo> myQuery = from things in repo.FO.FLOW2FO.Container2.Self.Children
	where ReferenceEquals(things.Name, repoItemName)
	select things;
myQuery.Click();
}
gives me:

Code: Select all

'Ranorex.Unknown' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'Ranorex.Unknown' could be found (are you missing a using directive or an assembly reference?) (CS1061) - D:\Repositories\Flow2TestAuto\RanorexStudio Projects\Flow2TestProject\Flow2TestProject\CodeTestProject\FO\FO.cs:122,35
and

Code: Select all

'System.Collections.Generic.IEnumerable<Ranorex.Core.Repository.RepoItemInfo>' does not contain a definition for 'Click' and no extension method 'Click' accepting a first argument of type 'System.Collections.Generic.IEnumerable<Ranorex.Core.Repository.RepoItemInfo>' could be found (are you missing a using directive or an assembly reference?) (CS1061) - D:\Repositories\Flow2TestAuto\RanorexStudio Projects\Flow2TestProject\Flow2TestProject\CodeTestProject\FO\FO.cs:125,13
it feels impossible to make this method... I need some kind of a way to use the adapter .Click but I'm not getting there :(

User avatar
RobinHood42
Posts: 239
Joined: Fri Jan 09, 2015 3:24 pm

Re: Convert String to Repo Element

Post by RobinHood42 » Tue Jan 03, 2017 9:34 am

Hi xibinki,

Based on your provided code, I have created a small sample. I hope it helps you to meet your requirements :mrgreen: :
string repoItemName = "Button1";

            //Query RepoItemInfo objects based on the repository item name
			IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children
				where ReferenceEquals(things.Name, repoItemName)
				select things;

            //Create "unkown" adapter for the first found element and click it
            myQuery.First().CreateAdapter<Unknown>(true).Click();
Cheers,
Robin

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

Re: Convert String to Repo Element

Post by Vaughan.Douglas » Tue Jan 03, 2017 1:45 pm

xibinki wrote:Is there a way to be able to use our "v" method to perform clicks with the repository items found?
Thanks.
You're asking for two very different things. Our initial functionality was about finding an object by name and waiting for it to exist, thus targeting the repoiteminfo. In order to click the object you'll need to target the object itself. (This is what RobinHood42 told mentioned above).

RobinHood42 also provides a reasonable solution
string repoItemName = "Button1";  
  
            //Query RepoItemInfo objects based on the repository item name  
            IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children  
                where ReferenceEquals(things.Name, repoItemName)  
                select things;  
  
            //Create "unkown" adapter for the first found element and click it  
            myQuery.First().CreateAdapter<Unknown>(true).Click();
The only difference I might suggest is separating the the find from the click.
<UNTESTED>
string repoItemName = "Button1";    
    
            //Query RepoItemInfo objects based on the repository item name    
            IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children    
                where ReferenceEquals(things.Name, repoItemName)    
                select things;   
            var myElement = _repo.SelfInfo.CreateAdapter<Ranorex.WebElement>(false);
            try
            {
                Host.Local.TryFindSingle(myQuery.First().Path, 50000, out myElement);
                myElement.Click();
            }
            catch (Exception)
            {
                //Throw specific error that provides detailed information
                throw;
            }
The only real difference is RobinHood42's example will throw an error if the it is unable to create the adapter whereas mine requires you to catch and handle this failure manually which is the way I prefer to deal with this type of situation.
Doug Vaughan

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Tue Jan 03, 2017 1:54 pm

RobinHood42 wrote:Hi xibinki,

Based on your provided code, I have created a small sample. I hope it helps you to meet your requirements :mrgreen: :
string repoItemName = "Button1";

            //Query RepoItemInfo objects based on the repository item name
			IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children
				where ReferenceEquals(things.Name, repoItemName)
				select things;

            //Create "unkown" adapter for the first found element and click it
            myQuery.First().CreateAdapter<Unknown>(true).Click();
Cheers,
Robin
Hi Robin,

First of all, thank you so much, that method works indeed!!! Although I'm having the stupidest problem of all time, which is, if I pass:

Code: Select all

string repoItemName = "Button5";
Everything works like a charm, but if I pass:

Code: Select all

string repoItemName = "Button" + arrayOfCharacters[i].ToString();
Which gives me exactly the same string "Button5" (I debugged and confirmed), Ranorex gives me an error on execution saying:
Sequence contains no elements
So my question is, why can't I get the method to work when I change on how I "build" my string?

Hope to get an answer from you and thanks once again.

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Tue Jan 03, 2017 2:14 pm

Vaughan.Douglas wrote:
xibinki wrote:Is there a way to be able to use our "v" method to perform clicks with the repository items found?
Thanks.
You're asking for two very different things. Our initial functionality was about finding an object by name and waiting for it to exist, thus targeting the repoiteminfo. In order to click the object you'll need to target the object itself. (This is what RobinHood42 told mentioned above).

RobinHood42 also provides a reasonable solution
string repoItemName = "Button1";  
  
            //Query RepoItemInfo objects based on the repository item name  
            IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children  
                where ReferenceEquals(things.Name, repoItemName)  
                select things;  
  
            //Create "unkown" adapter for the first found element and click it  
            myQuery.First().CreateAdapter<Unknown>(true).Click();
The only difference I might suggest is separating the the find from the click.
<UNTESTED>
string repoItemName = "Button1";    
    
            //Query RepoItemInfo objects based on the repository item name    
            IEnumerable<RepoItemInfo> myQuery = from things in repo.MyApp.SelfInfo.Children    
                where ReferenceEquals(things.Name, repoItemName)    
                select things;   
            var myElement = _repo.SelfInfo.CreateAdapter<Ranorex.WebElement>(false);
            try
            {
                Host.Local.TryFindSingle(myQuery.First().Path, 50000, out myElement);
                myElement.Click();
            }
            catch (Exception)
            {
                //Throw specific error that provides detailed information
                throw;
            }
The only real difference is RobinHood42's example will throw an error if the it is unable to create the adapter whereas mine requires you to catch and handle this failure manually which is the way I prefer to deal with this type of situation.
Hi Vaughan,

I tried your solution (I saw you typed UNTESTED) and it didn't work. At the:

Code: Select all

var myElement = _repo.SelfInfo.CreateAdapter<Ranorex.WebElement>(false);
It tells me that:
The name '_repo' does not exist in the current context (CS0103)
I tried to remove the "_" and when I run it, it appears to trying to find the element on my string and doesn't do anything :?.

Ahm, also I have a strange problem, which is, if I build my string as:

Code: Select all

string repoItemName = "Button" + arrayOfCharacters[i].ToString();
When I run the test, it gives me an error saying: "Sequence contains no elements".
But if I build my string as:

Code: Select all

string repoItemName = "Button5";
Everything runs as intended (with the method from Robin42).
The strings return the exact same thing "Button5" and I don't understand why I can't use the 1st string construction... :( any suggestions?

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

Re: Convert String to Repo Element

Post by Vaughan.Douglas » Tue Jan 03, 2017 4:12 pm

I've got a severe case of vacation brain, so I woudn't expect it to work :D You are correct _repo should be just repo as it refers to our repository variable
StringToRepoItemRepository repo = StringToRepoItemRepository.Instance;
You'll need to add something in the catch exception that tells you what the error is. The reason it appears to have just stalled out is probably because an error was thrown, but since there wasn't anything done in the catch it basically just ignored the error.

The point I was making was just to separate the object identification step from the click method to make debugging any actual issues a bit easier. I usually take that approach so I can provide better/customized messages in the execution log. RobinHood42's response should produce the desired results, so you should start there and expand as the need arises.

Instead of using
myQuery.First().CreateAdapter<Unknown>(true).Click();
try using a generic element like WebElement or another depending on your application, I think you might be able to just use Element. I'd have to look at the object structure to know for sure, but I'll leave that legwork to you. :shock:
myQuery.First().CreateAdapter<Element>(true).Click();
As far as your issue with how you're building the string.... I have no idea, it shouldn't make a difference. Except I know this won't work:
IEnumerable<RepoItemInfo> myQuery = from things in _repo.FO.FLOW2FO.Container2.Self.Children
                                                    where ReferenceEquals(things.Name, "Button" + arrayOfCharacters.ToString())
                                                    select things;


I would suggest encapsulating your search/click into it's own method and just pass the string:
public void ClickTheButton(string repoItemName)
        {
            IEnumerable<RepoItemInfo> myQuery = from things in _repo.FO.FLOW2FO.Container2.Self.Children
                                                where ReferenceEquals(things.Name, repoItemName)
                                                select things;

            myQuery.Click();
        }


and call it something like this:
for (int i = 0; i < length; i++)
     {
          ClickTheButton( "Button" + arrayOfCharacters.ToString());
     }
Doug Vaughan

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Tue Jan 03, 2017 4:55 pm

Vaughan.Douglas wrote:I've got a severe case of vacation brain, so I woudn't expect it to work :D You are correct _repo should be just repo as it refers to our repository variable
StringToRepoItemRepository repo = StringToRepoItemRepository.Instance;
You'll need to add something in the catch exception that tells you what the error is. The reason it appears to have just stalled out is probably because an error was thrown, but since there wasn't anything done in the catch it basically just ignored the error.

The point I was making was just to separate the object identification step from the click method to make debugging any actual issues a bit easier. I usually take that approach so I can provide better/customized messages in the execution log. RobinHood42's response should produce the desired results, so you should start there and expand as the need arises.

Instead of using
myQuery.First().CreateAdapter<Unknown>(true).Click();
try using a generic element like WebElement or another depending on your application, I think you might be able to just use Element. I'd have to look at the object structure to know for sure, but I'll leave that legwork to you. :shock:
myQuery.First().CreateAdapter<Element>(true).Click();
As far as your issue with how you're building the string.... I have no idea, it shouldn't make a difference. Except I know this won't work:
IEnumerable<RepoItemInfo> myQuery = from things in _repo.FO.FLOW2FO.Container2.Self.Children
                                                    where ReferenceEquals(things.Name, "Button" + arrayOfCharacters.ToString())
                                                    select things;


I would suggest encapsulating your search/click into it's own method and just pass the string:
public void ClickTheButton(string repoItemName)
        {
            IEnumerable<RepoItemInfo> myQuery = from things in _repo.FO.FLOW2FO.Container2.Self.Children
                                                where ReferenceEquals(things.Name, repoItemName)
                                                select things;

            myQuery.Click();
        }


and call it something like this:
for (int i = 0; i < length; i++)
     {
          ClickTheButton( "Button" + arrayOfCharacters.ToString());
     }


Tried the encapsulating strategy and it still gives me the "Sequence contains no elements", dammit lol... I've tried a few alternatives but always end up getting the same error message :(

xibinki
Posts: 28
Joined: Mon Jun 27, 2016 9:59 am

Re: Convert String to Repo Element

Post by xibinki » Tue Jan 03, 2017 5:49 pm

So I found the solution to my problem, along with some help from our fellow friends at stackoverflow :)

On our method:

Code: Select all

for (int i = 0; i < length; i++)
{
	if (arrayOfCharacters[i].ToString() == ".") {
	repo.FO.FLOW2FO.Container2.BtnComma.Click();
	}
				
	else {
		repoItemName = "Button" + arrayOfCharacters[i].ToString();
				
		//Query RepoItemInfo objects based on the repository item name 
		IEnumerable<RepoItemInfo> myQuery = from things in repo.FO.FLOW2FO.Container2.SelfInfo.Children
		where ReferenceEquals(things.Name, repoItemName)
		select things;

            	//Create "unkown" adapter for the first found element and click it
            	myQuery.First().CreateAdapter<Unknown>(true).Click();           	
      }
I just had to change to:

Code: Select all

where String.Equals(things.Name, repoItemName)
And everything worked perfectly :)

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

Re: Convert String to Repo Element

Post by Vaughan.Douglas » Wed Jan 04, 2017 6:45 pm

And everything worked perfectly :)
xibinki
I'm glad to hear it!
Doug Vaughan

fwason
Posts: 26
Joined: Wed Aug 24, 2011 10:39 pm

Re: Convert String to Repo Element

Post by fwason » Tue Apr 18, 2017 4:58 pm

If you prefer working in Visual Studio (as we do) because of the performance benefits when writing and debugging, then vote here:

http://uservoice.ranorex.com/forums/150 ... -webdriver

Let's get Ranorex to support the WebDriver via their API!!!