Troubleshooting
Known Problems¶
- Real devices with iOS/iPadOS 15+ show an overlay with the text
Automation Running Hold both volume buttons to stop
while WebDriverAgent is running. This is a known limitation of the XCTest framework. Note that screenshotting functionality is not affected (i.e. the overlay is not visible on taken screenshots). - Real devices with iOS/iPadOS 15+ require passcode or Touch ID when starting a new session. A workaround for this is to disable passcode/Touch ID on the device.
- After many failures on a real device, it could transition to a state where connections are no longer being accepted. Rebooting the device can help remedy this problem. Please read this issue for more details.
shake
is implemented via AppleScript and works only on Simulator due to lack of support from Apple
Interact with dialogs managed by com.apple.springboard
¶
System dialogs, such as permission dialogs, might not be interactable directly when the active application is not com.apple.springboard
.
Despite a similar look, dialogs belonging to the active session application (e.g. initially passed as appium:app
or appium:bundleId
capability value)
do not require such adjustment.
XCUITest driver offers a couple of approaches to handle them:
- Set the respectSystemAlerts setting to
true
. It enforces the active application detection algorithm to check a presence of system alerts and to return the Springboard app if this check succeeds. Such approach emulates the driver behavior prior to version 6 of XCUITest driver, although it might slightly slow down your scripts because each attempt to detect an active app would require to also query for alerts presence. - Start a session without
appium:app
norappium:bundleId
. Then XCUITest driver attempts to get the current active application. This requires you to start an application after a new session request withmobile: installApp
to install an app if needed andmobile: launchApp
/mobile: activateApp
, but it could automatically change the active application withcom.apple.springboard
or activate an application at the foreground. (Note that the automatic app detection might be lengthy, thus each action could take more time.)- When a permission alert exists at the foreground, it could select the
com.apple.springboard
- When another application is at the foreground by accepting/denying the system alert, or
mobile: activateApp
, the application would be selected as an active application.
- When a permission alert exists at the foreground, it could select the
mobile: alert
defaultActiveApplication
setting in Settings.- e.g. With the Appium Ruby client
- Enable
appium:autoAcceptAlerts
/appium:autoDismissAlerts
, or interact with alerts via User Prompts in WebDriver endpoints- e.g.
driver.switch_to.alert.accept
with the Appium Ruby client - It might be necessary to coordinate element selection via
acceptAlertButtonSelector
/dismissAlertButtonSelector
settings in Settings
- e.g.
- Activate
com.apple.springboard
withmobile: activateApp
before interacting with dialogs
mobile: activeAppInfo
helps to understand what application (bundleId) is considered as active for the XCUITest driver.
Interact with dialogs managed by com.apple.ContactsUI.LimitedAccessPromptView
¶
iOS 18 introduced a new process named com.apple.ContactsUI.LimitedAccessPromptView
. See this issue for more details.
As of XCUITest driver v7.26.4, the only workaround to interact with views available through the process is the below method:
defaultActiveApplication
setting in Settings.- e.g. With the Appium Ruby client
# Interacting with the test target driver.settings.update({defaultActiveApplication: "com.apple.ContactsUI.LimitedAccessPromptView"}) # to accept the alert driver.find_element("accessibility_id", "Select Contacts").click driver.settings.update({defaultActiveApplication: "auto"}) # keep interacting with the test target
- e.g. With the Appium Ruby client
The com.apple.ContactsUI.LimitedAccessPromptView
process can get elements available through com.apple.springboard
, such as several system permission dialogs.
iOS 18+ devices may be possible to use com.apple.ContactsUI.LimitedAccessPromptView
to interact with elements managed either by com.apple.ContactsUI.LimitedAccessPromptView
or com.apple.springboard
.
Leftover Application Data on Real Devices¶
There might be a situation where application data is present on the real device, even if the application itself is not installed. This could happen if:
- The app is in an offloaded state
- The application state is cached
- There was an unexpected failure while installing the app. An example of such failure is the
ApplicationVerificationFailed
which happens while installing an app signed with an invalid provisioning profile.
In the above cases, the application identifier will not be listed in the output of
mobile: listApps
, and it will not be detected
by mobile: isAppInstalled
. Setting
appium:fullReset
or appium:enforceAppInstall
capabilities to true
also will not help clear this data.
The only way to completely get rid of the cached application data is to call the
mobile: removeApp
command with the appropriate
bundle identifier.
The driver does automatically try to resolve application installs that failed because of the
MismatchedApplicationIdentifierEntitlement
error. However, in cases when the previously installed
application's provisioning profile is different from what currently the driver is trying to
install, and if you explicitly set the driver to not perform application uninstall, then consider
calling mobile: removeApp
before the
MismatchedApplicationIdentifierEntitlement
error occurs. Example steps can be as follows:
- Start a session without
appium:app
andappium:bundleId
capabilities - Call
mobile: removeApp
for the target application's bundle id - Install the test target with
mobile: installApp
- Launch the application with
mobile: launchApp
ormobile: activateApp
Weird State¶
Real Device Stops Responding¶
Running tests on a real device is particularly flakey. If things stop responding, the only recourse is, most often, to restart the device. Logs in the form of the following may start to occur:
info JSONWP Proxy Proxying [POST /session] to [POST http://10.35.4.122:8100/session] with body: {"desiredCapabilities":{"ap..."
dbug WebDriverAgent Device: Jul 26 13:20:42 iamPhone XCTRunner[240] <Warning>: Listening on USB
dbug WebDriverAgent Device: Jul 26 13:21:42 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - Unable to update application state promptly. <unknown> 0 1
dbug WebDriverAgent Device: Jul 26 13:21:57 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - Failed to get screenshot within 15s <unknown> 0 1
dbug WebDriverAgent Device: Jul 26 13:22:57 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - App state of (null) is still unknown <unknown> 0 1
Command Takes 60+ Seconds¶
Sometimes it is possible to encounter slowdowns for an additional 60 seconds for a command that
usually should not take long. This may be caused by a crash in the testmanagerd
process on the
device under test. In such case, the OS tries to restore the process, then wait for the resurrected
daemon to connect to the target process, which causes the aforementioned delay.
This can be fixed by terminating the target application process. For example, if this behavior
occurs while calling mobile: queryAppState
, you can terminate the application once, or restart the
device entirely. Please check this pull request
for more details.
Real Device Security Settings¶
On some systems, especially CI ones, where tests are executed by command line agents, macOS
Accessibility restrictions result in the WebDriverAgent process being unable to retrieve the
development keys from the system keychain. This usually manifests by xcodebuild
returning error
code 65
. One workaround for this is to use a private key that is not stored on the system
keychain. See this issue and
this Stack Exchange post.
To export the key, use
security create-keychain -p [keychain_password] MyKeychain.keychain
security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A
where MyPrivateKey.p12
is the private development key exported from the system keychain.
You can then use the appium:keychainPath
and
appium:keychainPassword
capabilities to pass this
keychain to WebDriverAgent.
Simulator Resetting¶
When testing on simulators, the driver tries to leave the simulator state as it found it:
- If no
udid
is provided, the driver will create a new iOS simulator, run tests on it, and then delete the simulator - If a specific
udid
is provided for a simulator that is not running, the driver will boot the specified simulator, run tests on it, and then shut the simulator down - If a specific
udid
is provided for a simulator that is running, the driver will connect to the existing simulator, run tests, and then leave the simulator running
You can use the appium:noReset
capability to adjust this behavior: setting it to true
will
leave the simulator running at the end of a test session.
Caching Issues During Build¶
Testing on iOS generates files that can sometimes get large. These include logs, temporary files, and derived data from Xcode runs, all of which are safe to delete if any issues arise. The files are usually found in the following locations, should they need to be deleted:
Frequent Disconnecting from remote debugger
error in iOS 17¶
Please try out iOS 17.6 or a newer version which includes a possible fix by Apple.
Frequent Web Inspector debugger disconnection started since iOS 17.2 (or iOS 17.0), that eventually caused Disconnecting from remote debugger
error.
It could be improved since iOS 17.6.
Please check the corresponding pull request for more details.