1

What are the possible ways to retrieve xpath or css (any logic) from WebElement object? For example I have created WebElement by following way:

WebElement obj=driver.findElement(By.cssSelector(".hello"));

Now I want to get back a By object from this WebElement Object or if I am able to retrieve xpath or css then I am able to create By object of it. Suggest me any idea.

Halvor Holsten Strand
  • 19,829
  • 17
  • 83
  • 99
NecessaryDevil
  • 105
  • 1
  • 10
  • I'm not sure I understand your question but you can do something like: `obj.findElement(By.ByXPath([yourXPath]))` – Titus Mar 09 '15 at 07:01
  • sir, i want a function through which i am able to pass WebElement object in argument and this function will return me either xpath/css or By Object. – NecessaryDevil Mar 09 '15 at 10:00
  • You can not get the x-apth by using your obj element, else you can get the location of that element in terms of (x,y) dimensions – Anil Chandna Mar 09 '15 at 12:51
  • possible duplicate of [How to calculate the XPath position of an element using Javascript?](http://stackoverflow.com/questions/3454526/how-to-calculate-the-xpath-position-of-an-element-using-javascript) – Louis Mar 11 '15 at 10:56

2 Answers2

1

You should understand that for any given element, there are many possible XPaths that will reach that element.

Our software auto-generates XPaths when recording a browser session and it does that using at least 5 different strategies. But each generator works on the same basic concept: iterate up the tree from the target element until we find some other identifiable element (e.g. root or an element with an id) that we can build a relative path from. Then build an XPath based on the identifiable element and a path to the target element.

CMerrill
  • 1,857
  • 1
  • 14
  • 16
  • FYI, I might have been willing to post some example code, but looking at your activity history, I can see that you don't bother to accept answers when people take the time to give them - which is the expected "thanks" mechanism on StackOverflow and is considered "good behavior" here on SO. – CMerrill Mar 10 '15 at 17:49
  • Pardon for delay,I have created a code in which i have stored all tag and there properties in a tree according to the hierarchy in html format,but it did't work for me the code is getting crash again again.its only able to retrieve 40% to 50% css of all element in html. – NecessaryDevil Mar 10 '15 at 19:46
0

Try implemeting below JavaScript functions.

// ************************************************************************************************
// XPath

/**
* Gets an XPath for an element which describes its hierarchical location.
*/
this.getElementXPath = function(element)
{
if (element && element.id)
return '//*[@id="' + element.id + '"]';
else
return this.getElementTreeXPath(element);
};

this.getElementTreeXPath = function(element)
{
var paths = [];

// Use nodeName (instead of localName) so namespace prefix is included (if any).
for (; element && element.nodeType == 1; element = element.parentNode)
{
var index = 0;
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
{
// Ignore document type declaration.
if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE)
continue;

if (sibling.nodeName == element.nodeName)
++index;
}

var tagName = element.nodeName.toLowerCase();
var pathIndex = (index ? "[" + (index+1) + "]" : "");
paths.splice(0, 0, tagName + pathIndex);
}

return paths.length ? "/" + paths.join("/") : null;
};

this.getElementCSSPath = function(element)
{
var paths = [];

for (; element && element.nodeType == 1; element = element.parentNode)
{
var selector = this.getElementCSSSelector(element);
paths.splice(0, 0, selector);
}

return paths.length ? paths.join(" ") : null;
};

this.cssToXPath = function(rule)
{
var regElement = /^([#.]?)([a-z0-9\\*_-]*)((\|)([a-z0-9\\*_-]*))?/i;
var regAttr1 = /^\[([^\]]*)\]/i;
var regAttr2 = /^\[\s*([^~=\s]+)\s*(~?=)\s*"([^"]+)"\s*\]/i;
var regPseudo = /^:([a-z_-])+/i;
var regCombinator = /^(\s*[>+\s])?/i;
var regComma = /^\s*,/i;

var index = 1;
var parts = ["//", "*"];
var lastRule = null;

while (rule.length && rule != lastRule)
{
lastRule = rule;

// Trim leading whitespace
rule = this.trim(rule);
if (!rule.length)
break;

// Match the element identifier
var m = regElement.exec(rule);
if (m)
{
if (!m[1])
{
// XXXjoe Namespace ignored for now
if (m[5])
parts[index] = m[5];
else
parts[index] = m[2];
}
else if (m[1] == '#')
parts.push("[@id='" + m[2] + "']");
else if (m[1] == '.')
parts.push("[contains(concat(' ',normalize-space(@class),' '), ' " + m[2] + " ')]");

rule = rule.substr(m[0].length);
}

// Match attribute selectors
m = regAttr2.exec(rule);
if (m)
{
if (m[2] == "~=")
parts.push("[contains(@" + m[1] + ", '" + m[3] + "')]");
else
parts.push("[@" + m[1] + "='" + m[3] + "']");

rule = rule.substr(m[0].length);
}
else
{
m = regAttr1.exec(rule);
if (m)
{
parts.push("[@" + m[1] + "]");
rule = rule.substr(m[0].length);
}
}

// Skip over pseudo-classes and pseudo-elements, which are of no use to us
m = regPseudo.exec(rule);
while (m)
{
rule = rule.substr(m[0].length);
m = regPseudo.exec(rule);
}

// Match combinators
m = regCombinator.exec(rule);
if (m && m[0].length)
{
if (m[0].indexOf(">") != -1)
parts.push("/");
else if (m[0].indexOf("+") != -1)
parts.push("/following-sibling::");
else
parts.push("//");

index = parts.length;
parts.push("*");
rule = rule.substr(m[0].length);
}

m = regComma.exec(rule);
if (m)
{
parts.push(" | ", "//", "*");
index = parts.length-1;
rule = rule.substr(m[0].length);
}
}

var xpath = parts.join("");
return xpath;
};
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Mayur Shah
  • 518
  • 3
  • 8