Metadata-Version: 2.4
Name: flowpilot-mobile
Version: 1.2.16
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):
        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):
        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
```

### **1.4 TestBase — The Testing Foundation**
Use a base class for your test files to share the `mobile` instance.

```python
class TestBase:
    @pytest.fixture(autouse=True)
    def setup_app(self, mobile):
        self.mobile = mobile
        self.settings = SettingsPage(mobile)
        # Global setup before every test
        mobile.launch_app("com.android.settings")
```

---

## 🧠 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 Zero-Sleep Synchronization**
FlowPilot eliminates `time.sleep()`. Every interaction includes a built-in polling mechanism that waits for the UI to be ready, the element to be clickable, and the keyboard to be dismissed before proceeding.

### **2.4 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 (Mac/Windows) 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 hardware encoding (zero performance drop). Includes professional 1s padding.
- **Smart Screenshots**: Captures specific UI states into `.flowpilot/screenshots/`.
- **Retention Policy**: Automatically purges recordings older than **5 days** (configurable) to save disk space.

---

## 📊 4. 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. |
| **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. |
| | `press_home()` | `mobile.press_home()` | Returns to device home screen. |
| | `press_back()` | `mobile.press_back()` | Simulates hardware back button. |
| | `toggle_wifi(state)`| `mobile.toggle_wifi(False)` | Turns Wi-Fi ON/OFF. |
| | `toggle_bluetooth(state)`| `mobile.toggle_bluetooth(True)`| Turns Bluetooth ON/OFF. |
| | `set_location(lat, lon)`| `mobile.set_location(12.9, 77.5)`| Spoofs GPS coordinates. |
| | `set_orientation(mode)`| `mobile.set_orientation("landscape")`| Rotates screen. |
| **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. |
| | `flick(x1,y1,x2,y2)` | `mobile.flick(500,800,500,200)`| Fast swipe/flick gesture. |
| | `scroll_to_text(text)`| `mobile.scroll_to_text("Accept")`| Scrolls down until text is found. |
| | `drag_and_drop(s, t)`| `mobile.drag_and_drop("App", "Bin")`| Moves one element to another. |
| | `pinch()` / `zoom()` | `mobile.pinch()` | Multi-touch mock (limited by shell). |
| | `open_notifications()`| `mobile.open_notifications()` | Reveals system notification tray. |
| **Discovery** | `inspect()` | `mobile.inspect()` | Prints UI tree to console. |
| | `get_page_source()` | `xml = mobile.get_page_source()`| Returns full UI hierarchy XML. |
| | `find_element(target)` | `mobile.find_element("Title")` | Waits and checks for element. |
| | `get_all_texts()` | `mobile.get_all_texts_displayed()`| Returns all visible strings. |
| | `get_text(target)` | `mobile.get_text("Title")` | Reads text from an 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. |
| | `stop_recording()` | `mobile.stop_screen_recording("run")`| Stops MP4 video capture. |
| | `capture_photo()` | `mobile.capture_photo()` | Triggers Camera + Auto-OK. |
| **State** | `is_enabled(target)` | `mobile.is_enabled("Submit")` | Boolean check for clickable state. |
| | `is_visible(target)` | `mobile.is_visible("Title")` | Boolean check for visible state. |
| | `is_checked(target)` | `mobile.checkbox("A").is_checked()`| Returns True/False state. |
| **Wait** | `wait_for_page_ready()`| `mobile.wait_for_page_ready()` | Waits for UI to stop moving. |
| | `wait_until_visible()` | `mobile.wait_until_visible("OK")`| Polling wait until visible. |
| | `wait_until_clickable()`| `mobile.wait_until_clickable("OK")`| Polling wait until enabled. |
| | `wait_until_gone()` | `mobile.wait_until_gone("Load")`| Polling wait until vanished. |
| **Validation** | `verify_text(text)` | `mobile.verify_text("Saved")` | Asserts exact text exists. |
| | `verify_present(t)` | `mobile.verify_element_present("id")`| Asserts element exists in UI. |
| **Advanced** | `execute_shell_command()`| `mobile.execute_shell_command("ls")`| Raw shell access on device. |
| | `execute_adb()` | `mobile.execute_adb("devices")`| Raw adb command from host. |
| | `find_by_image_click()`| `mobile.find_by_image_click("p.png")`| **Visual Match** and click. |

---

## 🏗️ 5. CLI Tooling Reference

FlowPilot comes with a powerful CLI to manage your environment and execute tests. Use `flowpilot <command> --help` for detailed argument lists.

### **5.1 General Commands**
| Command | Example | Description |
| :--- | :--- | :--- |
| `init` | `flowpilot init` | Scaffolds a new project with folders and `flowpilot.yaml`. |
| `setup` | `flowpilot setup` | Interactive wizard to configure `adb` and `scrcpy` paths. |
| `doctor` | `flowpilot doctor` | Performs a health check of your dependencies and tool paths. |
| `devices` | `flowpilot devices` | Lists all connected Android/Physical device serials. |
| `interactive`| `flowpilot interactive`| **Live REPL:** Run commands one-by-one on your device. |

### **5.2 Running Tests**
| Command | Example | Description |
| :--- | :--- | :--- |
| `run` | `flowpilot run` | Standard test execution (wrapper for pytest). |
| `-n <count>` | `flowpilot run -n 4` | **Parallel Execution:** Runs tests on up to 4 devices. |
| `-s` | `flowpilot run -s` | Shows live console output from tests. |
| `report` | `flowpilot report` | Generates/Serves the latest HTML test report. |

---

## 🛠️ 6. Advanced Feature Deep Dive

### **6.1 Smart Locators (Relational)**
Stop using fragile XPaths. Target elements by their position relative to others.

```python
# Tap the input box BELOW the "Email Address" label
mobile.below("Email Address").input().tap()

