Forum Discussion

nyczmagix's avatar
nyczmagix
Occasional Contributor
14 years ago

Get Mapped Object From Alias Object

Is there a way to get a Mapped Object from an Alias Object? I want to get the NodeDescription, but only have an Aliased object to work with.

8 Replies

  • AlexKaras's avatar
    AlexKaras
    Community Hero
    Hi Peter,



    The following code was posted by Automated's Support a long time ago when there was no WaitAliasedChild method in the Aliases object.

    The code may not work now, but maybe it might inspire you with some ideas...



    ============================

     The following script gets an object by its full name from the Aliases tree. I hope you will find the code useful:



     [JScript]

     function Test()

     {

       var obj;



       obj = WaitAliasedObject("Aliases.Sys.MainEdit", 5000);

       if (!obj.Exists)

         Log.Error("Object was not found");

     }



     function WaitAliasedObject(alias, timeout)

     {

       var mappedName;



       mappedName = GetMappedNameByAlias(alias);

       if (mappedName == "") {

         Log.Warning("A mapped name for the " + alias + " was not found");

         return Utils.CreateStubObject();

       }



       return WaitObjectByMappedPath(Utils.CreateStubObject(), mappedName, timeout);

     }



     function WaitObjectByMappedPath(parentObj, path, timeout)

     {

       var dotPosition, currentItemName, lowPath, startTime, childObj, newTimeout;



       if (path == "")

         return Utils.CreateStubObject();



       dotPosition = path.indexOf(".");

       if (dotPosition < 0) {

         currentItemName = path;

         lowPath = "";

       }

       else {

         currentItemName = path.substr(0, dotPosition);

         lowPath = path.substr(dotPosition + 1);

       }



       startTime = Win32API.GetTickCount();

       if (!parentObj.Exists) {

         dotPosition = lowPath.indexOf(".");

         if (dotPosition < 0)

           return Utils.CreateStubObject();

         else {

           currentItemName = currentItemName + "." + lowPath.substr(0, dotPosition);

           lowPath = lowPath.substr(dotPosition + 1);

         }

         childObj = eval(currentItemName);

       }

       else

         childObj = parentObj.WaitNamedChild(currentItemName, timeout);

       if (!childObj.Exists)

         return Utils.CreateStubObject();



       if (lowPath == "")

         return childObj;

       else {

         newTimeout = timeout - (Win32API.GetTickCount() - startTime);

         if (newTimeout < 0)

           return Utils.CreateStubObject();

         else

           return WaitObjectByMappedPath(childObj, lowPath, timeout);

       }

     }



     function GetMappedNameByAlias(alias)

     {

       var i, tcNM, nmFilePath, items, logicalNodes, aliasedNode, mappedNode, mappedName;



       nmFilePath = Project.Path + "NameMapping\\NameMapping.tcNM";



       tcNM = Sys.OleObject("Msxml2.DOMDocument.4.0");

       tcNM.async = false;



       if (!tcNM.load(nmFilePath)) {

         Log.Warning("Cannot load the " + nmFilePath + " NameMapping file");

         return "";

       }



       items = tcNM.selectNodes("//Node[@name='logical nodes']");

       if (items.length != 1) {

         Log.Warning("An invalid NameMapping file");

         return "";

       }

       logicalNodes = items.item(0);



       aliasedNode = GetAliasNode(logicalNodes, alias);

       if (aliasedNode == null) {

         Log.Warning("The " + alias + " alias was not found");

         return "";

       }



       items = aliasedNode.selectNodes("Prp[@name='owner' and @value]");

       if (items.length != 1) {

         Log.Warning("An invalid NameMapping file");

         return "";

       }



       return GetMappedNameByID(logicalNodes, items.item(0).attributes.getNamedItem(

    "value").nodeValue);

     }



     function GetMappedNameByID(tcNM, objectID)

     {

       var items, nmData, nmNode, mappedName;



       items = tcNM.selectNodes("//Node[@name='data']");

       if (items.length != 1) {

         Log.Warning("An invalid NameMapping file");

         return "";

       }

       nmData = items.item(0);



       items = nmData.selectNodes("//Node[@name='" + objectID.toLowerCase() + "']");

       if (items.length != 1) {

         Log.Warning("An invalid NameMapping file");

         return "";

       }

       nmNode = items.item(0);



       mappedName = "";

       do {

         if (mappedName == "")

           mappedName = nmNode.selectSingleNode("Prp[@name='name' and @value]").attributes.getNamedItem("value").nodeValue;

         else

           mappedName = nmNode.selectSingleNode("Prp[@name='name' and @value]").attributes.getNamedItem("value").nodeValue + "." + mappedName;

         nmNode = nmNode.parentNode.parentNode;

       } while(nmNode.attributes.getNamedItem("name").nodeValue != "data");



       return "NameMapping." + mappedName;

     }



     function GetAliasNode(parentNode, path)

     {

       var dotPosition, currentItemName, lowPath, items, aliasedNode;



       if (path == "")

         return null;



       dotPosition = path.indexOf(".");

       if (dotPosition < 0) {

         currentItemName = path;

         lowPath = "";

       }

       else {

         currentItemName = path.substr(0, dotPosition);

         lowPath = path.substr(dotPosition + 1);

       }



       items = parentNode.selectNodes("Prp[@name='name' and @value='" + currentItemName + "']");

       if (items.length > 0) {

         if (lowPath == "")

           return parentNode;

         items = parentNode.selectNodes("Node[@name]");

         for(i = 0; i < items.length; i++) {

           aliasedNode = GetAliasNode(items.item(i), lowPath);

           if (aliasedNode != null)

             return aliasedNode;

         }

       }

       return null;

     }

    ============================
  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor
    I'm not certain I understand the question.  In TestComplete mapped items and aliased items are effectively synonymous as all the Alias does is give you are more customized, user-friendly way of accessing mapped items.  Anything that is available in NameMapping.Sys.MyApp.MyForm is available in Aliases.MyForm.



    Could you clarify what you are looking for?
  • nyczmagix's avatar
    nyczmagix
    Occasional Contributor
    Hi Robert,



    Basically, I'm looking to get the Description value from the mapped object (this is the description the user can enter via the name mapping GUI). I believe this description is provided by the NodeDescription property; however this property only lives in the NameMapping.Sys.MyControl and not in the Aliases.MyControl.



    So if that's true, I figured if there was a way I can translate the Aliased object back to the Name Mapped object, I'd be able to access the NodeDescription property.
  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor
    Okay, I see that.  As far as I can tell, once an object has been "Aliased", it's no longer considered part of the "NameMapping" object set but is, instead, part of the "Aliases" object especially when being called from "Aliases."  



    Can I ask for what purpose you need the NodeDescription for your automation work?  As I understand it, this is simply a description for the user to label what something is within the NameMapping screen and, as far as I can tell, serves no real purpose in actual test automation beyond, possibly, logging something to the test log.  In which case, since supposedly the Alias is supposed to be a more user friendly description, wouldn't that suit as a logging item?
  • nyczmagix's avatar
    nyczmagix
    Occasional Contributor
    I had planned on attaching custom attributes through this field. With these attributes saved in NodeDescription, I can basically (for example) control which mapped objects need special treatment during runtime. Instead of specifically looking for "Aliases.MyControl" in my scripts, I'd be able to just look for "IsSpecial=True" in NodeDescription.



    Would you perhaps know of an alternate way to achieve something like this?
  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor
    I'm not sure off the top of my head as to the best way to implement it, but you might want to consider using the ODT object to create classes that would act as wrappers around your "special" objects.  It seems you already have these items pre-determined as to which ones are special and which ones aren't.



    So, just off the top of my head, it could be as simple as creating an ODT Data Group with a variable for each "special" item.  You could then use ODT.Data.Group.VariableExists("MyControlAliasName") to find out if it exists in that list.  If it does, then treat it "specail", if not, treat it normal.



    Bit of a kludge, I know, but off the top of my head that's one approach.  There are probably others that may work better.