Skip to content

dump ui (default/json) drops XCUIElementTypeOther nodes that carry an accessibilityIdentifier — React Native controls become invisible #289

Description

@rakesh-prabha

Summary
On iOS, the default mobilecli dump ui omits elements of type XCUIElementTypeOther even when they carry a non-empty accessibilityIdentifier (React Native testID) and/or accessibilityLabel. React Native renders almost all custom controls (Pressable, TouchableOpacity, custom buttons, text inputs wrappers) as XCUIElementTypeOther, so these interactive elements disappear from the processed tree. The same elements are present in dump ui --format raw, so the data reaches mobilecli from the agent — they are removed by the default tree processing.

This makes it impossible to locate most React Native controls by testID/label through the processed tree (and therefore through @mobilewright/*, which consumes device.dump.ui).

Environment
mobilecli 0.3.85
macOS (Apple Silicon), Xcode 16, iOS 18 simulator
A React Native app (reproduces on a fresh npx create-expo-app / RN CLI app)
Minimal repro
A plain Pressable with a testID and no explicit accessibilityRole (the common RN case):

import { Pressable, Text, View } from 'react-native';

export default function App() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Pressable testID="cta-button" onPress={() => {}}>
Continue


);
}
Run the app on a booted iOS simulator.
mobilecli dump ui --device → the cta-button element is absent; even the "Continue" text is absent (RN collapses the child text into the pressable's accessibility element).
mobilecli dump ui --device --format raw → the element is present, as:
{ "elementType": 1, "identifier": "cta-button", "label": "Continue", "enabled": true, "frame": { ... } }
(elementType: 1 = XCUIElementTypeOther.)

Expected
An element with a non-empty accessibilityIdentifier, label, or value should appear in the default/json dump ui, regardless of whether its elementType is Other. These are addressable, interactive controls.

Actual
All XCUIElementTypeOther nodes are filtered out during default processing. On a typical RN screen this removes the bulk of the tree — e.g. a screen whose raw elementType distribution is dominated by type-1 (Other) nodes ends up with only StaticText and Image survivors after processing. Native XCUIElementTypeButton controls (e.g. system permission dialogs) are kept, so the gap specifically hits RN-rendered controls.

Likely cause / suggested fix
The default tree processing appears to keep an allowlist of "meaningful" element types and discard XCUIElementTypeOther. Suggested change: retain an Other node when it has a non-empty identifier, label, or value (i.e., it is addressable), rather than filtering on elementType alone. Alternatively (or additionally), expose --format raw through the device.dump.ui RPC so SDK consumers can opt into the full tree.

Why it matters
React Native is a first-class supported target. As-is, testID-based location — the standard RN automation strategy used by Appium and Maestro — does not work through the processed tree for the majority of RN controls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions