skip to content

Cross-Platform Strategies

The strategy names both mobile drivers accept, and how far each one really carries once you know that the platforms underneath are matching completely different fields.

on this pageshow

explore

questions

15

In Appium, which app-side field does an `accessibility id` locator match on Android, and which on iOS?

level: juniorimportance: must knowfreq 72%

answer

  1. one strategy name, two app-side fields
  2. Android reads the accessibility description
  3. Apple platforms go through the name attribute
  4. identifier first, visible label second

basics

~20 s

On Android the accessibility id strategy matches an element's content-desc. On iOS the XCUITest driver resolves it through the name attribute, which is the element's accessibilityIdentifier or, when that is empty, its visible localised label.

solid answer

~40 s

`accessibility id` is one strategy name over two different app-side sources. On Android, the UiAutomator2 driver matches the element's `content-desc`, the accessibility description a widget exposes, which is not the visible text it renders. On Apple platforms, the XCUITest driver resolves `accessibility id` through its `name` attribute, and `name` is the element's `identifier` — the app-side `accessibilityIdentifier` — falling back to the element's `label`, the localised caption, when the identifier is empty. So the same search string is an invisible developer-set token on Android and, on Apple platforms, either that token or a piece of product copy. Nothing in the server translates between them: the address travels only because someone wrote the same string into both builds.

go deeper

for a junior

Be ready to name both fields without hedging: content-desc on Android, the name attribute on Apple platforms. Practise saying them in one breath, because the first thing an interviewer checks is whether you know they differ at all.

for a middle

Explain the resolution order on Apple platforms: name is the identifier, and only when that is empty does it become the visible label. Then say what Android does in the same situation, which is nothing — the find just fails.

for a senior

Show how the fallback turns a green Apple-platform run into weak evidence, and describe the check you would run on a real failure: read the element name, compare it with the caption, and decide which of the two app-side fields is actually missing.

for a principal

Own the tradeoff of leaning on one shared address across two builds. It is cheap and readable, but it is an unenforced convention held together by discipline, and you should be able to say what you do when that discipline lapses on one platform.

## One strategy name, two different app-side fields `accessibility id` is a **locator strategy**: the value a client puts in the `using` field of a find request, next to the string it wants matched in `value`. Appium's Android drivers and its XCUITest driver both declare that strategy, so the identical request body is legal against an Android session and an Apple one. What each driver does with the string is not identical, and that divergence is the whole content of this topic. Nothing in the server rewrites or translates the address; each driver compares your string against a field its own platform already had, for its own reasons. ## What Android compares it against On Android, the UiAutomator2 driver matches `accessibility id` against the element's **`content-desc`** — the accessibility description exposed by the widget, whose app-side source is `contentDescription`. Three consequences follow, and each of them catches people: - `content-desc` is **not** the widget's visible text. A button can render the caption *Scan pass* on a stadium turnstile screen and carry no description at all. - `content-desc` is **not** the element's id. On Android, `accessibility id` and `id` are separate strategies reading separate fields. - When the field is empty there is no second chance. The element is simply not addressable by this strategy and the find fails. So on Android the address is an invisible, developer-set token. If it is there, the match is unambiguous. If it is not, no amount of retrying or waiting will conjure it. ## What Apple platforms compare it against On Apple platforms the XCUITest driver resolves `accessibility id` through the element's **`name`** attribute, and `name` is a derived value rather than a stored one: 1. If the element has a non-empty `identifier` — the app-side `accessibilityIdentifier` — then `name` is that identifier. 2. If the identifier is empty, `name` falls back to the element's **`label`**, the visible caption a user reads and a screen reader speaks, which comes from the app-side `accessibilityLabel`. That fallback is the single most consequential fact here. An `accessibility id` lookup on Apple platforms can succeed for two entirely different reasons: because a developer set a stable token, or because your search string happened to equal a piece of localised product copy. The driver reports the same success either way, and the response carries no marker saying which rule fired. ## The two fields side by side | | Android (UiAutomator2) | Apple platforms (XCUITest) | |---|---|---| | Attribute matched | `content-desc` | `name` | | App-side source | `contentDescription` | `accessibilityIdentifier` | | Fallback when unset | none — the find fails | the element's `label` | | Can match visible copy | no | yes, whenever the fallback fires | | Sensitive to display language | no | yes, when matching through the label | ## Why the divergence is the answer, not a footnote Because both fields carry a plain string, one locator can serve both platforms, and this is the only mainstream Appium strategy of which that is routinely true. But the portability is a property of **the application**, not of the driver. Someone wrote the same string into `contentDescription` in the Android build and into `accessibilityIdentifier` in the Apple one, and nothing anywhere checks that the two stayed in step. A cross-platform address therefore behaves like a hand-kept contract with two independent copies: - If only the Android build sets it, the Android find passes and the Apple one fails outright. - If only the Apple build sets it, the Apple find may still pass through the label fallback — a pass for the wrong reason. - If both are set to the same string, the address is genuinely shared and is the cheapest reliable locator in the suite. ## How to check what you actually matched The honest check is per platform and takes a moment: - On Android, read the element's `content-desc`. If it is blank, the locator was never going to work there, whatever the Apple run says. - On Apple platforms, read the element's `name` and compare it with the visible caption. If they are identical, treat it as the label fallback until an identifier is proven to exist. - Run the check in the language the failing run used. A `name` that agrees with the caption in English tells you nothing about how the French build behaves. ## What an interviewer is listening for Say the strategy name once and then split the answer by platform immediately. A candidate who answers that it matches the accessibility id has restated the question. A candidate who says `content-desc` on Android and `name` on Apple platforms, and then volunteers the identifier-or-label fallback unprompted, has shown they understand why a cross-platform suite can be green on both platforms while addressing two different things on each.

  • On Apple platforms, what does the XCUITest driver report for `name` when the element has both an identifier and a label?
    The identifier wins. `name` falls back to the `label` only when the `identifier` is empty, so an element carrying a developer-set `accessibilityIdentifier` is matched by that token and never by its visible caption, however the caption is worded or translated.
  • Does an Appium `accessibility id` locator on Android match a button by the text it renders?
    No. On Android the strategy compares only `content-desc`, which is a separate field from the widget's rendered text. A button showing a caption and carrying no description is not addressable by `accessibility id`, and the find fails rather than matching the caption.

