بنقرة واحدة
appium-automation-contract
Appium launch contract, start routes, state presets, and wrong-screen test debugging.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Appium launch contract, start routes, state presets, and wrong-screen test debugging.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use this skill to generate well-branded interfaces and assets for RIPDPI (an Android-native, Compose-first VPN and DPI-bypass app), either for production or throwaway prototypes/mocks/etc. Contains essential design guidelines, colors, type, fonts, brand-ship icons, and an interactive UI kit of every public composable from the live ui/components tree.
Use when managing the Rust workspace, adding/removing crates, editing workspace dependencies, running cargo nextest/audit/deny, configuring Cargo profiles for Android cross-compilation, debugging Cargo.lock churn, migrating crate edition, or wiring Gradle to cargo via the ripdpi.android.rust-native plugin.
Use when modifying the diagnostics scan pipeline, ScanRequest/ScanReport types, ProbeTask families, ripdpi-monitor-engine / ripdpi-diagnostics-* crates, strategy-probe candidates, the diagnostics catalog (packs/profiles), wire-schema contracts between Rust and Kotlin, DIAGNOSTICS_ENGINE_SCHEMA_VERSION, golden contract tests, or adding a new probe type / profile. Triggers on diagnostics scans, strategy probes, automatic audit, dpi-detector profiles, or anything in core/diagnostics or native/rust/crates/ripdpi-monitor-*.
Android-specific Rust build, verification, and packaging — per-target 16 KiB page alignment, size-optimized release profile, ELF symbol allowlist, .so size budgets, NDK 29 specifics. Use when modifying .cargo/config.toml for Android targets, the workspace [profile.release] / [profile.android-jni] block, or when verifying a built .so before release.
Telemetry and observability discipline for the RIPDPI Android Rust stack — control-plane vs data-plane logging, bounded flume event queues, atomic counters, snapshot polling, readiness callbacks, and deterministic JSON contracts. Use when authoring or modifying telemetry emission code, the bounded event ring, the Kotlin-side telemetry consumer, or any per-packet logging.
Custom detekt rules, DI/privacy/suppression guardrails, detekt.yml configuration, and false-positive triage.
| name | appium-automation-contract |
| description | Appium launch contract, start routes, state presets, and wrong-screen test debugging. |
The automation contract launches the app directly to a specific screen with controlled state, bypassing normal navigation. It is the foundation for every Appium test.
Source of truth: Kotlin AutomationLaunchContract.kt in app/src/main/kotlin/com/poyka/ripdpi/automation/.
Python mirror: appium/lib/launch_contract.py.
conftest.py::launch_app (autouse fixture)
1. Read @pytest.mark.automation(...) kwargs from test
2. adb am force-stop com.poyka.ripdpi
3. sleep 0.5s (process teardown settle)
4. adb am start -n com.poyka.ripdpi/.activities.MainActivity \
--ez com.poyka.ripdpi.automation.ENABLED true \
--es com.poyka.ripdpi.automation.START_ROUTE {route} \
... (remaining extras)
5. wait_for_element(driver, "{route}-screen", timeout=15)
6. yield (test runs)
7. Screenshot on failure -> screenshots/{test_name}.png
| Python Constant | Extra Key | Type | Default | Purpose |
|---|---|---|---|---|
ENABLED | ...automation.ENABLED | bool | true | Activate automation mode |
RESET_STATE | ...automation.RESET_STATE | bool | true | Clear persisted state before launch |
DISABLE_MOTION | ...automation.DISABLE_MOTION | bool | true | Disable Compose animations |
START_ROUTE | ...automation.START_ROUTE | string | "home" | Target screen |
PERMISSION_PRESET | ...automation.PERMISSION_PRESET | string | "granted" | Simulated permission state |
SERVICE_PRESET | ...automation.SERVICE_PRESET | string | "idle" | Simulated service state |
DATA_PRESET | ...automation.DATA_PRESET | string | "clean_home" | Pre-populated data fixtures |
All extras are prefixed with com.poyka.ripdpi.automation..
| Route | Screen Resource ID | Typical data_preset |
|---|---|---|
home | home-screen | clean_home |
onboarding | onboarding-screen | clean_home |
config | config-screen | settings_ready |
diagnostics | diagnostics-screen | diagnostics_demo |
history | history-screen | settings_ready |
logs | logs-screen | settings_ready |
settings | settings-screen | settings_ready |
mode_editor | mode_editor-screen | settings_ready |
dns_settings | dns_settings-screen | settings_ready |
advanced_settings | advanced_settings-screen | settings_ready |
about | about-screen | settings_ready |
data_transparency | data_transparency-screen | settings_ready |
app_customization | app_customization-screen | settings_ready |
| Value | Simulates |
|---|---|
granted | All permissions granted (default) |
vpn_missing | VPN permission not granted |
notifications_missing | Notification permission not granted |
battery_review | Battery optimization not disabled |
| Value | Simulates |
|---|---|
idle | Service not running (default) |
connected_proxy | Proxy service connected |
connected_vpn | VPN service connected |
live | Live connection with real service |
| Value | Simulates |
|---|---|
clean_home | Fresh install state (default) |
settings_ready | Settings populated, configs available |
diagnostics_demo | Demo diagnostic data pre-loaded |
# Minimal -- all defaults (home screen, granted, idle, clean_home)
@pytest.mark.automation()
def test_home_loads(driver): ...
# Deep-link to sub-screen with populated data
@pytest.mark.automation(
start_route="dns_settings",
data_preset="settings_ready",
)
def test_dns_plain_save(driver): ...
# Permission-denied scenario
@pytest.mark.automation(
start_route="home",
permission_preset="vpn_missing",
)
def test_vpn_permission_banner(driver): ...
# Connected state testing
@pytest.mark.automation(
start_route="home",
service_preset="connected_vpn",
data_preset="clean_home",
)
def test_connected_vpn_stats(driver): ...
All parameters are keyword-only. Omitted params use defaults shown in the Intent Extras table.
Route sealed classAutomationLaunchContract.kt to navigate to the new screenModifier.testTag("{route}-screen") on the screen's root composable@pytest.mark.automation(start_route="{route}") in the Python testconftest.py wait (wait_for_element(driver, f"{route}-screen", timeout=15)) works automatically| Mistake | Fix |
|---|---|
Forgetting reset_state=True | Previous test's data leaks in. Default is True -- only set False if intentionally preserving state. |
Wrong data_preset for the screen | Screen renders empty or missing elements. Match route to its typical preset (see table above). |
Omitting disable_motion=True | Animations cause timing issues, especially in CI. Default is True -- only set False to test animations. |
start_route value not in Kotlin Route | App silently falls back to home screen. Verify the route exists in Route.kt. |
Screen resource-id doesn't match {route}-screen | wait_for_element times out on launch. The convention is {route}-screen. |
Testing connected state with service_preset="idle" | Stats/metrics cards won't be visible. Use connected_vpn or connected_proxy. |
.github/skills/appium-test-authoring/SKILL.md -- How to write tests using the automation marker.github/skills/appium-test-debug/SKILL.md -- Troubleshooting when launch fails.github/skills/android-device-debug/SKILL.md -- Raw ADB commands for device interaction