Understand the four components
A test client sends WebDriver commands to the Appium server. The XCUITest driver uses WebDriverAgent (WDA) on the simulator or device to control the app. Appium Inspector helps inspect elements; it does not replace the driver or WDA signing.
The older source notes used uiautomator2 for iOS and set automationName to Chromium. Those are incorrect for a current XCUITest session, so this guide follows the official driver documentation.
Swipe the table sideways to see every column →
| Component | Role | Typical address or choice |
|---|---|---|
| Appium server | Accepts test sessions | Usually localhost:4723 |
| XCUITest driver | iOS automation | Install xcuitest |
| WebDriverAgent | Device-side bridge | 8100 is not the usual Appium endpoint |
| Appium Inspector | Inspects UI elements | Cannot fix signing |
Install and prove a simulator session first
Install compatible Node.js, Appium and Xcode versions according to the current official guide. The commands below install XCUITest, confirm it is present and start the server. Confirm driver requirements for the versions you actually install.
Use a working iOS Simulator, a test app and its bundle ID before moving to a real iPhone. Set platformName=iOS, appium:automationName=XCUITest and appium:bundleId; add appium:udid when device selection is ambiguous.
npm install -g appium
appium driver install xcuitest
appium driver list --installed
appiumCreate a modern Python session
Install an Appium Python Client version compatible with your server and driver. Use XCUITestOptions and webdriver.Remote with options=options. Replace the example bundle ID and accessibility ID with your test app values; install that app before running the script.
from appium import webdriver
from appium.options.ios import XCUITestOptions
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
options = XCUITestOptions()
options.set_capability("appium:bundleId", "com.example.TestApp")
# If several devices are available:
# options.set_capability("appium:udid", "YOUR_DEVICE_UDID")
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
try:
button = WebDriverWait(driver, 10).until(
lambda d: d.find_element(AppiumBy.ACCESSIBILITY_ID, "start-button")
)
button.click()
driver.save_screenshot("after-tap.png")
finally:
driver.quit()Swipe the table sideways to see every column →
| Old note | Current approach |
|---|---|
| Positional desired_caps | XCUITestOptions and options=options |
| find_element_by_name | Explicit AppiumBy locator |
| Device port 8100 | Appium server port 4723 for ordinary sessions |
| A wait object as a sleep | Wait for a specific condition |
- Set appium:bundleId and, if needed, appium:udid.
- Connect to the Appium server, not directly to WDA's port 8100.
- Wait for a known element with WebDriverWait and an explicit AppiumBy locator.
- Call driver.quit() in finally even when an assertion fails.
Diagnose real-device WDA failures
A real iPhone needs a development team, valid signing and a trusted test device. Follow the XCUITest provisioning guide for xcodeOrgId, xcodeSigningId or an appropriate provisioning profile. Keep UDIDs, certificates and internal bundle IDs out of public logs.
Separate a build error from signing, device trust, missing app and network forwarding failures. Save the first actionable Appium and Xcode error and fix the failing layer before changing unrelated capabilities.
Find a hybrid app's WEBVIEW
Native controls are in NATIVE_APP. Web content is available only when the XCUITest driver can expose the relevant WEBVIEW context. Check that the app has an inspectable WKWebView and that the official Safari Web Inspector prerequisites are met; wait for the context, then switch. Do not change the iOS session's automationName to Chromium.
If only NATIVE_APP appears, check page load, inspection settings and permissions. Switch back to NATIVE_APP before interacting with native controls. Prefer the app's own Back button when relevant instead of generalizing one app's driver.back() behavior to all iOS apps.
Make the test reproducible
Keep one small case: cold-start the app, wait for a known element, tap it, capture a screenshot and end the session. Record Appium, driver, Python client, Xcode, iOS and app versions. Sources checked November 6, 2026. This guide adapts an older author's note and does not claim a fresh test on the reader's device.