Dynamic XPath in Selenium

This topic is very important while writing test cases. Many things which developer develops are based on an ‘array’ and ‘for loops’. For e.g. when we search for any job on naukari.com, the output shown is always dynamic i.e. the output will never be fixed.

Sometimes it may happen that we may have very long xpath right from the root of Dom i.e. from ‘html’ tag then our code lost readability and maintenance issue arises if anything is changed in our page.

Those who find it very difficult to locate element by using dynamic xpath there various tools are available in the market for getting dynamic xpath. One of it is webdriver element locator.

You can try adding this plugin into firefox.

If we want to generate it programmatically then we need to see some patterns. Just to summarize, we will start from basics of Xpath.



What is XPath?

XPath is defined as XML path. It is a syntax or language for finding any element on the web page using XML path expressions. XPath is used to find the location of any element on a web page using HTML DOM structure.

Types of XPath:

  • Absolute XPath

  • Relative XPath

1) 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 particular XPath gets failed.

The key characteristic of XPath is that it begins with the single forward slash (/) which means Dynamic XPATH you can select the element from the root node. Below is the example of an “absolute XPath” expression of the element shown in the below screen.


Disadvantages:

Example:
If the Path we defined is as follows:

  1. html/head/body/table/tbody/tr/th
    If there is a tag that has been added between body and table as shown below.

  2. html/head/body/form/table/tbody/tr/th
    The first path will not work as ‘form’ tag is added in between.

2) Relative XPath

A ‘relative xpath’ is one where the path starts from the node of your choice i.e. it doesn't need to start from the root node.

It starts with Double forward slash (//)
Syntax: //table/tbody/tr/th

The advantage of using relative xpath is that you don’t need to mention the long xpath instead you can start from the middle or from between.

The disadvantage here is that

  • It will take more time in identifying the element as we specify the partial path and not exact path.

  • If there are multiple elements in the same path then it will select the first element which has been identified.

Now to generate dynamic xpath we need to see XPATH AXES.

XPath has a total of 13 different axes, which we will look at in this section. An XPath axes tells the XPath processor, which “direction” to head in as it navigates around the hierarchical tree of nodes.

self Which contains only the context node
ancestor contains the ancestors of the context node,
That is, the parent of the context node, its parent, etc., if it has one.
ancestor-or-self contains the context node and its ancestors
attribute contains all the attribute nodes, if any, of the context node
child contains the children of the context node
descendant contains the children of the context node, the children of those children, etc.
descendant-or-self contains the context node and its descendants
following contains all nodes which occur after the context node, in document order
following-sibling Selects all siblings after the current node
namespace contains all the namespace nodes, if any, of the context node
parent Contains the parent of the context node if it has one
preceding contains all nodes which occur before the context node,
in document order
preceding-sibling contains the preceding siblings of the context node

XPath contains the path of the element situated on the web page. Standard syntax for creating XPath is:
Xpath = //tagname [@attribute=’value’]

  • //: Selects the current node.

  • Tagname: Tagname of the particular node.

  • @: Selects the attribute.

  • Attribute: Attribute name of the node.

  • Value: Value of the attribute.

We need to follow some functions for this, which is as mentioned below:

1) Basic XPATH:

The XPath expression selects nodes or a list of nodes on the basis of attributes like ID, Name, Classname etc from the XML document as illustrated below:

    Xpath=//input[@name=’uid’]

Some more basic xpath expressions:

    Xpath=//input[@type=’text’]
    Xpath=//label[@id=’message23’]
    Xpath=//input[@value=’RESET’]

2) Contains():

‘contains()’ is a method used in XPath expressions. It is used when the value of any attribute changes dynamically, for example, login information on any page.

In the below XPath expression partial value ‘sub’ is used in place of a submit button. It can be observed that the element is successfully found.

Complete value of ‘Type’ is ‘submit’ but using only partial value ‘sub’.

    Xpath=//*[contains(@type,’sub’)]

Complete value of ‘name’ is ‘btnLogin’ but using only partial value ‘btn’.

    Xpath=.//*[contains(@name,’btn’)]

Similarly, in the below expression, we have taken the ‘id’ as an attribute and ‘message’ as its partial value. This will check 2 elements (‘User-ID must not be blank’ & ‘Password must not be blank’) as its ‘name’ attribute begins with ‘message’.

    Xpath=//*[contains(@id,’message’)]
    Xpath=//*[contains(text(),’here’)]
    Xpath=//*[contains(@ href,’javabykiran.com’)]

3) Using OR & AND:

In OR expression, two conditions are used, either 1st condition OR 2nd condition should be true. It is also applicable if either of the two conditions is true or both which means any one condition should be true in oder to find the element.

    Xpath=//*[@type=’submit’ OR @name=’btnReset’]

4) Start-with function:

“Start-with” function finds the element whose attributes value changes on refresh or any operation on the web page. In this expression, match the starting text of the attribute which is used to find the element whose attribute changes dynamically. You can also find the element whose attributes value is static (i.e. which does not change).

For example: Suppose the ID of particular element changes dynamically like as that of naukari.com search job checkbox.
id=”job12” id=”job 345” id=”job 8769”

And so on.. But the initial text remains the same. In this case, we use Start-with expression.

    Xpath = //label[starts-with(@id,’message’)]

5) Text ():

In this expression, with “text()” function, we find the element with exact text match as shown below. In our case, we find the element with text/id “UserID”.

    Xpath = //td[text()=’UserID’]

Now we will discuss about XPATH axis, which we have seen in table given in XPath Axes section. Few are discussed here.

  1. Following:

    Selects all elements in the document of the current node( ) [here UserID input box is the current node] as shown below,

      Xpath = //*[@type=’text’]//following::input

    There are 3 “input” nodes matching by using “following” axis- password, login and sign in button. If you want to focus on any particular element, then you can use the below XPath method:

      Xpath = //*[@type=’text’]//following::input[1]
  2. Preceding:

    Selects all nodes that come before the current node as shown below.
    In the below expression, it identifies all the input elements before “LOGIN” button that is Userid and password input element.

      Xpath = //*[@type=’submit’]//preceding::input
  3. Following-sibling:

    Selects the following siblings of the context node. Siblings are at the same level of the current node as shown below. It will find the element after the current node.

      xpath = //*[@ type=’submit’]//following-sibling::input

Refer below code of testng and selenium for a complete example of dynamic Xpath. Here website which has been referenced is http://www.javabykiran.com/selenium/demo/