Modern, Intelligent Mobile Automation Framework (Compiled)
Project description
🚀 AppPilot Mobile — The Master Guide
Welcome to the world-class documentation for AppPilot Mobile. This framework is designed to be the "Playwright for Mobile" — a Python-first, human-readable automation engine that handles the complexity of mobile UI so you can focus on writing tests.
🏗️ 1. Professional Architecture (POM)
AppPilot is optimized for the Page Object Model (POM). By following this structure, your tests will be readable, maintainable, and stable.
1.1 BaseWindow — The Core Elements
Define common system-level elements (buttons, toolbars) here so every page can use them without re-locating.
class BaseWindow:
def __init__(self, mobile: Mobile):
self.mobile = mobile
# Standard buttons found across many screens
@property
def ok(self): return self.mobile.button("OK")
@property
def cancel(self): return self.mobile.button("Cancel")
@property
def save(self): return self.mobile.button("Save")
@property
def back_btn(self): return self.mobile.button("Back")
def go_back(self):
self.mobile.press_back()
return self
1.2 BasePage — Smart Synchronization
All specific app pages inherit from BasePage.
class BasePage(BaseWindow):
def __init__(self, mobile: Mobile):
super().__init__(mobile)
def wait_for_load(self):
"""Standard sync point for every page transition."""
self.mobile.wait_for_page_ready()
return self
1.3 Specific Page (e.g., SettingsPage)
class SettingsPage(BasePage):
def open_display_settings(self):
self.mobile.tap("Display")
return DisplaySettingsPage(self.mobile)
def toggle_wifi_off(self):
# Using the base button if 'Save' appears
self.mobile.checkbox("Wi-Fi").uncheck()
if self.mobile.find_text("Apply"):
self.save.tap() # Clean access to self.save from BaseWindow
🧠 2. Smart & AI-Powered Features
AppPilot goes beyond basic automation by using an Intelligent Layer to handle real-world mobile UI challenges.
2.1 Intelligent Locator Engine (Scoring)
Stop fighting with duplicate IDs or "distractor" elements. AppPilot uses a scoring engine to find exactly what you want.
- Example: If you search for "Search", it prioritizes the clickable search button and ignores "Search History" or "Search Labs" automatically.
- Priority: Accessibility ID > Visible Text > Resource ID > Content Description.
2.2 Auto-Scroll Search
Never worry if an element is off-screen. Methods like tap() and fill() will automatically:
- Check if the element is visible.
- If not, perform a smart swipe (Samsung optimized).
- Retry the search.
- Fail only after 5 failed scrolls (configurable).
2.3 AI Test Generation (TEST_GEN_PROMPT.md)
Every project initialized with apppilot setup includes a specialized AI prompt.
- Copy the contents of
TEST_GEN_PROMPT.md. - Paste it into ChatGPT or Gemini.
- Describe your test case (e.g., "Login, then go to Profile and change name").
- The AI will generate a complete, valid AppPilot Python test for you.
🖥️ 3. Live Monitoring & Evidence
3.1 Live Desktop Mirroring
See your phone's screen in a window on your desktop during execution using the integrated scrcpy support.
- Enable: Set
mirror_screen: truein yourapppilot.yaml.
3.2 Automated Evidence
- Hardware-Accelerated Recording (MP4): Every test is recorded with zero performance drop. Includes professional 1s padding.
- Smart Screenshots: Captures specific UI states into
.apppilot/screenshots/.
🛠️ 4. Developer & Diagnostic Tools
AppPilot includes powerful tools to help you debug and optimize your automation scripts in real-time.
4.1 UI Inspector (mobile.inspect())
Prints a detailed, categorized map of every element on the screen.
- Categorization: Automatically identifies
INPUT,BUTTON,TEXT,IMAGE,CHECKBOX, and more. - Precision: Includes exact screen bounds
[x1,y1][x2,y2]for every element. - Usage:
mobile.inspect()
Output Example:
[1] BUTTON: text='', desc='Google Search', id='', bounds='[45,744][182,882]', class='android.widget.Button'
[2] INPUT: text='', desc='', id='', bounds='[180,744][630,882]', class='android.widget.EditText'
4.2 Device Diagnostic (mobile.diagnose())
Provides a complete health check of the device and the automation environment.
- System Info: Model, Android version, and Serial.
- App State: Package and Activity currently in focus.
- Performance: Real-time Memory (MB) and CPU (%) usage.
- Usage:
mobile.diagnose()
4.3 Relational Selectors (Maestro-Style)
Find elements relative to other elements when they lack clear IDs or text.
- Methods:
below(),above(),left_of(),right_of(). - Usage:
# Fill an input field to the right of the "Search" button
mobile.right_of("Search").input().fill("AppPilot Mobile")
# Tap a button below a specific label
mobile.below("Username").button("Login").tap()
📊 5. Complete API Reference
| Category | Method | Example | Description |
|---|---|---|---|
| Core | tap(target) / click() |
mobile.click("Login") |
Smart tap/click with auto-scroll. |
fill(target, text) / set_text() |
mobile.set_text("User", "admin") |
Locates label and fills input. | |
clear(target) / clear_text() |
mobile.clear_text("Search") |
Wipes text from a field. | |
double_tap(t) / double_click() |
mobile.double_click("Map") |
Rapid two-tap gesture. | |
long_press(target) |
mobile.long_press("File") |
1s touch-and-hold. | |
| Diagnostics | inspect() |
mobile.inspect() |
Prints UI tree to console. |
diagnose() |
mobile.diagnose() |
Full device & app health check. | |
get_current_app() |
app = mobile.get_current_app() |
Returns package/activity. | |
get_performance() |
perf = mobile.get_performance() |
Returns CPU/Memory stats. | |
| Device Mgmt | connect_device(serial) |
mobile.connect_device("192.168.1.5:5555") |
Connects via ADB TCP/IP. |
disconnect_device() |
mobile.disconnect_device() |
Disconnects device. | |
get_device_info() |
info = mobile.get_device_info() |
OS, Model, Manufacturer. | |
install_app(path) |
mobile.install_app("app.apk") |
Installs APK. | |
uninstall_app(pkg) |
mobile.uninstall_app("com.app") |
Uninstalls package. | |
close_app(pkg) |
mobile.close_app("com.app") |
Force stops application. | |
clear_app_data(pkg) |
mobile.clear_app_data("com.app") |
Resets app state. | |
grant_permissions() |
mobile.grant_permissions(pkg, ["camera"]) |
Auto-allow permissions. | |
set_location(lat, lon) |
mobile.set_location(12.9, 77.5) |
Spoofs GPS coordinates. | |
set_orientation(mode) |
mobile.set_orientation("landscape") |
Portrait/Landscape switch. | |
| Keyboard | send_keys(text) |
mobile.send_keys("Hello") |
Direct text to focused field. |
hide_keyboard() |
mobile.hide_keyboard() |
Dismisses soft keyboard. | |
show_keyboard() |
mobile.show_keyboard() |
Forces keyboard to open. | |
press_key(key) |
mobile.press_key("ENTER") |
Hardware key (BACK, HOME, etc). | |
| Gestures | swipe(x1,y1,x2,y2) |
mobile.swipe(100,500,900,500) |
Raw coordinate movement. |
scroll_to_text(text) |
mobile.scroll_to_text("Accept") |
Scrolls until text found. | |
drag_and_drop(s, t) |
mobile.drag_and_drop("App", "Bin") |
Moves element. | |
flick(x1,y1,x2,y2) |
mobile.flick(500,800,500,200) |
Fast swipe gesture. | |
| Discovery | get_page_source() |
xml = mobile.get_page_source() |
Returns UI hierarchy XML. |
get_all_texts() |
mobile.get_all_texts_displayed() |
Returns all visible strings. | |
get_text(target) |
mobile.get_text("Title") |
Reads text from element. | |
| Media | take_screenshot(n) |
mobile.take_screenshot("err") |
Captures full screen. |
capture_element(t,n) |
mobile.capture_element_screenshot("Btn","c") |
Crops to element bounds. | |
start_recording() |
mobile.start_screen_recording() |
Captures MP4 video. | |
capture_photo() |
mobile.capture_photo() |
Shutter + Auto-OK. | |
| State | is_enabled(target) |
mobile.is_enabled("Submit") |
Clickable state check. |
is_visible(target) |
mobile.is_visible("Title") |
Visibility check. | |
| Wait | wait_for_page_ready() |
mobile.wait_for_page_ready() |
Waits for UI stability. |
wait_until_visible() |
mobile.wait_until_visible("OK") |
Polling wait until visible. | |
wait_until_gone() |
mobile.wait_until_gone("Load") |
Polling wait until vanished. | |
| Validation | verify_text(text) |
mobile.verify_text("Saved") |
Assert exact text exists. |
verify_present(t) |
mobile.verify_element_present("id") |
Assert element exists. | |
| Advanced | execute_shell() |
mobile.execute_shell_command("ls") |
Raw shell access. |
execute_adb() |
mobile.execute_adb("devices") |
Raw ADB command. | |
find_by_image() |
mobile.find_by_image_click("p.png") |
Visual Match + Click. |
🏗️ 6. CLI Tooling Reference
| Command | Example | Description |
|---|---|---|
init |
apppilot init |
Scaffolds a new project. |
setup |
apppilot setup --project_folder tests |
Initializes project in specific folder. |
--overwrite |
apppilot setup --overwrite |
Overwrites apppilot.yaml with latest defaults. |
doctor |
apppilot doctor |
Dependency and tool path health check. |
devices |
apppilot devices |
Lists all connected device serials. |
interactive |
apppilot interactive |
Live REPL: Run commands one-by-one. |
run |
apppilot run |
Standard test execution. |
report |
apppilot report |
Generates/Serves HTML test report. |
📂 7. Configuration (apppilot.yaml)
# apppilot.yaml
tools:
adb_path: 'C:\path\to\adb.exe'
scrcpy_path: 'C:\path\to\scrcpy.exe'
log_path: '.apppilot/logs' # Custom log folder
mirror_screen: true
auto_scroll: true
timeout: 30
Note for Windows Users: Always use single quotes
'for paths to avoid errors with backslashes.
🛠️ 8. Discovery & Debugging Example
When you are automating a new app and don't know the IDs, use this "Discovery Script" to find everything you need.
import pytest
from apppilot.api.mobile import Mobile
def test_discovery_session(mobile):
# 1. Launch the app and check health
mobile.launch_app("com.android.chrome")
mobile.diagnose() # Prints CPU/Memory and current Activity
# 2. Navigate to a complex page
mobile.navigate("https://www.google.com")
mobile.wait_for_page_ready()
# 3. Inspect the UI to find hidden locators
# This will print every INPUT, BUTTON, and TEXT with coordinates
mobile.inspect()
# 4. Use Relational Selectors for elements without IDs
# "Find the input to the right of the Google Search icon"
mobile.right_of("Google Search").input().fill("AppPilot Mobile")
# 5. Check performance after interaction
perf = mobile.get_performance()
print(f"Current App Memory Usage: {perf['memory_mb']} MB")
mobile.press_key(66) # Enter
mobile.screenshot("discovery_result")
© 2026 AppPilot Mobile Framework | Built for Engineers.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apppilot-1.2.21-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: apppilot-1.2.21-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 2.9 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7a50ad0de6093c8cc2c01d409ece3fa4b7d0d3b2612690471d100b61d4b1b73
|
|
| MD5 |
4df079fe1a6bbd0d6cf131805241c245
|
|
| BLAKE2b-256 |
073f4a016fb507a1ac78d7c7f06de53a7130f489c664492fe9d612a53f198ac1
|