With Selenium Webdriver, you normally locate an element by id, className, tag, or CSS amongst various other methods. Even though there are many ways to locate an element, for various reasons sometimes they don’t work. In this situation, you can use XPath to locate elements. This blog shows an example of how we leverage XPath in our Selenium automated testing work to locate web elements.

As background knowledge, an XPath axis defines a node-set relative to the current node. Names of axes include “ancestor”, “descendant”, “parent” etc. You can go to http://www.w3schools.com/xpath/xpath_axes.asp to learn more.

When using Selenium for automated testing, assume we are writing Selenium automation scripts for the following page.

wd01

The HTML code of the page is:

bank.htm

<html>
<head><title>Bank Search Result</title></head>
<body>
<table id=”BankList” style=”width:100%; border-collapse:collapse;” border=”1″ >
<tr>
<th>Action</th>
<th>Bank Name</th>
</tr>
<tr class=”className”>
<td class=”cName” align=”center”><a href=”edit.htm”>Edit</></td>
<td class=”cName” align=”center”>Bank 1</td>
</tr>
<tr class=”className”>
<td class=”cName” align=”center”><a href=”edit.htm”>Edit</></td>
<td class=”cName” align=”center”>Bank 2</td>
</tr>
<tr class=”className”>
<td class=”cName” align=”center”><a href=”edit.htm”>Edit</></td>
<td class=”cName” align=”center”>Bank 3</td>
</tr>
<tr class=”className”>
<td class=”cName” align=”center”><a href=”edit.htm”>Edit</></td>
<td class=”cName” align=”center”>Bank 4</td>
</tr>
</table>
</body>
</html>

This page is a search result page listing some bank names. Our next action is to click the “Edit” link for a given Bank Name. Because the class, href targets, and texts of all Edit links are the same, we can’t use common methods to identify them.

At the same time, we can see that the search results (the bank names) always change, so we can’t operate the expected Edit element with fix-positioned XPath like //td/a[1].

To solve this problem, we can use XPath Axis. For any bank name, if we can identify its sibling node, we then can operate the sibling’s anchor (“<a>” element).  The Java method is like this:

public void clickEditForABank(String bankName)
{
driver.findElement(By.xpath(“//td[contains(text(),'"+bankName+"')]/preceding-sibling::td/a”)).click();
}

Explanation:

  • //td[contains(text(),'"+bankName+"')] - Locates the wanted element which text contains the bank’s name.
  • preceding-sibling:: – The XPath Axis which selects the bank’s sibling before it.
  • td/a – Specify the <a> element of the sibling.

A complete Java sample code is copied here.

Package com.blog.tests;
 
Import java.util.concurrent.TimeUnit;
Import org.junit.*;
Import org.openqa.selenium.*;
Import org.openqa.selenium.firefox.FirefoxDriver;
 
public class blog {
private WebDriver driver;
private String baseUrl;
 
@Before
Public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = “file:///C:/bank.htm”;
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
 
@Test
public void testBlog() throws Exception {
driver.get(baseUrl);
clickEditForABank(“Bank 4″);
 
}public void clickEditForABank(String bankName)
{
driver.findElement(By.xpath(“//td[contains(text(),'"+bankName+"')]/preceding-sibling::td/a”)).click();
}@After
public void tearDown() throws Exception {
driver.quit();
}
}

Copy the code and you can run from Eclipse directly. Of course, besides “preceding-sibling”, we can use any other axes in the scripts.

One of the goals of automation is to make testing faster and more efficient. Yet many find that script maintenance often takes too much time and is counter to the overall objective. When using Selenium for automated testing, we find that using XPath Axes takes less effort, gets a better result, and makes our automation scripts flexible. Its powerful capabilities open up many new methods for locating complex and even dynamic elements which in the end, make your scripts easier to maintain.