Forum Discussion

Al2's avatar
Al2
Occasional Contributor
5 years ago
Solved

Using 'Timer' for Modal Overlays

Hi,

 

I have a question related to the use of Timer.

I don't understand what unit_name refers to here? 

 

I was running a program without using any unit reference and it errored. Any help would be appreciated!

 

 

Thank you

Al

  • tristaanogre's avatar
    tristaanogre
    5 years ago

    As an example.... let's consider the following basic OOP code


    class myObject{
        constructor(){
            this.Exists = true;
            this.someText = 'I think therefore I am';
        }
    }
    
    function testObject(){
        
        if (!someObject.Exists){
            Log.Message('It does not think therefore it is not')
        }
        someObject = new myObject();
        if (someObject.Exists){
            Log.Message(someObject.someText);
        }
    }

    Obviously, this is bad code. I'm trying to use the "Exists" property of someObject before the object is instantiated.  In doing so, I actually get an error in my log telling me, in no uncertain terms "Um, you did a dumb...someObject doesn't exist so I have no idea what you want me to do".

     

    What TestComplete does is that, once it finds an object and identfies it, it puts a wrapper around it based upon the kind of object it is that contains properties like "Exists" and "Visible" and so forth and contains methods like WaitChild and WaitWindow and so on.  

    So, in your case, you actually start with on object, Aliases.  That's a built in, root core object of the tool itself.  It has the WaitAliasChild method built into it.  You pass in the name of a child Alias (needs to be mapped and defined ahead of time) so that, at run time, you can check to see if the object referenced by that Alias is actually present in memory in your operating system.  Before you can do ANYTHING with that object, we need to make sure it's there... kind of like making sure you instantiate someObject before you try and use its properties.  So, you call WaitAliasChild as part of your detection logic.  For example, this code actually works properly if the object does not exist because we first check to see if it IS an object of the correct type before we try and reference it.

    var someObject;
    
    class myObject{
        constructor(){
            this.Exists = true;someObject
            this.someText = 'I think therefore I am';
        }
    
    }
    
    
    function testObject(){
    
    
        if (!(someObject instanceof myObject)){
            Log.Message('It does not think therefore it is not')
        }
        else {
            
            if (someObject.Exists){
                Log.Message(someObject.someText);
            }
        }
    }

     

    See?  This is why TestComplete "waits" for onscreen components before attempting to interact with them.  It's to make sure that it actually is present in memory before you access any of it's properties.

7 Replies

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    unit name = code unit.

    In the screenshot below, the items in the red box are units.  Within those units, you write functions, methods, routines, etc.  So, for your question, if I have a routine that I want to run on a timer called 'fightMe' and that routine is in the unit 'BridgeOfKhazadum', then the syntax of that Timer would be to use 

     

    var MyTimer = Utils.Timers.Add(10000, 'BridgeOfKhazadum.fightMe', true);

     

    • Al2's avatar
      Al2
      Occasional Contributor

      Thank you tristaanogre  I was thinking the same and then I exported funtion, and there was an error. so it confused me. I should not export and just use it with filename reference.

       

      So, I'm using this callTimerRoutines function to call the 'timeRoutine' function.

      When the 'timeRoutine' is called and the object in the if statement doesn't exist, it should just move on without waiting to find that object, but it's not the case.

       

      What I see is  this. Why would it wait for this object if the object doesn't exist?

       

       

      function callTimerRoutines(){ 
          var MyTimer = Utils.Timers.Add(10000, "Startup.timeRoutine", true);
      }
      
      //StartUp unit
      
      function timeRoutine(){ 
      if(!Aliases.panelErrorpanel.Exists){
      Log.Message("Move");
      }else{ 
      Log.Error(Aliases.panelErrorpanel.panelErrorContent.panelErrorContainer.textContent);
      Log.Picture(Sys.Desktop, "Modal Dialog", ) 
      Aliases.panelErrorpanel.panelErrorContent.panelErrorContainer.buttonOk.ClickButton();
      }
      }

      Appreciate your help!

       

      Thank you

      Al

       

      • tristaanogre's avatar
        tristaanogre
        Esteemed Contributor

        If you understand objects, then you understand properties of objects.  Exists is a property of the object Aliases.panelErrorpanel.  In order to check the Exists property, it first needs to detect if the object exists.  Well, if the object does not exist, it can't check the Exists property so, most likely, you'll get an error in your log saying something like "Aliases.panelErrorpanel does not exist"... which you're like... "Well, DUH!!!"

         

        So... to check existance of an object as you want to, rather than just checking the Exists property, you need to first Wait to see if the object comes around.  If it does , THEN you can start looking at properties.

         

        So...  Just some light reading...https://support.smartbear.com/testcomplete/docs/app-objects/common-tasks/checking-existence.html

        From that, I'd change your code to the following (see below).  Note the use of WaitAliasChild.  I have the timer set to 20 seconds on that method.  That means, it will wait up to 20 seconds for the object to return.  If it does, the object itself is returned and "Exists" is true.  If it doesn't, then a "stub" object with no properties but the "Exists" property is returned and that has a value of "false".

         

        function callTimerRoutines(){ 
            var MyTimer = Utils.Timers.Add(10000, "Startup.timeRoutine", true);
        }
        
        //StartUp unit
        
        function timeRoutine(){ 
        if(!Aliases.WaitAliasChild('panelErrorpanel', 20000).Exists){
        Log.Message("Move");
        }else{ 
        Log.Error(Aliases.panelErrorpanel.panelErrorContent.panelErrorContainer.textContent);
        Log.Picture(Sys.Desktop, "Modal Dialog", ) 
        Aliases.panelErrorpanel.panelErrorContent.panelErrorContainer.buttonOk.ClickButton();
        }
        }