Appium Inspector: encontrar elementos en la app con dispositivo físico
Motorola G51 por USB en vez de emulador. Appium Inspector para explorar elementos, locators de Products y Login. Dos errores reales resueltos.
Por qué dispositivo físico
En el post anterior (Primer test: abrir la app en el emulador con Appium) el emulador me consumía toda la RAM. 8GB no alcanzan para tener emulador + Appium Server + IntelliJ corriendo al mismo tiempo. El cuarto intento del primer test funcionó solo después de cerrar absolutamente todo.
La solución: usar mi Motorola G51 conectado por USB. Libero toda la RAM del emulador y los tests corren en hardware real.
Ventajas:
- Ahorra toda la RAM del emulador
- Testing en hardware real (pantalla, rendimiento, sensores)
- Más rápido para iniciar — no hay que esperar que bootee un emulador
Desventajas:
- Necesitás el celular conectado físicamente
- No escala (CI/CD necesita emuladores en la nube)
- Cada celular tiene su resolución, su versión de Android
Para desarrollo local y exploración: dispositivo físico. Para CI/CD: emulador. Los dos tienen su lugar.
Motorola G51: setup del dispositivo físico
3 pasos:
1. Habilitar Opciones de desarrollador
En el celular: Ajustes → Acerca del teléfono → Número de compilación → tocarlo 7 veces seguidas. Aparece un mensaje confirmando que las opciones de desarrollador están habilitadas.
2. Activar Depuración por USB
Ajustes → Sistema → Opciones de desarrollador → Depuración USB → activar.
3. Conectar y verificar
Conecté el celular por USB. El celular pidió autorizar la PC para depuración — acepté.
En PowerShell:
adb devices
List of devices attached
ZY32FJFXNF device

ZY32FJFXNF device — el Motorola G51 conectado por USB y reconocido por adb.device y no offline. Listo para usar.
ZY32FJFXNF es el serial (UDID) del Motorola. Es lo que uso en las capabilities en vez de emulator-5554.
Appium Inspector: qué es y para qué sirve
Appium Inspector es el equivalente al DevTools del browser, pero para apps mobile.
En web, para encontrar un elemento hacés click derecho → Inspect y ves el HTML: <div>, <button>, class, id. En mobile no hay HTML. Hay una jerarquía de Views de Android: TextView, ImageView, EditText, Button.
Appium Inspector te muestra:
- Una captura de la pantalla actual de la app
- El árbol completo de elementos (App Source)
- Los atributos de cada elemento:
resource-id,content-desc,text,class - Los locators sugeridos para usar en el código
Sin esta herramienta, no podés escribir tests — no sabés cómo identificar los elementos.
| Concepto | Web (Selenium) | Mobile (Appium) |
|---|---|---|
| Herramienta | Chrome DevTools | Appium Inspector |
| Estructura | HTML / DOM | Jerarquía de Views Android |
| Elementos | <div>, <button>, <input> |
TextView, ImageView, EditText |
| Identificadores | id, class, name |
resource-id, content-desc, text |
| Locators | CSS Selector, XPath, id | accessibility id, id, UiAutomator, XPath |
Instalación
Descargué la versión 2026.5.1 desde GitHub releases de Appium Inspector. El archivo: Appium-Inspector-2026.5.1-win.exe (238 MB).

Versión 2026.5.1, publicada hace 2 días al momento de escribir esto.
Instalación estándar de Windows. Nada especial.
Configuración: capabilities y conexión
Al abrir Appium Inspector, la pantalla muestra:
- Remote Host:
127.0.0.1(localhost) - Remote Port:
4723(el puerto default de Appium Server) - Remote Path:
/
Estos valores están bien por defecto. Inspector se conecta al mismo Appium Server que usé en el post anterior.
Capabilities
Las capabilities le dicen a Appium qué dispositivo usar, qué app abrir y con qué driver automatizar. Las cargué en el Capability Builder:
{
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "ZY32FJFXNF",
"appium:app": "D:\\Proyectos\\Testing\\appium-java-framework\\appium-java-framework\\apk\\mda-2.2.0-25.apk",
"appium:appWaitActivity": "*"
}

Capabilities listas. Appium Server corriendo en la terminal de al lado.
La diferencia con el emulador: en vez de deviceName: emulator-5554 usé udid: ZY32FJFXNF. El udid es el serial exacto del dispositivo — más confiable que el nombre genérico.
Antes de conectar
Levanté Appium Server en PowerShell (appium) y esperé a que diga "Appium REST http interface listener started on http://0.0.0.0:4723". Inspector necesita el server corriendo.
Dos errores antes de que funcione
No fue directo. Dos errores en el camino.
Error 1: "Invalid or unsupported WebDriver capabilities found (undefined)"

