Metadata-Version: 2.4
Name: flowpilot-mobile
Version: 1.2.20
Summary: Modern, Intelligent Mobile Automation Framework (Compiled)
Description-Content-Type: text/markdown
Requires-Dist: pytest>=8.0.0
Requires-Dist: pytest-xdist>=3.5.0
Requires-Dist: rich>=13.0.0
Requires-Dist: loguru>=0.7.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: cryptography>=41.0.0
Requires-Dist: requests>=2.31.0
Dynamic: description
Dynamic: description-content-type
Dynamic: requires-dist
Dynamic: summary

# 🚀 FlowPilot Mobile — The Master Guide

Welcome to the world-class documentation for **FlowPilot 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)

FlowPilot 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.

```python
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`.

```python
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)**
```python
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

FlowPilot 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. FlowPilot 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:
1. Check if the element is visible.
2. If not, perform a smart swipe (Samsung optimized).
3. Retry the search.
4. Fail only after 5 failed scrolls (configurable).

### **2.3 AI Test Generation (`TEST_GEN_PROMPT.md`)**
Every project initialized with `flowpilot setup` includes a specialized AI prompt.
1. Copy the contents of `TEST_GEN_PROMPT.md`.
2. Paste it into **ChatGPT** or **Gemini**.
3. Describe your test case (e.g., "Login, then go to Profile and change name").
4. **The AI will generate a complete, valid FlowPilot 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: true` in your `flowpilot.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 `.flowpilot/screenshots/`.

---

## 🛠️ 4. Developer & Diagnostic Tools

FlowPilot 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:**
```python
mobile.inspect()
```
*Output Example:*
```text
[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:**
```python
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:**
```python
# Fill an input field to the right of the "Search" button
mobile.right_of("Search").input().fill("FlowPilot 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` | `flowpilot init` | Scaffolds a new project. |
| `setup` | `flowpilot setup --project_folder tests` | Initializes project in specific folder. |
| `--overwrite`| `flowpilot setup --overwrite` | Overwrites `flowpilot.yaml` with latest defaults. |
| `doctor` | `flowpilot doctor` | Dependency and tool path health check. |
| `devices` | `flowpilot devices` | Lists all connected device serials. |
| `interactive`| `flowpilot interactive`| **Live REPL:** Run commands one-by-one. |
| `run` | `flowpilot run` | Standard test execution. |
| `report` | `flowpilot report` | Generates/Serves HTML test report. |

---

## 📂 7. Configuration (`flowpilot.yaml`)

```yaml
# flowpilot.yaml
tools:
  adb_path: 'C:\path\to\adb.exe'
  scrcpy_path: 'C:\path\to\scrcpy.exe'
  log_path: '.flowpilot/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.

```python
import pytest
from flowpilot.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("FlowPilot 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 FlowPilot Mobile Framework | Built for Engineers.
