A Java-based Appium test automation project with a built-in Runtime Element Inspector that automatically displays element information when NoSuchElementException occurs - similar to Appium Inspector but directly in your terminal!
-
Automatic Element Inspector: When an element is not found, the inspector automatically:
- Captures the current page source (XML hierarchy)
- Finds the closest matching element using a smart scoring algorithm
- Displays multiple locator suggestions (accessibility id, id, uiautomator, xpath)
- Shows all element attributes in a formatted table
- Prints the parent XML block for context
-
Colorful Terminal Output: Uses ANSI colors for easy reading
-
Enable/Disable Toggle: Turn inspector on/off as needed
-
TestNG Integration: Ready-to-use test framework
| Tool | Version | Description |
|---|---|---|
| JDK | 17+ | Java Development Kit |
| Maven | 3.8+ | Build and dependency management |
| Appium | 2.x | Mobile automation server |
| Android SDK | Latest | Android platform tools |
| Node.js | 18+ | Required for Appium |
| Android Emulator/Device | Any | Test target device |
Appium_Runtime_Inspector/
βββ pom.xml # Maven configuration
βββ testng.xml # TestNG suite configuration
βββ README.md # This file
βββ src/
βββ main/java/
β βββ base/
β β βββ BaseTest.java # Base test class with Inspector integration
β βββ utilities/
β βββ AndroidElementInspector.java # The main Inspector class
βββ test/java/
βββ tests/
βββ ApiDemosTest.java # Example test cases
<!-- Appium Java Client 8.6.0 (includes Selenium) -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>8.6.0</version>
</dependency>
<!-- TestNG 7.10.2 -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.10.2</version>
</dependency># Install Node.js (macOS)
brew install node
# Install Appium
npm install -g appium
# Install UiAutomator2 driver
appium driver install uiautomator2
# Verify installation
appium --version# Set ANDROID_HOME environment variable
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools
# Verify ADB
adb devicesDownload and install the ApiDemos-debug.apk on your emulator/device:
adb install ApiDemos-debug.apkappium --base-path /wd/hub# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=ApiDemosTestThe AndroidElementInspector is the core feature of this project. When a NoSuchElementException occurs during test execution, it automatically:
- Captures Page Source: Gets the current XML hierarchy from the Android driver
- Parses XML: Converts the page source to a DOM Document
- Extracts Search Term: Parses the failed locator to extract the search term
- Finds Best Match: Uses a scoring algorithm to find the closest matching element
- Prints Results: Displays formatted output with locator suggestions and attributes
The inspector uses a weighted scoring system to find the best match:
| Match Type | Points |
|---|---|
| Exact match (text/content-desc/resource-id) | 1000 |
Resource-id ends with :id/search |
900 |
Resource-id ends with /search |
800 |
| Text/content-desc contains search | 500 |
| Resource-id contains search | 400 |
| Class name contains search | 300 |
| Prefix similarity | 5 per char |
When an element is not found, you'll see output like this:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π ANDROID ELEMENT INSPECTOR β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β οΈ EXCEPTION: NoSuchElementException
π TARGET LOCATOR: By.xpath: //*[@text='Aksesibiliti']
β
CLOSEST MATCHING ELEMENT FOUND
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Find By Selector β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β -android uiautomator new UiSelector().text("Accessibility") β
β xpath //TextView[@text="Accessibility"] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Attribute Value β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β index 0 β
β package io.appium.android.apis β
β class android.widget.TextView β
β text Accessibility β
β content-desc - β
β resource-id - β
β enabled true β
β bounds [0,210][1080,273] β
β displayed true β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π¦ XML Block (Parent: ListView) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β <ListView> β
β <TextView text="Accessibility"/> β
β <TextView text="Animation"/> β
β <TextView text="App"/> β
β ... β
β </ListView> β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
You can control the inspector programmatically:
// Disable inspector output
AndroidElementInspector.setEnabled(false);
// Enable inspector output (default)
AndroidElementInspector.setEnabled(true);
// Check current status
boolean isEnabled = AndroidElementInspector.isEnabled();The BaseTest class automatically integrates the inspector with all element finding methods:
// These methods automatically trigger Inspector on NoSuchElementException
findElement(By locator) // Single element
findElements(By locator) // Multiple elements (triggers on empty list)
waitAndFind(By locator) // Wait + find (triggers on timeout)
findByText(String text) // Find by text attribute
findById(String resourceId) // Find by resource-idThe project includes 5 test cases:
| Test | Description |
|---|---|
testAccessibilityNavigation |
Navigate to Accessibility category |
testViewsButtonsNavigation |
Navigate to Views > Buttons |
| Test | Description |
|---|---|
testInspector_NoSuchElement_1 |
Search with wrong resource-id |
testInspector_NoSuchElement_2 |
Search with typo in text |
testInspector_NoSuchElement_3 |
Search with wrong XPath |
Default: http://127.0.0.1:4723/wd/hub
To change, edit BaseTest.java:
private static final String APPIUM_SERVER_URL = "http://YOUR_IP:PORT/wd/hub";Edit BaseTest.java to change the target app:
.setAppPackage("your.app.package")
.setAppActivity("your.app.MainActivity")| Error | Solution |
|---|---|
Connection refused |
Start Appium server: appium --base-path /wd/hub |
Response code 404 |
Add /wd/hub to server URL |
No device found |
Check adb devices and start emulator |
App not installed |
Install ApiDemos-debug.apk on device |
# Check Appium
appium --version
# Check connected devices
adb devices
# Check Java
java -version
# Check Maven
mvn -versionMIT License
Created for Android test automation with runtime element inspection capability.