Q3 of 26 · Mobile QA
How do you locate UI elements in Appium when CSS selectors are unavailable?
Short answer
Short answer: Appium supports accessibility id (the most portable — works on both platforms), UIAutomator2's UiSelector (Android only), XCUITest predicate strings (iOS only), and XPath as a fallback. Prefer accessibility id; avoid XPath for anything performance-critical.
Detail
Mobile apps don't have a DOM, so CSS selectors don't apply. Appium maps native element attributes into a set of locator strategies:
Accessibility id is the most cross-platform strategy. On Android it maps to the element's content-desc attribute; on iOS it maps to the accessibilityIdentifier. If developers set meaningful accessibility labels on interactive elements, this strategy gives you readable, maintainable selectors that work on both platforms.
UIAutomator2 UiSelector (Android only) lets you query by resource-id, text, class name, or combinations. It's powerful and fast because UIAutomator2 evaluates the query natively on the device: -android uiautomator with a UiSelector string.
XCUITest predicate strings (iOS only) let you query by label, value, type, or combinations. Class chain selectors are also available and faster for deep hierarchies.
XPath works on both platforms but is slow (Appium must dump the entire UI XML and evaluate the path) and brittle. Reserve it for one-off debugging or when no better strategy exists.
// EXAMPLE
locators.ts
// Preferred: works on Android and iOS
const loginBtn = await driver.$('~Login'); // accessibility id
// Android-specific: resource id
const emailField = await driver.$('id:com.example:id/email');
// Android-specific: UIAutomator2
const submitBtn = await driver.$('-android uiautomator',
'new UiSelector().text("Submit")');
// iOS-specific: predicate string
const title = await driver.$('-ios predicate string',
'label == "Welcome" AND type == "XCUIElementTypeStaticText"');