Forum Discussion

RUDOLF_BOTHMA's avatar
RUDOLF_BOTHMA
Community Hero
7 years ago

Best way to test that something doesn't exist without an error

Morning all,

 

I have a piece of script that waits for the loading panel to disappear off the page.  It's on the page 99% of the time, but not always.  It always has the same name and location in the structure if it is on the page (browser->form->panel->LoadPanel Table) So I use a FindChild on the form to get my loading panel.  While the loading panel is in the way, the VisibleOnScreen is true.  As soon as it goes away, VisibleOnScreen changes to false.  Very handy.  Find it, getpropertyvalue in a loop with short interval and continue as soon as it changes.  I don't need to tell any users anything.  It's just that it's more efficient than building in a 5 second delay in case the panel is still there.  In these situations TestComplete finds the Textbox/combobox/whatever I'm looking for and tries entering text because hey, it exists and is visible, but falls because it can't get focus...

 

I'm trying to avoid having to map this panel on ALL my pages, so my question comes on that 1% of pages where the table doesn't exist on the page at all. I want this function to just exit silently rather than error when the wait or find fails to find the object at all.  Thoughts?

/// <summary>
/// Waits for the Loading Panel to disappear off screen
/// </summary>
function WaitLoadExampple()

{

 //panel hasn't been loaded before.  First get it
 //But since it doesn't change, keep it in a variable
 //Not using .Exists, since it's a varaible which may not even be a stub yet
  if(Project.Variables.LoadingPanel==null || Project.Variables.LoadingPanel==undefined) 
  {
    Delay(1000,"Load Panel exist load");
    var formObj = Aliases.browser.FindChildEx("ObjectType","Form",2,true,5000);
    if(!formObj.Exists)
    {
      Log.Warning("WaitLoadingPanel() timed out while waiting for the form object","",pmNormal,"",GetPagePicture());
      return;
    }
    Project.Variables.LoadingPanel = ExecuteWait("TABLE",formObj,"LoadingPanelTable"); //this does a WaitTable() in a loop
    if(!Project.Variables.LoadingPanel.Exists)
    {
      Log.Warning("WaitLoadingPanel() timed out while waiting for the table object","",pmNormal,"",GetPagePicture());
      return;
    }
  }
   
   
  if(aqObject.IsSupported(Project.Variables.LoadingPanel,"VisibleOnScreen"))
  {
    var isVisible = aqObject.GetPropertyValue(Project.Variables.LoadingPanel,"VisibleOnScreen");
    if(isVisible)
      Log.Message("***** Loading panel was visible on screen ****","",pmNormal,"",GetPagePicture()); 
    var retries = 0;
    while(isVisible && retries < 100)
    {
      retries++;     
      if(retries==2)
        Log.Message("***** WaitLoadingPanel() had to wait ****","",pmNormal,"",GetPagePicture()); 
      if(Project.Variables.LoadingPanel.WaitProperty("VisibleOnScreen",false,100))
      {
        Log.Message("***** WaitLoadingPanel() finished waiting ****","",pmNormal,"",GetPagePicture()); 
        break;
      }
    }
  }
  return;  
}

 

  • AlexKaras's avatar
    AlexKaras
    Champion Level 3

    Hi,

     

    If I got your question and problem right...

     

    .FindChild() should work for you and it looks like you are using it correctly: call for .FindChild() and then check .Exists for the search result.

    It is something else that makes me doubting:

    > same name and location in the structure if it is on the page (browser->form->panel->LoadPanel Table)

    I guess (as I don't know the exact implementation in the tested application) that despite the fact that the location and the name of the loading panel is the same, it is created and recreated by some page script when the page and/or page's data is reloaded. If the above guess is correct, then you should not keep the reference for the loading panel object in the variable, but must get the reference a-new every time. (Performance penalty should be minimal as the search is done by the sought for object's name.) Especially, considering the fact that you are using Aliases as the search root.

    The reason for above is that the stored reference to the object uses explicit path to it (e.g. Aliases.browser.Form.Panel.LoadingPanelTable) and if the LoadingPanelTable object is recreated during page/data reload, then the stored referenced object is invalidated and thus TestComplete fails to find the old LoadingPanelTable object even if the new created one has the same name and position in the objects tree.

    https://support.smartbear.com/testcomplete/docs/testing-with/object-identification/name-mapping/how-to/refresh-cache.html might provide additional useful info.

     

    • RUDOLF_BOTHMA's avatar
      RUDOLF_BOTHMA
      Community Hero

      .FindChild() should work for you and it looks like you are using it correctly: call for .FindChild() and then check .Exists for the search result. 


      In theory, yes, but I'm getting an object does not exist error if it's not on the page at all

       


      The reason for above is that the stored reference to the object uses explicit path to it (e.g. Aliases.browser.Form.Panel.LoadingPanelTable) and if the LoadingPanelTable object is recreated during page/data reload, then the stored referenced object is invalidated and thus TestComplete fails to find the old LoadingPanelTable object even if the new created one has the same name and position in the objects tree.;


      Valid point. It's been working fine so far, but I should probably change it

      • AlexKaras's avatar
        AlexKaras
        Champion Level 3


        I'm getting an object does not exist error if it's not on the page at all

         

        Can you provide a relevant line of code and exact error message from test log, including the text from the Additional Info pane?