Join the webinar on 'Introduction to HeadSpin Performance KPI Capture & Analysis' on Sep 26
Register Now

Basic Element Locators

Appium tests typically need to interact with UI elements in order to do anything useful. In order to interact with them, we first need to be able to "find" them, using one of a variety of "locator strategies".

Basic Locators

Hello everyone and welcome back to the Appium Pro Intro Workshop. In this video we are going to talk about locators, locator strategies and selectors, which combine to help us find elements in our applications. And of course, we can't do anything in our applications until we've found UI elements to interact with. Let's get started.

Defining Locator Strategies

First of all, let's talk about locator strategies. Locator strategies are ways of finding an element, or multiple elements. We can either find one element at a time or multiple elements at a time. Strategies are used together with another concept, selectors. Now selectors are basically parameters that qualify what element should be found using the strategy that you specified.

The Java Appium client, which we're using in this workshop, has different methods, each of which correspond to a different locator strategy, and whether we're asking for one element or multiple elements. The Java client has a couple of special classes that help encapsulate locator information. The original class, which came from the Selenium client is called By. And Appium has extended By into another class called MobileBy, where we've added some additional locator strategies that really only make sense for mobile apps.

Here's a bit of code: driver.findElementById, and we're passing in a string of "foobar". What's going on here? Well, in this code it's pretty clear that we're trying to find an element since it's right there in the method name. And the "Id" in this case is what we mean by the locator strategy. We're saying we'd like to find an element whose ID matches "foobar". And in this line, "foobar" is what we call the selector. It is how the particular element is found when we're using the particular locator strategy of Id.

There is also, as we mentioned, a By class which can create locators when you call methods on the By class. Using By.Id and passing in a value of foobar will give us a locator whose type is id. Again, here Id is the locator strategy and foobar is the selector. Let's now look at a couple of the basic locator strategies that are available with Appium.

Common Locator Strategies

First of all, we have, or the Id locator strategy. This is a cross platform locator strategy which finds elements by their Id. Now on Android there's the concept of an Android resource Id. And if a resource Id has been set on a particular element, then you can find that element by its resource Id using this Id locator strategy. On iOS, there's not really something that maps directly to Id, and so the selector that's used with the Id locator strategy on iOS attempts to find an element by a number of different properties including accessibility Id on iOS.

Another strategy is called className, and this is a platform specific locator strategy because each platform has their own UI element class set. On Android, for example, you build Android apps using UI elements that come in the Android.widget package, or other packages as well. If you want to find all the buttons on the screen on an Android app you can say By.className and then pass in a selector of Android.widget.Button.

We're basically saying, find me the element or elements whose class name is this. And on iOS of course the class names are going to be different because iOS elements have different class names. You'll see something like XCUIElementTypeButton instead of android.widget.Button. This is not a cross platform locator strategy, but it can be useful for finding elements if all you know about them is the type of element that they are.

Xpath is another locator strategy which comes from Selenium along with Id and class name. And it basically lets you find elements by reference to their position in an XML document which represents the user interface. If you've worked with XML before, you might be familiar with xpath. If not, xpath is a way of querying an XML document using a certain string and getting back any nodes that match your query.

Because all application UIs are tree shaped, in other words, they are in a hierarchical format, we can represent them as XML documents. And in fact, we can then find nodes, which reprsent UI elements, in these XML documents using xpath queries. Finally, we're going to talk about accessibility Id. This is, in my opinion, the most useful locator strategy. It exists on the MobileBy class, so it's something that Appium has added to the API.

This is not a locator strategy which you could use with Selenium. And it basically finds elements by their accessibility Id or name or whatever the system uses to represent that element to somebody that's using the app in an accessibility context. What strategies do I think we should use? Well, I think we should use the Id strategy because it's cross platform or the accessibility Id strategy, also because it's cross-platform.

In general, I think using accessibility ID is the best because to use it, it means that you've had to set some kind of accessibility information on your elements as a developer and that's just good for people that are using the application who might need the UI to be read out to them or something like that. But it also helps a lot with testing. I recommend using accessibility Id if you can.

Hands-on with Locators

Let's have a little look at what this can look like in code. I've got two test files here, AndroidLocatorTest and IOSLocatorTest, both of which are in our project. Let's go give them a look.

I'll first open up AndroidLocatorTest. Here it is. It extends our base test class and it is using the Android version of our app capabilities as we would expect. And here is our actual test method. It's called Locator Test. And let's see what it does. Well, first of all, it's sleeping for 3000 milliseconds. At the moment we're doing this just to make sure that the app is fully loaded before we try and find an element.

This is not a great practice, but it is what we can do before we talk about how to appropriately wait for elements. Right now, we're just talking about finding elements. This line is really the main thing that we care about here. We are defining an object called el and it's of type WebElement. WebElement is the Java object that represents an Appium mobile UI element or indeed any kind of element that we might find with Selenium as well.

And now to calling driver.findElement. We're passing in a locator which we've constructed using MobileBy.AccessibilityId and the selector of "Login Screen". Essentially what we're doing here is we're saying, Hey Appium, try and find us the element that has an accessibility Id of login screen. And then we're just printing out this object, whatever it is, to the console.

And it's not very useful, but just showing that we found something, and it might tell us a little bit about what that thing is, even though it's just a Java object. Let's now open IOSLocatorTest and you can see that it is exactly the same actually. We have basically just the same code here, same accessibility Id and everything.

This shows the advantage again of using the accessibility Id locator strategy. It is cross platform. Because I have an app that has the same accessibility information in both the iOS and Android version, I can use the exact same Appium test code to automate it. Okay. Let's give these a run. I'm going to run from my command line here. You could of course run from IntelliJ if that's what you want to do.

I'm going to run, I believe it was called LocatorTest. I'm just going to run both versions of them using the star format here. It should run the iOS and Android versions of the locator test. Before I do that, I'm just going to confirm that I have my Appium server running and I do. Here it is over here. Excellent. It's running the Android test first.

I'll load up my Android emulators so we can see whenever something happens. Okay, it looks like our app has launched. We're waiting the three seconds and then, well, we didn't see anything else happen because all we dId was find the element. And now I'm going to load the iOS simulator as well and we'll see basically if the same thing happen.

There we go. If we look at our test output, we'll see that we did get something printed out. This is again, not something that's very useful, but it is a representation of the element that we found showing the driver that found it, the capabilities of the driver and the selector that was used along with the locator strategy that was used to find this element. That is basically how we find elements of Appium. You might be asking, okay, that's great, but how did you know that the app had an accessibility Id blocking screen that we could use? Well, stay tuned for the next module.