Appium Tip #16: Finding Elements with Appium Automation Engine

  December 29, 2015

It’s time to look at how different elements can be found with Appium and what actually happens in the background when Appium does most of the work for you. This is the 16th tip in our Things You Should Know About Appium and with the following blogs, I’ll be focusing more on Appium automation engine and commands, how to use them effectively and what tricks may be involved. As always, I’ll provide some code examples for each and every (popular) programming language that is used with Appium.

Mobile App Testing – What’s Under The Hood?

Appium is for mobile app testing and enables users to execute tests on mobile devices regardless of what OS version is used on devices. In short, this is possible as the Appium framework is a wrapper that translates Selenium WebDriver commands to UI Automation (on iOS), uiautomator (Android, API level 17 or higher) or Selendroid (Android, API level 16 or lower) commands, depending on which platform tests are executed on. For example, Android version 4.2 and higher are supported via Appium’s own uiautomator libraries and provides the default automation backend used by Appium. Download our free Appium beginner’s guide to check if you have a proper setup to successfully find elements with Appium automation engine.

Android versions 2.3 through 4.2 are supported via Appium’s bundled version of Selendroid, which utilizes Instrumentation. Selendroid has a bit different set of commands than the default Appium, which you need to take into account when targeting both over and under Android 4.2. To access this automation backend, use the automationName capability with the value Selendroid.

Other than the slightly different commands available, the automation backend doesn’t matter much. Appium takes care of running your tests regardless of what OS version will be installed on the device as long as automationName is correctly set.

How to Find Elements with Appium Automation Engine?

Here’s how to find elements with Appium automation engine in use with our Android sample app. The sample app provides a very basic menu-like selection of three items – “Buy 101 devices”, “Use Testdroid Cloud” and “Ask mom for help”. In addition, it provides a similar look-and-feel for both Android and iOS app so the same basic flows can be tried for both platforms. This is how it looks on Appium Inspector as an iOS app under inspection:

appium inspector automation engine

The same find strategies work on both Android and iOS as long as the actual attribute values are correct. Here are the examples:

Python:

elem(s) = driver.find_element(s)_by_class_name('android.widget.EditText')
elem(s) = driver.find_element(s)_by_name('Buy 101 devices')
elem(s) = driver.find_element(s)_by_id('com.bitbar.testdroid:id/radio0')

Note that you can find a list of all the elements matching the criteria by using the find_elements_by_ instead of find_element_by_. This list can then be further accessed via index numbers, for example: elems[0].click(). I’ve added the (s) to the examples to show the alternative layout for finding multiple elements.

Ruby:

driver.find_element(s)(:class_name, 'android.widget.EditText')
driver.find_element(s)(:name, 'Buy 101 devices')
driver.find_element(s)(:id, 'com.bitbar.testdroid:id/radio0')

Ruby implementation isn’t much different from others. When testing for mobile web, you can also find elements by Tag name, Link text, Partial link text or CSS  – e.g:

# <div class="highlight-java" style="display: none; ">...</div>
driver.find_element(:tag_name, 'div')
# <input id="id1" name='input' type='text'>…</input>
driver.find_element(:name, 'input')
# <a href="http://www.testdroid.com">testdroid.com</a>
driver.find_element(:link_text, 'testdroid.com')
# <a href="http://www.testdroid.com">testdroid.com</a>
driver.find_element(:partial_link_text, 'droid.com')

Java:

Using Selenium’s By class (import org.openqa.selenium.By;) can also make things easier in an IDE. Class By is a mechanism used to locate elements in any document. In order to create your own locating mechanisms, you can subclass this class and override the protected methods as required. Basic examples with By in use:

driver.findElement(s)(By.className('android.widget.EditText'));
driver.findElement(s)(By.name('Buy 101 devices'));
driver.findElement(s)(By.id('com.bitbar.testdroid:id/radio0'));

C#:

Using Selenium’s By class (using OpenQA.Selenium;)

driver.FindElement(s)(By.ClassName('android.widget.EditText'));
driver.FindElement(s)(By.Name('Buy 101 devices'));
driver.FindElement(s)(By.Id('com.bitbar.testdroid:id/radio0'));

JavaScript:

driver.element(s)ByClassName('UIATextField')
driver.element(s)ByName('Buy 101 devices')
driver.element(s)ById('com.bitbar.testdroid:id/radio0')

Is XPath Useful for Mobile App Testing?

You can also find by XPath, which we’ll look more in detail later. The most basic way is to use the full XPath, which would in our sample app’s case look like this:

elem = driver.find_element_by_xpath('//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.ScrollView[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.RadioGroup[1]/android.widget.RadioButton[1]')

Okay, that’s a good set of basic examples. Next week we’ll cover how to find elements with Selendroid automation backend in use – and how it can help your mobile app testing.