saying these in an interview costs you the question

  • Says accessibility id reads the same app-side field on both platforms.
  • Thinks it matches a button's visible text on Android.
  • Believes iOS matches accessibilityIdentifier only, with no fallback at all.
  • Describes it as a driver-side translation instead of two independent fields.
  • Assumes a match on Android proves the Apple build carries the same address.
open as a page

In Appium, what does the `id` locator strategy match on Android, and what on iOS?

level: juniorimportance: must knowfreq 76%

basics

~20 s

On Android the id strategy matches an element's resource-id, the package-qualified identifier fixed in the build. On iOS it is an alias for the name attribute, which XCUITest fills from the accessibility identifier. Same keyword, two unrelated attributes.

open as a page

In Appium, what does the `class name` strategy match on Android compared with iOS?

level: middleimportance: must knowfreq 61%

basics

~20 s

On Android the class name strategy matches a fully qualified widget class such as android.widget.Button. On iOS it matches an XCUIElementType value such as XCUIElementTypeButton. Both are exact string comparisons over two vocabularies that share nothing.

open as a page

In Appium, why is an xpath locator slow on Android and on iOS?

level: middleimportance: must knowfreq 62%

basics

~20 s

Neither platform evaluates XPath natively, so each xpath find first serialises the accessibility hierarchy into an XML document - built by the UiAutomator2 server on Android and by WebDriverAgent on iOS - and matches the expression against that copy.

open as a page

In Appium on Android, why does an `accessibility id` locator miss a button whose visible label reads Scan pass?

level: middleimportance: should knowfreq 38%

basics

~20 s

Because on Android the strategy compares only content-desc, a field separate from the text a widget renders. A button can display a caption and carry no description, and there is no fallback, so the find fails.

open as a page

In Appium on iOS, why can an `accessibility id` lookup match an element that has no identifier?

level: middleimportance: should knowfreq 56%

basics

~20 s

Because the XCUITest driver answers that lookup with the element's name attribute, and name falls back to the element's visible localised label when the accessibilityIdentifier is empty. The match then depends on product copy, not on a stable token.

open as a page

In Appium, what makes `accessibility id` the one locator that travels between Android and iOS?

level: middleimportance: should knowfreq 46%

basics

~20 s

Both drivers declare the strategy and both compare a plain string, so an identical find request is legal on either platform. The travelling is done by the application, which must carry the same string in two unrelated app-side fields.

open as a page

In Appium on iOS, what changes when you swap the `id` strategy for `accessibility id`?

level: middleimportance: should knowfreq 47%

basics

~20 s

Nothing changes on iOS. XCUITest aliases id, name and accessibility id onto the same name attribute, so all three return the same element. On Android the swap changes the matched attribute entirely, and the results diverge.

open as a page

In Appium, an `accessibility id` that finds the stadium turnstile scan button on Android returns nothing on iOS — how do you triage it?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Treat it as a one-sided address, not a broken locator. Confirm the Android element's content-desc holds the token, then read the Apple element's name attribute: the usual cause is that the Apple build never set that identifier.

open as a page

In Appium, why does a `class name` locator that works on Android hit the wrong control on iOS?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Because the two vocabularies have different resolution. An Android class string such as android.widget.EditText is often narrow enough to hit one control, while the iOS equivalent XCUIElementTypeTextField is a coarse role shared by many, so the find returns the first of several.

open as a page

In Appium, why do shared `id` and `class name` locators make one suite two different tests?

level: seniorimportance: should knowfreq 53%

basics

~20 s

Because only the strategy name is shared. On Android the driver compares against resource-id and a Java widget class; on iOS against the name attribute and an XCUIElementType. One locator constant therefore exercises two unrelated app-side contracts.

open as a page

In Appium, what does the limitXPathContextScope setting change on Android and on iOS?

level: seniorimportance: should knowfreq 31%

basics

~20 s

It decides what an element-scoped xpath find is matched against: by default only that element's subtree, and when switched off the whole page source. Both the UiAutomator2 driver on Android and the XCUITest driver on iOS expose it.

open as a page

An Appium xpath loop over 40 tram fare-inspection rows crawls on iOS but not on Android - why?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Each xpath find serialises the hierarchy again, so 40 single finds cost 40 documents on both platforms. The iOS document is built from an XCTest element snapshot across the app boundary, so its unit cost is far higher than Android's.

open as a page

How would you budget xpath use in an Appium tram fare-inspection suite spanning Android and iOS?

level: principalimportance: should knowfreq 40%

basics

~20 s

Budget by measured serialisations per platform, not a blanket rule. One xpath find on a shallow screen is affordable on both lanes; the same find inside a loop is wasteful on Android and a stall on iOS.

open as a page

In Appium, which XPath dialect does Android's UiAutomator2 driver evaluate, and which does iOS?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Android's UiAutomator2 driver evaluates XPath 2 by default and can be pushed back to XPath 1 with its enforceXPath1 setting. On iOS, WebDriverAgent evaluates XPath 1.0 only, and the XCUITest settings reference carries no equivalent switch.

open as a page