Ask a Question

Flex object is not presented in object tree

SOLVED
Rammherz
Occasional Contributor

Flex object is not presented in object tree

Hi all,

 

In Test Complete project, which was written in 2013 (not by me), I see that one of the flex objects can be successfully found:

 

function ActionToolbar()
{
    var oParent = MVVO_PageContainers.DocumentViewer();
    var aProps = ["ObjectType", "ObjectLabel"];
    var aVals = ["ActionToolbar", "actionToolbar"];
    return CFInternetBrowser.FindObjectByProperties(aProps, aVals, oParent, "ActionToolbar", 2);
}

But I don`t see object 'ActionToolbar' in object tree: 

 

4-27-2018 14-03-33.jpg

On pic above I marked objects which exactly have 'ActionToolbar' as parent object (according to autotests code).

 

Could you explain why 'ActionToolbar' object is not presented in object tree?

 

If it is make sense I use Debug Version of Flash Player approach.

 

P.S. Sorry for my questions, I`m new in automation testing 🙂

1 ACCEPTED SOLUTION

Accepted Solutions
Rammherz
Occasional Contributor

Re: Flex object is not presented in object tree

I found the solution. 

I just use page URL instead of ActionToolbar as parent object in the function 

 

function Approve()
{
    var oParent = ActionToolbar();
    var aProps = ["Caption", "ObjectType"];
    var aVals = ['Approve', 'ToolButton'];
    
    return CFInternetBrowser.FindObjectByProperties(aProps, aVals, oParent, "Approve");
}

and it finds both types of buttons.

 

So I wonder why developers of this autotests used ActionToolbar as parent objects... I suggest they had reasons for it.

But I have no problem to resolve now 🙂

@tristaanogre, thanks a lot!

View solution in original post

6 REPLIES 6
tristaanogre
Community Hero

Re: Flex object is not presented in object tree

There's a lot of custom code in the function you presented.  MVVO_PageContainers.DocumentViewer for one, the CFInternetBrowser.FindObjectByProperties is another.  These are methods that your predecessor(s) must have written so, with regards to your question, there's too much unknown for us to be able to help you fully.

 

My GUESS is this... you are mistaken in that there should be an "ActionToolbar" showing up explicitly in the ObjectBrowser.  What it appears to be is that there is some sort of custom code written around the native FindChild method common to all objects in TestComplete.  This means that "ActionToolbar" might not be the immediate parent nor even named that way in the object tree.

 

If the code works... then it works... and I wouldn't be overly concerned with it except for needing further understanding.  But for us to comment further, we would need to see more about your custom code as noted above to be able to give you a better determination of what's going on.


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Rammherz
Occasional Contributor

Re: Flex object is not presented in object tree

Thanks!

Actually another part of code doesn`t work, and I`m trying to understand the structure of objects to fix it.

 

Yes, here is a lot custom code.

MVVO_PageContainers.DocumentViewer returns Document Viewer object container:

function DocumentViewer()
{
  var oParent = Page();
  var aProps = ["ObjectType", "ObjectLabel"];
  var aVals = ["DocumentView", "documentView"];
  return CFInternetBrowser.FindObjectByProperties(aProps, aVals, oParent, "DocumentViewer", 100);
}

CFInternetBrowser.FindObjectByProperties is more complicated function, it searches the specified parent object for an object who's that matches the specified property values.

function FindObjectByProperties(aPropertyNames, aPropertyValues, oParentObject, strDescription, nDepth, bTryWaitForBrowser)
{
  var strModuleID = c_strModule + GetFunctionName(arguments.callee); 
  var strStatus = "(Object NOT found)";
  var oReturn = null;
  var oObject = null;
  var oPage;
    
  try
  {
    CFLog.DebugMessageBegin(strModuleID + " Values: " + aPropertyValues.toString());
            
    // Assign default parameter values.
    nDepth = CFGeneralUtilities.GetValueOrDefault(nDepth, 50);
    bTryWaitForBrowser = CFGeneralUtilities.GetValueOrDefault(bTryWaitForBrowser, true);
  
    if (CFObject.ObjectExists(oParentObject))
    {
      // Refresh the parent object
      oParentObject.Refresh();
    }
    else
    {
      // The ParentObject does not exist, so there is not point in continuing to attempt to find the child element
      throw new kfxException(strModuleID, "The provided oParentObject does not exist. #1", null, strDescription);
    }
    
    // Try to find the object the first time
    oObject = CFObject.FindObjectByProperties(aPropertyNames, aPropertyValues, oParentObject, strDescription, nDepth);
    
    // If the object was not found, try one last time.
    if ((CFException.IsException(oObject)) && (bTryWaitForBrowser))
    {
      // Find the page object in the hierarchy
      oPage = GetPageFromDescendent(oParentObject);
      CheckResult(oPage);

      // Make sure the page is loaded and rendered before trying again.
      CheckResult(WaitForBrowser(oPage));
      
      if (CFObject.ObjectExists(oParentObject))
      {
        // Refresh the parent again
        oParentObject.Refresh();
      }
      else
      {
        // The ParentObject does not exist, so there is not point in continuing to attempt to find the child element
        throw new kfxException(strModuleID, "The provided oParentObject does not exist. #2", null, strDescription);
      }

      // Try one more time to see if we can find the object.
      oObject = CFObject.FindObjectByProperties(aPropertyNames, aPropertyValues, oParentObject, strDescription, nDepth); 
    }

    // Finally if the object was not found, throw an exception.
    CheckResult(oObject, "Could not find object: " + strDescription);

    // Set the return value
    oReturn = oObject;
  }
  catch(oException)
  {
    oReturn = CFException.ProcessException(strModuleID, oException);
    CFLog.DebugException(oReturn);
  }
  CFLog.DebugMessageEnd(strModuleID);

  // Object was found
  if (! CFException.IsException(oObject))
    strStatus = "(Object found)";

  WriteToLog(strModuleID, strStatus + ": Names='" + aPropertyNames.toString() + "', Values='" + aPropertyValues.toString() + "', Depth=" + nDepth);
  return oReturn;
}

