What does a website consist of and how to create xpath
|HTML DOM Structure|
Each element could be looked upon if you traverse the DOM correctly. Similarly, Selenium uses this structure to identify any desired WebElement on a web page. There are various techniques to extract the WebElement (or locator) from DOM so that any further operation can be performed on it, for eg you may be interested in knowing the location of a text box so that you may enter some text in it.
Among various such techniques, xPath in Selenium is one of the techniques used to identify the locator. xPath in Selenium is the most powerful technique and if you know how to properly apply it, you will never face difficulty in identifying the locators and the saved time could be utilized in maintenance and optimization of your code.
Please be on a system while learning this chapter, the more you practice the better you get.
Types of xPath
xPath is further categorized in 2 parts:
Absolute xPath: This is not recommended and least used in real life projects. This returns the full path, starting from the HTML tag and traversing all the intermediate tags till the desired WebElement. Absolute xPath for the search text box in above image is /html/body/div/div/form/div/div/div/div/div/input. Absolute xPath tend to fail if any of the intermediate WebElement in the hierarchy gets changed.
- Relative xPath: This does not rely on any hierarchy, rather it tightly couples the tag, it’s corresponding attributes and attribute values. We will only learn to use Relative xPath as Absolute path is not used anywhere and it will only give you maintenance nightmares.
The following syntax can be generalized to extract the Relative xPath.
//tagname[@attribute = ‘value’]
xPath using the name attribute
Open your browser (preferably Chrome) and navigate to google search page. Once the page gets loaded, right click on the search text box, select Inspect Element and press Ctrl + F. You will see a window similar to below (highlighted in red):
The following table shows the mapping of the above HTML with the generalized syntax:
Replace the above keywords in the syntax and the Relative xPath is created.
It resulted in 1 matching result which is the yellow highlighted part. Remember, we should always create the xPath which is unique, hence the search count should always be zero.
There could be multiple attributes inside a tag, we can use any one or all of them at once too to create our xPath)
Using multiple attributes to create xPath
Upon inspecting the Google Search button, above HTML line is highlighted. Here we have the number of attributes like value, name, and type. We can create our customized xPath by using more than 1 attribute with and keyword.
Extend the previously used xpath to concatenate multiple attributes using and keyword. You must have observed that this xPath is still giving 2 results, as the page contains the same HTML code twice. Let’s see how to overcome this problem.
Finding the xPath in the hierarchy
If an element is not unique, we can specify the hierarchy where that element is located. Every WebElement is connected to some HTML tag in a hierarchy, and there is a parent-child and sibling relationship among all WebElements. In the above image, we want to create the xPath for 2nd element found in the result (highlighted in yellow). It has a div tag above it which has a class “FPdoLc VlcLAe”. Customize the xPath as following:
//div[@class=’FPdoLc VlcLAe’]//input[@value=’Google Search’ and @type=’submit’]
Above xpath will yield in a unique result.
Using text() method in xPath
Using text() we can extract any text, be it plain text or link text. Syntax to use the text() method is:
//tagname[text() = ‘Sample Text’]
Unlike other xPath techniques, text() does not require @ before its usage.
In above image, the xPath for the text filled in red color is //strong[text()=’The Free Encyclopedia’]. Similarly, the xPath for link text English would be //a[text()=’English’].
Using contains() to create xpath
If you are interested in identifying the locator for a text which is very long but does not wish to write that long string then you may use contains() method. This method takes text() as one of its arguments and returns the web element with specified text.
We can rewrite above xpath for “The Free Encyclopedia” as
Using contains() with attribute and text()- Best way to create your own xpath for links and text
So far, we have observed that any web element or locator of type link (a tag) and the text has some attribute assigned to it (in most of the cases), along with some text. We can combine all of the concepts that we have learned to create a customized xpath. In Wikipedia web page, at bottom of the page, there are few links and text and this technique make it so easy to create our own xpath. Below is an example:
Free library does not contain any other attribute than class, which is not enough to make it unique. Either we can choose to go with the parent-child approach or we can create a customized xpath like below:
//span[contains(@class, ‘other-project-tagline jsl10n’) and text()=’Free library’]
Create xpath for any locator: parent-sibling relationship
This method is the ultimate way to create xpath of your own if there are no sufficient attributes or tags to locate an element uniquely. Using xpath we can traverse DOM in reverse order also, this way we can locate our element using the xpath of locator which is in the immediate hierarchy with respect to our element.
To understand the above concept practically, let’s assume we have to create the xpath for check box next to “Ashton Cox” in below table (https://datatables.net/extensions/select/examples/initialisation/checkbox.html):
Inspect the checkbox and you’ll get the HTML DOM as follows:
The checkbox has td tag and class attribute only, which is not sufficient to identify it uniquely, hence we will go one-level down and inspect the element which is just after it, i.e. “Ashton Cox“. The checkbox and the text have the same parent (<tr role=”row” class=”odd”>) and we can use parent keyword to access it. xpath till parent is:
//td[@class=’sorting_1′ and text()=’Ashton Cox’]//parent::tr[@class=’odd’]
Since the checkbox is just below this parent, use preceding-sibling to create the xpath as follows:
//td[@class=’sorting_1′ and text()=’Ashton Cox’]//parent::tr[@class=’odd’]//preceding-sibling::td[@class=’ select-checkbox’]
This will give the xpath of checkbox. Similarly, try to apply the above technique in various WebElements and creating xpath will be a breeze if you practice this method thoroughly.