cancel
Showing results for 
Search instead for 
Did you mean: 

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

Community Leader

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;  
}

 


-------------------------------------------------
Standard syntax disclaimers apply
Regards,
7 REPLIES 7
Community Hero

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

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-... might provide additional useful info.

 

Regards,
Alex
[Community Expert Group]
____
[Community Expert Group] members are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Postings made by [Community Expert Group] members
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
[Community Expert Group] signature is used with permission by SmartBear Software.
http://smartbear.com/forums/f83/t86934/community-experts/
================================
Community Leader

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


.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


-------------------------------------------------
Standard syntax disclaimers apply
Regards,
Community Hero

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



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?

 

Regards,
Alex
[Community Expert Group]
____
[Community Expert Group] members are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Postings made by [Community Expert Group] members
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
[Community Expert Group] signature is used with permission by SmartBear Software.
http://smartbear.com/forums/f83/t86934/community-experts/
================================
Community Leader

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

My apologies.  That was old data - I was having the issue on Friday before a minor code change last thing in the day that fixed it and I forgot about it over the weekend doh ! Smiley Sad.  Today I have it working, but I'm still hoping to find a way of making it a bit more efficient.  My Run Timeout is currently 30 seconds (yes, some controls on my site actually take that long), so this function could take 30 seconds plus change before it continues.  On a page with just 4 controls, that could add 2 minutes.  I am using a FindChildEx though - that cuts it down.  I could do: 

var currentTimeout = Options.Run.Timeout;
Options.Run.Timeout = 100;
// find table, wait etc.
Options.Run.Timeout = currentTimeout

But that opens the window again for the table actually being there, but the timeout being too short for TC to track it down because the page loads a bit slow.  I'm not saying there's a better solution than the current one I have.  It would just be nice to ask TC to just tell me if it's on the page as quick as possible rather than try and find it for a long time that I make up and tweak every time the test doesn't find the table even though it's there all because I made the delay too short.


-------------------------------------------------
Standard syntax disclaimers apply
Regards,
Community Hero

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



It would just be nice to ask TC to just tell me if it's on the page as quick as possible

The general sequence is like this:

-- If the click on some web element can reload page/page data (as opposed to just displaying/hiding something on the page via script), then page.Wait() must be executed. .Wait() method of the page object waits until the web page source is obtained from web server and the browser completes initial page processing;

-- If the page contains elements that are downloaded from web server via additional requests (Ajax) and you either need to interact with these elements or web page is not responsive until these elements ere obtained, then you must execute page.<container>.WaitChildEx() with the long enough timeout to delay until the elements are obtained. (Note, it is safe to set very long timeouts here because .WaitXXX() methods return as soon as the sought for object is obtained. The only case when too long timeout might be not reasonable is when it is OK for the sought for object to be absent on the page. In this case you must find a good enough timeout value to wait long enough for the object but not wait too long.)

-- Optionally, depending on the implementation of the tested application, you may need to additionally wait for the found object become visible on the page. (It may be required to check different indicators to ensure element's visibility: from .Visible property in the simplest case to the values of class/width/height properties of the element itself or including a set of its parents.)

-- One more additional delay might be required if the data for the target web element are also obtained via separate request. If this is the case, then you must figure out criteria that are met when the element is populated with data and delay appropriately;

-- It is usually safe to proceed with the test actions after all above actions are done.

 

Regards,
Alex
[Community Expert Group]
____
[Community Expert Group] members are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Postings made by [Community Expert Group] members
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
[Community Expert Group] signature is used with permission by SmartBear Software.
http://smartbear.com/forums/f83/t86934/community-experts/
================================
Community Leader

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

OK,  Nuanced variation of the same question:

 

More detail:

If this table is on the page it will be there the moment the page is rendered and it just gets popped up when a callback starts and moved back when the callback ends, so the only thing that changes is the VisibleOnScreen property

 

How would you go about distinguishing between an item that doesn't exist anywhere on the page (not in the HTML) and an item that took too long to exist ?  In both cases a .Findxxx would come back after some time with a stub.  If it is because the table is on the page but TC couldn't find it in time, theres something wrong with the page and I want to at least log a warning.  If it's not there at all in the HTML it means I have no controls on the page that call the loading panel, so I can skip right obver this and continue.  I can survive without this to be honest, but it would be useful to be able to make sure those control changes run smoothly without having to know beforehand on each page if it has a loading panel or not and write tests ccordingly


-------------------------------------------------
Standard syntax disclaimers apply
Regards,
Community Hero

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

Well...

It is a usual and well-known problem with Ajax-enabled pages when they do not contain an indicator that all processing on the page has been completed - when test code fails to find the dynamic objects like LoadingPanel, it is not easy to determine whether the object was not found because the given data processing is over and the object has already been removed from page DOM (so there is no reason to wait for it) or because the data processing has not been started yet (for example, because of slow network or backend overload and thus the code must continue to wait for the object).

 


 

How would you go about distinguishing between an item that doesn't exist anywhere on the page (not in the HTML) and an item that took too long to exist ?  In both cases a .Findxxx would come back after some time with a stub.


No. If the object is not in the page DOM, then indeed .FindChild() or .FindChildEx() returns an empty stub and testcode must wait until the object appears. (Or the timeout defined by quality of service requirements elapses. In case such requirements exist.)

If test code should delay until the object is gone (e.g. LoadingPanel is hidden), then test code may use the .WaitProperty method. For the discussed example the code may be like this:

LoadingPanel = Aliases.<container>.FindChildEx('loadingPanel', 60000);

// some data processing is triggered here

...

// wait until the data processing is over

LoadingPanel.WaitProperty('Visible', false, 60000);

...

 

Regards,
Alex
[Community Expert Group]
____
[Community Expert Group] members are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Postings made by [Community Expert Group] members
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
[Community Expert Group] signature is used with permission by SmartBear Software.
http://smartbear.com/forums/f83/t86934/community-experts/
================================
February News
Top Kudoed Authors