appium-mobile
Skill2 starsChanged 3 months agoMITView on GitHub
Mobile automation with Appium: iOS and Android, gestures, device farms (BrowserStack, Sauce Labs), parallel execution, and CI/CD.
Files
SKILL.md
Appium Mobile
Mobile test automation with Appium for iOS and Android.
1. Architecture
Appium Test Suite
├── tests/
│ ├── conftest.py # Driver fixtures
│ ├── test_login.py
│ ├── test_checkout.py
│ └── pages/
│ ├── base_page.py
│ ├── login_page.py
│ └── home_page.py
├── capabilities/
│ ├── android.json # Device configs
│ └── ios.json
└── pytest.ini2. Driver Setup
# conftest.py
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.options.ios import XCUITestOptions
@pytest.fixture
def android_driver():
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "Pixel_7_API_34"
options.app = "./app/build/app-debug.apk"
options.automation_name = "UiAutomator2"
options.no_reset = False
driver = webdriver.Remote("http://localhost:4723", options=options)
yield driver
driver.quit()
@pytest.fixture
def ios_driver():
options = XCUITestOptions()
options.platform_name = "iOS"
options.device_name = "iPhone 15"
options.platform_version = "17.0"
options.app = "./app/build/ios-simulator.app"
options.automation_name = "XCUITest"
driver = webdriver.Remote("http://localhost:4723", options=options)
yield driver
driver.quit()3. Page Object Model
# pages/login_page.py
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
def find_username(self):
return self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "username")
def find_password(self):
return self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "password")
def find_login_button(self):
return self.driver.find_element(AppiumBy.ID, "com.example.app:id/login")
def login(self, user, password):
self.find_username().send_keys(user)
self.find_password().send_keys(password)
self.find_login_button().click()
def is_logged_in(self):
return self.wait.until(
EC.presence_of_element_located(
(AppiumBy.ACCESSIBILITY_ID, "welcome")
)
)4. Locators
| Strategy | Android | iOS | Best Practice |
ACCESSIBILITY_ID | content-desc | accessibilityLabel | Preferred — stable |
ID | resource-id | name (limited) | Good for unique IDs |
XPATH | Any XML path | Any XML path | Slow; use sparingly |
CLASS_NAME | android.widget.Button | XCUIElementTypeButton | For type filtering |
IOS_PREDICATE | N/A | type == 'XCUIElementTypeButton' | iOS-specific, fast |
ANDROID_UIAUTOMATOR | new UiSelector().text("OK") | N/A | Android-specific |
5. Gestures & Interactions
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput
# Tap
TouchAction(driver).tap(x=100, y=200).perform()
# Swipe / Scroll
def swipe(driver, start, end):
action = TouchAction(driver)
action.press(x=start[0], y=start[1])
action.wait(ms=500)
action.move_to(x=end[0], y=end[1])
action.release().perform()
# W3C Actions (modern)
actions = ActionBuilder(driver)
pointer = PointerInput("touch", "finger")
actions.pointer_action.move_to_location(100, 500)
actions.pointer_action.pointer_down()
actions.pointer_action.move_to_location(100, 200)
actions.pointer_action.pointer_up()
actions.perform()
# Wait for element
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(AppiumBy.ACCESSIBILITY_ID, "loading-complete")
)
)6. Device Farms
BrowserStack
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "Samsung Galaxy S23"
options.app = "bs://<app-id>"
# bs-local for local testing
from browserstack.local import Local
local = Local()
local.start({"key": BROWSERSTACK_KEY})
driver = webdriver.Remote(
f"https://{USER}:{KEY}@hub-cloud.browserstack.com/wd/hub",
options=options
)Sauce Labs
# Replace with your Sauce Labs credentials
# Endpoint format: ondemand.saucelabs.com/wd/hub
driver = webdriver.Remote(
"https://ondemand.example.com/wd/hub",
options=options
)7. Parallel Execution
# pytest-xdist with device-specific ports
pytest -n 2 --dist loadgroup \
--capabilities '{"udid": "emulator-5554"}' \
--capabilities '{"udid": "emulator-5556"}'8. CI/CD
# .github/workflows/mobile-tests.yml
name: Mobile Tests
on: [push]
jobs:
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
script: |
adb install app/build/app-debug.apk
pytest tests/ --driver=android9. Anti-Patterns
| Anti-Pattern | Fix |
| XPath without accessibility IDs | Add content-desc / accessibilityLabel |
| Hardcoded waits | Use WebDriverWait with expected conditions |
| Testing on emulators only | Run on real devices via cloud farm |
| No app state cleanup | Uninstall or clear data between tests |
| Ignoring rotation | Test landscape + portrait |
| No offline scenarios | Toggle airplane mode / network throttling |
10. Related Resources
- Skills:
android-native,playwright-e2e - Prompts:
generate-mobile-test-strategy
In this repository45 other files it gives its agents.
- AGENTS.mdAGENTS.md
- allure-reportsSkill
- android-nativeSkill
- appian-lowcodeSkill
- behave-bddSkill
- BiDiWave Cross-BrowserSkill
- BiDiWave Network InterceptionSkill
- CDPWave DebuggingSkill
- CDPWave TestingSkill
- db2-oracleSkill
- ebook-writerSkill
- flask-apiSkill
- flet-desktopSkill
- google-crawling-indexingSkill
- google-ranking-appearanceSkill
- google-seo-fundamentalsSkill
- google-seo-monitoringSkill
- jinja2-templatesSkill
- jmeter-load-testingSkill
- k6-load-testingSkill
- karate-api-testingSkill
- octane-almSkill
- paramiko-sshSkill
- postman-api-automationSkill
- prestashop-moduleSkill
- prompt-engineering-best-practicesSkill
- pytest-advancedSkill
- robot-frameworkSkill
- salesforce-devSkill
- sonarqube-quality-gatesSkill
- sql-serverSkill
- Skill NameSkill
- testcontainersSkill
- wave-ecosystem-guideSkill
- WaveXis AccessibilitySkill
- WaveXis CI/CD IntegrationSkill
- wavexis-cli-automationSkill
- wavexis-mcp-agent-integrationSkill
- WaveXis Network TestingSkill
- WaveXis Performance AuditSkill
- WaveXis Session RecordingSkill
- WaveXis Web ScrapingSkill
- webdriverioSkill
- wordpress-themesSkill
- xctest-iosSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

