What is the difference between Relative XPath and Minimal XPath? - xpath

Is there any difference between relative XPaths and minimal XPaths or both are same?
In Firebug there are two types of XPath mentioned in the options: 'XPath' and 'Minimal XPath'.

The difference between the two options is described within the documentation to the HTML panel.
The option Copy Minimal XPath is meant to make the XPath, which relates to one element, as short as possible. So the word 'minimal' actually refers to the length of the resulting XPath.
It is currently (Firebug 2.x) only available for elements, which have an ID. And for those elements it copies the XPath in the form of
//*[#id="elementID"]
where elementID represents the ID given within the id attribute of the element. So the words 'minimal' and 'relative' actually mean the same at the moment. Though future versions of Firebug may extend the feature to produce minimal XPaths for elements without ID. And those minimal paths don't necessarily have to be relative.
The option Copy XPath is available for all elements and copies an absolute XPath to an element, which e.g. looks like this:
/html/body/div/div[1]/div/div/table[4]/tbody/tr[17]/td[2]/a

Related

Watir how to click on nested element

I'm trying to click on "Mr" from the drop down list I've tried a combination of things but non of them seem to work.
I've even tried xpath which is usually reliable but for this case its failing.
$browser.element(:xpath, "/html/body/div[1]/div[1]/div[1]/div/div[2]/div[1]/div[2]/div/div[2]/div/div[2]/div[2]/form/div[2]/div/div[2]/div/div/div/div/div/ul/li[2]/a").click
The XPath suggested by Saurabh Gaur, can be written in a more readable Watir-like fashion using:
$browser.ul(class: 'dropdown-menu').link(text: 'Mr').click
Note that this assumes that there is only one ul element with class dropdown-menu. If there are multiple, you will need to scope the search to the specific dropdown using an element that likely exists higher in the DOM.
However, given there is likely only one link with text "Mr", you can probably get away with simply:
$browser.link(text: 'Mr').click
Given the link is a dialog that switches from hidden to visible, you may need to also wait:
$browser.link(text: 'Mr').when_present.click
Your xPath is positional which depends on element position.. it will not work if elements are change their position means adding some elements after some action on the page.
After seeing your attached image I have generated following xPath as below :-
//ul[contains(#class, 'dropdown-menu')]/descendant::span[contains(.,'Mr')]/parent::a
Try with this xPath.. May be it will work...:)

What is the difference between absolute and relative xpaths? Which is preferred in Selenium automation testing?