El error más tonto posible.
El Capability Builder tenía una fila vacía (Name/Value sin nada) con el checkbox activado. Eso mandaba una capability undefined al server.
Solución: eliminar la fila vacía con el ícono de basura.
Es el tipo de error que no aparece en ningún tutorial porque nadie lo menciona. Pero pasa.
Error 2: "Cannot start the 'com.saucelabs.mydemoapp.android' application. SplashActivity never started"

La app abrió en el celular. Inspector no se enteró.
La app se instaló y abrió correctamente en el Motorola — se veía la pantalla de Products. Pero Appium esperaba la SplashActivity (la pantalla de carga inicial) que ya había pasado.
Solución: agregar appium:appWaitActivity con valor *. El asterisco le dice a Appium "aceptá cualquier activity como válida, no te quedes esperando una específica".
Este error sí es relevante. En apps reales, el splash screen puede durar milisegundos o no existir. Si Appium se queda esperando una activity que ya pasó, la sesión falla.
Conectado: Inspector funcionando
Después de los dos fixes: Start Session → Inspector capturó la pantalla de la app desde el Motorola.

Inspector conectado al Motorola. A la izquierda la captura de la app, al centro el árbol de elementos, a la derecha el panel de Selected Element vacío esperando que toque algo.
Tres paneles:
- Izquierda: captura de pantalla de la app (clickeable)
- Centro: App Source — el árbol de elementos, equivalente al DOM en web
- Derecha: Selected Element — atributos y locators del elemento seleccionado
Al tocar un elemento en la captura, se resalta en el árbol y aparecen todos sus datos a la derecha.
Explorando la pantalla de Products
Toqué cada tipo de elemento para ver qué atributos tenía.
Título "Products"

Título de la pantalla. Tiene las tres cosas: text, content-desc y resource-id.
text: Productscontent-desc: titleresource-id: com.saucelabs.mydemoapp.android:id/productTVclass: android.widget.TextView- Locator sugerido por Inspector:
accessibility id → title
Imagen de producto
content-desc: Product Imageresource-id: com.saucelabs.mydemoapp.android:id/productIVtext: (vacío — es una imagen)class: android.widget.ImageView
Nombre de producto ("Sauce Labs Backpack")

El nombre del producto. content-desc genérico ("Product Title"), text específico ("Sauce Labs Backpack").
text: Sauce Labs Backpackcontent-desc: Product Titleresource-id: com.saucelabs.mydemoapp.android:id/titleTV
Acá hay un detalle importante: el resource-id es titleTV para todos los productos. Si quiero tocar "Sauce Labs Backpack" específicamente, el resource-id solo no alcanza. Necesito combinarlo con text o usar UiAutomator:
new UiSelector().text("Sauce Labs Backpack")
Precio ("$ 29.99")
text: $ 29.99content-desc: Product Priceresource-id: com.saucelabs.mydemoapp.android:id/priceTV
Mismo problema que el nombre: priceTV se repite para todos los productos.
Menú hamburguesa

AppiumBy.accessibilityId("View menu").El menú tiene accessibility id. Es el locator ideal.
content-desc: View menuresource-id: com.saucelabs.mydemoapp.android:id/menuIVaccessibility id: View menu
Carrito
content-desc: Displays number of items in your cartresource-id: com.saucelabs.mydemoapp.android:id/cartIVaccessibility id: Displays number of items in your cart
Rating (estrellas)

Las estrellas no tienen ni accessibility id ni resource-id propio. Solo un LinearLayout genérico. Inspector sugiere UiAutomator con className + instance.
class: android.widget.LinearLayout- Sin
accessibility id - Sin
resource-idpropio - Locator sugerido:
UiSelector().className("android.widget.LinearLayout").instance(2)
Este es el peor caso. Un elemento sin identificadores propios. En apps reales pasa mucho.
Resumen de la pantalla de Products
| Elemento | content-desc | resource-id | accessibility id |
|---|---|---|---|
| Título "Products" | title | productTV | title |
| Imagen producto | Product Image | productIV | — |
| Nombre producto | Product Title | titleTV | — |
| Precio | Product Price | priceTV | — |
| Menú | View menu | menuIV | View menu |
| Carrito | Displays number... | cartIV | Displays number... |
| Rating | — | — | — |
Conclusión: esta app está bien instrumentada. La mayoría de los elementos tienen content-desc y resource-id. En apps de producción reales (las del trabajo) no siempre tenés esa suerte.
Pantalla de Login
Navegué al login desde el menú hamburguesa en el celular, luego refresqué Inspector (botón de recarga) para que capture la nueva pantalla.
Campo Username

