Sunday, April 23, 2017

How to create custom xpath Using Different Techniques in Selenium WebDriver

I have discussed about selenium locators in the previous article. Actually xpath is one of the locators. It is very vital to find out different web elements in the web page. Selenium WebDriver supports xpath to locate web elements.  Due to many disadvantages of absolute xpath, most of the cases it is used relative xpath that can be created using different approaches. Here I will discuss about how to create custom/dynamic relative xpath based on various techniques.

1. xpath Using Single Attribute 

Syntax: 

//tagname[@attribute='value']

We can use * instead of tagname as follows.

//*[@attribute='value']

Here, 

// means point to the current node.

tagName means tagName of the particular node, basically HTML/XML tag like <input>, <button>, <image>, <div>, <span>, <table>, <td>, <tr>, <ul>, <li> and so on..

Attribute: one or more attributes may have a particular node. Mostly used some common attributes are id,name, class, href, img, label and so on

@ is used to address any attribute. It is placed prior to the attribute.

Value: value of the attribute.

 * is placed after double slash to match any tag with the expected attribute value or text

Example: 











From the web page as per above image if we want to locate search field using single attribute, the xpath expression is as follows.

//input[@id='search']

* is used instead of tagname.

//*[@id='search'] 

2. xpath Using Multiple Attribute 

Syntax: 

//tagname[@attribute1='attribute1_value'][@attribute2='attribute2_value]

Example:












From the web page as per above image if we want to locate search field using multiple attribute, the xpath expression is as follows.

//input[@id='search'][@name='q']

3. xpath Using and

Syntax: 

//tagname[@attribute1='attribute1_value' and @attribute2='attribute2_value]

Example:












From the web page as per above image if we want to locate search field using and, the xpath expression is as follows.

//input[@type='text' and @id='search']

4. xpath Using or

Syntax: 

//tagname[@attribute1='attribute1_value' or @attribute2='attribute2_value]

Example:














From the web page as per above image if we want to locate search field using or, the xpath expression is as follows.

//input[@id='search' or @name='q']

5. xpath Using Contains() Method

Contains() method is used to find web elements that contain particular attribute or text(full or partial).

Syntax: 

//tagname[contains(@attribute,'attribute_value')]

Example:












From the web page as per above image if we want to locate search field using contains() method, the xpath expression is as follows.

//input[contains(@id,'search')]

6. xpath Using Starts-with() Method

starts-with() method in xpath, identify the element which attribute value starts with given specific character or text. This method is actually used to interact dynamic web elements within the web pages. Suppose an element with attribute value that changes every time during the page loading. These web elements have some common starting characters followed by random dynamic texts. Besides dynamic attribute, starts-with() method can identify static elements as well.

Syntax:

//tag_name[starts-with(@attribute,'starting_with_fixed_part_of_Attribute_value')]

For example, the ID of a particular element changes dynamically such as,

Id="reg_12"

Id="reg_abc"

Id="reg_1ab"

Id="reg_312" and so on.

In this case the first part remains static and second part dynamically changes. We normally use starts-with expression to locate element in this situation. 















From the web page as per above image, there are two web elements(email address and password fields) whose id start with reg_ text that is fixed. To find those elements the xpath expression is as follows.

//input[starts-with(@id,'reg_')]

7. xpath Using ends-with() Method

ends-with() method in xpath, identify the element which attribute value ends with given specific character or text. This method is actually used to interact dynamic web elements within the web pages. Suppose an element with attribute value that changes every time during the page loading. These web elements have random dynamic texts followed by fixed ending characters. Besides dynamic attribute, ends-with() method can identify static elements as well.

Syntax:

//tag_name[ends-with(@attribute,'ending_with_fixed_part_of_Attribute_value')]

For example, the ID of a particular element changes dynamically such as,

Id="12_reg"

Id="abc_reg"

Id="1ab_reg"

Id="312_reg" and so on.

In this case the first part dynamically changes and second part remains static. We normally use ends-with expression to locate element in this situation. 

xpath expression is as follows.

//input[ends-with(@id,'_reg')]

In previous example, we used starts-with approach that is just opposite of ends-with approach. 

8. xpath using Text() Method

text() method is used to find the web element using text or string of the element within the web pages.

Syntax:

//tagname[text()='text or string of the element']

For example, any message, which always contain a static text or string.










From the web page as per above image if we want to locate CONTACT link using text() method, the xpath expression is as follows.

//a[text()='Contact']

9. xpath Using last() Method: 

Find out the last element of mentioned type out of all element present.

Example:























From the web page as per above image, In google sign up form, find out the last text field(last name) we can use following xpath.