What is the difference between absolute and relative xpaths? Which is preferred in Selenium automation testing?
I am preparing test scripts using Selenium and Robot framework.
Absolute Xpath: It uses Complete path from the Root Element to the desire element.
Relative Xpath: You can simply start by referencing the element you want and go from there.
Relative Xpaths are always preferred as they are not the complete paths from the root element. (//html//body). Because in future, if any webelement is added/removed, then the absolute Xpath changes. So Always use Relative Xpaths in your Automation.
Below are Some Links which you can Refer for more Information on them.
difference-between-absolute-path
xpath-tutorial-for-selenium
choosing-effective-xpath
An absolute xpath in HTML DOM starts with /html e.g.
/html/body/div[5]/div[2]/div/div[2]/div[2]/h2[1]
and a relative xpath finds the closed id to the dom element and generates xpath starting from that element e.g.
.//*[#id='answers']/h2[1]/a[1]
You can use firepath (firebug) for generating both types of xpaths
It won't make any difference which xpath you use in selenium, the former may be faster than the later one (but it won't be observable)
Absolute xpaths are prone to more regression as slight change in DOM makes them invalid or refer to a wrong element
Consider Below Html
<html>
<body>
<input type ="text" id="username">
</body>
</html>
so Absoulte path= html/body/input
and Relative path = //*[#id="username"]
Disadvantage with Absolute xpath is maintenance is high if there is nay change made in html it may disturb the entire path and also sometime we need to write long absolute xpaths so relative xpaths are preferred
Absolute XPath:
It is the direct way to find the element, but the disadvantage of the absolute XPath is that if there are any changes made in the path of the element then that XPath gets failed.
The key characteristic of XPath is that it begins with the single forward slash(/) ,which means you can select the element from the root node.
Below is the example of an absolute xpath.
/html/body/div[1]/section/div/div[2]/div/form/div[2]/input[3]
Relative Xpath:
Relative Xpath starts from the middle of HTML DOM structure. It starts with double forward slash (//). It can search elements anywhere on the webpage, means no need to write a long xpath and you can start from the middle of HTML DOM structure. Relative Xpath is always preferred as it is not a complete path from the root element.
Below is the example of a relative XPath.
//input[#name=’email’]
We can say mainly there are 3 differences:
Absolute will start with / where as Relative will start with //
Attributes is not used in absolute where as attribute is used in relative
Absolute is a complete path where as relative is partial path
Mainly Relative is preferred, Absolute is not preferred because since its a complete path and elements can change because of dynamic nature so there may be breakage of path so relative is preferred.

Would like to use wildcard within an xpath

I have two links on a page that have the text 'London'. I want to choose the second one on the page, but I want to define the xpath in a way that it chooses by the parent div, but I want to use wildcard in case the link is moved.
So, the two xpaths are
//div[#id="first-id"]/div/div[2]/a[text()="London"]
//div[#id="second-id"]/div[2]/div[3]/div/a[text()="London"]
I want to use a wildcard and define the xpath within the parent div:
i.e. //div[#id="second-id"]/*/a[text="London"]
I already understand I can just use the full xpath and not have any wildcards, but I want to know if there's a way to do what I am proposing using xpath. I thought maybe contains() in some way would work but am not familiar enough with it.
To find the a element wherever it may appear within the div element, the descendant path is represented simply by //:
//div[#id="second-id"]//a[text="London"]

XPATH - grab content from DIV with nestled a text

Can anyone help me with this? I cannot grab the 'Blue Shoes' text from this div no matter what I try! Been over an hour now and still cannot work it out. Tried:
//div[#class='breadcrumbs']/text(
//div[#class='breadcrumbs']
//div[#class='breadcrumbs']/div
Nothing seems to work. Any help MUCH appreciated.
<div class="breadcrumbs">Home/Blue Shoes</div>
</div>
//div[#class='breadcrumbs']/text()
should give you what you need in this case - it will select the set of all text nodes that lie directly under the breadcrumbs div. if you want to specifically target the one at the end (e.g. if there's more than two levels of breadcrumb and there's another text node for, say, a slash between two a elements) then the slightly more specific
//div[#class='breadcrumbs']/text()[last()]
may work better.
If this doesn't work then there are two other possibilities I can think of. Firstly, the HTML DOM uses upper case for element names, and since XPath is case-sensitive you may find you need //DIV instead of //div. Or maybe there's a namespace issue - if your document has an xmlns="..." on the root element then that puts your div elements in a namespace, and unprefixed names in xpath refer to nodes in no namespace. To select namespaced nodes you have to bind a prefix to the corresponding namespace URI and then use the prefix in your expressions (//xhtml:div). Exactly how you go about mapping prefixes depends on what library/tool/language you're using to execute the xpath queries.

Brackets in XPath expressions in SeleniumIDE

I have a problem with SeleniumIDE's evaulation of XPath. SeleniumIDE seems to not know the round brackets in this xpath:
(//span[#class='section-name entry-box'])[last()]/input
It cannot find even this xpath:
(//span[#class='section-name entry-box'])[last()]
or
(//span[#class='section-name entry-box'])/input
But in FireFox FireBug console or in FireFox plugin XPather, all the xpaths works and finds one (or in the last example two) elements on the page.
Do you know any solution? I need to choose last element, which has specific class.
Put "xpath=" at the beginning. Selenium locators can be a variety of different types, and Selenium assumes the type is XPath if the locator starts with "//". Your's doesn't, so you need to specify it explicitly.

Resources