Page 1 of 1

ForEach loop - adapter not available after page changes

Posted: Thu Jun 05, 2014 5:38 pm
by houseofcutler
Hi There,

I am testing an android app (snapshot attached), there are several pages which display a list of options but follow the same format. Rather than individually mapping all of these elements I thought I would have a go at doing it 'the popper way' and writing a generic solution that would select each of the options in the list and perform some actions - I can then reuse this code whenever I need to test the functionality on other pages with similar lists.

I have a GenericList repo item which identifies each of the items listed on page.
.//container[@rid='viewanimator']/container[@visible='True']//container[@rid='linearLayout1']/text[1]

Here is the code I am using:
public void Select_Each_Item()
        {
            Report.Info("Select Each Option Listed");
            IList<Ranorex.Text> varOptions = repo.ComGroupcallEmerge.ListSearch.GenericListInfo.CreateAdapters<Ranorex.Text>();
            Report.Info("User",varOptions.ToString());
       
            if (varOptions.Count >0)
            {
            	foreach (Ranorex.Text varOption in varOptions)
            	{
            		Report.Info("User","Click on " + varOption.Element.GetAttributeValueText("Text"));
            		
            		varOption.Touch();
             		Delay.Duration(5000);
            		
			//Report the new page title then click the back button to return to the list
             		Report.Info("User",repo.ComGroupcallEmerge.LeftPanel.Header.PageTitle.TextValue);
             		Report.Info("User","Clicking on Back Button");
             		repo.ComGroupcallEmerge.LeftPanel.Header.BackButton.Touch();
					Delay.Duration(5000);
            	}
            }
        	
        }
The list is built and the first option 'Name' is pressed, a new page opens, the title is reported and then then back button is used to return to the page with the original list. The next option in the list should then be pressed but it isn't (even though the report says it has been successfully)

The thought has just occurred to me that it is probably the fact that the page changed which means that when the next iteration of the foreach loop resumes the option is not actually pressed.

I have only been using c# as long as Ranorex which is only a couple of months so please excuse my limited understanding of c#

If anyone can tell me where I am going wrong that would be amazing as I plan for this code - or a much more sophisticated enhancement to it to form the basis of most of the testing of this app.

Many thanks

Ben

Re: ForEach loop - adapter not available after page changes

Posted: Thu Jun 05, 2014 5:52 pm
by krstcs
Ben,

This is by design in Ranorex. They made Ranorex invalidate any repository object immediately when the object is invalid. The page change/reload is one time when this happens. Menus and drop-down/combobox elements also do this.

I would recommend adding a Validate -> Exists on the element you are looking for before you attempt to use it. This will make Ranorex re-validate the element, and it will be a good way for you to know that that element is failing, if it does fail.

So, in your Click-Button module, add a Validate -> Exists -> Button at the very top of the module.

In code:

Code: Select all

Validate.Exists(<Button object>);

Re: ForEach loop - adapter not available after page changes

Posted: Fri Jun 06, 2014 10:35 am
by houseofcutler
Hi Krstcs,

Thank you for explaining that - I was not aware of that feature. I have added a validation as you suggested:
foreach (Ranorex.Text varOption in varOptions)
            	{
            		Validate.Exists(varOption);
            		Report.Info("User","Click on " + varOption.Element.GetAttributeValueText("Text"));
            		varOption.Touch();
             		Delay.Duration(5000);
When I run the user code The validation steps are reporting that the element exists but after the first item nothing is clicked but Ranorex believes it has been successful.

Do you have any other thoughts please..?

Thanks

Re: ForEach loop - adapter not available after page changes

Posted: Fri Jun 06, 2014 1:44 pm
by krstcs
You have a touch event in the example, is this on a mobile device? I have no experience with mobile, so I'm not going to be much help. :D

Could you post a sample project and a snapshot of the app so we can look at it?

Re: ForEach loop - adapter not available after page changes

Posted: Fri Jun 06, 2014 3:47 pm
by houseofcutler
I have already attached a snapshot - it is in the original post. I have now also attached my project.

The User code in question can be found in the Student Navigation test case and the student navigation module. All of the touch actions also included in the module were simply to prove that this did work when not using dynamically generated adapters.

Don't you need the actual app to be able to runt he project though?

Re: ForEach loop - adapter not available after page changes

Posted: Tue Jun 10, 2014 3:47 pm
by houseofcutler
For anyone that comes across this article looking for the answer here it is:
Regarding your problem that only the first item is clicked:

In your IList “varOptions” are all items stored you want to click. But when you reload this container (by clicking an item and go back again) the elements will be invalid.
In order to avoid this problem, you have to reload the items again.
public void Select_Each_Option()
        {
        	Report.Info("Select Each Option Listed");
        	
        	IList<Ranorex.Text> varOptions = repo.ComGroupcallEmerge.ListSearch.GenericList.Find<Ranorex.Text>("/mobileapp[@title='com.groupcall.emerge']//container[@rid='leftpanel']//container[@rid='viewanimator']/container[@visible='True']//container[@rid='linearLayout1']/../../container[@visible='true']/container/text[1]");
			int counter = varOptions.Count;
			Report.Info("Elements in list varOptions: "+counter.ToString());
			if(counter>0)
				{
			    for(int i=1; i<=counter; i++)
		             {
		             varOptions = repo.ComGroupcallEmerge.ListSearch.GenericList.Find<Ranorex.Text>("/mobileapp[@title='com.groupcall.emerge']//container[@rid='leftpanel']//container[@rid='viewanimator']/container[@visible='True']//container[@rid='linearLayout1']/../../container[@visible='true']/container/text[1]["+i+"]");
		             foreach(Ranorex.Text text in varOptions)
			             {
							text.Touch();
							;
							repo.ComGroupcallEmerge.Loading.LoadingInfo.WaitForExists(5000);
							
							if (repo.ComGroupcallEmerge.Loading.LoadingInfo.Exists())
							{
								Report.Info("User","Waiting for loading to complete - Max 30 seconds");
								repo.ComGroupcallEmerge.Loading.LoadingInfo.WaitForNotExists(30000);
							}
							
							Validate.NotExists(repo.ComGroupcallEmerge.Loading.LoadingInfo);
							Report.Info("User","Page Title: " + repo.ComGroupcallEmerge.LeftPanel.Header.PageTitle.TextValue);
							Report.Info("User","Click back button");
							repo.ComGroupcallEmerge.LeftPanel.Header.BackButton.Touch();
							repo.ComGroupcallEmerge.Loading.LoadingInfo.WaitForNotExists(30000);
							Validate.NotExists(repo.ComGroupcallEmerge.Loading.LoadingInfo);
							Delay.Duration(5000);
						  }
			          }
			      }
        }
All thanks go to Markus @ Ranorex support for providing me with this :D :D :D