2

Using Selenium WebDriver, I am having a list of all web elements in the page. I want to write one function which will return me the XPath string of passed element.

Call for Function will be like:- String XpathOfElement = myWebDriver.getXpath(My_Web_Element)

Hint :- I think we can use javascript(using JavaScriptExecuter). But not familiar with javascript.

Sumit Shitole
  • 110
  • 1
  • 3
  • 20
  • 1
    Please ellobrate liitile bit and sahre complete code and HTML – iamsankalp89 Nov 02 '17 at 07:09
  • I have a list of web elements of the current page( elements = myDriver.getElements(By.TagName("*")).ToList). If i want xpath of elements(1) then i will pass this element to desired function like String XpathOfElement = myWebDriver.getXpath(elements(1)). – Sumit Shitole Nov 02 '17 at 07:39
  • 1
    Take a look at [this link](https://stackoverflow.com/questions/18510576/find-an-element-by-text-and-get-xpath-selenium-webdriver-junit) – DonCallisto Nov 02 '17 at 08:22

3 Answers3

10

Check this post, I wrote code to get an absolute XPath.

public static String getAbsoluteXPath(WebElement element)
{
    return (String) ((JavascriptExecutor) driver).executeScript(
            "function absoluteXPath(element) {"+
                    "var comp, comps = [];"+
                    "var parent = null;"+
                    "var xpath = '';"+
                    "var getPos = function(element) {"+
                    "var position = 1, curNode;"+
                    "if (element.nodeType == Node.ATTRIBUTE_NODE) {"+
                    "return null;"+
                    "}"+
                    "for (curNode = element.previousSibling; curNode; curNode = curNode.previousSibling) {"+
                    "if (curNode.nodeName == element.nodeName) {"+
                    "++position;"+
                    "}"+
                    "}"+
                    "return position;"+
                    "};"+

                    "if (element instanceof Document) {"+
                    "return '/';"+
                    "}"+

                    "for (; element && !(element instanceof Document); element = element.nodeType == Node.ATTRIBUTE_NODE ? element.ownerElement : element.parentNode) {"+
                    "comp = comps[comps.length] = {};"+
                    "switch (element.nodeType) {"+
                    "case Node.TEXT_NODE:"+
                    "comp.name = 'text()';"+
                    "break;"+
                    "case Node.ATTRIBUTE_NODE:"+
                    "comp.name = '@' + element.nodeName;"+
                    "break;"+
                    "case Node.PROCESSING_INSTRUCTION_NODE:"+
                    "comp.name = 'processing-instruction()';"+
                    "break;"+
                    "case Node.COMMENT_NODE:"+
                    "comp.name = 'comment()';"+
                    "break;"+
                    "case Node.ELEMENT_NODE:"+
                    "comp.name = element.nodeName;"+
                    "break;"+
                    "}"+
                    "comp.position = getPos(element);"+
                    "}"+

                    "for (var i = comps.length - 1; i >= 0; i--) {"+
                    "comp = comps[i];"+
                    "xpath += '/' + comp.name.toLowerCase();"+
                    "if (comp.position !== null) {"+
                    "xpath += '[' + comp.position + ']';"+
                    "}"+
                    "}"+

                    "return xpath;"+

                    "} return absoluteXPath(arguments[0]);", element);
}
Amol Chavan
  • 3,835
  • 1
  • 21
  • 32
  • 2
    Works great with Chrome 62. I use it to get Xpath of element, which is visible, then use this Xpath as a String and modify it to use as a locator for another element :) Thanks Amol! – Krzysztof Walczewski Jan 17 '18 at 15:32
  • 3
    In case somebody is looking for the plain JavaScript code: https://gist.github.com/beatngu13/a3312b98de57610c5ecd27ea84a7fbeb – beatngu13 Dec 11 '18 at 13:05
0

This code works perfectly.

public String getXpath(WebElement ele) {
    String str = ele.toString();
    String[] listString;
    if(str.contains("xpath")
      listString = str.split("xpath:");
    else if(str.contains("id")
      listString = str.split("id:");
    String last = listString[1].trim();
    return last.substring(0, last.length() - 1);
}

This above function works only if the WebElement has xpath. Suppose your element has class, then use if-else concept with "class:" as split expression.

DINESH KUMAR
  • 70
  • 2
  • 12
-3

Almost any element in DOM can have a lot of valid xPathes. For example input field on Google search page can be found as: //*[@id='lst-ib'] //*[@class='gsfi'][1] //body//div//input[3]... Which one do you expect to get?

Actually google has this algorithm in chrome. We can copy xpath of the element and in most cases it is awfull. So it's possible to do, and if it's really vital for you look at NHtmlUnit - you can get dom of the page, find your element there and go up to root element adding tags to path string. I guess, it's poosible to get something like //body/div/div[2]/div[3]/... But why?

SerhiiBond
  • 247
  • 3
  • 8