Skip to main content

Locators

getByRole() lets a single test target the same element on both Android and iOS, even though each platform names its native classes differently. Mobilewright does this by normalizing the native type reported by the device and mapping it to a semantic role.

How a native type becomes a role

When you call screen.getByRole('textfield'), the query engine:

  1. Takes the raw native type from the UI dump (Android: android.widget.EditText, iOS: XCUIElementTypeTextField).
  2. Normalizes it — strips the Android package prefix (android.widget., androidx.*, …) and the iOS XCUIElementType prefix — leaving a bare name (edittext, textfield).
  3. Matches that bare name against the role's class list.

getByType() skips normalization and matches the raw native class instead, so use it (or getByLabel() / getByTestId()) for classes that have no role mapping.

Android class → role

Android reports the base framework class (e.g. android.widget.EditText, even when the app uses AppCompatEditText).

Native classgetByRole()
android.widget.Buttonbutton
android.widget.ImageButtonbutton
android.widget.EditTexttextfield
android.widget.TextViewtext
android.widget.ImageViewimage
android.widget.Switchswitch
android.widget.ToggleButtonswitch
android.widget.CheckBoxcheckbox
android.widget.SeekBarslider
android.widget.ListViewlist
androidx.recyclerview.widget.RecyclerViewlist
android.widget.ScrollViewlist
android.widget.LinearLayoutlistitem
android.widget.RelativeLayoutlistitem
android.widget.Toolbarheader

React Native (Android)

Native classgetByRole()
…textinput.ReactEditTexttextfield
…text.ReactTextViewtext
…image.ReactImageViewimage
…scroll.ReactScrollViewlist
…view.ReactViewGroupbutton — only when clickable="true" or accessible="true"

iOS class → role

Native classgetByRole()
XCUIElementTypeButtonbutton
XCUIElementTypeTextFieldtextfield
XCUIElementTypeSecureTextFieldtextfield
XCUIElementTypeSearchFieldtextfield
XCUIElementTypeStaticTexttext
XCUIElementTypeTextViewtext — see note below
XCUIElementTypeImageimage
XCUIElementTypeSwitchswitch
XCUIElementTypeSliderslider
XCUIElementTypeTablelist
XCUIElementTypeCollectionViewlist
XCUIElementTypeScrollViewlist
XCUIElementTypeCelllistitem
XCUIElementTypeOtherlistitem
XCUIElementTypeTabtab
XCUIElementTypeTabBartab
XCUIElementTypeLinklink
XCUIElementTypeNavigationBarheader

Notes and known gaps

  • Classes with no role. Anything not listed above has no role mapping — getByRole() won't find it. Target it with getByType('<raw.native.Class>'), getByLabel(), or getByTestId(). Examples: Android Spinner, RadioButton, RadioGroup, CheckedTextView; iOS Picker, DatePicker.

  • iOS source filtering. mobilecli currently surfaces only a subset of iOS classes — Button, TextField, SecureTextField, SearchField, Switch, StaticText, Image, Icon, WebView. Other rows in the iOS table (Slider, Table, CollectionView, Cell, Tab, NavigationBar, Link, TextView) are filtered out before they reach the query engine, so getByRole() cannot match them yet even though the mapping exists.

  • TextView is platform-ambiguous. On Android, TextView is a static label (text). On iOS, XCUIElementTypeTextView is an editable multiline input (UITextView / SwiftUI TextEditor), which is closer to textfield. Both normalize to the same textview token, so they currently share the text role. Aligning an editable iOS text view with textfield (matching the web/ARIA model, where <textarea> and <input> are both textbox) is tracked separately.