CFObject.FindObjectByProperties:

function FindObjectByProperties(aPropertyNames, aPropertyValues, oParentObject, strDescription, nDepth)
{
  var strModuleID = c_strModule + CFGeneralUtilities.GetFunctionName(arguments.callee); 
  var oObject = null;

  try
  {
    CFLog.DebugMessageBegin(strModuleID + " Values: " + aPropertyValues.toString());

    // Assign default parameter values.
    nDepth = CFGeneralUtilities.GetValueOrDefault(nDepth, 100);

    // See if provided parent object is an exception object
    if (CFException.IsException(oParentObject))
      throw new kfxException(strModuleID, "The provided oParentObject was already an exception object.", oParentObject, strDescription);    

    // Make sure we were given a valid parent object.
    if (oParentObject == null)
      throw new kfxException(strModuleID, "You must supply a valid parent object. The parent object specified is null.");

    // We need to convert the arrays for use with the TestComplete API.
    var aConvertedPropertyNames = CFGeneralUtilities.ConvertArrayToDictionary(aPropertyNames);
    var aConvertedPropertyValues = CFGeneralUtilities.ConvertArrayToDictionary(aPropertyValues); 

    // Attempt to locate an object that matches the set of properties we were given.
    oObject = oParentObject.Find(aConvertedPropertyNames, aConvertedPropertyValues, nDepth);

    // Finally if the object was not found, throw an exception.
    if (! ObjectExists(oObject))
      throw new kfxException(strModuleID, "Could not find object: " + strDescription, null, "", arguments);
  }
  catch(oException)
  {
    oObject = CFException.ProcessException(strModuleID, oException);
    CFLog.DebugException(oObject);
  }
  CFLog.DebugMessageEnd(strModuleID);
  return oObject;
}

And this object uses parent ActionToolbar (successfully):

function Approve()
{
    var oParent = ActionToolbar();
    var aProps = ["Caption", "ObjectType"];
    var aVals = ['Approve', 'ToolButton'];
    
    return CFInternetBrowser.FindObjectByProperties(aProps, aVals, oParent, "Approve");

All objects in my application which were used in code I could see object tree, except of ActionToolbar.

In debug mode I also see ActionToolbar object:4-27-2018 12-33-35.jpg

 So as I see this is real object.. So why I can`t see it in project tree?)) I don`t understand.

 

 

tristaanogre
Community Hero

Re: Flex object is not presented in object tree

OK, best that I can see...

 

DocumentViewer is searching for a child object of the page that could be anywhere within 100 layers of the page that is of ObjectType DocumentViewer with ObjectLabel documentViewer.  So... that's where you need to start.  Yes, you're seeing buttons in your viewer... but I don't see in your initial screenshot where that Document Viewer object is... it could be ANYWHERE in your tree within 100 layers deep.  

 

Keep in mind that ObjectType and ObjectLabel don't always display in the object tree.  You need to inspect the details of the objects in your tree to find the specific object.

 

So... once it finds the DocumentViewer, it then finds another object with ObjectType ActionToolbar with label actionToolBar.  Again... it might not show up exactly like that in the tree, you need to inspect the object details.

 

Again... it all comes down to, as I suspected, a LOT of code being wrapped around the native "Find" method.  To understand the custom code, you need to understand that method.

 

Start with reading this

 

https://support.smartbear.com/testcomplete/docs/reference/test-objects/members/common-for-all/find-m...

 

Now.... you say something is not working... what EXACTLY is not working?  Any error message? If so, what?  


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Rammherz
Occasional Contributor

Re: Flex object is not presented in object tree

Ok, thanks..

 

I`ll try to explain the origin problem. 

I need to click action button. Here are actions:4-27-2018 16-32-29.jpg

As you can see actions Approve and Request Comment are in "More Actions" menu. The problem is to find their objects.

All logic of autotest looks good: we look for action, if we cannot find it we look for "More actions" button (little arrow on the pic), click it, and then try to find action button again. In both cases (in "More actions" and not in "More actions") we use the same function to find the action button, you can see it in my message above.

But if the action button is in "More actions" menu (i.e. Approve on the screenshot) TestComplete can`t find it.

 

I marked action buttons in object tree on screen below:

4-27-2018 16-46-31.jpg

 

It seems that it worked when this test was created, but I`m not sure, nobody knows... 

Maybe it something wrong with my environment?

 

tristaanogre
Community Hero

Re: Flex object is not presented in object tree

My guess is that, for the More Actions, you need to select, potentially, either a different parent object or a different set of criteria.  Again, the object tree only shows the tree relationship.  Click on the buttons you want to access and look at their properties.  Use those to work with your find methods to find the specific buttons.  


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Rammherz
Occasional Contributor

Re: Flex object is not presented in object tree

I found the solution. 

I just use page URL instead of ActionToolbar as parent object in the function 

 

function Approve()
{
    var oParent = ActionToolbar();
    var aProps = ["Caption", "ObjectType"];
    var aVals = ['Approve', 'ToolButton'];
    
    return CFInternetBrowser.FindObjectByProperties(aProps, aVals, oParent, "Approve");
}

and it finds both types of buttons.

 

So I wonder why developers of this autotests used ActionToolbar as parent objects... I suggest they had reasons for it.

But I have no problem to resolve now 🙂

@tristaanogre, thanks a lot!

View solution in original post

cancel
Showing results for 
Search instead for 
Did you mean: