Skip to content

Mobile Inspector

Ghost’s mobile inspector is the killer feature — it unifies traffic inspection, UI element analysis, and traffic-UI correlation in a single tool. No competitor offers this combination.

┌──────────────────┬──────────────────┬──────────────────┐
│ │ │ │
│ Device Screen │ Element Tree │ Element Detail │
│ (live mirror) │ (hierarchy) │ │
│ │ │ Attributes │
│ Tap to select │ Searchable │ Selectors │
│ Hover highlight │ Collapsible │ Correlated │
│ Freeze/Scrub │ Color-coded │ Traffic │
│ │ Compressed │ │
│ │ │ │
└──────────────────┴──────────────────┴──────────────────┘
PlatformScreenshotElement TreeSelectorsTouch MonitorInteraction Capture
Android (ADB)screencapuiautomator dump5 strategiesgetevent parserReal-time
Android EmulatorSame as physicalSameSameSameSame
iOS Simulatorsimctl io screenshotWDA /source4 strategiesHierarchy diffingOn-demand
iOS PhysicalDeferredDeferredDeferredDeferredDeferred

Ghost automatically discovers connected devices:

  • Android: adb track-devices listener — real-time USB/WiFi device detection
  • iOS: xcrun simctl list devices --json polling — booted simulator detection
  • WDA: Automatic build + launch for iOS simulators when connecting

Devices appear in the Device Navigator in the scope panel sidebar. Click a device to open the inspector.

The device screen is mirrored via screenshot polling:

  • 1 FPS refresh rate (screenshots every ~1 second)
  • Ring buffer of 30 frames for scrubbing back in time
  • Tap on the screenshot to select the element at those coordinates
  • Hover to see element highlight overlay
  • Freeze to stop refreshing (for analysis)
  • Scrub slider to navigate screenshot history

Touch coordinates are mapped from the screenshot display to device coordinates using separate X/Y scaling ratios (critical for non-square aspect ratios). iOS WDA uses its own coordinate system that requires platform-specific translation.

The element tree shows the native view hierarchy parsed from platform-specific sources:

  • Android: uiautomator dump XML → unified element model
  • iOS: WDA /source accessibility tree XML → unified element model
  • Search — find elements by text, class, or attribute
  • Expand/Collapse — navigate the hierarchy
  • Compression — zero “container noise” (empty layout wrappers removed, +N badges show compressed children)
  • Color coding — element types color-coded (text, buttons, images, inputs)
  • Auto-refresh — 3-second polling with fingerprint-based skip (only re-renders when hierarchy changes)

Both platforms map to a common Element struct (Go type, serialized as JSON to the frontend):

type Element struct {
ID string // Unique within the tree
ClassName string // "UIButton" (iOS), "android.widget.TextView" (Android)
Text string // Visible text content
ResourceID string // Android resource-id (e.g., "com.app:id/btnCart")
AccessibilityID string // Accessibility identifier
ContentDesc string // Android content-desc
Label string // iOS accessibility label
Name string // iOS accessibility name
Value string // Current value (text fields)
Bounds Bounds // Screen coordinates {X, Y, Width, Height}
Attributes map[string]string // Extra platform-specific attributes
Children []*Element // Child elements in the hierarchy
Depth int // Nesting depth from root
Platform string // "android" or "ios"
Visible bool
Clickable bool
Enabled bool
Focused bool
Scrollable bool
Selected bool
Checked bool
Traits string // iOS only: "Button, Selected"
PackageName string // Android only
ElementCount int // Total descendant count (root only)
}

When you select an element, Ghost generates all applicable selectors with reliability scoring:

StrategyExampleReliability
accessibility_id"Add to Cart" (from content-desc attribute)Excellent
resource_id"com.example:id/btnCart"Good
content_desc"Add to Cart" (only when different from accessibility_id)OK
ui_selectornew UiSelector().className("Button").text("Add to Cart")OK
xpath//android.widget.Button[@text="Add to Cart"]Fragile
StrategyExampleReliability
accessibility_id"addToCart" (from name attribute)Excellent
predicate_stringtype == "XCUIElementTypeButton" AND label == "Add to Cart"Good
class_chain**/XCUIElementTypeButton[\label == “Add to Cart”`]`OK
xpath//XCUIElementTypeButton[@label="Add to Cart"]Fragile

Each selector can be copied in multiple automation framework formats:

FormatExample
RawDirect selector value
Appium Javadriver.findElement(MobileBy.accessibilityId("Add to Cart"))
Appium Pythondriver.find_element(AppiumBy.ACCESSIBILITY_ID, "Add to Cart")
Maestro- tapOn: "Add to Cart"
EspressoonView(withContentDescription("Add to Cart"))
XCUITestapp.buttons["addToCart"].tap()

The inspector’s most powerful feature: tap a button → see the API call it triggered.

Correlation uses:

  • Time window: ±3 seconds between interaction and flow
  • Relevance ranking: Closer in time = higher relevance
  • Static asset filtering: CDN/image/font requests excluded
  • Deduplication: Multiple touches on same element don’t multiply

Ghost monitors /dev/input/ events via adb getevent:

  • Tap detection (touch down + up within threshold)
  • Scroll detection (multi-touch movement)
  • Long press detection (sustained contact)
  • Raw coordinate → pixel conversion using input device calibration
  • Hierarchy hit-testing to identify the tapped element

Ghost polls the hierarchy every 2.5 seconds and diffs snapshots:

  • Value changes — text field content changed
  • Text changes — labels updated
  • Screen changes — new screen appeared
  • State changes — element enabled/disabled/visibility

From the inspector, press Cmd+B to generate a premium bug report:

  1. Instant loading — overlay opens immediately with skeleton
  2. AI-enhanced — LLM analyzes device context, interactions, and traffic
  3. Screenshot GIF — animated replay from the ring buffer (30 frames, 0.25x scale)
  4. Repro steps — auto-generated from interaction timeline
  5. Network waterfall — timing chart of related API calls
  6. Mermaid diagram — sequence diagram of the user flow
  7. Editable — modify title, description, repro steps before export
  8. Export — Markdown, HTML (standalone with embedded images), Jira, JSON

See Bug Reports for full details.

ActionDescription
Select modeClick screenshot to select element
Tap modeClick screenshot to send tap to device
Freeze/ResumePause screenshot updates
RefreshForce hierarchy refresh
ScreenshotSave current frame
Bug ReportGenerate premium bug report (Cmd+B)
Text InputType text into the focused field on device