Appium Driver¶
jumpstarter-driver-appium gives every UI-automation target the same
Appium client interface. Test code opens
WebDriver sessions on one URL with the capabilities the target provides,
whether the target is a physical device, an emulator or a simulator, on Android
or iOS.
Appium is Jumpstarter’s default UI-automation framework: one WebDriver API for
every platform it supports, an official Python client that installs with pip,
and nothing to install on the client beyond that client library. See
Appium UI Automation for the reasons in full and
for setting up an exporter.
Target drivers add an appium child built on AppiumDriver. It runs an
operator-installed Appium on the exporter for each lease, listening on exporter
loopback only, and clients reach it over the lease through verified HTTPS.
Installation¶
$ pip3 install --extra-index-url https://pkg.jumpstarter.dev/simple jumpstarter-driver-appium
The exporter needs Node.js, Appium and the Appium drivers for its targets, such as UiAutomator2 or XCUITest. Containerized exporters usually pin them in their image; see Appium UI Automation for an example. Jumpstarter does not bundle, download or build Appium, its drivers or WebDriverAgent.
To use the Python examples below, install Appium-Python-Client on the client. The client does not need Appium itself.
Configuration¶
Target drivers usually create the appium child and fix the capabilities
that identify their device. AppiumDriver can also be configured directly:
export:
appium:
type: jumpstarter_driver_appium.driver.AppiumDriver
config:
executable: /opt/appium/node_modules/.bin/appium
home: /opt/appium/home
drivers: [uiautomator2]
capabilities:
platformName: Android
appium:automationName: UiAutomator2
appium:udid: emulator-5554
Parameter |
Description |
Default |
|---|---|---|
|
Appium launcher, resolved on the exporter’s |
|
|
|
none |
|
Appium drivers to load; all installed ones when empty |
|
|
Capabilities fixed on every session; clients cannot override them |
|
|
Extra environment for Appium, such as |
|
|
Existing directory for the lease’s private state |
system temporary directory |
|
Seconds to wait for Appium to become ready |
|
|
Largest application a client may upload |
4 GiB |
Usage¶
from appium import webdriver
from appium.options.common import AppiumOptions
from jumpstarter.common.utils import env
with env() as root, root.appium.serve() as target:
options = AppiumOptions().load_capabilities(target.capabilities())
driver = webdriver.Remote(target.url, options=options, client_config=target.client_config())
try:
print(driver.page_source)
finally:
driver.quit()
serve() starts the lease’s Appium on first use and yields an AppiumTarget:
url: a loopback HTTPS address that reaches the exporter’s Appium.capabilities(): the capabilities the target fixes, such asplatformNameandappium:udid; add your own before opening a session. Host paths stay on the exporter and are not shown.client_config(): an Appium-Python-Client configuration that trusts the lease’s certificate authority. Usessl_context()orca_filewith other clients. Certificate and hostname verification stay enabled.environment(): the caller’s environment plusJUMPSTARTER_APPIUM_URL,JUMPSTARTER_APPIUM_CAPABILITIES(JSON),JUMPSTARTER_APPIUM_CA_FILEand Node’sNODE_EXTRA_CA_CERTS, for tools written in other languages.
Closing the block removes the listener. Appium keeps running until stop(),
reset or the end of the lease.
Applications¶
Appium on the exporter cannot read files on the client, so upload applications first and pass the returned token where Appium expects an application:
token = root.appium.upload_app("build/MyApp.ipa") # or target.upload_app(...) inside serve()
options.set_capability("appium:app", token)
# or later, inside a session:
driver.execute_script("mobile: installApp", {"app": token})
upload_app() accepts .apk, .aab, .apks, .ipa and .zip files and
.app bundles, which it zips first. Uploads last until reset or the end of the
lease.
Command line¶
Inside a jmp shell, with the child named appium:
j appium # print url, ca_file and capabilities until Ctrl+C
j appium -- pytest tests/ui # run a command with environment()
j appium upload build/MyApp.ipa # print an application token
j appium stop
Security and limits¶
A lease holder controls the target through Appium, so the driver keeps Appium from reaching beyond it:
Appium binds exporter loopback, starts with every insecure feature denied and no plugins, and gets a private
HOME.Capabilities the target driver fixes replace any value a client sends.
Capabilities whose string values name files, directories, executables or URLs (for example
appium:chromedriverExecutableorappium:mjpegScreenshotUrl), theproxycapability and anyremotePathargument are rejected, so clients cannot make the exporter read its files or contact other hosts.app,otherAppsandappPathaccept only tokens fromupload_app().
Appium runs as a child process of the exporter, in the exporter’s container, so the rules above, not a container boundary, are what keep a lease to its device. Keep exporter images to what the targets need, and reset or re-provision devices between untrusted tenants. See Appium UI Automation for an overview of every target.
API Reference¶
- class jumpstarter_driver_appium.driver.AppiumDriver¶
Run an operator-installed Appium on the exporter for one lease.
Appium listens on exporter loopback only and is reached through the lease over verified HTTPS. Target drivers subclass it to add the capabilities they fix at runtime, or configure
capabilitiesdirectly.
- class jumpstarter_driver_appium.client.AppiumClient¶
Open Appium sessions on a leased target, wherever its driver runs Appium.
- info() dict¶
Start the target’s Appium if needed and describe it.
- serve(*, port: int = 0) Generator[AppiumTarget, None, None]¶
Expose the target’s Appium on a loopback HTTPS port for the length of the block.
port=0picks an unused port. Closing the block removes the listener and the CA file; the exporter keeps Appium running untilstop(), power off, reset or the end of the lease.
- stop() None¶
Stop the target’s Appium; the next session starts a fresh one.
- upload_app(path: str | PathLike) str¶
Upload an application for this lease and return the token to use as
appium:app.Accepts
.apk,.aab,.apks,.ipaand.zipfiles and.appbundles, which are zipped first. The token also works as theappargument ofmobile: installApp. Uploads last until reset or the end of the lease.
- class jumpstarter_driver_appium.common.AppiumTarget¶
An Appium server for one leased target, valid inside its context.
Open WebDriver sessions on
urlwithcapabilities(), and give applications fromupload_app()asappium:app. Where Appium runs is the driver’s choice: on the exporter, reached over the lease, or on this machine for targets only it can reach. Sessions behave the same either way.- capabilities() dict[str, Any]¶
W3C capabilities for a session on this target; add your own before use.
- client_config(**kwargs)¶
An Appium-Python-Client
AppiumClientConfigthat trusts this target.Needs the
Appium-Python-Clientpackage, which Jumpstarter does not install.
- environment(base: Mapping[str, str] | None = None) dict[str, str]¶
Copy the environment and describe this target to a tool in another language.
Adds
JUMPSTARTER_APPIUM_URL,JUMPSTARTER_APPIUM_CAPABILITIES(JSON) and, for HTTPS targets,JUMPSTARTER_APPIUM_CA_FILEand Node’sNODE_EXTRA_CA_CERTS. Certificate verification stays enabled.
- ssl_context() SSLContext | None¶
Python’s normal trust plus this target’s CA, or None for plain HTTP.
- upload_app(path: str | PathLike) str¶
Make an application available to this target; returns the token to use as
appium:app.The token also works as the
appargument ofmobile: installApp.
Targets that only the client can reach, such as an iOS device shown through
Device Hub, run the user’s installed Appium on the client instead and yield the
same AppiumTarget. They put the same policy in front of it, so sessions accept
the same capabilities and upload_app() tokens as on the exporter:
- jumpstarter_driver_appium.local.local_appium(executable: str = 'appium', *, env: Mapping[str, str] | None = None, timeout: float = 60.0) Generator[str, None, None]¶
Run the user’s installed Appium on a loopback port and yield its URL.
Appium uses the caller’s environment, so its
APPIUM_HOMEand installed drivers apply. It stops when the context closes.