Appium Locators: How to Find Elements in Mobile Apps
Learn how Appium finds mobile UI elements, how to choose a locator for your driver, and how to troubleshoot element lookups.
Appium finds mobile UI elements through WebDriver element-finding commands sent during an active session. Your client supplies a locator strategy and selector; the active driver interprets that request and performs the lookup. Because drivers can support different locator strategies, check the current reference for the driver and version in your test setup before using an example.
For example, the official Appium Python quickstart uses XPath to find the “Apps” element in an Android session running UiAutomator2:
el = self.driver.find_element(by=AppiumBy.XPATH, value='//*[@text="Apps"]')
el.click()
This is specifically a Python, Android, UiAutomator2, XPath example. It is not a validated iOS recipe or evidence that XPath is universally the fastest or most stable choice.
1. How Appium element lookup works
An Appium client sends a WebDriver find command to the server as part of a session. The command asks for one matching element or a collection of matching elements. Most WebDriver endpoints are proxied to the active driver, which implements them. As a result, locator behavior depends on the driver rather than on one universal Appium locator engine. Appium WebDriver protocol reference.
At a high level, the flow is:
- Start a session with the platform and driver your test will use.
- Choose a locator strategy supported by that driver.
- Call the client’s element-finding method with the strategy and selector.
- Use the returned element, or handle the result when nothing matches.
A driver may support only some standard WebDriver strategies, or it may add custom ones. Requests using unsupported strategies can be rejected. Consult the locator-strategy reference for your chosen driver and version before copying a selector. Appium driver authoring guide.
2. Python example: Android with UiAutomator2
The following lookup matches the official Appium Python quickstart’s Android and UiAutomator2 example. It assumes you already have a running Appium server, the UiAutomator2 driver installed, and an Android device or emulator available. The session setup uses the quickstart’s options pattern; provide the server URL and device capabilities appropriate to your environment.
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
options = UiAutomator2Options()
options.platform_name = "Android"
options.automation_name = "uiautomator2"
options.device_name = "Android Emulator"
# Set this to the Appium server URL used by your environment.
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
try:
# Android + UiAutomator2 + XPath: from the official Python quickstart.
apps = driver.find_element(
by=AppiumBy.XPATH,
value='//*[@text="Apps"]',
)
apps.click()
finally:
driver.quit()
The example’s selector is tied to the screen and accessibility/UI tree in that quickstart. For your own app, inspect the active screen and choose a selector that identifies the intended element in your driver’s supported locator set. The quickstart notes that the Appium Python Client inherits from Selenium’s Python binding. It also states: “The Appium Python client adds the appium: vendor prefix automatically.” Appium Documentation: Write a Test (Python).
Find one element or find all matches
Use the single-element method when the test expects one target. Use the plural method when you need to inspect or act on multiple matches. The WebDriver protocol defines findElement and findElements; client method names follow their binding’s conventions. WebDriver protocol reference.
# One match; the client reports an error if the element cannot be found.
button = driver.find_element(AppiumBy.XPATH, '//button')
# A collection; check the result before indexing or acting on an item.
buttons = driver.find_elements(AppiumBy.XPATH, '//button')
if not buttons:
raise AssertionError("No matching buttons were found")
The //button selectors above only demonstrate the method shape. They are not a cross-platform recommendation: the actual selector and strategy must match the app’s UI and active driver.
Scope a lookup to a parent element
When the client and driver support it, a lookup can be scoped to an existing element. This can make the intended relationship clearer when a screen contains repeated controls, but the nested selector still needs to be valid for the active driver.
container = driver.find_element(AppiumBy.XPATH, "YOUR_SUPPORTED_PARENT_SELECTOR")
child = container.find_element(AppiumBy.XPATH, "YOUR_SUPPORTED_CHILD_SELECTOR")
Replace the placeholders with selectors verified for your platform, driver, and screen. Element-scoped lookup endpoints are part of the WebDriver reference. Appium WebDriver protocol reference.
3. Choose a locator strategy for your app and driver
There is no single strategy that this evidence establishes as best for every platform, app, and driver. Compare candidate locators against these practical criteria:
- Driver support: Is the strategy listed for the exact driver and version in use?
- Target specificity: Does the selector identify the intended element clearly, including when similar controls appear?
- Resilience to UI changes: Does the selector depend on details likely to change in your app?
- Measured lookup time: If speed matters, measure it in your own setup with representative screens and repeated runs. The sources cited here provide no comparative benchmark.
Start by checking the driver’s current locator reference, then confirm the selector against the screen your test actually encounters. Avoid copying a strategy from another platform or driver without checking its support. Driver locator-strategy guidance.
4. Troubleshoot element lookup problems
| Symptom | Likely cause | What to check |
|---|---|---|
| The server rejects the locator strategy | The active driver does not allow that strategy, or the request is otherwise invalid for that driver. | Confirm the session’s platform, active driver, driver version, and supported strategy list. Choose a supported strategy and retry. |
| A single-element lookup fails | No element matched at lookup time, or the screen and selector differ from the expected state. | Verify that the session reached the expected screen and that the selector describes an element present there. Check the driver’s selector behavior. |
| A plural lookup returns an empty collection | No elements matched the supplied selector at that point in the session. | Check the current screen, selector, and driver support before indexing or interacting with the result. |
| An example works on Android but not on iOS | The example is platform- and driver-specific; locator support and UI representation can vary. | Use the reference for the iOS driver and version in your session. Do not assume an Android XPath example is an iOS recipe. |
| The test finds the wrong repeated control | The selector matches more than one element or does not distinguish the intended target. | Make the selector more specific using supported information from your app’s UI, or scope the lookup to an appropriate parent element. |
Most WebDriver endpoints are implemented by the driver receiving the proxied request, so investigate the actual session driver when a lookup behaves differently than expected. Appium WebDriver protocol reference.
5. Performance, reliability, and cost
Performance
The reviewed sources do not establish a universal speed ranking among locator strategies. If lookup time is important, benchmark the strategies your driver supports in the app and environment you will ship: use the same screen state, selector target, device conditions, and repeated-run approach. Record the driver and version alongside the result so it remains interpretable.
Reliability
Reliability starts with matching the strategy to the active driver and validating the selector against the state the test reaches. A valid strategy alone does not guarantee a match: the target must be present, and the selector must identify it as intended. When investigating failures, distinguish an unsupported strategy from a supported lookup that returns no match.
Cost
Appium locator calls do not have a per-lookup price stated in the cited documentation. Your operational cost depends on the infrastructure and services you use to run tests. For browser screenshot work associated with debugging or documenting a web page, ScreenshotNeo provides a separate screenshot API; it does not locate native mobile app elements or replace Appium.
6. Capture a web page while debugging a test
If your test workflow also needs a screenshot of a web page, a browser automation setup is one way to capture it. Appium locator calls remain the way to find elements in the mobile app; the example below is for capturing a website screenshot with ScreenshotNeo.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation for the request options. The API returns a screenshot or PDF from a URL. ScreenshotNeo also offers an MCP server for AI agents, with tools including take_screenshot, get_page_info, and capture_pdf. Its usage and billing headers report the page verdict and whether the request was billed.
7. Or skip the browser setup
For web page captures, ScreenshotNeo accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Each of these steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and billing status. AI agents can use its MCP server for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the API documentation, learn about ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.
8. Frequently asked questions
Does Appium have one locator engine for every platform?
No. The active driver implements most proxied WebDriver endpoints, and supported strategies can vary by driver.
Can I use the Android quickstart’s XPath on iOS?
The quickstart example is specifically for Python with Android and UiAutomator2. Check the reference for your iOS driver and validate its locator support before using a selector.
Which locator strategy is fastest?
The reviewed sources do not provide a universal ranking. Measure supported strategies in your own app and driver if lookup time is a deciding factor.
When should I use the plural find method?
Use it when your test needs a collection of matches or needs to check whether any matches exist. Use a single-element lookup when the test expects one element.


