Passing containers to different class methods

Ask general questions here.
louiskfinney
Posts: 2
Joined: Thu Jun 20, 2019 4:30 pm

Passing containers to different class methods

Post by louiskfinney » Thu Jun 20, 2019 7:18 pm

Hey guys,

I'm working on a way to automate testing for mobile app development. I am creating a generic function that should take in a repo element, go into a try catch statement to determine what to do if the element cannot be found. This is to ensure that the test will continue if it fails the check, allow for specific debugging messages and make the higher level code more flexible. If the container is visible, it will click on the container and return. It will catch the exception, log the error and return back.
Ideally, I want to be able to pass in both containers/Elements so that this framework is compatible with both iOS and Android. The android and iOS have enough differences that I made two public classes that will be calling these generic functions in a third class. The android and iOS classes both have a separate repo object and therefore have to pass it into the generic as a parameter.

Here is the function I am calling

Code: Select all

public static void checkAndClick(Ranorex.Container repoElement)
{
                try
                {
                                if(repoElement.Valid)
                                {
                                                repoElement.Touch();
                                }
                                return;
                }
                catch(ElementNotFoundException)
                {
                                Report.Log(ReportLevel.Info, "Status", "Error: Element Catch");
                                return;
                }
}

When I pass in a container that is visible, the try catch works as expected.
However, if I pass in a container that exists in the repository but is not visible on the screen, it fails as a parameter. Any log statements that are in the function will not be reached and Ranorex errors out with the ElementNotFoundException. I believe this is because the element does not exists when passing it into the function and therefore makes the try useless.

I also tried passing in the parameter as a RepoItemInfo and was met with the same error with this code.

Code: Select all

public static void checkAndClick(RepoItemInfo repoInfo)
{
               var element = repoInfo.CreateAdapter<Unknown>(true);
        try
        {
               if (element.Visible)
                {
                              element.Touch();
                }
            }
            catch(ElementNotFoundException)
            {
               Report.Log(ReportLevel.Info, "Element catch");
            }
}
I want to know if there is a way to pass in a non-visible repo item that would not cause the function to error out. Ideally, I would want to pass in elements that work for both iOS and Android repos.

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

Re: Passing containers to different class methods

Post by odklizec » Fri Jun 21, 2019 7:37 am

Hi,

I think that visibility is one thing and not existence of an element another. If an element is invisible (visible attribute set 'false'), yet the element is available in the UI, Ranorex should be able to find and work with it? The only problem could be that your xpath explicitly expects @visible='true'. In this case, ElementNotFoundException will be thrown in any attempt to access such invisible repo element.

Could you please post an example of problematic xpath and snapshot (NOT screenshot) of your app, so we can evaluate both and eventually, suggest the best approach? Thanks.
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

louiskfinney
Posts: 2
Joined: Thu Jun 20, 2019 4:30 pm

Re: Passing containers to different class methods

Post by louiskfinney » Wed Jun 26, 2019 4:16 pm

I believe I have solved my issue. Odklizec gave me the idea that something was not working with my paths when it comes to containers. I don't believe Ranorex handles elements not visible in the UI in an intuitive way but I'm also just a beginner. I decided that using RepoItemInfo for Containers made most of my issues go away.
I was also able to handle the mobile OS by implementing different Adapters. Here is my near complete function.

Code: Select all

public bool SafeClick(RepoItemInfo item_info)
{
 //Report.Log(ReportLevel.Info, "Status", "At RepoItemInfo Try Catch");
 try
 {
  if(item_info.Exists(20000))
   {
     //Report.Log(ReportLevel.Info, "Status", "Item Info exists");
     if(os == "iOS")
     {
      Container test = item_info.CreateAdapter<Container>(true);
      test.Touch();
     }
     else
     {
      AndroidElement test = item_info.CreateAdapter<AndroidElement>(true);
      test.Touch();
     }
     return true;
    }
   }
  catch(RanorexException e)
  {
   Report.Log(ReportLevel.Error, "Failure", "Failed to find "+ item_info.Name);
   Report.Log(ReportLevel.Failure, "Failure", "Exception thrown \n\r"+e.ToString() );
   return false;
  }
  Report.Log(ReportLevel.Error, "Failure", "Failed to find "+ item_info.Name);
  return false;
}
This meets my desired outcome of being able to pass in an item that I would like to click on without having to worry about the mobile OS. It's a little crude, but it is an building block to be able to try to click on a Container or AndroidElement and log any failure that occurs. I have made similar methods to do the same with entering text and reading a text value from a UI element.

I appreciate the help! I wanted to post this incase anyone else was having this idea.