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.
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:
So as I see this is real object.. So why I can`t see it in project tree?)) I don`t understand.
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.