Forum Discussion

IrinaManea's avatar
IrinaManea
New Contributor
2 years ago

Check if object exists

Hello everyone,

 

I want to create a function which returns true if an object exist and is visible on screen without waiting for the full timeout period.

Here is the function I tried to create:

 

def isObjectVisible(object):
    name = object.Name
    parent = object.Parent
    if parent.WaitChild(name, 100).Exists:
         return object.Visible
    return False

 

The issue I encountered is that accessing the name property of the object causes the test to wait 10 seconds for the name property

I there a way to achieve this result?

 

I can create another function which takes the parent and child name as parameter but that is cumbersome.

 

 

  • AlexKaras's avatar
    AlexKaras
    2 years ago

    Hi,

     

    Specific of your code is that you are not passing an object to your function, but you are passing unresolved aliased name. As the name is unresolved, we do not know whether the object exists or not. The name is resolved when you try to call its method or property (e.g. .Exists). At this moment TestComplete will wait for the object to appear if the object does not exist.

    In order to avoid the above situation, you may modify your function so that it accepts two arguments - the root parent that always exists (as per your previous description) and the name of its aliased child, existence of which you like to check.

    E.g. (JScript, as I am not good with Python)

    function IfAliasedChildExists(oRoot, strChild) {

      return oRoot.WaitAliasChild(strChild, 0).Exists;

    }

     

    function main {

      Log.Message(IfAliasedChildExists(Aliases.MyApp, "Dialog1"));

    }

     

    P.S. If, for some reason, you prefer not to use function with two parameters, you may consider something like this (JScript pseudocode):

    function main {

      Log.Message(IfAliasedChildExists("Aliases.MyApp.Dialog1"));

    }

    function IfAliasedChildExists(strAliasedFullName) {

      var strRoot = ...; // get here everything up to and including last point (i.e.: "Aliases.MyApp.")

      var strObj = ...; // get here only the part after last point (i.e.: "Dialog1")

      var obj = eval(strRoot + "WaitAliasChild(" + strObj + ", 0)"); // parameter of eval after concatenation must result in the string like in my first example: "Aliases.MyApp.WaitAliasChild("Dialog1", 0)".

     

      return obj.Exists;

    }

     

  • rraghvani's avatar
    rraghvani
    Champion Level 3

    In order to return the property value of Visible, the Object must exist. A simple function would be,

    function IsVisible(parent)
    {
        if (parent.Exists) {
            return parent.Visible;
        } else {
            Log.Error("Object does not exist");
        }
    }

    TC project settings is configured to wait 10 seconds for the object to become available.

     

    • IrinaManea's avatar
      IrinaManea
      New Contributor
      The problem with that approach is that the object is a dialog which might not exist therefore would trigger a 10 seconds wait. I simply want to see if it exists without waiting the full 10 seconds.
      I can use WaitChild function on the parent object but that requires the object name which I must pass as a parameter since accessing the "Name" property on the object would also trigger a 10 seconds wait.
      Note that the parent is always visible it is just that the child object might appear or not.
      So the question remains, given an object(an alias) is it possible using only that object to see if it is visible without waiting 10 seconds?


      Get Outlook for Android<>

      Disclaimer

      The information contained in this communication from the sender is confidential. It is intended solely for use by the recipient and others authorized to receive it. If you are not the recipient, you are hereby notified that any disclosure, copying, distribution or taking action in relation of the contents of this information is strictly prohibited and may be unlawful.

      This email has been scanned for viruses and malware, and may have been automatically archived by Mimecast, a leader in email security and cyber resilience. Mimecast integrates email defenses with brand protection, security awareness training, web security, compliance and other essential capabilities. Mimecast helps protect large and small organizations from malicious activity, human error and technology failure; and to lead the movement toward building a more resilient world. To find out more, visit our website.
      • AlexKaras's avatar
        AlexKaras
        Champion Level 3

        Hi,

         

        rraghvani is basically correct: one must use .Exists property to check if the object exists and the value of the property is evaluated immediately.

        Specifics may begin in the way, how the target object is referenced. If the variable that references the target object already exists (regardless of whether it references valid or already destroyed object), then the value of .Exists property is returned immediately. TestComplete will wait for the object to appear if the reference to the object is not resolved yet.

        Additional note: reference to aliased object is not resolved immediately, but only when test code tries to use methods/properties of aliased object.

         

        Sample pseudo-code to illustrate the above:

        var obj1 = Aliases.App.DialogRoot.Dialog; // executed without delay

        Log.Message(obj1.Exists); // will wait if any of App, DialogRoot or Dialog objects do not exist

         

        var obj1 = Aliases.App.DialogRoot.WaitAliasChild("Dialog", 0); // searches for the Dialog object once and returns immediately

        Log.Message(obj1.Exists); // returns immediately as obj1 is already resolved

         

        Log.Message(Aliases.App.DialogRoot.Dialog.Name); // will wait for the Dialog object to appear and errors-out if Dialog object does not exist

         

  • IrinaManea's avatar
    IrinaManea
    New Contributor

    Thanks for the responses,

     

    I get it, i must use a Wait function to check if the object exists without waiting the full 10 seconds.

    Is there a way to extract the alias name from a given object?

     

    I want to do something like this

     

    def wait(obj)

      parent = obj.parent

      aliasName = obj.?????

      if parent.WaitChildAlias(aliasName, 0).Exists:

         return True

      return False

     

    and call it in the script like this:

     

    exist = wait(Aliases.MyApp.Dialog1)

     

    Is it possible to do such a function which returns if the object exists without waitiing and passing only the object?

     

    • AlexKaras's avatar
      AlexKaras
      Champion Level 3

      Hi,

       

      Specific of your code is that you are not passing an object to your function, but you are passing unresolved aliased name. As the name is unresolved, we do not know whether the object exists or not. The name is resolved when you try to call its method or property (e.g. .Exists). At this moment TestComplete will wait for the object to appear if the object does not exist.

      In order to avoid the above situation, you may modify your function so that it accepts two arguments - the root parent that always exists (as per your previous description) and the name of its aliased child, existence of which you like to check.

      E.g. (JScript, as I am not good with Python)

      function IfAliasedChildExists(oRoot, strChild) {

        return oRoot.WaitAliasChild(strChild, 0).Exists;

      }

       

      function main {

        Log.Message(IfAliasedChildExists(Aliases.MyApp, "Dialog1"));

      }

       

      P.S. If, for some reason, you prefer not to use function with two parameters, you may consider something like this (JScript pseudocode):

      function main {

        Log.Message(IfAliasedChildExists("Aliases.MyApp.Dialog1"));

      }

      function IfAliasedChildExists(strAliasedFullName) {

        var strRoot = ...; // get here everything up to and including last point (i.e.: "Aliases.MyApp.")

        var strObj = ...; // get here only the part after last point (i.e.: "Dialog1")

        var obj = eval(strRoot + "WaitAliasChild(" + strObj + ", 0)"); // parameter of eval after concatenation must result in the string like in my first example: "Aliases.MyApp.WaitAliasChild("Dialog1", 0)".

       

        return obj.Exists;

      }