As we’ve been discussing here at Appium Weekly blog, there are various different ways and tricks to locate elements in a web page. Appium – based on Selenium foundation – provides excellent methods to locate elements by using a 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 37 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 are 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.
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 the 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 Examples for Different Languages
Regardless of what programming language you are using, the XPath parameter is built up the same way. Here are few basic exmaples with appropriate driver->find_element calls.
Python Example with Web Browser Locators
We start with a basic example: to find element “a” of any index, 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:
The following examples allows you to go in sub-divisions of product ‘ID’:
Here is the example from http://bitbar.com/testing/. The following HTML code can be found using 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)
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/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.Button"));
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']"));
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 example below:
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.
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:
- link text
- partial text in link
- tag name
- name of 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.