Forum Discussion

pkudrys's avatar
pkudrys
Contributor
10 months ago

How to get xpath from alias object

Hi folks,

 

Is there a (JavaScript) way to get the xpath from alias object?

 

Basically, I want to pass a mapped object as a parameter to my coded method. In this method, I need to use that mapped element as a parameter for FindElements functions, but that's not directly possible. FindElements requires xpath or css selector as a parameter. So what I need is a method, which returns xpath from mapped/alias element.

 

Thank you in advance.

5 Replies

  • rraghvani's avatar
    rraghvani
    Champion Level 3

    AlexKaras that confused me as well!

     

    I didn't quite understand why you would want to use an alias objects' XPath in FindElement, if the alias object is already defined using XPath ğŸ˜•

  • Haha, I already found a solution. Since I didn't find a dedicated method, I used something like this:

     

    //get xpath from mapped element
    function GetXpathFromAlias(mappedElement) 
    {
      const str = mappedElement.Name; // returns something like this "FindElement(\"//parent::div//following-sibling::div[@class='editFormTabs']//*[name()='mat-form-field' or name()='mat-button-toggle' or name()='mat-radio-button' or name()='mat-checkbox' and not(@class='mat-button-toggle-group') and not(@class='ripple')]//*[name()='mat-label' or contains(@class,'toggle-label') or @class='mat-checkbox-label' or @class='mat-radio-label-content' and not (contains(@class,'container')) and not (contains(.,''))]\")"
      const pattern = /\"(\/\/.*?(\')?\])\"/;
      const match = pattern.exec(str);
      if (match) 
      {
        const xpath = match[1];
        return xpath;
      } else 
      {
        Log.Error("XPath not found." + str);
      }
    }

     

     Just a little reminder, this method will return xpath only if it starts with '//' and ends with ']'.

    • AlexKaras's avatar
      AlexKaras
      Champion Level 3

      Hi,

       

      Great to hear that you found a solution.

      Small note for others: It is my opinion, that described approach will work only for projects that use css/xpath NameMapping approach but not native NameMapping.

       

      Out of curiosity: given you already have aliased object and this object exists, why do you need to repeat the search and search for the same object again?

       

      • pkudrys's avatar
        pkudrys
        Contributor

        Hi,

         

        I'm working on a webform-filling method (Angular based) and the mapped object points to multiple elements (labels). The form is not just a single page full of inputs, but it consists of header and tab-based section (mutliple tabs, full of different inputs). To make things even more complicated, the form design regularly changes. And as a bonus, the inputs does not have (most of them) unique or usable IDs.

         

        So I have a method, which gets all form labels, match them with related inputs and then fill the inputs with values stored in CSV file. The method can also save inputs to csv files. I'm using it also for creating new ref. data.

         

        So, I have a mapped element for header and tab(s) section, from which I search for all labels, using FindElements method. And for this, unless I missed something, I need the xpath.

         

         

        let listOfObjects = mappedElement.FindElements(xpathFromMappedObject); // where mappedElement points to onscreen object, either header or tab, and xpathFromMappedObject points to xpath of mapped element, containing all labels for given header or tab

         

         

        I then cycle through the list of returned elements and do whatever is required to set or get their values. Hope it makes it clearer? 🙂 If there is a better way, I'm all ears. Of course, I'm aware that I can type the xpath directly to code, or assign the xpath as a method parameter. But I prefer using object mapping, instead of hardcoding xpath in code or test modules.

         

        Basically, I don't want to record or manually map and handle all individual input elements 😉 I've originally developed this method for Ranorex and now I'm working on TC version.