# Fill the input box to the RIGHT OF "Zip Code"
mobile.right_of("Zip Code").fill("560001")
```

### **6.2 Specialized Components**
```python
# Dropdowns / Spinners
mobile.dropdown("Language").select(option="English") # By Text
mobile.dropdown("Theme").select(index=1)            # By Index

# Checkboxes & Radios (State-Aware)
mobile.checkbox("Terms").check()   # Only taps if NOT already checked
mobile.radio("Option 1").uncheck() # Only taps if NOT already unchecked

# Signature Drawing (Real Gesture)
mobile.signature.on("Signature Pad").draw() # Multi-stroke realistic scribbling
```

### **6.3 "On-The-Fly" Diagnostics**
Monitor logs and network without stopping your test.

```python
# Start background capture
mobile.start_log_capture(path="project/logs/debug.log")

# ... do stuff ...

# Read logs for a specific event while they are still being captured
auth_logs = mobile.get_logs(filters=["AuthToken", "Exception"])

# Check API calls
calls = mobile.get_api_calls()
```

---

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

Control your environment globally or per-command.

### **Global Config**
```yaml
# flowpilot.yaml
tools:
  adb_path: "/opt/homebrew/bin/adb"
  scrcpy_path: "/opt/homebrew/bin/scrcpy"
  log_path: ".flowpilot/logs"  # Default folder for all captures
```

### **Manual Path Injection**
If you need a specific log file for a single test:
```python
mobile.start_log_capture(path="tests/evidence/login_run.log")
```

---

## 💡 8. Pro-Tips for Freshers
1.  **Never Use `time.sleep()`:** Use `mobile.wait_for_page_ready()` or `mobile.wait_until_visible()`. They are faster and more reliable.
2.  **Use `inspect()`:** If you don't know the name/ID of a button, call `mobile.inspect()` to see exactly how the framework sees the screen.
3.  **Visual Matching:** For games or custom icons without text, use `mobile.find_by_image_click("assets/icon.png")`.
4.  **Implicit Execution:** Most methods queue commands. They execute either when you call a "Synchronous" method (like `verify_text`) or at the end of the test. To force immediate action, call `mobile.execute()`.

---

© 2026 FlowPilot Mobile Framework | Built for Engineers.