nameET), sin accessibility id. Las credenciales de prueba se ven abajo.Campo de username. resource-id único, sin accessibility id.
resource-id: com.saucelabs.mydemoapp.android:id/nameETclass: android.widget.EditTexttext: (vacío)- Sin
accessibility id
Campo Password

passwordET), sin accessibility id.resource-id: com.saucelabs.mydemoapp.android:id/passwordETclass: android.widget.EditTexttext: (vacío)- Sin
accessibility id
Botón Login

El botón de Login tiene todo: accessibility id, resource-id y text.
text: Logincontent-desc: Tap to login with given credentialsresource-id: com.saucelabs.mydemoapp.android:id/loginBtnaccessibility id: Tap to login with given credentialsclass: android.widget.Button
Credenciales de prueba
La app muestra credenciales en la misma pantalla:
- Username:
[email protected] - Password:
10203040
Estas son las que voy a usar en el próximo post para el test de login.
Resumen de la pantalla de Login
| Elemento | resource-id | accessibility id | text |
|---|---|---|---|
| Username | nameET | — | — |
| Password | passwordET | — | — |
| Login button | loginBtn | Tap to login... | Login |
Los campos de input no tienen accessibility id pero tienen resource-id únicos. Alcanza.
Jerarquía de locators en mobile
Del mejor al peor:
1. accessibility id — el más estable. No cambia con idioma, versión de Android ni refactoreo del código. Es el equivalente a data-testid en web. Ejemplo: View menu, title.
2. resource-id — bueno si es único en la pantalla. Puede cambiar entre versiones de la app. Ejemplo: loginBtn, nameET.
3. UiAutomator selector — flexible y potente. Permite combinar criterios: new UiSelector().text("Sauce Labs Backpack"). Más verboso pero útil cuando no hay id o accessibility id.
4. XPath — último recurso. Frágil: cualquier cambio en la estructura de la app lo rompe. Lento en comparación con los otros. Ejemplo: //android.widget.TextView[@content-desc="Product Title"].
En la serie de Selenium expliqué una jerarquía similar para web: id > CSS Selector > XPath. El concepto es el mismo: usar el locator más estable y legible posible. En mobile, accessibility id ocupa ese lugar.
Paralelo con Selenium
| Prioridad | Web (Selenium) | Mobile (Appium) |
|---|---|---|
| 1° (mejor) | id / data-testid |
accessibility id |
| 2° | CSS Selector | resource-id |
| 3° | XPath (relativo) | UiAutomator selector |
| 4° (peor) | XPath (absoluto) | XPath |
Tip: guardar las capabilities
Antes de cerrar Inspector, usé Save As... para guardar el set de capabilities con un nombre ("Motorola G51 - My Demo App"). La próxima vez no tengo que cargarlas de nuevo — están en la pestaña "Saved Capability Sets".
Estado actual
| Elemento | Detalle |
|---|---|
| Dispositivo | Motorola G51 (ZY32FJFXNF) por USB |
| Appium Inspector | 2026.5.1 |
| App target | Sauce Labs My Demo App 2.2.0 |
| Pantallas exploradas | Products, Login |
| Locators identificados | resource-id, accessibility id, text, UiAutomator |
| Capabilities guardadas | "Motorola G51 - My Demo App" |
Takeaways:
accessibility ides el locator preferido en mobile (cuando existe)- Los
resource-idse repiten entre elementos del mismo tipo (todos los productos compartentitleTV) - Inspector necesita refresh manual cuando navegás en la app
appWaitActivity: *resuelve el problema de SplashActivity que ya pasó- El dispositivo físico es más práctico que el emulador para desarrollo local
Siguiente en la serie
Interacciones básicas: tap, input, scroll y assertions. Los locators de este post se convierten en un test de login completo — abrir la app, navegar al login, ingresar credenciales y verificar el resultado.
Tabla de contenido de la serie
| Post | Tema | Estado |
|---|---|---|
| 1 | Por qué Appium: decisiones técnicas | ✅ Publicado |
| 2 | Setup completo: Node.js, Android Studio, Appium Server y emulador | ✅ Publicado |
| 3 | Primer test: abrir la app en el emulador | ✅ Publicado |
| 4 | Appium Inspector: encontrar elementos con dispositivo físico | ← Este post |
| 5 | Interacciones básicas: tap, input, scroll, assertions | Siguiente |