(//input[@type='text'])[last()]

or

(//*[@type='text'])[last()]

If we use [last()-1], to find out the last but one element of mentioned type out of all element present.

Example:















From the web page as per above image, in google sign up form, find out the last-1 text field(first name) we can use following xpath.

(//input[@type='text'])[last()-1]

or

(//*[@type='text'])[last()-1]

10. xpath Using position() Method: 

Find out the element based on mentioned position number out of all element present

Example:















From the web page as per above image, in google sign up form, there are 2 input text fields(first name and last name). If we mention the position=2 to find out the desired text field(last name field) in following xpath expression, we can get easily the expected element of 2nd position.

(//input[@type='text'])[position()=2]

11. xpath Using index within Square Bracket:

We can identify the nth element out of all similar type of elements present.

Example:















From the web page as per above image, in google sign up form, there are 2 input text fields(first name and last name). To identify the 1st element(first name field) we have to mention index in square bracket of following  xpath expression.

(//input[@type='text'])[1]

12. xpath axes Methods:

xpath axes methods are used to identify the dynamic elements. There are different types of xpath axes methods such as following, ancestor, ancestor-or-self, child, preceding, following-sibling, preceding-sibling, parent, self, descendant, descendant-or-self and so on.

i) following

following axis finds all nodes present in the DOM after the current node that is the base node. 

Syntax: 

//tagname[attribute='attribute_value']//following::tagname 

//tagname[attribute='attribute_value']//following::attribute

//tagname[attribute='attribute_value']//following::tagname[index]

//tagname[attribute='attribute_value']//following::tagname[@attribute='attribute_value']

When we use following axis in xpath expression, we have to use two colons(::) after following and then the others like attribute or tagname such as input, button, label and so on.

Example:















From the web page as per above image, in google sign up form, to find the input field of type text after the first name field, we have to use the xpath as follows.

//input[@name='firstName']//following::input[@type='text']
















As per above image, there are 6 input fields, to find only the input fields after the first name field, we have to use the xpath as follows.

//input[@name='firstName']//following::input

ii) Preceding:

peceding axis finds all nodes that come before the current node in DOM except ancestors, attribute nodes and namespace nodes.

Syntax:

//tagname[attribute='attribute_value']//preceding::tagname 

//tagname[attribute='attribute_value']//preceding::tagname[index]

//tagname[attribute='attribute_value']//preceding::attribute

When we use preceding axis in xpath expression, we have to use two colons(::) after preceding and then the others like attribute or tagname such as input, button, label and so on.

Example:















From the web page as per above image, in google sign up form, to find the input field of type text before the Show password checkbox, we have to use the xpath as follows.

//input[@type='checkbox']//preceding::input[@type='text']
















As per above web image, there are 6 input fields, to find only the input fields before the Show password checkbox, we have to use the xpath as follows.

//input[@type='checkbox']//preceding::input

iii) ancestor

ancestor axis finds all ancestors(parent, grandparent and so on) of the current node. It may be from parent node up to the root node. 

Syntax:

//tagname[attribute='attribute_value']//ancestor::tagname 

//tagname[attribute='attribute_value']//ancestor::tagname[index]

//tagname[attribute='attribute_value']//ancestor::tagname[@attribute='attribute_value']

When we use ancestor axis in xpath expression, we have to use two colons(::) after ancestor and then the others like attribute or tagname such as input, button, label and so on.

Example:

From the bellow web page, we are looking for ancestors element of the current node.


Here, we are getting 52 "div" nodes matching by using "ancestor" axis. If we want to locate any particular element then we have to use the below xpath using index =1,2,3,... and so on.

//div[@class='innercomencontent']//ancestor::div[index]

iv) ancestor-or-self

ancestor-or-self axis finds the current node and its ancestors(parent, grandparent and so on).

Syntax:

//tagname[attribute='attribute_value']//ancestor-or-self::tagname 

//tagname[attribute='attribute_value']//ancestor-or-self::tagname[index]

//tagname[attribute='attribute_value']//ancestor-or-self::tagname[@attribute='attribute_value']

When we use ancestor-or-self axis in xpath expression, we have to use two colons(::) after ancestor-or-self and then the others like attribute or tagname such as input, button, label and so on.

From the previous example (iii) we see there are 52 "div" nodes matching by using "ancestor" axis. If we use  ancestor-or-self axis instead of  ancestor axis, we can get 53 div nodes including current node as bellow image.











xpath expression:

 //div[@class='innercomencontent']//ancestor-or-self::div

v) child

child axis finds all child elements of the current node.

Syntax:

//tagname[attribute='attribute_value']//child::tagname 

//tagname[attribute='attribute_value']//child::tagname[index]

//tagname[attribute='attribute_value']//child::attribute

When we use child axis in xpath expression, we have to use two colons(::) after child and then the others like attribute or tagname such as input, button, label and so on.

Example:

From the bellow web page, we are looking for child element of the current node("top navigation" div node).


Here, we are getting 6 "li" nodes matching by using "child" axis. If we want to locate CONTACT element then we have to use the below xpath using index=4.

//div[@id='topnav']//ul//child::li[4]

vi) following-sibling

