XPath Axes For Dynamic XPath In Selenium WebDriver

This Tutorial Explains XPath Axes for Dynamic XPath in Selenium WebDriver With the help of Various XPath Axes Used, Examples and Explanation of Structure:

In the previous tutorial, we have learned about XPath functions and its importance in identifying the element. However, when more than one elements have too similar orientation and nomenclature, it becomes impossible to identify the element uniquely.

=> Check Out The Perfect Selenium Training Guide Here.

Xpath Axes for Dynamic Xpath in Selenium

Understanding XPath Axes

Let us understand the above-mentioned scenario with the help of an example.

Think about a scenario where two links with “Edit” text are used. In such cases, it becomes pertinent to understand the nodal structure of the HTML.

Please copy-paste the below code into notepad and save it as .htm file.

<!DOCTYPE html>
<html>
<body>
<div class="1" align="left">
<a href="">Edit</a>
<div class="2" align="left">
<a href="">Edit</a>
</div>
</body>
</html>

The UI will look like the below screen:

UI

Problem Statement

Q #1) What to do when even XPath Functions fail to identify the element?

Answer: In such a case, we make use of the XPath Axes along with XPath Functions.

The second part of this article deals with how we can use the hierarchical HTML format to identify the element. We will start by getting a little information on the XPath Axes.

Q #2) What are XPath Axes?

Answer: An XPath axes defines the node-set relative to the current (context) node. It is used to locate the node that is relative to the node on that tree.

Q #3) What is a Context Node?

Answer: A context node can be defined as the node the XPath processor is currently looking at.

Different XPath Axes Used In Selenium Testing

There are thirteen different axes that are listed below. However, we’re not going to use all of them during Selenium testing.

  1. ancestor: This axes indicates all the ancestors relative to the context node, also reaching up to the root node.
  2. ancestor-or-self: This one indicates the context node and all the ancestors relative to the context node, and includes the root node.
  3. attribute: This indicates the attributes of the context node. It can be represented with the “@” symbol.
  4. child: This indicates the children of the context node.
  5. descendent: This indicates the children, and grandchildren and their children (if any) of the context node. This does NOT indicate the Attribute and Namespace.
  6. descendent-or-self: This indicates the context node and the children, and grandchildren and their children (if any) of the context node. This does NOT indicate the attribute and namespace.
  7. following: This indicates all the nodes that appear after the context node in the HTML DOM structure. This does NOT indicate descendent, attribute, and namespace.
  8. following-sibling: This one indicates all the sibling nodes (same parent as context node) that appear after the context node in the HTML DOM structure. This does NOT indicate descendent, attribute, and namespace.
  9. namespace: This indicates all the namespace nodes of the context node.
  10. parent: This indicates the parent of the context node.
  11. preceding: This indicates all the nodes that appear before the context node in the HTML DOM structure. This does NOT indicate descendent, attribute, and namespace.
  12. preceding-sibling: This one indicates all the sibling nodes (same parent as context node) that appear before the context node in the HTML DOM structure. This does NOT indicate descendent, attribute and namespace.
  13. self: This one indicates the context node.

Structure Of XPath Axes

Consider the below hierarchy for understanding how the XPath Axes works.

Xpath Axes work hierarchy

Refer below a simple HTML code for the above example. Please copy-paste the below code in the notepad editor and save it as .html file.

<!DOCTYPE html>
<html>
<body>
<div class="Animal" align="center">
<h2>Animal</h2>
	<div class="Vertebrate" align="left" >
		<h3 align="left">Vertebrate</h3>
		<div class="Fish" white-space=:pre>
		<h4 >Fish</h4>
		</div>
		<div class="Mammal">
		<h4>Mammal</h4>
			<div class="Herbivore">
				<h5>Herbivore</h5>
			</div>
			<div class="Carnivore">
				<h5>Carnivore</h5>
					<div class="Lion">
						<h6>Lion</h6>
					</div>
					<div class="Tiger">
						<h6>Tiger</h6>
					</div>
			</div>
		</div>
		<div class="Other">
		<h4>Other</h4>
		</div>
	</div>
	<div class="Invertebrate">
		<h3>Invertebrate</h3>
		<div class="Insect">
		<h4>Insect</h4>
		</div>
		<div class="Crustacean">
		<h4>Crustacean</h4>
		</div>
	</div>
	
</div>
</body>
</html>

The page will look like below. Our mission is to make use of the XPath Axes to find the elements uniquely. Let’s try to identify the elements that are marked in the chart above. The context node is “Mammal”

#1) Ancestor

Agenda: To identify the ancestor element from the context node.

XPath#1: //div[@class='Mammal']/ancestor::div

ancestor element

The XPath “//div[@class='Mammal']/ancestor::div” throws two matching nodes:

  • Vertebrate, as it is the parent of “Mammal”, hence it is considered the ancestor too.
  • Animal as it the parent of the parent of “Mammal”, hence it is considered an ancestor.

Now, we only need to identify one element that is “Animal” class. We can use the XPath as mentioned below.

XPath#2: //div[@class='Mammal']/ancestor::div[@class='Animal']

Animal class

If you want to reach the text “Animal”, below XPath can be used.

xpath #3

to reach the text “Animal”

#2) Ancestor-or-self 

Agenda: To identify the context node and the ancestor element from the context node.

XPath#1: //div[@class='Mammal']/ancestor-or-self::div

