Forum Discussion

dipali's avatar
dipali
Occasional Contributor
6 years ago

FindChild method fails intermittently when called from keyword test

I've following common wait function for our web application which fails 7 out of 10 times when called from keyword tests - the parameters passed to function are of string type so I'm using eval as suggested in other community posts.

 

function Wait_for_child_object_to_exist(parentObject, propertiesArray, valuesArray, depth)
{
 var counter = 0;
 Sys.Refresh();
    if (typeof propertiesArray == 'string') {
        propertiesArray = eval(propertiesArray);
    }
    if (typeof valuesArray == 'string') {
        valuesArray = eval(valuesArray);
    }
   
    parentObject = eval(parentObject);
/* //printing arrays and param values  
 Log.Message(parentObject);
 Log.Message(propertiesArray.length);
 for (var i=0; i<propertiesArray.length; i+=1)
 {
 Log.Message(propertiesArray[i] + " ");
  Log.Message(valuesArray[i] + " ");
  } */
 
  
 if(!parentObject.Exists) //wait for the parent object if it doesn't exists
 Delay(3000);
 
  if(parentObject.Exists){
    var child_object = parentObject.FindChild(propertiesArray, valuesArray, depth, true); // This will find the child at any level
       
  while((!child_object.Exists) && (counter < 90)){ //This will wait until child_object exists
        aqUtils.Delay(500);
        counter++;
        Log.Message("wait for child loop counter " + counter);
        }
   if(child_object.Exists)
   {
    Log.Message("child object found in the system");
    return child_object;
    }
   else
    Log.Error("Failed to find the child object with given properties");
 }
  else
    Log.Error("Parent object: " + parentObject+ " is missing"); //if parent object doesn't exist     
}

 

However if I call this function as a part of another function so that parameter passing can be handled through script itself then it works consistently. But it doesn't always work if I pass the function paramters from keyword tests, it ends up with error "Failed to find the child object with given properties" even thought that object exists in the system.

 

Can anyone please suggest if the above FindChild approach is right? Is there anything wrong with parameter passing from keyword tests?

  • Hi,

     

    > fails 7 out of 10 times 

    Does failure and pass occur for exactly the same data? Or just with different data the function may pass or fail ?

     

    It is difficult to provide an answer without seen how the function is called (I am interested in exact parameters' values). I am wondering because, for example, if you search by more than one parameter, then you must pass arrays for properties and values, but if the actual paremeter is, say, 'Param1, Param2' string then it will not be resolved to the array even with the help of eval() function.

     

    Another note:

    var child_object = parentObject.FindChild(propertiesArray, valuesArray, depth, true); // This will find the child at any level
            
    while((!child_object.Exists) && (counter < 90)){ //This will wait until child_object exists
    ...

    This code will not work as expected, because if child_object is not found by .FindChild() at the moment of search, the returned value will be an empty stub object with .Exists property equal to false. And the object will not be re-evaluated even if the sought for object appears later. So while loop is useless here.

    The correct way is

    either to use the .FindChildEx() method instead of the .FindChild()

    or use the loop like this:

     var child_object;
    do
    {
      child_object = parentObject.FindChild(propertiesArray, valuesArray, depth, true);
      if (!child_object.Exists)
        Delay(500);
    }
    while((!child_object.Exists) && (counter < 90));

    The first approach will just wait for the object to appear within the specified timaout while the second one allows some additional actions to be done while waiting. For example, some confirmation window that must be closed before the sought for object appears can be processed with the latter approach.

     

    P.S.

    > // This will find the child at any level

    Actually, not at 'any level' but at the level up to the 'depth' depth.

    Incorrect commenting might appear to be even worse than absence of the such at all... :)

     

  • AlexKaras's avatar
    AlexKaras
    Champion Level 3

    Hi,

     

    > fails 7 out of 10 times 

    Does failure and pass occur for exactly the same data? Or just with different data the function may pass or fail ?

     

    It is difficult to provide an answer without seen how the function is called (I am interested in exact parameters' values). I am wondering because, for example, if you search by more than one parameter, then you must pass arrays for properties and values, but if the actual paremeter is, say, 'Param1, Param2' string then it will not be resolved to the array even with the help of eval() function.

     

    Another note:

    var child_object = parentObject.FindChild(propertiesArray, valuesArray, depth, true); // This will find the child at any level
            
    while((!child_object.Exists) && (counter < 90)){ //This will wait until child_object exists
    ...

    This code will not work as expected, because if child_object is not found by .FindChild() at the moment of search, the returned value will be an empty stub object with .Exists property equal to false. And the object will not be re-evaluated even if the sought for object appears later. So while loop is useless here.

    The correct way is

    either to use the .FindChildEx() method instead of the .FindChild()

    or use the loop like this:

     var child_object;
    do
    {
      child_object = parentObject.FindChild(propertiesArray, valuesArray, depth, true);
      if (!child_object.Exists)
        Delay(500);
    }
    while((!child_object.Exists) && (counter < 90));

    The first approach will just wait for the object to appear within the specified timaout while the second one allows some additional actions to be done while waiting. For example, some confirmation window that must be closed before the sought for object appears can be processed with the latter approach.

     

    P.S.

    > // This will find the child at any level

    Actually, not at 'any level' but at the level up to the 'depth' depth.

    Incorrect commenting might appear to be even worse than absence of the such at all... :)

     

    • dipali's avatar
      dipali
      Occasional Contributor

      Hi Alex,

      Updating while loop to do while has resolved the issue!

      Thank you for your help!

       

    • dipali's avatar
      dipali
      Occasional Contributor

      Thanks Alex for the responses, please see my responses inline..

       

      > fails 7 out of 10 times 

      >>Does failure and pass occur for exactly the same data? Or just with different data the function may pass or fail ?

      >>>Test data is constant, sometimes it passes sometimes fails. I've seen the required object exists on the screen but Testcomplete fails to recognise it i.e. waits in the while loop and ultimately fails with error "object doesn't exist". After interrupting the test run, I'm able to locate that same child object from the name mapping so the child properties I'm passing to the function must be right (also evidently it passes on the other occasions).

      Yes, I was calling that function from keyword tests with array parameters. I've now changed it thinking it works when called as a part of another function but it still fails so ideally this function intermittently fails no matter from where you're calling it - keyword test or as a part of another function.

      Please find attached screenshots for

      1) the parameter passing from Keyword test. I've tried different depth parameters too e.g. 15 but that doesn't resolve the problem. Please note that "Page_MetapraxisLocalhost" (i.e. the first object highlighted in object browser) is a variable declared in separate script called desclaration and I'm using USEUNIT in other function scripts.

      2) the name mapping and 3) object browser (invisible objects is turned on) for the child object (highlighted in red) for which function fails.(Panel 0 is a dynamic object and it appears at several places in the application)

       

      Meanwhile I will udpate my while loop to "do while" and will check if that helps at all.

       

      > // This will find the child at any level

      >> You're right, actually those comments were added in hurry. Also initially I was struggling to find a single TC function to find the children with the given grand parent object and I later realised the depth is an important parameter of Finchild which controls this.(Also it wasn't obvious from the initial description of the method in the TC documentation, so I had to make a quick note before I forget the fact :) ). I will update it now.

       

      On the similar line, there is a new qustion on my mind -> do we need to use separate wait methods for the parent objects which are created at run time before using FindChild methods on their child objects? Or FindChild is enough to handle these situations?