Siblings indicate in xpath expression the same level of a particular node. following-sibling axis finds all siblings after the current node.

Syntax:

//tagname[attribute='attribute_value']//following-sibling::tagname 

//tagname[attribute='attribute_value']//following-sibling::tagname[index]

//tagname[attribute='attribute_value']//following-sibling::attribute

When we use following-sibling axis in xpath expression, we have to use two colons(::) after following-sibling and then the others like attribute or tagname such as input, button, label and so on.

Example:

In the below web page, 2 "p" nodes are highlighted on the same level and both are siblings. If we select the first "p" node as current node(forgot your password?), so the second node(Sign in button) will be the following-sibling of this current node.











 


xpath expression:

//p[@class='lost_password form-group']//following-sibling::p[1]

vii) preceding-sibling

preceding-sibling axis finds all siblings before the current node.

Syntax:

//tagname[attribute='attribute_value']//preceding-sibling::tagname 

//tagname[attribute='attribute_value']//preceding-sibling::tagname[index]

//tagname[attribute='attribute_value']//preceding-sibling::attribute

When we use preceding-sibling axis in xpath expression, we have to use two colons(::) after preceding-sibling and then the others like attribute or tagname such as input, button, label and so on.

Example:

In the below web page, 2 "p" nodes are highlighted on the same level and both are siblings. If we select the second "p" node as current node(Sign in button), so the first node(Forgot your password? link) will be the preceding-sibling of this current node.



 










xpath expression:

//p[@class='submit']//preceding-sibling::p[1]

viii) parent

parent axis finds the parent of the current node.

Syntax:

//tagname[attribute='attribute_value']//parent::tagname 

//tagname[attribute='attribute_value']//parent::tagname[index]

//tagname[attribute='attribute_value']//parent::attribute

When we use parent axis in xpath expression, we have to use two colons(::) after parent and then the others like attribute or tagname such as input, button, label and so on.

Example:

In the below web page, 8 "li" nodes are highlighted on the same level and both are siblings. If we select the any "li" node as current node, so the parent of this current node is as follows image.



 






xpath expression:

//a[@class='top-heading']//parent::li

ix) self

self axis finds the current node. In another word, it represents the node itself.

Syntax:

//tagname[attribute='attribute_value']//self::tagname 

//tagname[attribute='attribute_value']//self::tagname[index]

//tagname[attribute='attribute_value']//self::attribute

When we use self axis in xpath expression, we have to use two colons(::) after self and then the others like attribute or tagname such as input, button, label and so on.

Example:

If we select any node using self axis, it only finds one node as it represents self-element.

From above web image, if we locate Email field using self axis, the xpath expression is as follows.

//*[@id='email']//self::input

x) descendant

descendant axis finds all descendants (children, grandchildren and so on) of the current node. 

Syntax:

//tagname[attribute='attribute_value']//descendant ::tagname 

//tagname[attribute='attribute_value']//descendant ::tagname[index]

//tagname[attribute='attribute_value']//descendant ::attribute

When we use descendant axis in xpath expression, we have to use two colons(::) after descendant and then the others like attribute or tagname such as input, button, label and so on.

Example:

From the bellow web page, we are looking for descendant elements of the current node(<div id="homepagefootersection">).











Here, we are getting 8 "div" nodes matching by using "descendant" axis. If we want to locate any particular element then we have to use the below xpath using index 1,2,3... and so on.

//div[@id='homepagefootersection']//descendant::div[index]

xi) descendant-or-self

descendant-or-self finds the current node and its descendants (children, grandchildren and so on).

Syntax:

//tagname[attribute='attribute_value']//descendant-or-self::tagname 

//tagname[attribute='attribute_value']//descendant-or-self::tagname[index]

//tagname[attribute='attribute_value']//descendant-or-self::tagname[@attribute='attribute_value']

When we use descendant-or-self axis in xpath expression, we have to use two colons(::) after descendant-or-self and then the others like attribute or tagname such as input, button, label and so on.

From the previous example (x) we see there are 8 "div" nodes matching by using "descendant" axis. If we use descendant-or-self axis instead of descendant axis, we can get 9 div nodes including current node(<div id="homepagefootersection">).











xpath expression:

//div[@id='homepagefootersection']//descendant-or-self::div[index]

That is all about different xpath methods. I hope this article will help to build custom xpath.