Forum Discussion

harshad_w's avatar
harshad_w
Occasional Contributor
6 years ago

FindChild method is not working in iterations

     function openRoadCommonFunctions_sideOfCL(sideOfCL)
    {
    try
         {
     
     var hostForm = Aliases.OpenRoadsDesigner.HostForm;
     var listItemsObj = Aliases.OpenRoadsDesigner.DropDownFormEx.StandardValuesListBox;

           var propNames = new Array ("WinFormsControlName");  
           var propValues = new Array ("Misc::Side Of Centerline"); 
         depth = 0;
         counter = 1;
         do
         {
           depth++;
           counter++;
           var sideOfCLTxtBx = hostForm.FindChild(propNames, propValues, 100, true); 
           if(counter > 100)
          {
            break;
          }  
         }
         while(!sideOfCLTxtBx.Exists);    
           

     var propNames = new Array ("ClrClassName");  
     var propValues = new Array ("EditorButton");
         depth = 0;
         counter = 1;
         do
         {
           depth++;
           counter++;
           var sideOfCLListBox = sideOfCLTxtBx.FindChild(propNames, propValues, 100, true);
           if(counter > 100)
          {
            break;
          }  
         }
         while(!sideOfCLListBox.Exists);   
      
       if(sideOfCLListBox.Exists){
          while(!listItemsObj.Exists){
          sideOfCLListBox.ClickButton();
          if(listItemsObj.Exists){
            break;
          }
          }
          Delay(3000, "Selecting Side Of Centerline...");
          methodCount = listItemsObj.wItemCount;
          methodNames = listItemsObj.wItemList;
          Log.Message("Count of Side Of Centerlines " + methodCount +" <::> "+ "Side Of Centerline Types:: " + methodNames);
          listItemsObj.ClickItem(sideOfCL);
       }
       else
       Log.Error("Side Of CL Box does not exist");
   
   }
    catch(exception)
            {
            
            Log.Error("Exception in Side Of CL function", exception.description);
            }
        finally
            {
            Log.PopLogFolder();
            }
    }

I am trying to use the above code in order to select the two values (Left, Right) displayed in the "Lane Creation Method" dropdown. The code works when I select the first option (Left), and it does not click on the dropdown for the second time. It gives me the exception saying  "'Exists' is null or not an object". Is there any other method that can make the clicks on the dropdown without any errors? 

 

 

  • Hi,

     

    Well, you did not mention language/technology your tested application is based on and if it uses some non-standard controls or the way how they are filled with data, the code might have sence...

    Nevertheless, I would recommend to replace search loops with the call to .FindChildEx() or .WaitAliasChild() whatever is more appropriate.

    The potential problem with search loops that are based on the objects referred to via Aliases is that for performance reasons TestComplete caches such objects and may not always update their state. This means that if for some reason aliased object was not found when it was referenced and used for the first time, the reference to the empty object might be cached and used within the search loop. Even if the sought for object will appear later while the code is within the loop.

    .FindChildEx() should handle the above problem.

    Also you may consider to use the .RefreshMappingInfo() method. At least I would strongly recommend to read its description to get a better understanding about the things I mentioned above.

     

  • AlexKaras's avatar
    AlexKaras
    Champion Level 3

    Hi,

     

    The code seems to be unnecessary obscured and complex... Maybe because of some reason which is not clear to me.

    First: it might help if you let us know what code line errors out with exception and how do you call the function.

    Second: what is the real need for all those loops with .FindChild() and .Click() calls inside?

    Considering that this is a desktop application, all controls usually exist and are populated with data when the form is opened (or, after some spinner disappears). Even if this is not a case, consider to use the .FindChildEx() method where you may specify the timeout to use for the sought for control to appear.

     

    Can you provide a plain language description of what your function is expected to do?

     

    • harshad_w's avatar
      harshad_w
      Occasional Contributor

      Hi,

       

      I have to use the loops because sometimes the child is not found in a first go. First, I try to find the text box object   then the dropdown. Second, I need to click on the dropdown once it's found.

      Third,  I need to select the two options (Left/Right) displayed in the list (please see the attached image). 

       

      So, the parameter I pass to the function will be Left/Right depending on the need. 

       e.g. openRoadCommonFunctions_sideOfCL("Left"). The function should click on the list box and select the parameter I passed. Sometimes, it does not click on the list box and moves to the else block and throws the error "Aliases.OpenRoadsDesigner.DropDownFormEx.StandardValuesListBox" not found. 

       

      I want to select Left/Right option as required. I have also attached a video that shows the steps I do manually.

       

      Thanks,

      Harshad

      • AlexKaras's avatar
        AlexKaras
        Champion Level 3

        Hi,

         

        Well, you did not mention language/technology your tested application is based on and if it uses some non-standard controls or the way how they are filled with data, the code might have sence...

        Nevertheless, I would recommend to replace search loops with the call to .FindChildEx() or .WaitAliasChild() whatever is more appropriate.

        The potential problem with search loops that are based on the objects referred to via Aliases is that for performance reasons TestComplete caches such objects and may not always update their state. This means that if for some reason aliased object was not found when it was referenced and used for the first time, the reference to the empty object might be cached and used within the search loop. Even if the sought for object will appear later while the code is within the loop.

        .FindChildEx() should handle the above problem.

        Also you may consider to use the .RefreshMappingInfo() method. At least I would strongly recommend to read its description to get a better understanding about the things I mentioned above.