RanorexSpy: How Ranorex's Object Recognition Engine Works

RanorexSpy: How Ranorex's Object Recognition Engine Works

RanorexSpy is the element inspection tool at the core of Ranorex's test automation framework. Before you can automate any UI action — clicking a button, reading a text field, validating a state — you need to identify the element reliably. RanorexSpy is how you do that.

Understanding RanorexSpy well is the difference between a test suite that works consistently and one that breaks every time a developer touches the UI.

What Is RanorexSpy?

RanorexSpy is a UI inspector that can examine the element tree of any running application: Windows desktop apps, web browsers, Android devices, and iOS simulators. You point RanorexSpy at a UI element, it shows you the complete element hierarchy and all available attributes, and you capture the element as a test object stored in the Repository.

The result is a RanorexPath — a structured selector that uniquely identifies the element. This path is what Ranorex uses at test runtime to find and interact with the element.

How to Use RanorexSpy

Launching RanorexSpy

From Ranorex Studio: Tools → RanorexSpy, or press F5 while a recording module is open.

RanorexSpy opens as a separate window. Your cursor becomes a crosshair when you move over trackable applications.

Capturing an Element

  1. Move your mouse over the target element in the running application
  2. The element highlights with a colored border; RanorexSpy shows the element hierarchy
  3. Press F4 (or click Track) to capture the element
  4. RanorexSpy displays:
    • Element tree — the full parent/child hierarchy from root to the selected element
    • Properties panel — all attributes of the selected element
    • Generated path — Ranorex's auto-generated RanorexPath for this element

Understanding the Element Tree

For a WPF application button:

Form 'MainWindow' (class: MainWindow)
  └── Grid 'root' 
       └── StackPanel 'btnPanel'
            └── Button 'btnSubmit' [text: "Submit", automationId: "btn-submit"]

For a web element in Chrome:

Browser (domain: app.example.com, title: "My App")
  └── Document
       └── Form (id: "login-form")
            └── Button (id: "btn-submit", class: "primary-btn", innertext: "Log In")

The tree shows you the full path from the application root to your element. Every node in this path can be used as part of the RanorexPath selector.

RanorexPath Syntax

RanorexPath uses a syntax similar to XPath but adapted for Ranorex's cross-platform element model.

Basic structure

/element-type[@attribute='value']/child-element-type[@attribute='value']

Desktop example (WPF button):

/form[@title='MainWindow']/button[@automationid='btn-submit']

Web example (Chrome):

/dom[@domain='app.example.com']//button[@id='btn-submit']

Mobile example (Android):

/mobileapp[@packagename='com.example.myapp']//button[@text='Submit']

Path operators

/ — direct child
// — any descendant (skips levels)
.. — parent element

Using // creates more resilient paths — a button found anywhere under the domain is better than one that must be at a specific nesting level that might change.

Attribute selectors

You can combine multiple attributes:

/dom[@domain='app.example.com']//button[@id='btn-submit' and @visible='True']

Or use partial matching:

/dom[@domain='app.example.com']//button[contains(@class, 'submit-')]

Or use ordinal position (less stable, use as last resort):

/dom[@domain='app.example.com']//button[3]

Choosing Good Locators

RanorexSpy generates paths automatically, but the auto-generated path isn't always the most stable. Here's how to evaluate what you're getting.

Attributes in order of stability

  1. automationId (desktop) / id (web) — set by developers, stable across builds, best choice
  2. name / accessibilityId — often stable, meaningful
  3. class + text combination — moderately stable
  4. text / innertext alone — breaks when copy changes
  5. position/index — breaks when siblings are added or reordered

Flags for unstable generated paths

Auto-generated paths that include these are likely to break:

// BAD: position-based — breaks when new items are added
/form[@title='MainWindow']//listitem[4]

// BAD: auto-generated ID — unique per session, not per element
//div[@id='ember1234']

// BAD: full class string — breaks on any CSS refactor
//button[@class='btn btn-primary btn-lg disabled active']

Fix these by editing the path in RanorexSpy to use stable attributes:

// BETTER: automationId (set by developer)
//button[@automationid='submit-order']

// BETTER: partial class match
//button[contains(@class, 'btn-primary')]

// BETTER: text content (if text is stable)
//button[@innertext='Submit Order']

Editing a Path in RanorexSpy

After capturing an element, edit the path directly in the RanorexPath input field in the bottom panel. Press Enter to evaluate — RanorexSpy highlights the element the path resolves to. If nothing highlights, the path doesn't match anything in the current UI.

This real-time validation is one of RanorexSpy's most useful features. You can iterate on the path until it reliably identifies exactly the element you want.

Working with Complex UI Scenarios

Web: Dynamic IDs

Many web frameworks (Ember, React in some configurations) generate IDs dynamically:

<button id="ember1842">Submit</button>

That ID changes every session. Use a data attribute or text content instead:

//button[@data-testid='submit-order']
//button[@innertext='Submit Order']

Best practice: ask your developers to add data-testid attributes to elements that need to be tested. This creates a stable, test-explicit locator that survives CSS and DOM refactors.

Desktop: Multiple Windows

When your application opens dialogs or secondary windows, the RanorexPath needs to identify the correct window context:

/form[@title='Confirm Delete' and @visible='True']/button[@text='OK']

The @visible='True' constraint ensures you're targeting the active dialog, not a hidden background window with the same title.

Mobile: Device-Specific Elements

Mobile elements may differ between device models or OS versions. If your path includes a class name that's device-specific, use accessibilityId or text instead:

// Less portable
//view[@class='android.widget.EditText' and @bounds='[0,200][1080,300]']

// More portable
//textfield[@hint='Email address']

Repository Best Practices

Once captured in RanorexSpy, elements are stored in the Repository. How you organize this determines long-term maintainability.

Name elements descriptively:

  • Bad: Button1, TextBox3
  • Good: BtnSubmitOrder, InputEmailAddress

Group by page/screen:

Repository
├── LoginPage
│   ├── InputEmail
│   ├── InputPassword
│   └── BtnSubmit
├── Dashboard
│   ├── LabelWelcome
│   └── NavMenuItems
└── Checkout
    ├── InputCardNumber
    └── BtnPlaceOrder

Add multiple locator strategies. For each element, add 2–3 alternative paths ranked by stability. Self-healing uses these alternatives when the primary path fails.

Review generated paths after recording. Don't trust auto-generated paths in production tests without reviewing them. Spend 5 minutes in RanorexSpy validating each path looks stable.


Understanding element locators is important for any test automation tool. HelpMeTest handles element identification automatically — write what you want to test, and the platform figures out the selectors.

Start now free