Ancestor-or-self

The above XPath#1 throws three matching nodes:

  • Animal(Ancestor)
  • Vertebrate
  • Mammal(Self)

#3) Child

Agenda: To identify the child of context node “Mammal”.

XPath#1: //div[@class='Mammal']/child::div

child of context node “Mammal”

XPath#1 helps to identify all the children of context node “Mammal”. If you want to get the specific child element, please use XPath#2.

XPath#2: //div[@class='Mammal']/child::div[@class='Herbivore']/h5

get the specific child element

#4) Descendent

Agenda: To identify the children and grandchildren of the context node (for instance: ‘Animal’).

XPath#1: //div[@class=’Animal’]/descendant::div

Descendent

As Animal is the top member in the hierarchy, all the child and descendant elements are getting highlighted. We can also change the context node for our reference and use any element we want as the node.

#5) Descendant-or-self

Agenda: To find the element itself, and its descendants.

XPath1: //div[@class='Animal']/descendant-or-self::div

Descendant-or-self

The only difference between descendent and descendent-or-self is that it highlights itself in addition to highlighting the descendants.

#6) Following

Agenda: To find all the nodes that follow the context node. Here, the context node is the div that contains the Mammal element.

XPath: //div[@class='Mammal']/following::div

Following

In the following-axes, all the nodes that follow the context node, be it the child or descendant, are getting highlighted.

#7) Following-sibling

Agenda: To find all the nodes after the context node that share the same parent, and are a sibling to the context node.

XPath: //div[@class='Mammal']/following-sibling::div

Following-sibling

The major difference between the following and following-sibling is that the following-sibling takes all the sibling nodes after the context but will also share the same parent.

#8) Preceding

Agenda: It takes all the nodes that come before the context node. It may be the parent or the grandparent node.

Preceding

Here the context node is Invertebrate and highlighted lines in the above image are all the nodes that come before the Invertebrate node.

#9) Preceding-sibling

Agenda: To find the sibling that shares the same parent as the context node, and that comes before the context node.

Preceding-sibling

As the context node is the Invertebrate, the only element that is being highlighted is the Vertebrate as these two are siblings and share the same parent ‘Animal’.

#10) Parent

Agenda: To find the parent element of the context node. If the context node itself is an ancestor, it won’t have a parent node and would fetch no matching nodes.

Context Node#1: Mammal

XPath: //div[@class=’Mammal’]/parent::div

Context Node#1: Mammal

As the context node is Mammal, the element with Vertebrate is getting highlighted as that is the parent of the Mammal.

Context Node#2: Animal

XPath: //div[@class=’Animal’]/parent::div

Context Node#2: Animal

As the animal node itself is the ancestor, it won’t highlight any nodes, and hence No Matching nodes were found.

#11) Self

Agenda: To find the context node, the self is used.

Context Node: Mammal

XPath: //div[@class='Mammal']/self::div

Self

As we can see above, the Mammal object has been identified uniquely. We can also select the text “Mammal by using the below XPath.

XPath: //div[@class='Mammal']/self::div/h4

Mammal object

Uses Of Preceding And Following Axes

Suppose you know that your target element is how many tags ahead or back from the context node, you can directly highlight that element and not all the elements.

Example: Preceding (with index)

Let’s assume our context node is “Other” and we want to reach the element “Mammal”, we would use the below approach to do so.

First Step: Simply use preceding without giving any index value.

XPath: //div[@class='Other']/preceding::div

use preceding without giving any index value

This gives us 6 matching nodes, and we want only one targeted node “Mammal”.

Second Step: Give the index value[5] to the div element(by counting upwards from context node).

XPath: //div[@class='Other']/preceding::div[5]

Give the index value[5] to the div element

In this way, the “Mammal” element has been identified successfully.

Example: following (with index)

Let’s assume our context node is “Mammal” and we want to reach the element “Crustacean”, we will use the below approach to do so.

First Step: Simply use the following without giving any index value.

XPath: //div[@class=’Mammal’]/following::div

following without giving any index value

This gives us 4 matching nodes, and we want only one targeted node “Crustacean”

Second Step: Give the index value[4] to the div element(count ahead from the context node).

XPath: //div[@class='Other']/following::div[4]

index value[4] to the div element

This way the “Crustacean” element has been identified successfully.

The above scenario can also be re-created with preceding-sibling and following-sibling by applying the above approach.

Conclusion

Object Identification is the most crucial step in the automation of any website. If you can acquire the skill to learn the object accurately, 50% of your automation is done. While there are locators available to identify the element, there are some instances where even the locators fail to identify the object. In such cases, we must apply different approaches.

Here we have used XPath Functions and XPath Axes to uniquely identify the element.

We conclude this article by jotting down a few points to remember:

  1. You shouldn’t apply “ancestor” axes on the context node of the context node itself is the ancestor.
  2. You shouldn’t apply “parent” axes on the context node of the context node itself is the ancestor.
  3. You shouldn’t apply “child” axes on the context node of the context node itself is the descendant.
  4. You shouldn’t apply “descendant” axes on the context node of the context node itself is the ancestor.
  5. You shouldn’t apply “following” axes on the context node it’s the last node in the HTML document structure.
  6. You shouldn’t apply “preceding” axes on the context node it’s the first node in the HTML document structure.

Happy Learning!!!

=> Visit Here For The Exclusive Selenium Training Tutorial Series.