Appium Tip #18: How To Use XPath Locators Efficiently

  January 18, 2016

As we’ve been discussing here at Appium Weekly blog, there are various different ways and tricks to locate elements on a web page. Appium – based on Selenium foundation – provides excellent methods to locate elements by using an XPath function. And in fact, there are lots of different XPath methods you can use, by name, ID, link texts, partial link text, tags, class names and some others. This is the eighteenth blog in our Things You Should Know About Appium – and now, let’s take a look at those different XPath tricks you might find useful.

Using the name, ID or link information (text) for your Appium tests is just fine, but when use cases are becoming more complex and there is more logic in your websites, you might want to consider using XPath. The XPath is originally designed to allow the navigation of XML content with the purpose of locating individual UI elements, attributes and some other things in an XML content. Download our free Appium beginner’s tutorial and check if you have a proper setup to successfully and efficiently use XPath Locators.

Going into how XPath parameters are formulated, some of the XPath queries can be made in many different ways. There isn’t necessarily “the right way” to do this, but in general, good advice is to keep it simple and as straightforward as possible. You can either make a full XPath query with specific indexes for each parent/child or make it more generic and use other search criteria, such as attribute values of the element. You can even leave the element type out of the criteria if you can’t be sure what type of element it will be.

XPath Tutorial and Few Appium Examples for Different Languages

Regardless of what programming language you are using, the XPath parameter is built up the same way. Here are a few basic examples with appropriate driver->find_element calls.

Python Example with Web Browser Locators

We start with a basic example: to find the “a” element, with parent “li” of index 1, with parent “ul” of any index, with any type of parent with id “menu”, the example goes as follows:

driver.find_element_by_xpath('//*[@id="menu"]/ul/li[1]/a')

The following examples allow you to go in sub-divisions of product ‘ID’:

driver.find_element_by_xpath('//*[@id="products"]/div[1]/div/div[1]/div[3]/a')
driver.find_element_by_xpath('//*[@id="topBox"]/div[1]/div/a[2]')

The following HTML code can be found using the web browser’s Inspect tool:

driver.find_element_by_xpath("//button[contains(@class, 'navbar-toggle collapsed')]")
driver.find_element_by_xpath("//li[contains(@class, 'menu-why-testdroid')]")
driver.find_element_by_xpath("//a[contains(@class, 'navbar-brand')]")

The second one (menu-why-testdroid) contains a list (menu) and sub-items can be found if index definition is used. The visual inspection should look like this (Chrome Developer Tools -> Inspect):

Ruby with Native iOS Application

As discussed in the two prior blogs about identifying and locating the UI elements, the XPath can be also identified using the uiautomatorviewer or Appium inspector. The indexes can be given the same way for native apps as those are given to websites, for example: (All UIAButtons, with parent UIAWindow index 1, with parent UIAApplication index 1)

@appium_driver.find_elements(:xpath, "//UIAApplication[1]/UIAWindow[1]/UIAButton")
Java Example with Native Android App

For example, certain UI elements can be located using the UI element definition (e.g. RadioButton) and the XPath call with return any given parameter defined inside the function call:

/* Any android.widget.RadioButton with text value 'Use Testdroid Cloud' */
driver.findElement(By.xpath("//android.widget.RadioButton[@text='Use Testdroid Cloud']"));
/* Any android.widget.EditText with resource-id value 'com.bitbar.testdroid:id/editText1' */
driver.findElement(By.xpath("//android.widget.EditText[@resource-id='com.bitbar.testdroid:id/editText1']"));
/* Button index 1, with parent LinearLayout index 2, with parent LinearLayout index 1, with parent ScrollView index 1. */
driver.findElement(By.xpath("//android.widget.ScrollView[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]/android.widget.Button[1]"));
C# Example:

The C# example isn’t really different from Java but the syntax is naturally according to C#:

// The Same example as the first on Java, but with c# syntax.
driver.FindElement(By.XPath("//android.widget.RadioButton[@text='Use Testdroid Cloud']"));
Additional Examples

For example, any iOS element type of UIAElement, that contains at least ‘Notifications tab’ in a value. The “contains” call is great because we can use only a part of the value. e.g. contains ‘Notifi’ would probably also work:

//UIAElement[contains(@value, 'Notifications tab')]

Also, you could for example search for any UIAStaticText element that does not have a name-value that contains at least ‘_subtitle’, as illustrated in the example below:

//UIAStaticText[not(contains(@name, '_subtitle'))]

And finally, any android.widget.ImageButton that has content-description (content-desc) of ‘Back’. This one must match completely since we don’t use contains.

//android.widget.ImageButton[@content-desc='Back']

Other Find Element Functions – Usable for Mobile Web Testing

Appium (derived from Selenium) provides the following methods to locate elements in a page – you can find elements by:

  • ID
  • name
  • link text
  • partial text in the link
  • tag name
  • name of the class
  • CSS selector

And to find multiple elements (these methods will return a list) you just add find_elements instead of find_element.

One of the greatest thing XPath is that it provides already options with a function call and you don’t have to build everything for a parameter from scratch. Basically, the find_elements_by_ function calls are dedicated and less is required to define what elements you are looking from your web page.

Remember! Keep those parameters relatively short and understandable – and use many variants of find_elements_by functions to define the location from your page. This makes the test execution faster, easier to maintain and more simple for everyone to interpret.

Next week, we’ll continue with the XPath theme and look more specific tips and tricks – and how to use them efficiently.

Happy XPathing!