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.

Appium Inspector conectado al Motorola mostrando pantalla Products con título seleccionado y atributos accessibility id title
Inspector funcionando. Título "Products" seleccionado: text, content-desc y resource-id visibles a la derecha.

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
Terminal PowerShell mostrando adb devices con dispositivo ZY32FJFXNF conectado como 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).

GitHub releases de Appium Inspector mostrando versión 2026.5.1 con highlights y changelog de nuevas features
Versión 2026.5.1, la más reciente al momento de escribir esto.

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": "*"
}
PowerShell con Appium Server v3.3.1 corriendo y Appium Inspector al lado con capabilities cargadas para Motorola G51
Appium Server corriendo en PowerShell, Inspector con las capabilities del Motorola. La fila vacía de abajo todavía no la vi.

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)"

Appium Inspector mostrando error Invalid or unsupported WebDriver capabilities found undefined con fila vacía visible
El error más tonto posible: una fila vacía con el checkbox activado mandaba una capability 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"

Appium Inspector mostrando error SplashActivity never started después de que la app ya abrió en el Motorola
La app abrió en el celular, pero Inspector se quedó esperando la SplashActivity que ya había pasado.

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.

Appium Inspector conectado al Motorola mostrando pantalla Products con título seleccionado y atributos accessibility id title
Inspector funcionando. Título "Products" seleccionado: text, content-desc y resource-id visibles a la derecha.

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"

Appium Inspector con pantalla Products y elemento título seleccionado mostrando content-desc title y resource-id productTV
El mismo elemento en otra captura. Los tres atributos que importan: text, content-desc, resource-id.

Título de la pantalla. Tiene las tres cosas: text, content-desc y resource-id.

  • text: Products
  • content-desc: title
  • resource-id: com.saucelabs.mydemoapp.android:id/productTV
  • class: android.widget.TextView
  • Locator sugerido por Inspector: accessibility id → title

Imagen de producto

  • content-desc: Product Image
  • resource-id: com.saucelabs.mydemoapp.android:id/productIV
  • text: (vacío — es una imagen)
  • class: android.widget.ImageView

Nombre de producto ("Sauce Labs Backpack")

Appium Inspector con Sauce Labs Backpack seleccionado mostrando content-desc Product Title y resource-id titleTV
El nombre del producto. content-desc genérico ("Product Title"), text específico ("Sauce Labs Backpack"). El resource-id se repite entre todos los productos.

El nombre del producto. content-desc genérico ("Product Title"), text específico ("Sauce Labs Backpack").

  • text: Sauce Labs Backpack
  • content-desc: Product Title
  • resource-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.99
  • content-desc: Product Price
  • resource-id: com.saucelabs.mydemoapp.android:id/priceTV

Mismo problema que el nombre: priceTV se repite para todos los productos.

Menú hamburguesa

Appium Inspector con menú hamburguesa seleccionado mostrando accessibility id View menu y resource-id menuIV
El menú tiene accessibility id — el locator más estable. En código: AppiumBy.accessibilityId("View menu").

El menú tiene accessibility id. Es el locator ideal.

  • content-desc: View menu
  • resource-id: com.saucelabs.mydemoapp.android:id/menuIV
  • accessibility id: View menu

Carrito

  • content-desc: Displays number of items in your cart
  • resource-id: com.saucelabs.mydemoapp.android:id/cartIV
  • accessibility id: Displays number of items in your cart

Rating (estrellas)

Appium Inspector con estrellas de rating seleccionadas mostrando LinearLayout sin accessibility id ni resource-id propio
Las estrellas no tienen ni accessibility id ni resource-id propio. Solo un LinearLayout genérico. El peor caso para locators.

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-id propio
  • 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

Appium Inspector en pantalla de Login con campo Username seleccionado mostrando resource-id nameET y class EditText
Campo Username: resource-id único (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/nameET
  • class: android.widget.EditText
  • text: (vacío)
  • Sin accessibility id

Campo Password

Appium Inspector en pantalla de Login con campo Password seleccionado mostrando resource-id passwordET y class EditText
Campo Password: misma estructura que Username. resource-id único (passwordET), sin accessibility id.
  • resource-id: com.saucelabs.mydemoapp.android:id/passwordET
  • class: android.widget.EditText
  • text: (vacío)
  • Sin accessibility id

Botón Login

Appium Inspector en pantalla de Login con botón Login seleccionado mostrando accessibility id resource-id loginBtn y text Login
El botón Login tiene todo: accessibility id, resource-id y text. Tres formas de encontrarlo.

El botón de Login tiene todo: accessibility id, resource-id y text.

  • text: Login
  • content-desc: Tap to login with given credentials
  • resource-id: com.saucelabs.mydemoapp.android:id/loginBtn
  • accessibility id: Tap to login with given credentials
  • class: android.widget.Button

Credenciales de prueba

La app muestra credenciales en la misma pantalla:

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
CSS Selector resource-id
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 id es el locator preferido en mobile (cuando existe)
  • Los resource-id se repiten entre elementos del mismo tipo (todos los productos comparten titleTV)
  • 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