Python client library for Appium mobile automation framework extending Selenium WebDriver with iOS and Android testing capabilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Application lifecycle management including installation, background/foreground control, and state querying across mobile platforms. These capabilities enable comprehensive app testing workflows and device state management.
Control application foreground/background state and query current application status across mobile platforms.
def background_app(self, seconds: int):
"""
Put the current application in background for specified time.
Args:
seconds (int): Duration to keep app in background (seconds)
Use -1 to keep in background indefinitely
"""
def activate_app(self, app_id: str):
"""
Bring application to foreground by app ID.
Args:
app_id (str): Application identifier (bundle ID for iOS, package name for Android)
"""
def terminate_app(self, app_id: str, **options):
"""
Terminate running application.
Args:
app_id (str): Application identifier
**options: Platform-specific termination options
timeout (int): Termination timeout in milliseconds
"""
def query_app_state(self, app_id: str) -> int:
"""
Query the current state of an application.
Args:
app_id (str): Application identifier
Returns:
int: Application state constant:
0 - NOT_INSTALLED
1 - NOT_RUNNING
2 - RUNNING_IN_BACKGROUND_SUSPENDED
3 - RUNNING_IN_BACKGROUND
4 - RUNNING_IN_FOREGROUND
"""Install, uninstall, and verify application presence on mobile devices.
def is_app_installed(self, bundle_id: str) -> bool:
"""
Check if application is installed on device.
Args:
bundle_id (str): Application bundle ID (iOS) or package name (Android)
Returns:
bool: True if app is installed, False otherwise
"""
def install_app(self, app_path: str, **options):
"""
Install application on device.
Args:
app_path (str): Path to application file (.apk for Android, .app/.ipa for iOS)
**options: Platform-specific installation options
replace (bool): Replace existing app if installed
timeout (int): Installation timeout in milliseconds
allowTestPackages (bool): Allow test packages (Android)
useSdcard (bool): Install on SD card (Android)
grantPermissions (bool): Grant runtime permissions (Android)
"""
def remove_app(self, app_id: str, **options):
"""
Uninstall application from device.
Args:
app_id (str): Application identifier
**options: Platform-specific removal options
keepData (bool): Keep application data after removal
timeout (int): Removal timeout in milliseconds
"""Access application strings and localized content for testing and validation.
def app_strings(self, language: str = None, string_file: str = None) -> dict:
"""
Get application strings/localized content.
Args:
language (str, optional): Language code (e.g., 'en', 'es', 'fr')
string_file (str, optional): Specific string file to read
Returns:
dict: Dictionary of string keys and localized values
"""from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.applicationstate import ApplicationState
# Setup driver
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "Android Emulator"
driver = webdriver.Remote("http://localhost:4723", options=options)
# Check if app is installed
app_id = "com.example.myapp"
if driver.is_app_installed(app_id):
print("App is already installed")
else:
# Install the app
driver.install_app("/path/to/myapp.apk", replace=True)
# Query app state
state = driver.query_app_state(app_id)
if state == ApplicationState.NOT_RUNNING:
driver.activate_app(app_id)
# Put app in background for 5 seconds
driver.background_app(5)
# Check state after backgrounding
state = driver.query_app_state(app_id)
print(f"App state: {state}")# Android installation with specific options
driver.install_app(
"/path/to/app.apk",
replace=True,
grantPermissions=True,
allowTestPackages=True,
timeout=60000
)
# iOS installation
driver.install_app("/path/to/app.ipa", replace=False)
# Verify installation success
if driver.is_app_installed("com.example.app"):
print("Installation successful")import time
from appium.webdriver.common.applicationstate import ApplicationState
def monitor_app_state(driver, app_id, duration=30):
"""Monitor app state changes over time."""
start_time = time.time()
while time.time() - start_time < duration:
state = driver.query_app_state(app_id)
if state == ApplicationState.NOT_INSTALLED:
print("App not installed")
elif state == ApplicationState.NOT_RUNNING:
print("App not running")
elif state == ApplicationState.RUNNING_IN_BACKGROUND:
print("App in background")
elif state == ApplicationState.RUNNING_IN_FOREGROUND:
print("App in foreground")
time.sleep(2)
# Usage
monitor_app_state(driver, "com.example.myapp", 60)# Get all app strings in default language
strings = driver.app_strings()
print(f"Found {len(strings)} strings")
# Get strings for specific language
spanish_strings = driver.app_strings("es")
print(f"Spanish strings: {spanish_strings}")
# Get strings from specific file
specific_strings = driver.app_strings(string_file="strings.xml")
# Use strings for validation
expected_title = strings.get("app_title", "Default Title")
actual_title = driver.find_element("id", "title").text
assert actual_title == expected_titledef multi_app_test_workflow(driver):
"""Example workflow testing multiple apps."""
apps = [
{"id": "com.example.app1", "path": "/path/to/app1.apk"},
{"id": "com.example.app2", "path": "/path/to/app2.apk"}
]
# Install all test apps
for app in apps:
if not driver.is_app_installed(app["id"]):
print(f"Installing {app['id']}")
driver.install_app(app["path"])
# Test app switching
for app in apps:
print(f"Testing {app['id']}")
# Activate app
driver.activate_app(app["id"])
# Verify app is in foreground
state = driver.query_app_state(app["id"])
assert state == ApplicationState.RUNNING_IN_FOREGROUND
# Perform app-specific tests
perform_app_tests(driver, app["id"])
# Background the app
driver.background_app(2)
# Cleanup - remove test apps
for app in apps:
if driver.is_app_installed(app["id"]):
driver.remove_app(app["id"])
def perform_app_tests(driver, app_id):
"""Placeholder for app-specific test logic."""
passfrom selenium.common.exceptions import WebDriverException
try:
# Attempt to install app
driver.install_app("/path/to/app.apk", timeout=30000)
except WebDriverException as e:
print(f"Installation failed: {e}")
# Try alternative approach
if "INSTALL_FAILED_UPDATE_INCOMPATIBLE" in str(e):
print("Removing existing app and retrying...")
driver.remove_app("com.example.app")
driver.install_app("/path/to/app.apk", replace=True)
# Safe app state checking
def safe_query_app_state(driver, app_id):
"""Safely query app state with error handling."""
try:
return driver.query_app_state(app_id)
except WebDriverException:
# App might not be installed or driver issue
return ApplicationState.NOT_INSTALLED
state = safe_query_app_state(driver, "com.example.app")# Application state constants
class ApplicationState:
NOT_INSTALLED: int = 0
NOT_RUNNING: int = 1
RUNNING_IN_BACKGROUND_SUSPENDED: int = 2
RUNNING_IN_BACKGROUND: int = 3
RUNNING_IN_FOREGROUND: int = 4
# Type definitions
AppId = str # Bundle ID (iOS) or package name (Android)
AppPath = str # File path to application binary
BackgroundDuration = int # Seconds, -1 for indefinite
AppStrings = Dict[str, str] # Localized string key-value pairs
InstallationOptions = Dict[str, Union[bool, int, str]]Install with Tessl CLI
npx tessl i tessl/pypi-appium-python-client