diff --git a/5.14/guides/run-preinstalled-wda/index.html b/5.14/guides/run-preinstalled-wda/index.html index fc636b27e..6593f0564 100644 --- a/5.14/guides/run-preinstalled-wda/index.html +++ b/5.14/guides/run-preinstalled-wda/index.html @@ -2324,8 +2324,8 @@
Warning
-This method currently does not work for iOS 17/tvOS 17 due to platform changes. Please use the
-default xcodebuild
approach.
This method currently does not work natively for iOS 17/tvOS 17 due to platform changes.
+Please use the default xcodebuild
approach or 3rd party tools such as pymobiledevice3
.
Some 3rd party tools such as ios-deploy, -go-ios and +
Some 3rd party tools such as pymobiledevice3, +ios-deploy, go-ios and tidevice can install the WebDriverAgent package.
The WDA app package (WebDriverAgentRunner-Runner.app
) can be generated in the derivedDataPath
directory, as explained in Manual Configuration for a Generic Device.
@@ -2440,7 +2440,7 @@
appium:prebuiltWDAPath
- 2024-01-18
+ 2024-01-29
diff --git a/5.14/search/search_index.json b/5.14/search/search_index.json
index c914f5b0d..d80c3ec70 100644
--- a/5.14/search/search_index.json
+++ b/5.14/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome","text":"Welcome to the Appium XCUITest Driver documentation! The XCUITest driver is a test automation framework for iOS, iPadOS and tvOS devices, enabling automated black-box testing of native, hybrid and WebKit web apps, on both emulators and real devices.
The XCUITest driver is part of the Appium test automation tool. For information on Appium itself, please visit the Appium documentation.
"},{"location":"#explore-the-documentation","title":"Explore the Documentation","text":"Contributions to this project are welcome! To start off, clone it from GitHub and run:
npm install\n
To watch changes during development:
npm run watch\n
To run unit/functional tests:
npm run test # unit \nnpm run e2e-test # functional\n
To develop documentation:
npm run install-docs-deps # install the dependencies (Python packages)\nnpm run dev:docs # serve the docs locally and watch for changes\n
There are also a number of environment variables that can be used when running the tests locally. These include:
REAL_DEVICE
- set to anything truthy, makes the tests use real device capabilities_FORCE_LOGS
- set to 1
to get the log output, not just specPLATFORM_VERSION
- change the version to run the tests against (defaults to 11.3
)XCCONFIG_FILE
- specify where the Xcode config file is for a real device run (if blank, and running a real device test, it will search for the first file in the root directory of the repo with the extension .xcconfig
)UICATALOG_REAL_DEVICE
- path to the real device build of UICatalog, in case the npm
installed one is not built for a real device* implemented but intentionally not supported
** not implemented handlers
"},{"location":"endpoints/","title":"Endpoints","text":""},{"location":"endpoints/#appium-ios-jsonwp-endpoints","title":"Appium iOS JSONWP Endpoints","text":""},{"location":"endpoints/#session-less-commands","title":"Session-less commands","text":"method endpoint req params opt params GET /status POST /session desiredCapabilities requiredCapabilities GET /sessions"},{"location":"endpoints/#session-commands","title":"Session commands","text":"method endpoint req params opt params GET /:sessionId DELETE /:sessionId POST /timeouts type, ms POST /timeouts/async_script ms POST /timeouts/implicit_wait ms GET /window_handle GET /window_handles GET /url POST /url url POST /forward none POST /back none POST /refresh none POST /execute script, args POST /execute_async script, args GET /screenshot POST /frame id POST /window name DELETE /window GET /window/:windowhandle/size GET /cookie POST /cookie cookie DELETE /cookie DELETE /cookie/:name GET /source GET /title POST /element using, value POST /elements using, value POST /element/active none POST /element/:elementId/element using, value POST /element/:elementId/elements using, value POST /element/:elementId/click none POST /element/:elementId/submit none GET /element/:elementId/text none POST /element/:elementId/value value POST /keys value GET /element/:elementId/name POST /element/:elementId/clear none GET /element/:elementId/selected GET /element/:elementId/enabled GET /element/:elementId/attribute/:name GET /element/:elementId/equals/:otherId GET /element/:elementId/displayed GET /element/:elementId/location GET /element/:elementId/location_in_view GET /element/:elementId/size GET /element/:elementId/css/:propertyName GET /orientation POST /orientation orientation GET /alert_text POST /alert_text text POST /accept_alert none POST /dismiss_alert none POST /click button POST /touch/click element POST /touch/flick element, xspeed, yspeed, xoffset, yoffset, speed GET /location POST /location location POST /log type GET /log/types GET /context POST /context name GET /contexts POST /touch/perform actions POST /touch/multi/perform actions elementId POST /receive_async_response status, value"},{"location":"endpoints/#appium-specific-commands","title":"Appium-specific commands","text":"method endpoint req params opt params POST /appium/device/shake none GET /appium/device/system_time POST /appium/device/lock seconds POST /appium/device/rotate x, y, radius, rotation, touchCount, duration element POST /appium/device/remove_app appId or bundleId POST /appium/device/hide_keyboard strategy, key, keyCode, keyName POST /appium/device/push_file path, data POST /appium/device/pull_file path POST /appium/device/pull_folder path POST /appium/simulator/touch_id match POST /appium/app/launch none POST /appium/app/close none POST /appium/app/background seconds POST /appium/app/strings language, stringFile POST /appium/element/:elementId/value value POST /appium/receive_async_response response"},{"location":"overview/","title":"Overview","text":"The XCUITest driver combines several different technologies to achieve its functionality:
appium-ios-device
libraryappium-ios-simulator
libraryThe XCUITest driver provides the appium:webDriverAgentUrl
capability to attach to a running WebDriverAgent (WDA) application. This works for real devices and simulators, but the primary usage is for real devices.
appium:webDriverAgentUrl
capabilityPlease read Manage WebDriverAgent by Yourself and Real Device Configuration about how to prepare WDA for a real device.
The appium:webDriverAgentUrl
value should be the WDA URL: http://<reachable ip address for the device>:8100
. If the environment has port-forward to the connected device, it can be http://localhost:8100
.
{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:udid\": \"<device udid>\",\n \"appium:deviceName\": \"iPhone\",\n \"appium:webDriverAgentUrl\": \"http://<reachable ip address for the device>:8100\"\n}\n
This method allows you to manage the WDA process by yourself. The XCUITest driver then simply attaches to the WDA process, which may improve the application performance.
Some XCUITest driver APIs (for example, mobile: calibrateWebToRealCoordinatesTranslation) might still require the port number of the remote device if it is a real device. Providing the appium:webDriverAgentUrl
capability might not be sufficient to recognize the remote port number, in case it is different from the local one. Consider settings the appium:wdaRemotePort
capability in such cases, to supply the driver with the appropriate data.
Appium XCUITest driver provides a possibility to record iOS audio stream and save it to a file, which could be then retrieved on the client side. Apple does not provide any API to directly retrieve the audio stream from a Simulator or a real device, but it is possible to redirect that stream to the host machine, where it could be captured.
mobile: startAudioRecording
mobile: stopAudioRecording
ffmpeg
installed and added to PATH. It can be installed via brew
: brew install ffmpeg
.For macOS 10.15+, applications recording Microphone audio need to be explicitly granted this permission. This can be done in the following settings menu:
Ensure that either ffmpeg
itself or the parent Appium process (e.g. Terminal) is present in that list.
As this is a potentially insecure feature, it must be explicitly allowed on the server side. See the Appium documentation on Security for more details. The feature name is audio_record
.
The following steps are necessary to setup iOS Simulator audio capture:
ffmpeg -f avfoundation -list_devices true -i \"\"
to get the identifier of the Soundflower (2ch)
device. This identifier prefixed with :
will be then used as audioInput
argument to mobile: startAudioRecording
call-i
argument value with the one you got from the previous step: ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n
After 5 seconds, a file named out.mp4
should be created on your desktop, containing the recorded audio stream.The following steps are necessary to setup iOS Real Device audio capture:
open -a /System/Applications/Utilities/Audio\\ MIDI\\ Setup.app
Enable
next to itffmpeg -f avfoundation -list_devices true -i \"\"
to get the identifier of your device in the AVFoundation audio devices
list. This identifier prefixed with :
will be then used as audioInput
argument to mobile: startAudioRecording
call-i
argument value with the value you got from the previous step: ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n
After 5 seconds, a file named out.mp4
should be created on your desktop, containing the recorded audio stream.Note
Apple does not allow phone calls to be redirected this way. You can only record application or system sounds.
"},{"location":"guides/audio-capture/#further-reading","title":"Further Reading","text":"Setting up the XCUITest driver in an automated environment brings a few challenges with it. Any scenario where user interaction is required must be automated or avoided altogether. For real device setup, you should first follow the Real Device Configuration tutorial.
"},{"location":"guides/ci-setup/#keychains","title":"Keychains","text":"One common scenario is a prompt asking for a keychain to be unlocked in order to sign the WebDriverAgent. There are multiple possible solutions for this:
It is recommended to go with the second or third option. The third one is the easiest and most reliable one to set up, at the cost of having to set the keychain password as an environment variable.
"},{"location":"guides/ci-setup/#xcode","title":"Xcode","text":"When setting up a new machine as a CI server, you are probably going to install Xcode, without executing it once, because you are not going to use it for development. Make sure to start Xcode at least once and do the initial set up and install the suggested extensions.
"},{"location":"guides/ci-setup/#linking-apple-account","title":"Linking Apple Account","text":"This only applies for real device set up. Make sure to link your 'Apple Developer Account' in the machine's system wide \"Account Panel\" when using the \"Basic Automatic Configuration\" described here.
"},{"location":"guides/ci-setup/#troubleshooting","title":"Troubleshooting","text":"Enable the appium:showXcodeLog
capability and check the Appium server output.
Working with the clipboard on real devices has an Apple security limitation, where the WebDriverAgentRunner application must be in foreground in order for the action to work. Otherwise an empty string is always returned, or it could raise an exception like this issue.
Consider using mobile: activateApp
and mobile: backgroundApp
to change the foreground application.
Applies to iOS 13+ real devices. You can also use mobile: getPasteboard
for simulators.
# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Get the clipboard content\ndriver.get_clipboard\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n
"},{"location":"guides/clipboard/#set-clipboard","title":"Set Clipboard","text":"Applies to iOS 15+ real devices. You can also use mobile: setPasteboard
for simulators.
# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Set the clipboard content\ndriver.set_clipboard(content: 'happy testing')\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n
"},{"location":"guides/file-transfer/","title":"File Transfer","text":"The XCUITest driver provides several extension commands for file transfer:
mobile: pullFolder
mobile: pullFile
mobile: pushFile
mobile: deleteFolder
mobile: deleteFile
This documentation aims to help to understand how they work on iOS.
"},{"location":"guides/file-transfer/#formats","title":"Formats","text":"All commands require a parameter with a path to the file/folder on the target device. There are 3 possible formats this path can take:
"},{"location":"guides/file-transfer/#format-1","title":"Format 1","text":"@<app-bundle-id>:<container-type>/<path-to-file-or-folder>\n
@<app-bundle-id>
is the application bundle identifier<container-type>
is the container typeapp
, data
, groups
, but a custom one can also be provideddocuments
. All others are treated as Format 2UIFileSharingEnabled
flag set to true
. You can use the mobile: listApps
extension to identify such apps.<path-to-file-or-folder>
is the target file or folder<container-type>
is set to documents
, this path will be mapped to On My iPhone/<app name>
in the Files app@<app-bundle-id>/<path-to-file-or-folder>\n
<container-type>
is set to app
.UIFileSharingEnabled
flag set to true
in their info.plist
can be mounted. You can use the mobile: listApps
extension to identify such apps.<path-to-file-or-folder>\n
This format is only supported on simulators. The implicit <container-type>
is set to app
. Eventually the whole simulator file system is available directly from the macOS Finder, so you may pull any file from there by providing a path to it relatively to the simulator's file system root.
pullFile
","text":"This example pulls a file present in Files -> On My iPhone -> Keynote:
Top On My iPhone Keynote JS (WebdriverIO)Rubylet data = driver.pullFile('@com.apple.Keynote:documents/Presentation.key');\nawait fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_file '@com.apple.Keynote:documents/Presentation.key'\nFile.open('presentation.key', 'wb') { |f| f<< file }\n
If the file is in deeper place like Keynote/Dir1/Dir2, then the path changes:
JS (WebdriverIO)Rubylet data = driver.pullFile('@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key');\nawait fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_file '@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key'\nFile.open('presentation.key', 'wb') { |f| f<< file }\n
Example for a simulator using Format 3:
// Java\n// Get AddressBook.sqlitedb in test app package ('app' container)\nbyte[] fileContent = driver.pullFile(\"Library/AddressBook/AddressBook.sqlitedb\");\nPath dstPath = Paths.get(new File(\"/local/path/AddressBook.sqlitedb\"));\nFiles.write(dstPath, fileContent);\n
"},{"location":"guides/file-transfer/#pullfolder","title":"pullFolder
","text":"You can pull folders similarly to files, but the path must end with a forward slash (/
).
let data = driver.pullFolder('@com.apple.Keynote:documents/');\nawait fs.writeFile('documents.zip', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_folder '@com.apple.Keynote:documents/'\nFile.open('documents.zip', 'wb') { |f| f<< file }\n
"},{"location":"guides/file-transfer/#pushfile","title":"pushFile
","text":"JS (WebdriverIO)Ruby driver.pushFile('@com.apple.Keynote:documents/text.txt', new Buffer(\"Hello World\").toString('base64'));\n
@driver.push_file '@com.apple.Keynote:documents/text.txt', (File.read 'path/to/file')\n
"},{"location":"guides/file-transfer/#references","title":"References","text":"iOS uses the Events concept to handle signals received from different input devices. An Event is an object generated in response to a signal from an input device. These objects are then delivered to the corresponding kernel subsystem, which processes them and notifies all listening processes about taps, key presses, swipes, etc. This means that in order to emulate a signal generated by an external device, such as a touch screen, it is necessary to just send Event objects with the same properties and in the same sequence as they would be generated by a real device.
"},{"location":"guides/input-events/#simulating-a-single-tap","title":"Simulating a Single Tap","text":"The Events API itself is a part of Apple private API, and it is neither open sourced nor documented. The XCTest framework also does not expose any public APIs for input events generation, although there is a possibility to perform events generation via XCTest private undocumented APIs.
In particular, we are interested in the XCPointerEventPath
and XCSynthesizedEventRecord
interfaces. These APIs allow to create chains of input events and supply them to the system kernel for execution.
In order to synthesize a single tap, it is necessary to:
XCPointerEventPath
instance and initialize it for touch at the starting pointliftUp
event at 0.125s
offset using liftUpAtOffset:
methodXCSynthesizedEventRecord
instance using addPointerEventPath:
methodsynthesizeWithError:
method of XCSynthesizedEventRecord
instance and control the returned errorThere are several limitations to these APIs:
XCPointerEventPath
instance can only be executed for a single action. If one tries to add, for example, two taps to a single path, then these are effectively ignoredXCPointerEventPath
instance can only be initialized for a particular pointer type: touch, mouse (since Xcode 10.2) or keyboard (since Xcode 10.2)XCPointerEventPath
instanceUnfortunately, because the API is private and has zero documentation, one can only figure out what it can do by playing with it and trying different input combinations.
It is known that providing multiple XCPointerEventPath
instances with overlapping timeouts will generate a multitouch action with the amount of fingers equal to the amount of the supplied event paths. So, in order to generate two-finger symmetric swipe we need to supply the following events:
XCPointerEventPath
instances and init them for touch at the starting pointmoveToPoint
event at 0.525s
offset using moveToPoint:
method to each pathliftUp
eventa at 0.525s
offset using liftUpAtOffset:
method to each pathXCSynthesizedEventRecord
instance using addPointerEventPath:
methodsynthesizeWithError:
method of XCSynthesizedEventRecord
instance and control the returned errorUnfortunately, there is no information on this topic at all (private API \u00af\\_(\u30c4)_/\u00af
). Consider visiting the following resources:
Unfortunately, Apple does not provide any command line options which can help to install self-signed certificate on a real device or simulator. However, there is over-the-air enrollment technology, which allows the deployment of several entity types, including such certificates, by simply downloading specially prepared configuration files with the built-in web browser. After the configuration is downloaded it can be installed and trusted by going through several simple wizard steps.
You can use the following extension methods to assist with this:
mobile: installCertificate
mobile: removeCertificate
If you have multiple Xcode installations, you may choose which toolset Appium should use with one of two ways:
"},{"location":"guides/multiple-xcode-versions/#xcode-select-tool","title":"xcode-select
tool","text":"Only available with sudo
privileges, affects the whole system.
Assuming you want to choose /Applications/Xcode13.app
:
sudo xcode-select -s /Applications/Xcode13.app/Contents/Developer\n
appium\n
No privileges needed, affects only the current shell, so Appium should be started within that shell.
Assuming you want to choose /Applications/Xcode12.app
:
DEVELOPER_DIR
environment variable export DEVELOPER_DIR=/Applications/Xcode12.app/Contents/Developer\n
appium\n
It is possible to execute tests in parallel using XCUITest driver. Appium allows to do this on a per-process (multiple server processes running on different ports managing single session) or a per-request basis (single server process managing multiple sessions, more preferable, uses less resources and ensures better control over running sessions).
Note
If you are not going to run your tests in parallel, consider enabling the --session-override
Appium server argument. It forces the server to close all pending sessions before a new one could be opened, which allows you to avoid possible issues with such sessions silently running/expiring in the background.
udid
must be a unique device UDID for each parallel session.wdaLocalPort
must be a unique port number for each parallel session. The default value is 8100
.derivedDataPath
set the unique derived data path root for each driver instance. This will help to avoid possible conflicts and to speed up the parallel execution.mjpegServerPort
must be a unique port number for each parallel session if you are going to record a video stream from it. The default value is 9100
.udid
, which is the unique simulator UDID for each parallel session (it could be retrieved from xcrun simctl list
command output), or a unique combination of deviceName
and platformVersion
capabilities to identify the appropriate simulator with the given name and version number for each parallel session.wdaLocalPort
must be a unique port number for each parallel session. The default value is 8100
.derivedDataPath
set the unique derived data path root for each driver instance. This will help to avoid possible conflicts and to speed up the parallel execution.mjpegServerPort
must be a unique port number for each parallel session if you are going to record a video stream from it. The default value is 9100
.The XCUITest driver runs xcodebuild
to build and install the WebDriverAgentRunner (WDA) app on the target device. You can manually run a modified version of this command in order to prebuild the WDA.
xcodebuild
Works","text":"By default, xcodebuild
is run with two commands: build-for-testing
and test-without-building
. build-for-testing
builds a test bundle package, whereas test-without-building
actually runs it.
For instance, XCUITest driver issues an xcodebuild
command like so:
xcodebuild build-for-testing test-without-building \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n
This translates to xcodebuild
building WebDriverAgent.xcodeproj
and running the resulting package on the specified device.
The command can be split into build-for-testing
and test-without-building
parts as follows:
xcodebuild build-for-testing \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n
xcodebuild test-without-building \\\n -xctestrun wda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\"\n
The build-for-testing
command generates two files: an .app
package and an .xctestrun
file, e.g.:
wda_build/Build/Products/Debug-iphonesimulator/WebDriverAgentRunner-Runner.app\nwda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun\n
The .xctestrun
file name depends on the -destination
preference. The file contains metadata about the package (the DependentProductPaths
key).
The test-without-building
command starts the WDA application for testing by referencing the provided .xctestrun
file. Once this is done, http://localhost:8100
will be able to receive commands for the target device.
The XCUITest driver provides two capabilities that allow skipping the build-for-testing
command, and executing only the test-without-building
command: appium:useXctestrunFile
and appium:bootstrapPath
(see Capabilities).
Note
These capabilities expect that the WDA files are already prebuild, so make sure to first run xcodebuild
to create the files.
This method can be used on both real devices and simulators, but real devices requires proper signing as described in Run Preinstalled WebDriverAgentRunner. We recommend using this method for real devices.
The capabilities can be used as follows:
{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:deviceName\": \"iPhone 12\",\n \"appium:useXctestrunFile\": true,\n \"appium:bootstrapPath\": \"/path/to/wda_build/Build/Products\"\n}\n
Not all combinations have been tested, but the target device can probably be anything.
The same thing can be achieved with the appium:derivedDataPath
and appium:usePrebuiltWDA
capabilities, but this may fail if xcodebuild
cannot find or handle the .xctestrun
file properly. The stability depends on Xcode.
The Appium WebDriverAgent GitHub page provides downloads for WebDriverAgent packages for real devices. They do not have embedded XCTest frameworks.
The Release and Building WebDriverAgent workflows may help with validating the build script.
"},{"location":"guides/run-preinstalled-wda/","title":"Run Preinstalled WebDriverAgentRunner","text":"The XCUITest driver can be configured to launch an already-installed WebDriverAgentRunner-Runner
application (WDA) on a real device. This allows you to start a session without the xcodebuild
command execution, improving the session startup performance.
Warning
This method currently does not work for iOS 17/tvOS 17 due to platform changes. Please use the default xcodebuild
approach.
appium:usePreinstalledWDA
appium:updatedWDABundleId
appium:prebuiltWDAPath
Running a test for the WDA package in Xcode is the easiest way to prepare the device environment:
appium driver run xcuitest open-wda
if using XCUITest driver 4.13 or newerIf using a real device, you may need to change your bundle ID. Please check the Full Manual Provisioning Profile setup for details.
"},{"location":"guides/run-preinstalled-wda/#using-3rd-party-tools","title":"Using 3rd Party Tools","text":"Some 3rd party tools such as ios-deploy, go-ios and tidevice can install the WebDriverAgent package.
The WDA app package (WebDriverAgentRunner-Runner.app
) can be generated in the derivedDataPath directory, as explained in Manual Configuration for a Generic Device. The app can then be installed without xcodebuild
using the 3rd party tools.
After installing the WebDriverAgentRunner-Runner
application, you can start the Appium server and launch an XCUITest driver session with the specified capabilities:
appium\n
# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:updatedWDABundleId\": \"com.appium.WebDriverAgentRunner\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n
If the <udid>
device has a WebDriverAgent package with com.appium.WebDriverAgentRunner.xctrunner
bundle ID, the session will launch the WebDriverAgent process without xcodebuild
.
Note
Please ensure that the WDA application is launchable before starting an XCUITest driver session. For example, check whether the provisioning profile is trusted.
"},{"location":"guides/run-preinstalled-wda/#set-appiumprebuiltwdapath","title":"Setappium:prebuiltWDAPath
","text":"If the appium:prebuiltWDAPath
capability is provided with a properly signed WebDriverAgentRunner-Runner.app
test bundle, the XCUITest driver will install the application and launch it every test session. Test bundles cannot be versioned using CFBundleVersion
as vanilla applications do, which is why it is necessary to (re)install them for every test session.
Usually you can find the WDA application bundle at the below location if you use Xcode to build it.
~/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\n
You can then set your Appium capabilities as follows:
# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:prebuiltWDAPath\": \"/path/to/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n
Note
As of iOS 17, the testmanagerd service name has changed from com.apple.testmanagerd
to com.apple.dt.testmanagerd.runner
. It causes an unexpected WDA process crash with embedded XCTest frameworks while running a single WebDriverAgent package on various OS environments without xcodebuild
.
Since WDA v5.10.0, the module can refer to the device's local XCTest frameworks. It lets the Appium/WebDriverAgent package use proper dependencies for the device with a single prebuilt WebDriverAgent package. To set this up, you should remove the package internal frameworks from WebDriverAgentRunner-Runner.app
with rm -rf WebDriverAgentRunner-Runner.app/Frameworks/XC*.framework
. The WDA package itself is available from https://github.com/appium/WebDriverAgent.
The XCUITest driver has the capability to simulate Touch ID.
Note
This functionality is only supported on simulators.
"},{"location":"guides/touch-id/#configuration","title":"Configuration","text":"To use Touch ID, the application that Appium launches from (Terminal, iTerm, etc.) must be added to the accessibility preferences on your Mac. Navigate to System Preferences -> Privacy & Security -> Accessibility and under Allow the apps below to control your computer add the application.
Why this is needed: The only way Appium can enable enrollment and toggling of Touch ID is to use system-level accessibility APIs to simulate mouse clicks on the simulator menus via AppleScript.
"},{"location":"guides/touch-id/#usage","title":"Usage","text":"appium:allowTouchIdEnroll
to true
.mobile: enrollBiometric
extensionNote
Remember that not all iOS devices have Touch ID, so your tests should handle cases where Touch ID is not supported.
"},{"location":"guides/troubleshooting/","title":"Troubleshooting","text":""},{"location":"guides/troubleshooting/#known-problems","title":"Known Problems","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).shake
is implemented via AppleScript and works only on Simulator due to lack of support from AppleThere 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:
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:
appium:app
and appium:bundleId
capabilitiesmobile: removeApp
for the target application's bundle idmobile: installApp
mobile: launchApp
or mobile: activateApp
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...\"\ndbug WebDriverAgent Device: Jul 26 13:20:42 iamPhone XCTRunner[240] <Warning>: Listening on USB\ndbug 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\ndbug 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\ndbug 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\n
"},{"location":"guides/troubleshooting/#command-takes-60-seconds","title":"Command Takes 60+ Seconds","text":"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.
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\nsecurity import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A\n
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.
When testing on simulators, the driver tries to leave the simulator state as it found it:
udid
is provided, the driver will create a new iOS simulator, run tests on it, and then delete the simulatorudid
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 downudid
is provided for a simulator that is running, the driver will connect to the existing simulator, run tests, and then leave the simulator runningYou 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.
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:
$HOME/Library/Logs/CoreSimulator/*\n$HOME/Library/Developer/Xcode/DerivedData/*\n
"},{"location":"guides/tvos/","title":"tvOS Support","text":"The XCUITest driver supports automation of the tvOS platform.
Warning
Apple TV 4K is not supported. This is because appium-ios-device
, which is used to support low-level communication with devices, only supports devices connected via USB.
You can run tests for tvOS by setting the platformName
capability to tvOS
:
{\n \"platformName\": \"tvOS\", // here\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"12.2\",\n \"appium:deviceName\": \"Apple TV\",\n ...\n}\n
Note
If using a simulator, make sure the tvOS simulator exists in your simulator list. You can run xcrun simctl list | grep \"com.apple.CoreSimulator.SimRuntime.tvOS\"
to verify this.
tvOS provides remote controller based actions. The XCUITest driver implements these actions using the mobile: pressButton
extension, with the following button values: menu
, up/down/left/right
, home
, playpause
and select
.
All actions are performed on the focused element (which has the focus
attribute set). The focused element is automatically changed after using mobile: pressButton
.
It is also possible to use the standard findElement
and click
methods. The XCUITest driver will automatically calculate the necessary sequence of up/down/left/right
and select
button presses, so you should not care about which keys should be pressed to reach an arbitrary element every time.
WebElement element = driver.findElementByAccessibilityId(\"element on the app\");\nelement.getAttribute(\"focused\"); // => 'true'\n// Appium moves the focus to the element by pressing the corresponding keys and clicking the element\nelement.click();\ndriver.queryAppState(\"test.package.name\"); // => :running_in_foreground\ndriver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Home\"));\ndriver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Up\"));\nelement = driver.switchTo().activeElement();\nelement.getAttribute(\"label\");\n
const element = $('~SomeAccessibilityId');\nelement.getAttribute('focused');\nelement.click();\ndriver.execute('mobile: pressButton', {name: 'Home'});\ndriver.execute('mobile: pressButton', {name: 'Up'});\nconst activeElement = driver.getActiveElement();\nactiveElement.getAttribute('label');\n
element = driver.find_element_by_accessibility_id('element on the app')\nelement.get_attribute('focused')\nelement.click()\ndriver.query_app_state('test.package.name')\ndriver.execute_script('mobile: pressButton', { 'name': 'Home' })\ndriver.execute_script('mobile: pressButton', { 'name': 'Up' })\nelement = driver.switch_to.active_element\nelement.get_attribute('label')\n
element = @driver.find_element :accessibility_id, 'element on the app'\nelement.focused\nelement.click\n@driver.app_state('test.package.name')\n@driver.execute_script 'mobile: pressButton', { name: 'Home' }\n@driver.execute_script 'mobile: pressButton', { name: 'Up' }\nelement = @driver.switch_to.active_element\nelement.label\n
"},{"location":"guides/tvos/#more-actions","title":"More Actions","text":"wait
methods, since tvOS also has animationmenu
button works as back for iOS context in tvOSThe XCUITest driver uses WebDriverAgent (WDA) as the automation backend. This backend is based on Apple's XCTest framework and shares all the known problems that are present in XCTest. For some of them we have workarounds, but there are some that are hardly possible to workaround (here is one example). The approach described in this article enables you to have full control over how WDA is built, managed, and run on the device. This way you may fine-tune your automated tests in a CI environment and make them more stable inlong-running perspective.
Note
In order to setup and launch WDA, please check the provided steps in the Run Preinstalled WDA documentation.
"},{"location":"guides/wda-custom-server/#wda-startup-via-code","title":"WDA Startup via Code","text":"WebDriverAgent application acts as a REST server, which proxies external API requests to native XCTest calls for your application under test. The server address will be localhost
if you run your tests on a simulator, or the actual phone IP address in case of real device. Appium uses appium-ios-device
to route network requests to a real device from localhost
via USB, which means one can use this tool to unify the WDA network addresses for a simulator and real device.
You can use appium-ios-device
to connect to a remote device by requiring the module from your JavaScript code. Alternatively, you can use iproxy
, go-ios
or tidevice
to handle the WDA process outside Appium, by installing and launching the WDA package. For instance, iproxy
can be installed using npm
: npm install -g iproxy
.
This helper class written in Java illustrates the main implementation details with iproxy
:
public class WDAServer {\n private static final Logger log = ZLogger.getLog(WDAServer.class.getSimpleName());\n\n private static final int MAX_REAL_DEVICE_RESTART_RETRIES = 1;\n private static final Timedelta REAL_DEVICE_RUNNING_TIMEOUT = Timedelta.ofMinutes(4);\n private static final Timedelta RESTART_TIMEOUT = Timedelta.ofMinutes(1);\n\n // These settings are needed to properly sign WDA for real device tests\n // See https://github.com/appium/appium-xcuitest-driver for more details\n private static final File KEYCHAIN = new File(String.format(\"%s/%s\",\n System.getProperty(\"user.home\"), \"/Library/Keychains/MyKeychain.keychain\"));\n private static final String KEYCHAIN_PASSWORD = \"******\";\n\n private static final File IPROXY_EXECUTABLE = new File(\"/usr/local/bin/iproxy\");\n private static final File XCODEBUILD_EXECUTABLE = new File(\"/usr/bin/xcodebuild\");\n private static final File WDA_PROJECT =\n new File(\"~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent\" +\n \"/WebDriverAgent.xcodeproj\");\n private static final String WDA_SCHEME = \"WebDriverAgentRunner\";\n private static final String WDA_CONFIGURATION = \"Debug\";\n private static final File XCODEBUILD_LOG = new File(\"/usr/local/var/log/appium/build.log\");\n private static final File IPROXY_LOG = new File(\"/usr/local/var/log/appium/iproxy.log\");\n\n private static final int PORT = 8100;\n public static final String SERVER_URL = String.format(\"http://127.0.0.1:%d\", PORT);\n\n private static final String[] IPROXY_CMDLINE = new String[]{\n IPROXY_EXECUTABLE.getAbsolutePath(),\n Integer.toString(PORT),\n Integer.toString(PORT),\n String.format(\"> %s 2>&1 &\", IPROXY_LOG.getAbsolutePath())\n };\n\n private static WDAServer instance = null;\n private final boolean isRealDevice;\n private final String deviceId;\n private final String platformVersion;\n private int failedRestartRetriesCount = 0;\n\n private WDAServer() {\n try {\n this.isRealDevice = !getIsSimulatorFromConfig(getClass());\n final String udid;\n if (isRealDevice) {\n udid = IOSRealDeviceHelpers.getUDID();\n } else {\n udid = IOSSimulatorHelpers.getId();\n }\n this.deviceId = udid;\n this.platformVersion = getPlatformVersionFromConfig(getClass());\n } catch (Exception e) {\n throw new RuntimeException(e);\n }\n ensureToolsExistence();\n ensureParentDirExistence();\n }\n\n public synchronized static WDAServer getInstance() {\n if (instance == null) {\n instance = new WDAServer();\n }\n return instance;\n }\n\n private boolean waitUntilIsRunning(Timedelta timeout) throws Exception {\n final URL status = new URL(SERVER_URL + \"/status\");\n try {\n if (timeout.asSeconds() > 5) {\n log.debug(String.format(\"Waiting max %s until WDA server starts responding...\", timeout));\n }\n new UrlChecker().waitUntilAvailable(timeout.asMillis(), TimeUnit.MILLISECONDS, status);\n return true;\n } catch (UrlChecker.TimeoutException e) {\n return false;\n }\n }\n\n private static void ensureParentDirExistence() {\n if (!XCODEBUILD_LOG.getParentFile().exists()) {\n if (!XCODEBUILD_LOG.getParentFile().mkdirs()) {\n throw new IllegalStateException(String.format(\n \"The script has failed to create '%s' folder for Appium logs. \" +\n \"Please make sure your account has correct access permissions on the parent folder(s)\",\n XCODEBUILD_LOG.getParentFile().getAbsolutePath()));\n }\n }\n }\n\n private void ensureToolsExistence() {\n if (isRealDevice && !IPROXY_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"%s tool is expected to be installed (`npm install -g iproxy`)\",\n IPROXY_EXECUTABLE.getAbsolutePath()));\n }\n if (!XCODEBUILD_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"xcodebuild tool is not detected on the current system at %s\",\n XCODEBUILD_EXECUTABLE.getAbsolutePath()));\n }\n if (!WDA_PROJECT.exists()) {\n throw new IllegalStateException(String.format(\"WDA project is expected to exist at %s\",\n WDA_PROJECT.getAbsolutePath()));\n }\n }\n\n private List<String> generateXcodebuildCmdline() {\n final List<String> result = new ArrayList<>();\n result.add(XCODEBUILD_EXECUTABLE.getAbsolutePath());\n result.add(\"clean build-for-testing test-without-building\");\n result.add(String.format(\"-project %s\", WDA_PROJECT.getAbsolutePath()));\n result.add(String.format(\"-scheme %s\", WDA_SCHEME));\n result.add(String.format(\"-destination id=%s\", deviceId));\n result.add(String.format(\"-configuration %s\", WDA_CONFIGURATION));\n result.add(String.format(\"IPHONEOS_DEPLOYMENT_TARGET=%s\", platformVersion));\n result.add(String.format(\"> %s 2>&1 &\", XCODEBUILD_LOG.getAbsolutePath()));\n return result;\n }\n\n private static List<String> generateKeychainUnlockCmdlines() throws Exception {\n final List<String> result = new ArrayList<>();\n result.add(String.format(\"/usr/bin/security -v list-keychains -s %s\", KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security -v unlock-keychain -p %s %s\",\n KEYCHAIN_PASSWORD, KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security set-keychain-settings -t 3600 %s\", KEYCHAIN.getAbsolutePath()));\n return result;\n }\n\n public synchronized void restart() throws Exception {\n if (isRealDevice && failedRestartRetriesCount >= MAX_REAL_DEVICE_RESTART_RETRIES) {\n throw new IllegalStateException(String.format(\n \"WDA server cannot start on the connected device with udid %s after %s retries. \" +\n \"Reboot the device manually and try again\", deviceId, MAX_REAL_DEVICE_RESTART_RETRIES));\n }\n\n final String hostname = InetAddress.getLocalHost().getHostName();\n log.info(String.format(\"Trying to (re)start WDA server on %s:%s...\", hostname, PORT));\n UnixProcessHelpers.killProcessesGracefully(IPROXY_EXECUTABLE.getName(), XCODEBUILD_EXECUTABLE.getName());\n\n final File scriptFile = File.createTempFile(\"script\", \".sh\");\n try {\n final List<String> scriptContent = new ArrayList<>();\n scriptContent.add(\"#!/bin/bash\");\n if (isRealDevice && isRunningInJenkinsNetwork()) {\n scriptContent.add(String.join(\"\\n\", generateKeychainUnlockCmdlines()));\n }\n if (isRealDevice) {\n scriptContent.add(String.join(\" \", IPROXY_CMDLINE));\n }\n final String wdaBuildCmdline = String.join(\" \", generateXcodebuildCmdline());\n log.debug(String.format(\"Building WDA with command line:\\n%s\\n\", wdaBuildCmdline));\n scriptContent.add(wdaBuildCmdline);\n try (Writer output = new BufferedWriter(new FileWriter(scriptFile))) {\n output.write(String.join(\"\\n\", scriptContent));\n }\n new ProcessBuilder(\"/bin/chmod\", \"u+x\", scriptFile.getCanonicalPath())\n .redirectErrorStream(true).start().waitFor(5, TimeUnit.SECONDS);\n final ProcessBuilder pb = new ProcessBuilder(\"/bin/bash\", scriptFile.getCanonicalPath());\n final Map<String, String> env = pb.environment();\n // This is needed for Jenkins\n env.put(\"BUILD_ID\", \"dontKillMe\");\n // This line is important. If USE_PORT environment variable is not set then WDA\n // takes port number zero by default and won't accept any incoming requests\n env.put(\"USE_PORT\", Integer.toString(PORT));\n log.info(String.format(\"Waiting max %s for WDA to be (re)started on %s:%s...\", RESTART_TIMEOUT.toString(),\n hostname, PORT));\n final Timedelta started = Timedelta.now();\n pb.redirectErrorStream(true).start().waitFor(RESTART_TIMEOUT.asMillis(), TimeUnit.MILLISECONDS);\n if (!waitUntilIsRunning(RESTART_TIMEOUT)) {\n ++failedRestartRetriesCount;\n throw new IllegalStateException(\n String.format(\"WDA server has failed to start after %s timeout on server '%s'.\\n\"\n + \"Please make sure that iDevice is properly connected and you can build \"\n + \"WDA manually from XCode.\\n\"\n + \"Xcodebuild logs:\\n\\n%s\\n\\n\\niproxy logs:\\n\\n%s\\n\\n\\n\",\n RESTART_TIMEOUT, hostname,\n getLog(XCODEBUILD_LOG).orElse(\"EMPTY\"), getLog(IPROXY_LOG).orElse(\"EMPTY\"))\n );\n }\n\n log.info(String.format(\"WDA server has been successfully (re)started after %s \" +\n \"and now is listening on %s:%s\", Timedelta.now().diff(started).toString(), hostname, PORT));\n } finally {\n scriptFile.delete();\n }\n }\n\n public boolean isRunning() throws Exception {\n if (!isProcessRunning(XCODEBUILD_EXECUTABLE.getName())\n || (isRealDevice && !isProcessRunning(IPROXY_EXECUTABLE.getName()))) {\n return false;\n }\n return waitUntilIsRunning(isRealDevice ? REAL_DEVICE_RUNNING_TIMEOUT : Timedelta.ofSeconds(3));\n }\n\n public Optional<String> getLog(File logFile) {\n if (logFile.exists()) {\n try {\n return Optional.of(new String(Files.readAllBytes(logFile.toPath()), Charset.forName(\"UTF-8\")));\n } catch (IOException e) {\n e.printStackTrace();\n }\n }\n return Optional.empty();\n }\n}\n
The following piece of code should then be called before starting the XCUITest driver:
if (!WDAServer.getInstance().isRunning()) {\n WDAServer.getInstance().restart();\n}\n
It is important to set the appium:webDriverAgentUrl
capability for the driver to let it know that WDA is ready for use:
capabilities.setCapability(\"webDriverAgentUrl\", WDAServer.SERVER_URL);\n
"},{"location":"guides/wda-custom-server/#important-notes","title":"Important Notes","text":"xcodebuild
and iproxy
processes are killed before restart to make sure compilation succeeds, in case the processes are frozenbash
script is used to detach the iproxy
/xcodebuild
processes, so they can continue running in background even after the actual code execution is finished. This is extremely important if multiple tests/suites are executed on the same machine/node in automation lab, which requires minimum human interactionBUILD_ID
environment variable is changed to avoid the CI agent killing the background process after the job is finishedisRunning
check is done by verifying the actual network endpointsystem_profiler SPUSBDataType
outputxcrun simctl list
outputUrlChecker
class is imported from the org.openqa.selenium.net
packageInfo
Before installing, make sure to check the System Requirements.
Use the Appium extension CLI to add this driver to your Appium install:
appium driver install xcuitest\n
Alternatively, if you are running a Node.js project, you can include appium-xcuitest-driver
as one of your dependencies.
To activate the driver, simply launch the Appium server. By default, Appium will load all the installed drivers:
appium\n
You should see some output that includes a line like this:
[Appium] XCUITestDriver has been successfully loaded in 0.789s\n
Once you have installed the driver and confirmed it works, you should continue with device preparation.
"},{"location":"installation/requirements/","title":"System Requirements","text":""},{"location":"installation/requirements/#main-dependencies","title":"Main Dependencies","text":"Like all Appium drivers, the XCUITest driver requires Appium to be installed. Refer to the Appium documentation for its requirements and prerequisites.
Note
Since version 4.0.0, the XCUITest driver has dropped support for Appium 1, and is only compatible with Appium 2.
In addition to Appium system requirements, the XCUITest driver expects the following prerequisites:
xcpretty
can be used to make Xcode output easier to read. It can be installed by running gem install xcpretty
.ffmpeg
is used for test video recording. It can be installed using brew
: brew install ffmpeg
idb
, go-ios
and tidevice
can be used to improve device interactionspy-ios-device
is required in several mobile:
extensions, and can improve the general testing experience for real devicesSince driver version 5.13.0, you can automate the validation for the most of the above requirements as well as various optional ones needed by driver extensions by running the appium driver doctor xcuitest
command.
The XCUITest driver functionality relies on the XCTest framework, and changes in the XCTest API are published in new Xcode and iOS versions. Many major and even some minor Xcode/iOS versions include breaking changes in this API, which require updating the driver code. Similarly, maintaining compatibility with older Xcode/iOS versions often requires workarounds, which are eventually dropped in order to simplify the code and use newer XCTest features.
Generally, the driver aims to support at least two latest major Xcode and iOS versions.
The following table lists the minimum driver versions required for specific Xcode/iOS versions:
Xcode/iOS version Minimum required XCUITest driver version Xcode 13 / iOS 15 3.48.0 Xcode 14-beta.3 / iOS 16 Beta 4.7.4 Xcode 14.3 / iOS 16.4 4.21.7 Xcode 15 / iOS 17 4.35.0The following table lists the last driver versions that are compatible with older Xcode versions:
Xcode version Last supported XCUITest driver version Xcode 8 2.95.0 Xcode 9 2.133.1 Xcode 10-10.1 3.31.1 Xcode 10.2 3.56.3 Xcode 11 4.3.2 Xcode 12 4.27.2The following table lists the last driver versions that are compatible with older iOS versions:
iOS version Last supported XCUITest driver version iOS < 15 4.27.2"},{"location":"preparation/","title":"Device Preparation","text":"Before using the XCUITest driver with a simulator or real device, some device preparation is required.
"},{"location":"preparation/#automatic-adjustments","title":"Automatic Adjustments","text":"The XCUITest driver automatically adjusts some device preferences for testing purposes.
"},{"location":"preparation/#keyboard-configuration","title":"Keyboard Configuration","text":"Some keyboard preferences are changed in order to make test runs more stable. You can change some of them via the Settings API.
Unfortunately, not all configuration can be done automatically, and some changes must be applied manually.
"},{"location":"preparation/#accessibility-settings","title":"Accessibility Settings","text":"WKWebView
and/or JSContext
component must have the isInspectable
property set to true
. Please read the WebKit documentation page for more details on this property.get-task-allow
entitlement present as true
in the application manifest.Some settings are enabled by default on simulators, but need to be manually changed for real devices. See the Real Device Configuration document for details.
"},{"location":"preparation/prov-profile-basic-auto/","title":"Basic Automatic Configuration","text":"If you have a paid Apple Developer account, the easiest way to create the provisioning profile is to use the automatic configuration strategy. There are two ways to do this:
xcodeOrgId
and xcodeSigningId
capabilities: {\n \"appium:xcodeOrgId\": \"<Team ID>\",\n \"appium:xcodeSigningId\": \"Apple Developer\"\n}\n
.xcconfig
file somewhere on your file system and add the following to it: DEVELOPMENT_TEAM = <Team ID>\nCODE_SIGN_IDENTITY = Apple Developer\n
Then use the xcodeConfigFile
capability to specify the path to this file: {\n \"appium:xcodeConfigFile\": \"/path/to/xcconfig/file\"\n}\n
Note that these are mutually exclusive strategies; use either the xcodeConfigFile
capability or the combination of xcodeOrgId
and xcodeSigningId
.
xcodeOrgId
/ DEVELOPMENT_TEAM
is a unique 10-character string generated by Apple that is assigned to your team.xcodeSigningId
/ CODE_SIGN_IDENTITY
is usually either Apple Developer
or iPhone Developer
.Once this configuration is done, you should specify your real device UDID with the udid
desired capability, after which you should be able to start your test. Proceed with Validating the WDA Install for the next steps.
There are many cases in which the basic automatic configuration is not enough. Often this happens when the development account being used is a \"Free\" one, in which case it is not possible to create a wildcard provisioning profile.
You can confirm this by opening the WDA project in Xcode. The issue will manifest as something like an error that Xcode failed to create provisioning profile:
The easiest way around this is to create a new project:
The type does not matter, other than it being \"iOS\". \"Single View Application\" is the easiest:
The important part is to use a unique \"Product Name\" and \"Organization Name\". Also, at this point, specify your \"Team\".
You can confirm that the provisioning profile was created by looking at the \"Project\" tab:
Or by going into your account preferences and seeing the provisioning profile:
At this point you have a valid provisioning profile. Make note of the bundle identifier you associated with it, and add that in the updatedWDABundleId
capability for your tests. Then follow the initial instructions for automatic configuration.
The provisioning profile can also be manually associated with the WDA project. Keep in mind that this will have to be done each time WDA is updated (such as when updating the XCUITest driver), and is not recommended:
mkdir -p Resources/WebDriverAgent.bundle\n
WebDriverAgent.xcodeproj
in Xcode. This will likely open a screen with an empty editor.Check Automatically manage signing, and then select your Team (you may need to first sign into Xcode). The outcome should be similar to the following:
Xcode will likely fail to create a provisioning profile due to an invalid bundle identifier:
Change the Bundle Identifier from com.facebook.WebDriverAgentRunner
to something that Xcode will accept. You can also do this in the Build Settings tab:
Note
Versions of Xcode older than 11 have a different naming convention. This feature may not work for a package which is built by Xcode versions below 12.
If your bundle identifier is accepted, you should see that Xcode has created a provisioning profile and all is well:
Finally, you can verify that everything works:
Proceed with Validating the WDA Install for the next steps!
"},{"location":"preparation/prov-profile-generic-manual/","title":"Manual Configuration for a Generic Device","text":"It is possible to build WebDriverAgentRunner
for a generic iOS/iPadOS/tvOS device, and install the generated .app
package to a real device.
# iOS/iPadOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_ios -scheme WebDriverAgentRunner -destination generic/platform=iOS CODE_SIGNING_ALLOWED=YES\n\n# tvOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_tvos -scheme WebDriverAgentRunner_tvOS -destination generic/platform=tvOS CODE_SIGNING_ALLOWED=YES\n
On successful completion the resulting package WebDriverAgentRunner-Runner.app
should be located in the Build/Products/Debug-iphoneos/
subfolder under WebDriverAgent sources root, or in the path provided as derivedDataPath
argument.
Note
If the build fails, please make sure WebDriverAgent.xcodeproj
has codesigning properties configured properly. For example, you may need to change the bundle id for the provisioning profile.
The WebDriverAgentRunner-Runner.app
can now be installed to any real device as allowed by the provisioning profile.
You can install the package with 3rd party tools and manage it separately as explained in How To Set Up And Customize WebDriverAgent Server. Note that if the codesigning was not correct, the installation will fail.
As a more advanced method, you can generate the package with CODE_SIGNING_ALLOWED=NO
and do codesign
by yourself. This would make the device management more flexible, but you would need to know about advanced codesign usage scenarios.
Note
The Appium team distributes generic builds with CODE_SIGNING_ALLOWED=NO
at https://github.com/appium/WebDriverAgent/releases. It is recommended to sign packages with a wildcard (*
) provisioning profile, although such profiles require a paid Apple Developer account. In case of a free account, you may need to update the bundle id before building the WebDriverAgent package.
In order to communicate with the device under test, the XCUITest driver automatically installs the WebDriverAgentRunner-Runner
(WDA) application on it, using Xcode's command-line utility xcodebuild
. Unlike simulators, real devices have several security restrictions that need to be manually configured, before this can work:
devmodectl streaming
CLI on macOS 13+ and installing development signed apps also help enabling the mode.Finally, the WDA application must have a valid provisioning profile, which includes signing the app and linking it to a development team.
"},{"location":"preparation/real-device-config/#provisioning-profile-setup","title":"Provisioning Profile Setup","text":"Generally, unless your device under test already has WDA installed, or you already have a prebuilt WDA on your local system, you will need an Apple ID to be able to sign the app.
Once you have an Apple ID, there are several approaches you can take.
If the automatic configuration did not work or does not apply to you, you will need to follow one of the manual configuration approaches. All of these involve the WDA Xcode project, so at the very least, you must know the local path to the project file - WebDriverAgent.xcodeproj
:
appium-webdriveragent
, which is installed as a dependency of the XCUITest driver. You can therefore find the project file in /path/to/xcuitest/driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj
. By default, drivers are installed in ~/.appium
, so the project would be located at ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj
.appium driver run xcuitest open-wda
driver script to directly open WebDriverAgent.xcodeproj
in Xcode.The WDA project file can now be used in the manual configuration approaches:
xcodebuild
to build WDA, then manually install itOnce you have configured the WDA project or have the app ready, you can try installing it. It is possible that you may encounter some errors:
xcodebuild exited with code '65' and signal 'null'
This usually happens when attempting the automatic configuration, and it means that the necessary code signing is not set up correctly. Follow the steps in any of the manual configuration approaches to fix this.
Unable to launch <your-bundle-id>.WebDriverAgentRunner-Runner because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.
This means that the developer is not trusted on the device. If you manually try to open the WDA app on the device, you will see a popup message:
To fix this, you need to open Settings -> General -> VPN & Device Management on the device, then select your development team and trust it. Afterwards you should be able to open/launch the app. See Apple documentation for more information.
For other issues, please refer to the Troubleshooting page
Since iOS 16, Apple requires a device to have a live internet connection for validating the code signing. It is possible to set up an offline enabled provisiong profile, which allows you to avoid the limitation. Please read this issue regarding detailed configuration steps.
"},{"location":"reference/capabilities/","title":"Capabilities","text":"This page lists various capabilities used and implemented by the XCUITest driver. To learn more about capabilities, refer to the Appium documentation.
"},{"location":"reference/capabilities/#general","title":"General","text":"Capability DescriptionplatformName
Could be set to ios
. Appium itself is not strict about this capability value if automationName
is provided, so feel free to assign it to any supported platform name if this is needed, for example, to make Selenium Grid working. browserName
The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read Automating hybrid apps for more details. Usually equals to safari
. appium:automationName
Must always be set to xcuitest
. Values of automationName
are compared case-insensitively. appium:deviceName
The name of the device under test. Consider setting udid
for real devices and use this one for Simulator selection instead appium:platformVersion
The platform version of an emulator or a real device. This capability is used for device autodetection if udid
is not provided appium:udid
UDID of the device to be tested. Could be retrieved from Xcode->Window->Devices and Simulators window. Always set this capability if you run parallel tests or use a real device to run your tests. appium:noReset
Prevents the device to be reset before the session startup if set to true
. This means that the application under test is not going to be terminated neither its data cleaned. false
by default appium:fullReset
Being set to true
always enforces the application under test to be fully uninstalled before starting a new session. The application data might be cached on real devices under particular circumstances. Please check troubleshooting for more details regarding obsolete application data cleanup on real devices. false
by default appium:printPageSourceOnFindFailure
Enforces the server to dump the actual XML page source into the log if any error happens. false
by default. appium:includeDeviceCapsToSessionInfo
Whether to include screen information as the result of Get Session Capabilities. It includes pixelRatio
, statBarHeight
and viewportRect
, but it causes an extra API call to WDA which may increase the response time like this issue. Defaults to true
. This capability has no effect since driver version 5 appium:resetLocationService
Whether reset the location service in the session deletion on real device. Defaults to false
. appium:customSSLCert
Adds a root SSL certificate to IOS Simulators and real devices. Real devices only work if py-ios-device tool is available on the server machine. The certificate content must be provided in PEM format, e.g. -----BEGIN CERTIFICATE-----MIIFWjCCBEKg...-----END CERTIFICATE-----
"},{"location":"reference/capabilities/#app","title":"App","text":"Capability Description appium:bundleId
Bundle identifier of the app under test, for example com.mycompany.myapp
. The capability value is calculated automatically if app
is provided. If neither app
or bundleId
capability is provided then XCUITest driver starts from the Home screen. appium:app
Full path to the application to be tested (the app must be located on the same machine where the server is running). .ipa
and .app
application extensions are supported. Zipped .app
bundles are supported as well. Could also be an URL to a remote location. If neither of the app
or bundleId
capabilities are provided then the driver starts from the Home screen and expects the test to know what to do next. Do not provide both app
and browserName
capabilities at once. appium:enforceAppInstall
If set to false
it will make xcuitest driver to verify whether the app version currently installed on the device under test is older than the one, which is provided as appium:app
value. No app reinstall is going to happen if the candidate app has the same or older version number than the already installed copy of it. The version number used for comparison must be provided as CFBundleVersion Semantic Versioning-compatible value in the application's Info.plist. No validation is performed by default, e.g. the provided app is always (re)installed, which could potentially slow down your test suites. The application data might be cached on real devices under particular circumstances when appium:enforceAppInstall
is true
if the application under test remained on the device under a certain situation. Please check troubleshooting for more details regarding obsolete application data cleanup on real devices. Available since XCUITest driver 4.19.0. appium:localizableStringsDir
Where to look for localizable strings in the application bundle. Defaults to en.lproj
appium:otherApps
App or list of apps (as a JSON array) to install prior to running tests. For example: [\"http://appium.github.io/appium/assets/TestApp9.4.app.zip\", \"/path/to/app-b.app\"]
appium:language
Language to set for iOS app, for example fr
. Please read Language IDs to get more details about available values for this capability. If a test is executed on a Simulator then UI language is changed as well. You can also change Simulator language in runtime using mobile: configureLocalization extension. appium:locale
Locale to set for iOS app, for example fr_CA
. Please read Locale IDs to get more details about available values for this capability. If a test is executed on a Simulator then UI locale is changed as well. You can also change Simulator locale in runtime using mobile: configureLocalization extension. appium:calendarFormat
Calendar format to set for iOS Simulator, for example gregorian
or persian
. Can only be set in conjunction with appium:locale
. appium:appPushTimeout
The timeout for application upload in milliseconds. Works for real devices only. The default value is 30000
ms appium:appInstallStrategy
Select application installation strategy for real devices. The following strategies are supported:serial
(default) - pushes app files to the device in a sequential order; this is the least performant strategy, although the most reliableparallel
- pushes app files simultaneously; this is usually the the most performant strategy, but sometimes could not be very stableios-deploy
- tells the driver to use a third-party tool ios-deploy to install the app; obviously the tool must be installed separately first and must be present in PATH before it could be used."},{"location":"reference/capabilities/#webdriveragent","title":"WebDriverAgent","text":"Capability Description Example appium:xcodeOrgId
Apple developer team identifier string. Must be used in conjunction with xcodeSigningId
to take effect. JWL241K123
appium:xcodeSigningId
String representing a signing certificate. Must be used in conjunction with xcodeOrgId
. This is usually just Apple Development
or iPhone Developer
, so the default (if not included) is iPhone Developer
Apple Developer
appium:xcodeConfigFile
Full path to an optional Xcode configuration file that specifies the code signing identity and team for running the WebDriverAgent
on the real device. /path/to/myconfig.xcconfig
appium:updatedWDABundleId
Bundle id to update WDA to before building and launching on real devices. This bundle id must be associated with a valid provisioning profile. io.appium.WebDriverAgentRunner
appium:keychainPath
Full path to the private development key exported from the system keychain. Used in conjunction with keychainPassword
when testing on real devices. /path/to/MyPrivateKey.p12
appium:keychainPassword
Password for unlocking keychain specified in keychainPath
. super awesome password
appium:derivedDataPath
Use along with usePrebuiltWDA capability and choose where to search for the existing WDA app. If the capability is not set then Xcode will store the derived data in the default root taken from preferences. appium:webDriverAgentUrl
If provided, Appium will connect to an existing WebDriverAgent
instance at this URL instead of starting a new one. http://localhost:8100
appium:useNewWDA
If true
, forces uninstall of any existing WebDriverAgent
app on device. Set it to true
if you want to apply different startup options for WebDriverAgent
for each session. Although, it is only guaranteed to work stable on Simulator. Real devices require WebDriverAgent
client to run for as long as possible without reinstall/restart to avoid issues like https://github.com/facebook/WebDriverAgent/issues/507. The false
value (the default behaviour since driver version 2.35.0) will try to detect currently running WDA listener executed by previous testing session(s) and reuse it if possible, which is highly recommended for real device testing and to speed up suites of multiple tests in general. A new WDA session will be triggered at the default URL (http://localhost:8100) if WDA is not listening and webDriverAgentUrl
capability is not set. The negative/unset value of useNewWDA
capability has no effect prior to xcuitest driver version 2.35.0. true
appium:wdaLaunchTimeout
Time, in ms, to wait for WebDriverAgent
to be pingable. Defaults to 60000ms. 30000
appium:wdaConnectionTimeout
Timeout, in ms, for waiting for a response from WebDriverAgent
. Defaults to 240000ms. 1000
appium:wdaStartupRetries
Number of times to try to build and launch WebDriverAgent
onto the device. Defaults to 2. 4
appium:wdaStartupRetryInterval
Time, in ms, to wait between tries to build and launch WebDriverAgent
. Defaults to 10000ms. 20000
appium:wdaLocalPort
This value if specified, will be used to forward traffic from Mac host to real ios devices over USB. Default value is same as port number used by WDA on device. 8100
appium:wdaRemotePort
This value if specified, will be used as the port number to start WDA HTTP server on the remote device. This is only relevant for real devices, because Simulator shares ports with its host. If webDriverAgentUrl
is provided then it might be used to provide a hint for the remote port number if it differs from the default one. Default value is 8100. 8100
appium:wdaBaseUrl
This value if specified, will be used as a prefix to build a custom WebDriverAgent
url. It is different from webDriverAgentUrl
, because if the latter is set then it expects WebDriverAgent
to be already listening and skips the building phase. Defaults to http://localhost
http://192.168.1.100
appium:showXcodeLog
Whether to display the output of the Xcode command used to run the tests. If this is true
, there will be lots of extra logging at startup. Defaults to false
true
appium:iosInstallPause
Time in milliseconds to pause between installing the application and starting WebDriverAgent
on the device. Used particularly for larger applications. Defaults to 0
8000
appium:usePrebuiltWDA
Skips the build phase of running the WDA app. Building is then the responsibility of the user. Only works for Xcode 8+. Defaults to false
. true
appium:prebuiltWDAPath
The path to a WebDriverAgentRunner application package to be installed with appium:usePreinstalledWDA
capability for real devices. The package's bundle id will be used over appium:updatedWDABundleId
. /path/to/WebDriverAgentRunner-Runner.app
appium:usePreinstalledWDA
Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client (via com.apple.instruments
service) instead of running xcodebuild
for real devices. If appium:prebuiltWDAPath
is provided, XCUITest driver will install it before launching the application. The preinstalled WebDriverAgent package must have been built by Xcode 12+. The default target bundle identifier is com.facebook.WebDriverAgentRunner.xctrunner
. If appium:updatedWDABundleId
is provided, <appium:updatedWDABundleId>.xctrunner
will be launched. Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to false
. true
or false
appium:shouldUseSingletonTestManager
Use default proxy for test management within WebDriverAgent
. Setting this to false
sometimes helps with socket hangup problems. Defaults to true
. false
appium:waitForIdleTimeout
The amount of time in float seconds to wait until the application under test is idling. XCTest requires the app's main thread to be idling in order to execute any action on it, so WDA might not even start/freeze if the app under test is constantly hogging the main thread. The default value is 10
(seconds). Setting it to zero disables idling checks completely (not recommended) and has the same effect as setting waitForQuiescence
to false
. Available since Appium 1.20.0. 1
appium:useXctestrunFile
Use Xctestrun file to launch WDA. It will search for such file in bootstrapPath
. Expected name of file is WebDriverAgentRunner_iphoneos<sdkVersion>-arm64.xctestrun
for real device and WebDriverAgentRunner_iphonesimulator<sdkVersion>-x86_64.xctestrun
for simulator. One can do build-for-testing
for WebDriverAgent
project for simulator and real device and then you will see Product Folder like this and you need to copy content of this folder at bootstrapPath
location. Since this capability expects that you have already built WDA
project, it neither checks whether you have necessary dependencies to build WDA
nor will it try to build project. Defaults to false
. Tips: Xcodebuild
builds for the target platform version. We'd recommend you to build with minimal OS version which you'd like to run as the original WDA module. e.g. If you build WDA for 12.2, the module cannot run on iOS 11.4 because of loading some module error on simulator. A module built with 11.4 can work on iOS 12.2. (This is xcodebuild's expected behaviour.) true
appium:useSimpleBuildTest
Build with build
and run test with test
in xcodebuild for all Xcode version if this is true
, or build with build-for-testing
and run tests with test-without-building
for over Xcode 8 if this is false
. Defaults to false
. true
or false
appium:wdaEventloopIdleDelay
Delays the invocation of -[XCUIApplicationProcess setEventLoopHasIdled:]
by the number of seconds specified with this capability. This can help quiescence apps that fail to do so for no obvious reason (and creating a session fails for that reason). This increases the time for session creation because -[XCUIApplicationProcess setEventLoopHasIdled:]
is called multiple times. If you enable this capability start with at least 3
seconds and try increasing it, if creating the session still fails. Defaults to 0
. 5
appium:processArguments
Process arguments and environment which will be sent to the WebDriverAgent
server in a new session request. Please use mobile: launchApp to launch an application with process arguments in the middle of a session. { args: [\"a\", \"b\", \"c\"] , env: { \"a\": \"b\", \"c\": \"d\" } }
or '{\"args\": [\"a\", \"b\", \"c\"], \"env\": { \"a\": \"b\", \"c\": \"d\" }}'
appium:autoLaunch
When set to false
, prevents the application under test from being launched automatically as a part of the new session startup process. The launch become the responsibility of the user. Defaults to true
. true
or false
appium:allowProvisioningDeviceRegistration
Allow xcodebuild
to register your destination device on the developer portal if necessary. Requires a developer account to have been added in Xcode's Accounts preference pane. Defaults to false
. true
or false
appium:resultBundlePath
Specify the path to the result bundle path as xcodebuild
argument for WebDriverAgent
build under a security flag (Please check Opt-in Features section below). WebDriverAgent
process must start/stop every time to pick up changed value of this property. Specifying useNewWDA
to true
may help there. Please read man xcodebuild
for more details. /path/to/resultbundle
appium:resultBundleVersion
Specify the version of result bundle as xcodebuild
argument for WebDriverAgent
build. The default value depends on your Xcode version. Please read man xcodebuild
for more details. /path/to/resultbundle
appium:maxTypingFrequency
Maximum frequency of keystrokes for typing and clear. If your tests are failing because of typing errors, you may want to adjust this. Defaults to 60 keystrokes per minute. 30
appium:simpleIsVisibleCheck
Use native methods for determining visibility of elements. In some cases this takes a long time. Setting this capability to false
will cause the system to use the position and size of elements to make sure they are visible on the screen. This can, however, lead to false results in some situations. Defaults to false
. true
, false
appium:waitForQuiescence
It allows to turn on/off waiting for application quiescence in WebDriverAgent
, while performing queries. The default value is true
. You can avoid this kind of issues if you turn it off. Consider using waitForIdleTimeout
capability instead for this purpose since Appium 1.20.0 false
appium:mjpegServerPort
The port number on which WDA broadcasts screenshots stream encoded into MJPEG format from the device under test. It might be necessary to change this value if the default port is busy because of other tests running in parallel. Default value: 9100
12000
appium:screenshotQuality
Changes the initial quality of display screenshots. This capability affects the screenshoting speed and the actual quality of resulting screenshots. Before version 5.4.0 of WebDriverAgent possible values were: 0
, 1
(default), 2
, where 0
abbreviates lossless PNG, 1
is a high-quality JPEG and 2
is a low-quality JPEG. In the version 5.4.0 one more mode has been added (3
), which is now the default one. It abbreviates lossless HEIC with fallback to PNG if the device does not support hardware-accelerated HEIC encoding. You can also change the value of screenshotQuality in settings. 2
appium:autoAcceptAlerts
Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is false
. true
or false
appium:autoDismissAlerts
Dismiss all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is false
. true
or false
appium:disableAutomaticScreenshots
Disable automatic screenshots taken by XCTest at every interaction. Default is up to WebDriverAgent
's config to decide, which currently defaults to true
. true
or false
appium:shouldTerminateApp
Specify if the app should be terminated on session end. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is true
unless noReset
capability is set to true
. true
or false
appium:forceAppLaunch
Specify if the app should be forcefully restarted if it is already running on session startup. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is true
unless noReset
capability is set to true
. true
or false
appium:useNativeCachingStrategy
Set this capability to false
in order to use the custom elements caching strategy. This might help to avoid stale element exception on property change. By default the native XCTest cache resolution is used (true
) for all native locators (e.g. all, but xpath). Check the corresponding WebDriverAgent pull request for more details. true
or false
"},{"location":"reference/capabilities/#simulator","title":"Simulator","text":"Capability Description Example appium:orientation
Start a test session in a certain orientation. Note, that Simulator may ignore this capability if the simulated device itself does not support orientation change in its current state. For example, iPhones only allow orientation change to landscape if an app that declares landscape support in its manifest is running. Thus changing the orientation from portrait to something else being on home screen won't have any effect. LANDSCAPE
or PORTRAIT
appium:scaleFactor
Simulator scale factor. This is useful to have if the default resolution of simulated device is greater than the actual display resolution, so you can scale the simulator to see the whole device screen without scrolling. Must be a string containing a positive float value. '2.0'
appium:connectHardwareKeyboard
Set this option to true
in order to enable hardware keyboard in Simulator. The preference works only when XCUITest driver launches a simulator instance with this value. It is set to false
by default, because this helps to workaround some XCTest bugs. connectHardwareKeyboard: true
makes forceSimulatorSoftwareKeyboardPresence: false
if no explicit value is set for forceSimulatorSoftwareKeyboardPresence
capability since Appium 1.22.0. true
or false
appium:forceSimulatorSoftwareKeyboardPresence
Set this option to true
in order to turn software keyboard on and turn hardware keyboard off in Simulator since Appium 1.22.0. This option helps to avoid Keyboard is not present
error. It is set to true
by default. XCUITest driver respects preset simulator software/hardware keyboard preference when this value is false
, so connectHardwareKeyboard: false
and forceSimulatorSoftwareKeyboardPresence: false
means for XCUITest driver to keep the current Simulator keyboard preferences. This option has priority over connectHardwareKeyboard
. true
or false
appium:skipSyncUiDialogTranslation
Set this option to true
in order to skip synchronizing UI dialogs translation. While this option might leave some system UI alerts untranslated, it helps to avoid unexpected side effects (see this issue for more details). It is set to false
by default. true
or false
Deprecated appium:calendarAccessAuthorized
This capability is obsolete. Please use appium:permissions
one instead with the calendar
key. true
or false
appium:isHeadless
Set this capability to true
if automated tests are running on Simulator and the device display is not needed to be visible. This only has an effect since Xcode9 and only for simulators. All running instances of Simulator UI are going to be automatically terminated if headless test is started. false
is the default value. true
appium:simulatorWindowCenter
Allows to explicitly set the coordinates of Simulator window center for Xcode9+ SDK. This capability only has an effect if Simulator window has not been opened yet for the current session before it started. Must be a tuple containing floats or integers, with no spaces. {-100.0,100.0}
appium:simulatorStartupTimeout
Allows to change the default timeout for Simulator startup. By default this value is set to 120000ms (2 minutes), although the startup could take longer on a weak hardware or if other concurrent processes use much system resources during the boot up procedure. 300000
appium:simulatorTracePointer
Whether to highlight pointer moves in the Simulator window. The Simulator UI client must be shut down before the session startup in order for this capability to be applied properly. false
by default. true
appium:shutdownOtherSimulators
If this capability set to true
and the current device under test is an iOS Simulator then Appium will try to shutdown all the other running Simulators before to start a new session. This might be useful while executing webview tests on different devices, since only one device can be debugged remotely at once due to an Apple bug. The capability only has an effect if --relaxed-security
command line argument is provided to the server. Defaults to false
. true
appium:enforceFreshSimulatorCreation
Creates a new simulator in session creation and deletes it in session deletion. Defaults to false
. true
or false
appium:keepKeyChains
Set the capability to true
in order to preserve Simulator keychains folder after full reset. This feature has no effect on real devices. Defaults to false
true
appium:keychainsExcludePatterns
This capability accepts comma-separated path patterns, which are going to be excluded from keychains restore while full reset is being performed on Simulator. It might be useful if you want to exclude only particular keychain types from being restored, like the applications keychain. This feature has no effect on real devices. *keychain*.db*
appium:reduceMotion
It allows to turn on/off reduce motion accessibility preference. Setting reduceMotion on
helps to reduce flakiness during tests. Only on simulators true
appium:reduceTransparency
It allows you to turn on/off reduce transparency accessibility preference. Setting reduceTransparency on
helps to reduce screenshot image distortion during tests. Only on simulators true
appium:autoFillPasswords
It allows you to turn on/off autofill passwords function when text field is foccused. Works only with iOS16.4+ simulators true
appium:permissions
Allows to set permissions for the specified application bundle on Simulator only. The capability value is expected to be a valid JSON string with {\"<bundleId1>\": {\"<serviceName1>\": \"<serviceStatus1>\", ...}, ...}
format. Since Xcode SDK 11.4 Apple provides native APIs to interact with application settings. Check the output of xcrun simctl privacy booted
command to get the list of available permission names. Use yes
, no
and unset
as values in order to grant
, revoke
or reset
the corresponding permission. Below Xcode SDK 11.4 it is required that applesimutils
package is installed and available in PATH. The list of available service names and statuses can be found at https://github.com/wix/AppleSimulatorUtils. {\"com.apple.mobilecal\": {\"calendar\": \"YES\"}}
appium:iosSimulatorLogsPredicate
Set the --predicate
flag in the ios simulator logs 'process != \"locationd\" AND process != \"DTServiceHub\"' AND process != \"mobileassetd\"
appium:simulatorPasteboardAutomaticSync
Handle the -PasteboardAutomaticSync
flag when simulator process launches. It could improve launching simulator performance not to sync pasteboard with the system when this value is off
. on
forces the flag enabled. system
does not provide the flag to the launching command. on
, off
, or system
is available. They are case insensitive. Defaults to off
system
appium:simulatorDevicesSetPath
This capability allows to set an alternative path to the simulator devices set in case you have multiple sets deployed on your local system. Such feature could be useful if you, for example, would like to save disk space on the main system volume. /MyVolume/Devices
appium:webkitResponseTimeout
(Real device only) Set the time, in ms, to wait for a response from WebKit in a Safari session. Defaults to 5000
10000
appium:safariGlobalPreferences
Allows changing of Mobile Safari's preferences at the session startup. Check the documentation on arguments of mobile: updateSafariPreferences extension to get more details on the value type requirements. { ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }
"},{"location":"reference/capabilities/#web-context","title":"Web Context","text":"Capability Description Example appium:absoluteWebLocations
This capability will direct the Get Element Location
command, when used within webviews, to return coordinates which are relative to the origin of the page, rather than relative to the current scroll offset. This capability has no effect outside of webviews. Default false
. true
appium:safariGarbageCollect
Turns on/off Web Inspector garbage collection when executing scripts on Safari. Turning on may improve performance. Defaults to false
. true
or false
appium:includeSafariInWebviews
Add Safari web contexts to the list of contexts available during a native/webview app test. This is useful if the test opens Safari and needs to be able to interact with it. Defaults to false
. true
or false
appium:safariLogAllCommunication
Log all plists sent to and received from the Web Inspector, as plain text. For some operations this can be a lot of data, so it is recommended to be used only when necessary. Defaults to false
. true
or false
appium:safariLogAllCommunicationHexDump
Log all communication sent to and received from the Web Inspector, as raw hex dump and printable characters. This logging is done before any data manipulation, and so can elucidate some communication issues. Like appium:safariLogAllCommunication
, this can produce a lot of data in some cases, so it is recommended to be used only when necessary. Defaults to false
. true
or false
appium:safariSocketChunkSize
The size, in bytes, of the data to be sent to the Web Inspector on iOS 11+ real devices. Some devices hang when sending large amounts of data to the Web Inspector, and breaking them into smaller parts can be helpful in those cases. Defaults to 16384
(also the maximum possible) 1000
appium:safariWebInspectorMaxFrameLength
The maximum size in bytes of a single data frame for the Web Inspector. Too high values could introduce slowness and/or memory leaks. Too low values could introduce possible buffer overflow exceptions. Defaults to 20MB (20*1024*1024
) 1024
, 100*1024*1024
appium:additionalWebviewBundleIds
Array (or JSON array) of possible bundle identifiers for webviews. This is sometimes necessary if the Web Inspector is found to be returning a modified bundle identifier for the app. If the value includes *
, XCUITest driver will return all available webview contexts on the device. Defaults to []
[\"io.appium.modifiedId', 'ABCDEF\"]
, [\"*\"]
appium:webviewConnectTimeout
The time to wait, in ms
, for the initial presence of webviews in MobileSafari or hybrid apps. Defaults to 0
5000
appium:safariIgnoreWebHostnames
Provide a list of hostnames (comma-separated) that the Safari automation tools should ignore. This is to provide a workaround to prevent a webkit bug where the web context is unintentionally changed to a 3rd party website and the test gets stuck. The common culprits are search engines (yahoo, bing, google) and about:blank
'www.yahoo.com, www.bing.com, www.google.com, about:blank'
appium:nativeWebTap
Enable native, non-javascript-based taps being in web context mode. Defaults to false
. Warning: sometimes the preciseness of native taps could be broken, because there is no reliable way to map web element coordinates to native ones. true
appium:nativeWebTapStrict
Enabling this capability would skip the additional logic that tries to match web view elements to native ones by using their textual descriptions. Depending on the actual web view content this algorithm might sometimes be not very reliable and will slow down each click as we anyway fallback to the usual coordinates transformation flow if it fails. It is advised to enable strict tap if you use mobile: calibrateWebToRealCoordinatesTranslation extension. Only applicable if nativeWebTap
is enabled. false
by default true
appium:safariInitialUrl
Initial safari url, default is a local welcome page. Setting it to an empty string will skip the initial navigation. https://www.github.com
appium:safariAllowPopups
(Simulator only) Allow javascript to open new windows in Safari. Default keeps current sim setting. true
or false
appium:safariIgnoreFraudWarning
(Simulator only) Prevent Safari from showing a fraudulent website warning. Default keeps current sim setting. true
or false
appium:safariOpenLinksInBackground
(Simulator only) Whether Safari should allow links to open in new windows. Default keeps current sim setting. true
or false
appium:webviewConnectRetries
Number of times to send connection message to remote debugger, to get webview. Default: 8
12
appium:webkitResponseTimeout
(Real device only) Set the time, in ms, to wait for a response from WebKit in a Safari session. Defaults to 5000
10000
appium:enableAsyncExecuteFromHttps
Capability to allow simulators to execute asynchronous JavaScript on pages using HTTPS. Defaults to false
true
or false
appium:fullContextList
Returns the detailed information on contexts for the Get Contexts command. If this capability is enabled, then each item in the returned contexts list would additionally include WebView title, full URL and the bundle identifier. Defaults to false
. true
or false
appium:enablePerformanceLogging
Enable Safari's performance logging (default false
) true
, false
appium:autoWebview
Move directly into Webview context if available. Default false
true
, false
appium:skipTriggerInputEventAfterSendkeys
If this capability is set to true
, then whenever you call the Send Keys method in a web context, the driver will not fire an additional input
event on the input field used for the call. This event, turned on by default, helps in situations where JS frameworks (like React) do not respond to the input events that occur by default when the underlying Selenium atom is executed. Default false
true
, false
"},{"location":"reference/capabilities/#other","title":"Other","text":"Capability Description Example appium:resetOnSessionStartOnly
Whether to perform reset on test session finish (false
) or not (true
). Keeping this variable set to true
and Simulator running (the default behaviour since version 1.6.4) may significantly shorten the duration of test session initialization. Defaults to true
true
or false
appium:commandTimeouts
Custom timeout(s) in milliseconds for WDA backend commands execution. This might be useful if WDA backend freezes unexpectedly or requires too much time to fail and blocks automated test execution. The value is expected to be of type string and can either contain max milliseconds to wait for each WDA command to be executed before terminating the session forcefully or a valid JSON string, where keys are internal Appium command names (you can find these in logs, look for \"Executing command 'command_name'\" records) and values are timeouts in milliseconds. You can also set the 'default' key to assign the timeout for all other commands not explicitly enumerated as JSON keys. '120000'
, '{\"findElement\": 40000, \"findElements\": 40000, \"setValue\": 20000, \"default\": 120000}'
appium:useJSONSource
Get JSON source from WDA and transform it to XML on the Appium server side. Defaults to false
. true
appium:skipLogCapture
Skips to start capturing logs such as crash, system, safari console and safari network. It might improve performance such as network. Log related commands will not work. Defaults to false
. true
or false
appium:launchWithIDB
Launch WebDriverAgentRunner with idb instead of xcodebuild. This could save a significant amout of time by skiping the xcodebuild process, although the idb might not be very reliable, especially with fresh Xcode SDKs. Check the idb repository for more details on possible compatibility issues. Defaults to false
true
or false
appium:showIOSLog
Whether to show any logs captured from a device in the appium logs. Default false
true
or false
appium:clearSystemFiles
Whether to clean temporary XCTest files (for example logs) when a testing session is closed. false
by default true
or false
appium:newCommandTimeout
How long (in seconds) the driver should wait for a new command from the client before assuming the client has stopped sending requests. After the timeout the session is going to be deleted. 60
seconds by default. Setting it to zero disables the timer. 100
"},{"location":"reference/commands/","title":"Commands","text":"The driver comes with a set of many available commands, in addition to the commands included in the Appium base driver. Refer to the documentation of your Appium client for the exact syntax to call these commands.
Please note that most of the driver-specific functionality is available using Execute Methods instead.
Info
Check the Appium base driver documentation for commands inherited by the XCUITest driver
"},{"location":"reference/commands/#getclipboard","title":"getClipboard
","text":"POST
/session/:sessionId/appium/device/get_clipboard
Gets the content of the primary clipboard on the device under test. See Get/Set Clipboard for more details
"},{"location":"reference/commands/#arguments","title":"Arguments","text":"Name TypecontentType?
any
"},{"location":"reference/commands/#returned-result","title":"Returned Result","text":"string
The actual clipboard content encoded into base64 string. An empty string is returned if the clipboard contains no data.
"},{"location":"reference/commands/#setclipboard","title":"setClipboard
","text":"POST
/session/:sessionId/appium/device/set_clipboard
Sets the primary clipboard's content on the device under test. See Get/Set Clipboard for more details
"},{"location":"reference/commands/#arguments_1","title":"Arguments","text":"Name Type Descriptioncontent
any
- contentType?
any
- label?
string
The content to be set as base64 encoded string."},{"location":"reference/commands/#returned-result_1","title":"Returned Result","text":"null
getGeoLocation
","text":"GET
/session/:sessionId/location
Returns the location of the device under test. Location Services for WebDriverAgent must be set to 'Always' to get the location data correctly.
The 'latitude', 'longitude' and 'altitude' could be zero even if the Location Services are set to 'Always', because the device may need some time to update the location data.
Throws
If the device under test returns an error message. i.e.: tvOS returns unsupported error
"},{"location":"reference/commands/#returned-result_2","title":"Returned Result","text":"Promise
<altitude
: number
, latitude
: number
, longitude
: number
>
setGeoLocation
","text":"POST
/session/:sessionId/location
Set location of the device under test.
For iOS 17+ real devices, this method will call the mobile: setSimulatedLocation
extension.
location
Location
An object with latitude
and longitude
values"},{"location":"reference/commands/#returned-result_3","title":"Returned Result","text":"Promise
<altitude
: number
, latitude
: number
, longitude
: number
>
startRecordingScreen
","text":"POST
/session/:sessionId/appium/start_recording_screen
Start recording the device screen. This functionality is available in the iOS Simulator since Xcode 9, and in real devices since iOS 11.
Screen activity is recorded to an MPEG-4 file. Note that audio is not recorded with the video file. If the screen recording has already been started, this command will force stop it and start a new recording. The previously recorded video file will also be deleted.
Info
This command requires the ffmpeg
utility to be installed (brew install ffmpeg
)
Throws
If the screen recording has failed to start.
"},{"location":"reference/commands/#arguments_3","title":"Arguments","text":"Name Typeoptions?
any
"},{"location":"reference/commands/#returned-result_4","title":"Returned Result","text":"string
Base64-encoded content of the recorded media file if any screen recording is currently running, or an empty string.
"},{"location":"reference/commands/#stoprecordingscreen","title":"stopRecordingScreen
","text":"POST
/session/:sessionId/appium/stop_recording_screen
Stop an ongoing screen recording and return the video. This functionality is available in the iOS Simulator since Xcode 9, and in real devices since iOS 11.
If no screen recording process is running, the command will attempt to retrieve the most recently recorded file. If no previously recorded file is found, the method will return an empty string.
Throws
If there was an error while getting the name of a media file, or the file content cannot be uploaded to the remote location.
"},{"location":"reference/commands/#arguments_4","title":"Arguments","text":"Name Typeoptions?
any
"},{"location":"reference/commands/#returned-result_5","title":"Returned Result","text":"null
| string
Base64-encoded content of the recorded media file if remotePath
parameter is empty or null, or an empty string.
getSize
","text":"GET
/session/:sessionId/element/:elementId/size
Get the size of an element
"},{"location":"reference/commands/#returned-result_6","title":"Returned Result","text":"Size
The positions of the element
"},{"location":"reference/commands/#submit","title":"submit
","text":"POST
/session/:sessionId/element/:elementId/submit
Submit the form an element is in
"},{"location":"reference/commands/#returned-result_7","title":"Returned Result","text":"null
background
","text":"Note
We recommend using the mobile: backgroundApp
extension instead
POST
/session/:sessionId/appium/app/background
Close app (simulate device home button). It is possible to restore the app after the timeout or keep it minimized based on the parameter value.
"},{"location":"reference/commands/#arguments_5","title":"Arguments","text":"Name Typeseconds
any
"},{"location":"reference/commands/#returned-result_8","title":"Returned Result","text":"unknown
queryAppState
","text":"Note
We recommend using the mobile: queryAppState
extension instead
POST
/session/:sessionId/appium/device/app_state
Get the running state of an app
"},{"location":"reference/commands/#returned-result_9","title":"Returned Result","text":"AppState
A number representing the state. 0
means not installed, 1
means not running, 2
means running in background but suspended, 3
means running in the background, and 4
means running in the foreground
isLocked
","text":"Note
We recommend using the mobile: isLocked
extension instead
POST
/session/:sessionId/appium/device/is_locked
Determine whether the device is locked
"},{"location":"reference/commands/#returned-result_10","title":"Returned Result","text":"boolean
true
if the device is locked, false
otherwise
lock
","text":"Note
We recommend using the mobile: lock
extension instead
POST
/session/:sessionId/appium/device/lock
Lock the device (and optionally unlock the device after a certain amount of time)
Default Value
0
"},{"location":"reference/commands/#arguments_6","title":"Arguments","text":"Name Typeseconds?
any
"},{"location":"reference/commands/#returned-result_11","title":"Returned Result","text":"null
unlock
","text":"Note
We recommend using the mobile: unlock
extension instead
POST
/session/:sessionId/appium/device/unlock
Unlock the device
"},{"location":"reference/commands/#returned-result_12","title":"Returned Result","text":"null
mobileShake
","text":"Note
We recommend using the mobile: shake
extension instead
POST
/session/:sessionId/appium/device/shake
Shake the device
"},{"location":"reference/commands/#returned-result_13","title":"Returned Result","text":"null
getStrings
","text":"Note
We recommend using the mobile: getAppStrings
extension instead
POST
/session/:sessionId/appium/app/strings
Return the language-specific strings for an app
"},{"location":"reference/commands/#arguments_7","title":"Arguments","text":"Name Type Default value Descriptionlanguage?
any
undefined
- stringFile?
string
null
The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned"},{"location":"reference/commands/#returned-result_14","title":"Returned Result","text":"StringRecord
<string
>
A record of localized keys to localized text
"},{"location":"reference/commands/#click","title":"click
","text":"Deprecated
This method is deprecated. Please use the mobile: tap
extension instead
POST
/session/:sessionId/touch/click
Click/tap an element
See
https://w3c.github.io/webdriver/#element-click
"},{"location":"reference/commands/#arguments_8","title":"Arguments","text":"Name Typeelement
any
"},{"location":"reference/commands/#returned-result_15","title":"Returned Result","text":"any
setValueImmediate
","text":"Deprecated
This method is deprecated
POST
/session/:sessionId/appium/element/:elementId/value
text
any
"},{"location":"reference/commands/#returned-result_16","title":"Returned Result","text":"null
keys
","text":"Deprecated
This method is deprecated. Please use setValue
instead
POST
/session/:sessionId/keys
Send keys to the app
"},{"location":"reference/commands/#arguments_10","title":"Arguments","text":"Name Typevalue
any
"},{"location":"reference/commands/#returned-result_17","title":"Returned Result","text":"null
receiveAsyncResponse
","text":"Deprecated
This method is deprecated
POST
/session/:sessionId/appium/receive_async_response
Collect the response of an async script execution
"},{"location":"reference/commands/#arguments_11","title":"Arguments","text":"Name Typeresponse
any
"},{"location":"reference/commands/#returned-result_18","title":"Returned Result","text":"null
toggleEnrollTouchId
","text":"Deprecated
This method is deprecated. Please use the mobile: enrollBiometric
extension instead
POST
/session/:sessionId/appium/simulator/toggle_touch_id_enrollment
Toggle whether the device is enrolled in the touch ID program
"},{"location":"reference/commands/#arguments_12","title":"Arguments","text":"Name Type Default valueenabled?
any
true
"},{"location":"reference/commands/#returned-result_19","title":"Returned Result","text":"null
touchId
","text":"Deprecated
This method is deprecated. Please use the mobile: sendBiometricMatch
extension instead
POST
/session/:sessionId/appium/simulator/touch_id
Trigger a touch/fingerprint match or match failure
"},{"location":"reference/commands/#arguments_13","title":"Arguments","text":"Name Type Default valuematch
any
true
"},{"location":"reference/commands/#returned-result_20","title":"Returned Result","text":"null
asyncScriptTimeout
","text":"Deprecated
This method is deprecated. Please use scriptTimeoutW3C
instead
POST
/session/:sessionId/timeouts/async_script
Alias for XCUITestDriver.scriptTimeoutW3C.
"},{"location":"reference/commands/#arguments_14","title":"Arguments","text":"Name Typems
any
"},{"location":"reference/commands/#returned-result_21","title":"Returned Result","text":"null
getLocation
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/element/:elementId/location
Get the position of an element on screen
"},{"location":"reference/commands/#returned-result_22","title":"Returned Result","text":"Position
The position of the element
"},{"location":"reference/commands/#getlocationinview","title":"getLocationInView
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/element/:elementId/location_in_view
Alias for getLocation
Position
The position of the element
"},{"location":"reference/commands/#getwindowsize","title":"getWindowSize
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/window/:windowhandle/size
Get the window size
"},{"location":"reference/commands/#returned-result_24","title":"Returned Result","text":"any
performMultiAction
","text":"Deprecated
This method is deprecated. Please use performActions
instead
POST
/session/:sessionId/touch/multi/perform
Perform a set of touch actions
"},{"location":"reference/commands/#arguments_15","title":"Arguments","text":"Name Typeactions
any
elementId?
any
"},{"location":"reference/commands/#returned-result_25","title":"Returned Result","text":"unknown
performTouch
","text":"Deprecated
This method is deprecated. Please use performActions
instead
POST
/session/:sessionId/touch/perform
Perform a set of touch actions
"},{"location":"reference/commands/#arguments_16","title":"Arguments","text":"Name Typeactions
any
"},{"location":"reference/commands/#returned-result_26","title":"Returned Result","text":"unknown
The XCUITest driver supports the following element attributes:
Name Description Examplename
Could contain either element's identifier or its label, depending on which one is available first. Could also be null
. It is recommended to prefer the usage of accessibilityIdentifier over accessibilityLabel for automation purposes, since the identifier
property is supposed to stay constant under different locales and does not affect accessibility services such as VoiceOver. hello
label
Element's label value. Could be null
. Since XCUITest driver 4.7.3 (WebDriverAgent 4.8.0), the behavior of this value was better aligned with XCTest, so it could include line breaks (\\n
). Before this version, line breaks were replaced by spaces. hello
, hello\\nworld
type
Element's type name XCUIElementTypeButton
visible
Whether the element is visible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer false
focused
Whether the element is focused. Before driver version 4.25.4, this was only available for tvOS. true
accessible
Whether the element is accessible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer true
enabled
Whether the element is enabled. false
selected
Whether the element is selected false
index
Element's index in the hierarchy relatively to its parent. Only available since Appium 1.20.0. Indexing starts from 0
. 2
rect
Element's rectangle. The actual data of this attribute is based on element's frame. {'x': 0, 'y': 0, 'width': 100, 'height': 100}
value
Element's value. This is a complex attribute, whose calculation algorithm depends on the actual element type. Check WebDriverAgent sources to know more about how it is compiled (method - (NSString *)wdValue
). Could be null
hello
hittable
Whether the element is hittable. This attribute is not included into the XML page source due to performance reasons, although you can use it in element locators or fetch its value using getAttribute API. Available since driver version 4.35. true
"},{"location":"reference/execute-methods/","title":"Execute Methods","text":"In addition to standard W3C APIs, the driver provides many custom command extensions for executing platform-specific scenarios. Use the following examples in order to invoke them from your client code:
JavaJS (WebdriverIO)PythonRubyC#var result = driver.executeScript(\"mobile: <methodName>\", Map.ofEntries(\n Map.entry(\"arg1\", \"value1\"),\n Map.entry(\"arg2\", \"value2\")\n // you may add more pairs if needed or skip providing the map completely\n // if all arguments are defined as optional\n));\n
const result = await driver.executeScript('mobile: <methodName>', [{\n arg1: \"value1\",\n arg2: \"value2\",\n}]);\n
result = driver.execute_script('mobile: <methodName>', {\n 'arg1': 'value1',\n 'arg2': 'value2',\n})\n
result = @driver.execute_script 'mobile: <methodName>', {\n arg1: 'value1',\n arg2: 'value2',\n}\n
object result = driver.ExecuteScript(\"mobile: <methodName>\", new Dictionary<string, object>() {\n {\"arg1\", \"value1\"},\n {\"arg2\", \"value2\"}\n}));\n
"},{"location":"reference/execute-methods/#mobile-selectpickerwheelvalue","title":"mobile: selectPickerWheelValue","text":"Performs selection of the next or previous picker wheel value. This might be useful if these values are populated dynamically, so you don't know which one to select or value selection suing sendKeys
API does not work because of an XCTest bug. The method throws an exception if it fails to change the current picker value.
element
before version 1.22) string yes PickerWheel's internal element id (as hexadecimal hash string) to perform value selection on. The element must be of type XCUIElementTypePickerWheel abcdef12-1111-2222-3333-444444 order string yes Either next
to select the value next to the current one from the target picker wheel or previous
to select the previous one. next offset number no The value in range [0.01, 0.5]. It defines how far from picker wheel's center the click should happen. The actual distance is calculated by multiplying this value to the actual picker wheel height. Too small offset value may not change the picker wheel value and too high value may cause the wheel to switch two or more values at once. Usually the optimal value is located in range [0.15, 0.3]. 0.2
by default 0.15 value string no If provided WDA will try to automatically scroll in the given direction until the actual picker value reaches the expected one or the amount of scrolling attempts is exceeded. myvalue maxAttempts number no The maximum number of scrolling attempts to reach value
before an error will be thrown. Only makes sense in combination with value
. 25 by default 50"},{"location":"reference/execute-methods/#mobile-alert","title":"mobile: alert","text":"Tries to apply the given action to the currently visible alert.
"},{"location":"reference/execute-methods/#arguments_1","title":"Arguments","text":"Name Type Required Description Example action string yes The actual action to apply. Could be either:accept
, dismiss
or getButtons
accept buttonLabel string no The name of the button used to perform the chosen alert action. Only makes sense if the action is accept
or dismiss
Accept"},{"location":"reference/execute-methods/#returned-result","title":"Returned Result","text":"The list of alert button names if the selected action is getButtons
Sets the Simulator's pasteboard content to the given value. Does not work for real devices.
"},{"location":"reference/execute-methods/#arguments_2","title":"Arguments","text":"Name Type Required Description Example content string yes The content to set hello encoding string no The content's encoding.utf8
by default ascii"},{"location":"reference/execute-methods/#mobile-getpasteboard","title":"mobile: getPasteboard","text":"Gets the Simulator's pasteboard content. Does not work for real devices.
"},{"location":"reference/execute-methods/#arguments_3","title":"Arguments","text":"Name Type Required Description Example encoding string no The expected encoding of the returned string.utf8
by default ascii"},{"location":"reference/execute-methods/#returned-result_1","title":"Returned Result","text":"The pasteboard content string.
"},{"location":"reference/execute-methods/#mobile-source","title":"mobile: source","text":"Allows to retrieve the source tree of the current page in different representation formats.
"},{"location":"reference/execute-methods/#arguments_4","title":"Arguments","text":"Name Type Required Description Example format string yes One of possible page tree source representation formats:xml
(the default value), description
and json
. The xml
format generates the output similar to what getPageSource
standard API returns. description
representation is how XCTest \"sees\" the page internally and is the same string as debugDescription API would return for the root application element. This source representation format is useful for debugging purposes and is the fastest one to fetch. json
representation is similar to xml
, but the tree hierarchy there is represented as JSON elements tree rather than as XML nodes. description excludedAttributes string no One or more comma-separated attribute names to be excluded from the XML output, thus only makes sense if format
is set to xml
. It might be sometimes helpful to exclude, for example, the visible
attribute, to significantly speed-up page source retrieval. visible,accessible"},{"location":"reference/execute-methods/#returned-result_2","title":"Returned Result","text":"The page source tree formatted according to the given format argument.
"},{"location":"reference/execute-methods/#mobile-getcontexts","title":"mobile: getContexts","text":"Retrieves the list of available contexts including the extended context information, like urls and page names. This is different from the standard getContexts
API, because the latter only has web view names without any additional information. In situation where multiple web views are available at once the client code would have to connect to each of them in order to detect the one, which needs to be interacted with. Although, this extra effort is not needed with the information provided by this extension.
5000
ms by default 10000"},{"location":"reference/execute-methods/#returned-result_3","title":"Returned Result","text":"The list of available context objects along with their properties:
null
null
Installs the given application to the device under test. Make sure the app is built for a correct architecture and is signed with a proper developer signature (for real devices) prior to install it.
"},{"location":"reference/execute-methods/#arguments_6","title":"Arguments","text":"Name Type Required Description Example app string yes See the description of theappium:app
capability /path/to/my.app timeoutMs number no The maximum time to wait until app install is finished in milliseconds on real devices. If not provided then the value of appium:appPushTimeout
capability is used. If the capability is not provided then equals to 240000ms 500000 strategy string no One of possible app installation strategies on real devices. This argument is ignored on simulators. If not provided then the value of appium:appInstallStrategy
is used. If the latter is also not provided then serial
is used. See the description of appium:appInstallStrategy
capability for more details on available values. parallel"},{"location":"reference/execute-methods/#mobile-isappinstalled","title":"mobile: isAppInstalled","text":"Checks whether the given application is installed on the device under test. Offloaded applications are handled as not installed.
"},{"location":"reference/execute-methods/#arguments_7","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be checked com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_4","title":"Returned Result","text":"Either true
or false
Removes the given application from the device under test. Offloaded application can also be removed.
For real devices, please also check how to explicitly clear the application local data.
"},{"location":"reference/execute-methods/#arguments_8","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be removed com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_5","title":"Returned Result","text":"Either true
if the app was successfully uninstalled, otherwise false
Executes the given app on the device under test. If the app is already running then it would be activated. If the app is not installed or cannot be launched then an exception is thrown.
"},{"location":"reference/execute-methods/#arguments_9","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be launched com.mycompany.myapp arguments string|array no One or more command line arguments for the app. If the app is already running then this argument is ignored. ['-s', '-m'] environment dict no Environment variables mapping for the app. If the app is already running then this argument is ignored. {'var': 'value'}"},{"location":"reference/execute-methods/#mobile-terminateapp","title":"mobile: terminateApp","text":"Terminates the given app on the device under test via XCTest's terminate API. If the app is not installed an exception is thrown. If the app is not running then nothing is done.
"},{"location":"reference/execute-methods/#arguments_10","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be terminated com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_6","title":"Returned Result","text":"Either true
if the app was successfully terminated, otherwise false
Kill the given app on the real device under test by instruments service. If the app is not running or failed to kill, then nothing is done.
XCUITest driver 4.4 and higher does not require py-ios-device. XCUITest driver 4.3 requires py-ios-device.
"},{"location":"reference/execute-methods/#arguments_11","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be terminated com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_7","title":"Returned Result","text":"Either true
if the app was successfully killed, otherwise false
Queries the state of an installed application from the device under test. An exception will be thrown if the app with given identifier is not installed.
"},{"location":"reference/execute-methods/#arguments_12","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be queried com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_8","title":"Returned Result","text":"An integer number is returned, which encodes the application state. Possible values are described in XCUIApplicationState XCTest documentation topic.
"},{"location":"reference/execute-methods/#mobile-activateapp","title":"mobile: activateApp","text":"Puts the given application to foreground if it is running in the background. An error is thrown if the app is not installed or is not running. Nothing is done if the app is already running in the foreground.
"},{"location":"reference/execute-methods/#arguments_13","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be activated com.mycompany.myapp"},{"location":"reference/execute-methods/#mobile-listapps","title":"mobile: listApps","text":"List applications installed on the real device under test. This extension throws an error if called for a Simulator device. Offload applications will not be in the result.
"},{"location":"reference/execute-methods/#arguments_14","title":"Arguments","text":"Name Type Required Description Example applicationType string no The type of applications to list. EitherSystem
or User
(the default one) System"},{"location":"reference/execute-methods/#returned-result_9","title":"Returned Result","text":"A list of apps, where each item is a map where keys are bundle identifiers and values are maps of platform-specific app properties. Having UIFileSharingEnabled
set to true
in the app properties map means this app supports files upload and download into its documents
container. Read the File Transfer guide for more details.
Deletes data files from the data container of an installed app, so it could start from the clean state next time it is launched. The destination app will be terminated if it is running when this API is invoked. Sometimes it might also be necessary to invoke the following APIs to fully reset the state of an installed app (make sure the app is not running while calling them): - mobile: clearKeychains - mobile: resetPermission
This API might not be 100% reliable for some apps. The only reliable method to fully reset an existing app that Apple supports is to uninstall it and then perform a fresh install of the same app.
This API only works on simulators. An exception is thrown if executed with real devices.
"},{"location":"reference/execute-methods/#arguments_15","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be cleared com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_10","title":"Returned Result","text":"true
if at least one item has been successfully deleted from the app data container.
Starts performance profiling for the device under test. Relaxing security is mandatory for simulators. It can always work for real devices. Since XCode 12 the method tries to use xctrace
tool to record performance stats. The instruments
developer utility is used as a fallback for this purpose if xctrace
is not available. It is possible to record multiple profiles at the same time. Read Instruments User Guide for more details. If the recording for the given profile is already running then nothing is done.
300000
ms by default (5 minutes) 600000
profileName string no The name of existing performance profile to apply. Can also contain the full path to the chosen template on the server file system. Note, that not all profiles are supported on mobile devices. Activity Monitor
by default. Time Profile
pid string or number no The ID of the process to measure the performance for. Set it to current
in order to measure the performance of the process, which belongs to the currently active application. All processes running on the device are measured if pid is unset (the default setting). current"},{"location":"reference/execute-methods/#mobile-stopperfrecord","title":"mobile: stopPerfRecord","text":"Stops the performance recording operation previosuly started by mobile: startPerfRecord
call. If the previous call has already been completed due to the timeout then its result is returned immediately. An error is thrown if the performance recording has failed to start and recorded no data.
Activity Monitor
by default. Time Profile
remotePath string no The path to the remote location, where the resulting zipped .trace file should be uploaded. The following protocols are supported: http/https, ftp Null or empty string value (the default setting) means the content of resulting file should be zipped, encoded as Base64 and passed as the endpoint response value. An exception will be thrown if the generated file is too big to fit into the available process memory. https://myserver/upload user string no The name of the user for the remote authentication. Only works if remotePath
is provided. myuser pass string no The password for the remote authentication. Only works if remotePath
is provided. mypassword method string no The http multipart upload method name. Only works if remotePath
is provided. PUT
by default POST headers dict no Additional headers mapping for multipart http(s) uploads {'User-Agent': 'Myserver 1.0'} fileFieldName string no The name of the form field, where the file content BLOB should be stored for http(s) uploads. file
by default payload formFields dict or array no Additional form fields for multipart http(s) uploads {'field2': 'value2'}"},{"location":"reference/execute-methods/#returned-result_11","title":"Returned Result","text":"The resulting file in .trace format can be either returned directly as base64-encoded zip archive or uploaded to a remote location (such files could be pretty large), depending on the remotePath
argument value. Afterwards it is possible to unarchive and open such file with Xcode Developer Tools.
Installs a custom certificate onto the device. Since Xcode SDK 11.4 Apple has added a dedicated simctl subcommand to quickly handle certificates on Simulator over CLI. On real devices the certificate could be installed via CLI if py-ios-device tool is available on the server machine. On simulators before Xcode 11.4 SDK Apple provides no official way to do it via the command line. In such case (and also as a fallback if CLI setup fails) this method tries to wrap the certificate into .mobileconfig format and then deploys the wrapped file to the internal HTTP server, so one can open it via mobile Safari. Then the algorithm goes through the profile installation procedure by clicking the necessary buttons using WebDriverAgent.
"},{"location":"reference/execute-methods/#arguments_18","title":"Arguments","text":"Name Type Required Description Example content string yes Base64-encoded content of the public certificate in PEM format a23234... commonName string no Common name of the certificate. If this is not set then the script will try to parse it from the given certificate content. com.myorg isRoot boolean no This option defines where the certificate should be installed to: either Trusted Root Store (true
, the default option) or the Keychain (false
). On environments other than Xcode 11.4+ Simulator this option is ignored. false"},{"location":"reference/execute-methods/#returned-result_12","title":"Returned Result","text":"The content of the generated .mobileconfig file as base64-encoded string. This config might be useful for debugging purposes. If the certificate has been successfully set via CLI then nothing is returned.
"},{"location":"reference/execute-methods/#mobile-removecertificate","title":"mobile: removeCertificate","text":"Removes installed certificate for real devices only if py-ios-device tool is available on the server machine since driver version 4.19.2.
"},{"location":"reference/execute-methods/#arguments_19","title":"Arguments","text":"Name Type Required Description Example name string yes Name of the profile com.orgname.profile.mdmprofile"},{"location":"reference/execute-methods/#returned-result_13","title":"Returned Result","text":"Returns status acknowledgment {'Status': 'Acknowledged'}
if successfully removed certificate or None
if unable to remove certificate.
Lists installed certificates for real devices only if py-ios-device tool is available on the server machine since driver version 4.10.0.
"},{"location":"reference/execute-methods/#returned-result_14","title":"Returned Result","text":"Returns map of certificates installed on the real device. The response looks like:
{\n 'OrderedIdentifiers': ['com.orgname.profile.mdmprofile'],\n 'ProfileManifest': {\n 'com.orgname.profile.mdmprofile': {\n 'Description': 'MDM Profile',\n 'IsActive': True\n }\n },\n 'ProfileMetadata': {\n 'com.orgname.profile.mdmprofile': {\n 'PayloadDescription': 'MDM Profile for testing,\n 'PayloadDisplayName': 'MDM Profile',\n 'PayloadOrganization': 'My Org, Inc.',\n 'PayloadRemovalDisallowed': False,\n 'PayloadUUID': '9ab3fa27-cc45-4c23-a94a-714686397a86',\n 'PayloadVersion': 1\n }\n },\n 'Status': 'Acknowledged'\n}\n
"},{"location":"reference/execute-methods/#mobile-startlogsbroadcast","title":"mobile: startLogsBroadcast","text":"Starts iOS system logs broadcast websocket on the same host and port where Appium server is running at /ws/session/:sessionId:/appium/syslog
endpoint. The method will return immediately if the web socket is already listening. Each connected webcoket listener will receive syslog lines as soon as they are visible to Appium. Read Using Mobile Execution Commands to Continuously Stream Device Logs with Appium Appium Pro article for more details on this feature.
Stops the syslog broadcasting wesocket server previously started by mobile: startLogsBroadcast
. This method will return immediately if no server is running.
Reads the battery information from the device under test. This endpoint only returns reliable result on real devices.
"},{"location":"reference/execute-methods/#returned-result_15","title":"Returned Result","text":"The actual battery info map, which consists of the following entries:
Returns the miscellaneous information about the device under test. It includes device information via lockdown in a real device since XCUITest driver 4.2.0.
"},{"location":"reference/execute-methods/#returned-result_16","title":"Returned Result","text":"Check the + (id<FBResponsePayload>)handleGetDeviceInfo:(FBRouteRequest *)request
method in FBCustomCommands.m for more details on the available map entries.
Returns the actual device time.
"},{"location":"reference/execute-methods/#arguments_20","title":"Arguments","text":"Name Type Required Description Example format string no The format specifier string. Read MomentJS documentation to get the full list of supported datetime format specifiers. The default format isYYYY-MM-DDTHH:mm:ssZ
, which complies to ISO-8601 YYYY-MM-DD HHss"},{"location":"reference/execute-methods/#returned-result_17","title":"Returned Result","text":"The retrieved datetime string formatted according to the given format specfier.
"},{"location":"reference/execute-methods/#mobile-activeappinfo","title":"mobile: activeAppInfo","text":"Returns information about the active application.
"},{"location":"reference/execute-methods/#returned-result_18","title":"Returned Result","text":"Check the + (id<FBResponsePayload>)handleActiveAppInfo:(FBRouteRequest *)request
method in FBCustomCommands.m for more details on the available map entries.
Emulates press action on the given physical device button. iOS is pressButton:, tvOS is pressButton: or pressButton:forDuration:. mobile: performIoHidEvent calls a more universal API to perform press with duration on any supported device.
"},{"location":"reference/execute-methods/#arguments_21","title":"Arguments","text":"Name Type Required Description Example name string yes The name of the button to be pressed. Supported button names for iOS-based devices are (case-insensitive):home
, volumeup
, volumedown
. For tvOS-based devices (case-insensitive): home
, up
, down
, left
, right
, menu
, playpause
, select
home durationSeconds number no Duration in float seconds for tvOS-based devices since Appium 1.22.0 10"},{"location":"reference/execute-methods/#mobile-pushnotification","title":"mobile: pushNotification","text":"Simulates push notification delivery to Simulator. Only application remote push notifications are supported. VoIP, Complication, File Provider, and other types are not supported. Check the output of xcrun simctl help push
command for more details.
Create the JSON Payload
topic of the official Apple documentation for more details on the payload creation. {\"aps\": {\"alert\": {\"title\": \"This is a simulated notification!\"}, \"badge\": 3, \"sound\": \"default\"} }
"},{"location":"reference/execute-methods/#mobile-expectnotification","title":"mobile: expectNotification","text":"Blocks until the expected notification is delivered. It is a thin wrapper over XCTNSNotificationExpectation and XCTDarwinNotificationExpectation entities. The extension call throws TimeoutError if the expected notification has not been delivered within the given timeout.
"},{"location":"reference/execute-methods/#arguments_23","title":"Arguments","text":"Name Type Required Description Example name string yes The name of the notification to expect com.example.fooAllDone type string no Which notification type to expect. Eitherplain
(the default value) to wait for a notification from the default notification center or darwin
to wait for a system notification. darwin timeoutSeconds number no For how long to wait until the notification is delivered in float seconds. 60 seconds by default 5.5"},{"location":"reference/execute-methods/#mobile-performiohidevent","title":"mobile: performIoHidEvent","text":"Emulates triggering of the given low-level IO HID device event. Constants for possible events are defined in HID Usage Tables. For example, in order to emulate single press on Home button the extension should be called with the following arguments: - page: 0x0C
(kHIDPage_Consumer
, select the Customer
page) - usage: 0x40
(kHIDUsage_Csmr_Menu
, the Csmr
prefix here means this usage is dedicated to the Customer
page) - durationSeconds: 0.005
(The event duration should be 5 milliseconds to be recognized as a single press by iOS)
Some popular constants:
Name Value Description kHIDPage_Consumer 0x0C The page containing all usages prefixed withkHIDUsage_Csmr_
kHIDUsage_Csmr_VolumeIncrement 0xE9 Volume Up kHIDUsage_Csmr_VolumeDecrement 0xEA Volume Down kHIDUsage_Csmr_Menu 0x40 Home kHIDUsage_Csmr_Power 0x30 Power/Lock kHIDUsage_Csmr_Snapshot 0x65 Power + Home"},{"location":"reference/execute-methods/#arguments_24","title":"Arguments","text":"Name Type Required Description Example page int yes The event page identifier. Look for constants perfixed with kHIDPage_
in the table above 0x0C usage int yes The event usage identifier (usages are defined per-page). Look for constants prefixed with kHIDUsage_
in the table above 0x40 durationSeconds number yes The event duration in float seconds. XCTest uses 0.005
for a single press event duration 2.5"},{"location":"reference/execute-methods/#mobile-enrollbiometric","title":"mobile: enrollBiometric","text":"Enrolls biometric authentication on Simulator.
"},{"location":"reference/execute-methods/#arguments_25","title":"Arguments","text":"Name Type Required Description Example isEnabled boolean no Whether to enable/disable biometric enrollment.true
by default. true"},{"location":"reference/execute-methods/#mobile-sendbiometricmatch","title":"mobile: sendBiometricMatch","text":"Emulates biometric match/non-match event on Simulator. The biometric feature is expected to be already enrolled before executing that.
"},{"location":"reference/execute-methods/#arguments_26","title":"Arguments","text":"Name Type Required Description Example type string no The biometric feature name. EithertouchId
or faceId
. touchId
by default. faceId match boolean no Whether to simulate biometric match (true
, the default value) or non-match (false
). true"},{"location":"reference/execute-methods/#mobile-isbiometricenrolled","title":"mobile: isBiometricEnrolled","text":"Checks whether biometric is currently enrolled or not on a Simulator device.
"},{"location":"reference/execute-methods/#returned-result_19","title":"Returned Result","text":"Either true
or false
Clears keychains on Simulator. An exception is thrown for real devices.
"},{"location":"reference/execute-methods/#mobile-getpermission","title":"mobile: getPermission","text":"Gets application permission state on Simulator. This method requires WIX applesimutils to be installed on the host where Appium server is running.
"},{"location":"reference/execute-methods/#arguments_27","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the destination app. com.mycompany.myapp service string yes One of available service names. The following services are supported:calendar
, camera
, contacts
, homekit
, microphone
, photos
, reminders
, medialibrary
, motion
, health
, siri
, speech
. true"},{"location":"reference/execute-methods/#returned-result_20","title":"Returned Result","text":"Either 'yes', 'no', 'unset' or 'limited'
"},{"location":"reference/execute-methods/#mobile-setpermission","title":"mobile: setPermission","text":"Set application permission state on Simulator.
location
and location-always
services are by xcrun simctl privacy
command since XCUITest driver version 5.11.0. The command will kill the bundleId
application process if it is running.
Other services such as contacts
are processed by WIX applesimutils, which will not kill the bundleId
application process. WIX applesimutils needs to be installed on the host where Appium server is running.
all
(Apply the action to all services), calendar
(Allow access to calendar), contacts-limited
(Allow access to basic contact info), contacts
(Allow access to full contact details), location
(Allow access to location services when app is in use), location-always
(Allow access to location services at all times), photos-add
(Allow adding photos to the photo library), photos
(Allow full access to the photo library), media-library
(Allow access to the media library), microphone
(Allow access to audio input), motion
(Allow access to motion and fitness data), reminders
(Allow access to reminders), siri
(Allow use of the app with Siri.). The following values are supported: yes
(To grant the permission), no
(To revoke the permission), unset
(To reset the permission) {'all': 'yes'}"},{"location":"reference/execute-methods/#mobile-resetpermission","title":"mobile: resetPermission","text":"Resets the given permission for the active application under test. Works for both Simulator and real devices using Xcode SDK 11.4+
"},{"location":"reference/execute-methods/#arguments_29","title":"Arguments","text":"Name Type Required Description Example service string or int yes One of available service names. The supported service names are:calendar
, camera
, contacts
, health
, homekit
, keyboardnet
, location
, medialibrary
, microphone
, photos
, reminders
, systemroot
, userdesktop
, userdocuments
, userdownloads
, bluetooth
. This could also be an integer protected resource identifier taken from XCUIProtectedResource photos"},{"location":"reference/execute-methods/#mobile-getappearance","title":"mobile: getAppearance","text":"Get the device's UI appearance style.
"},{"location":"reference/execute-methods/#returned-result_21","title":"Returned Result","text":"An object, with the following entries: - style: The device's UI appearance value. This could be one of: light
, dark
, unknown
, unsupported
Set the device's UI appearance style.
"},{"location":"reference/execute-methods/#arguments_30","title":"Arguments","text":"Name Type Required Description Example style string yes Eitherlight
or dark
dark"},{"location":"reference/execute-methods/#mobile-siricommand","title":"mobile: siriCommand","text":"Presents the Siri UI, if it is not currently active, and accepts a string which is then processed as if it were recognized speech. Check the documentation on activateWithVoiceRecognitionText XCTest method for more details.
"},{"location":"reference/execute-methods/#arguments_31","title":"Arguments","text":"Name Type Required Description Example text string yes The actual command that will be passed to Siri service Hello Siri"},{"location":"reference/execute-methods/#mobile-pullfile","title":"mobile: pullFile","text":"Pulls a remote file from the device.
"},{"location":"reference/execute-methods/#arguments_32","title":"Arguments","text":"Name Type Required Description Example remotePath string yes The path to an existing remote file on the device. See the File Transfer guide for accepted formats. If the file with the given name does not exist an exception will be thrown. @com.mycompany.myapp:documents/myfile.txt"},{"location":"reference/execute-methods/#returned-result_22","title":"Returned Result","text":"Base64-encoded string, which represents the content of the remote file.
"},{"location":"reference/execute-methods/#mobile-pushfile","title":"mobile: pushFile","text":"Pushes a local file to the device.
"},{"location":"reference/execute-methods/#arguments_33","title":"Arguments","text":"Name Type Required Description Example remotePath string yes The path on the device to where the payload should be written. The value format is similar to the one used in pullFile extension. If the file with the same name already exists then it will be silently overridden. @com.mycompany.myapp:documents/myfile.txt payload string yes Base64-encoded content of the file to be pushed. QXBwaXVt"},{"location":"reference/execute-methods/#mobile-pullfolder","title":"mobile: pullFolder","text":"Pulls a remote folder from the device.
"},{"location":"reference/execute-methods/#arguments_34","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same as for pullFile extension, but should be pointing to a remote folder @com.mycompany.myapp:documents/myfolder/"},{"location":"reference/execute-methods/#returned-result_23","title":"Returned Result","text":"Base64-encoded string, which represents the zipped content of the remote folder.
"},{"location":"reference/execute-methods/#mobile-deletefile","title":"mobile: deleteFile","text":"Deletes the given file from the device under test.
"},{"location":"reference/execute-methods/#arguments_35","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same as for pullFile extension @com.mycompany.myapp:documents/myfile.txt"},{"location":"reference/execute-methods/#mobile-deletefolder","title":"mobile: deleteFolder","text":"Deletes the given folder from the device under test.
"},{"location":"reference/execute-methods/#arguments_36","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same value as formobile: deleteFile
except of the fact it should be pointing to a folder and should end with a single slash /
@com.mycompany.myapp:documents/myfolder/"},{"location":"reference/execute-methods/#mobile-configurelocalization","title":"mobile: configureLocalization","text":"Change localization settings on the currently booted Simulator. The changed settings are only applied for the newly started applications/activities. Currently running applications will stay unchanged. This means, for example, that the keyboard should be hidden and shown again in order to observe the changed layout, and corresponding apps must be restarted in order to observe their interface using the newly set locale/language. Also this method might leave some system UI alerts untranslated. Be careful while setting the actual arguments since their actual values are not strictly checked. This could lead to an unexpected behavior if an incorrect/unsupported language or locale abbreviation is provided.
"},{"location":"reference/execute-methods/#arguments_37","title":"Arguments","text":"Name Type Required Description Example keyboard map no On-screen keyboard properties. Thename
key is required and should be set to a valid locale abbreviation. The layout
key is also required. The hardware
key is optional and could be omitted or set to Automated
. You could switch the keyboard layout in system preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleKeyboards
to see possible combinations. {\"name\": \"de_CH\", \"layout\": \"QWERTZ\", \"hardware\": \"Automated\"}
language map no System language properties. The name
key is required and should be set to a valid language abbreviation. You could switch the system language in preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleLanguages
to see possible combinations. {\"name\": \"zh-Hant-CN\"}
locale map no System locale properties. The name
key is required and should be set to a valid language abbreviation. The calendar
key is optonal and could be set to a valid calendar format name. You could switch the system locale/calendar format in preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleLocale
to see possible combinations. {\"name\": \"uk_UA\", \"calendar\": \"gregorian\"}
"},{"location":"reference/execute-methods/#returned-result_24","title":"Returned Result","text":"true
if any of settings has been successfully changed.
Records the given hardware audio input into an .mp4 file. You must allow the audio_record
security feature in order to use this extension. Also it is required that FFMpeg is installed on the machibe where Appium server is running.
ffmpeg -f avfoundation -list_devices true -i \"\"
Terminal command. 1 audioCodec string no The name of the audio codec. The Advanced Audio Codec (aac) is used by default. aac audioBitrate string no The bitrate of the resulting audio stream. 128k
by default. 256k audioChannels string or int no The count of audio channels in the resulting stream. Setting it to 1
will create a single channel (mono) audio stream. 2
By default 1 audioRate string or int no The sampling rate of the resulting audio stream. 44100 by default 22050 timeLimit string or int no The maximum recording time, in seconds. The default value is 180
, the maximum value is 43200
(12 hours). 60 forceRestart boolean no Whether to restart audio capture process forcefully when startRecordingAudio is called (true
) or ignore the call until the current audio recording is completed (false
, the default value). true"},{"location":"reference/execute-methods/#mobile-stopaudiorecording","title":"mobile: stopAudioRecording","text":"Stops recording of the audio input. If no audio recording process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active audio recording processes are running then the method returns an empty string.
"},{"location":"reference/execute-methods/#returned-result_25","title":"Returned Result","text":"Base64-encoded content of the recorded media file or an empty string if no audio recording has been started before.
"},{"location":"reference/execute-methods/#mobile-startpcap","title":"mobile: startPcap","text":"Start mobile device network traffic capture. This extension only works if py-ios-device utility is installed on the server machine and only supports real iOS devices.
"},{"location":"reference/execute-methods/#arguments_39","title":"Arguments","text":"Name Type Required Description Example timeLimitSec string or int no The maximum recording time, in seconds. The default value is180
, the maximum value is 43200
(12 hours). 60 forceRestart boolean no Whether to restart traffic capture process forcefully when startPcap is called (true
) or ignore the call until the current traffic capture is completed (false
, the default value). true"},{"location":"reference/execute-methods/#mobile-stoppcap","title":"mobile: stopPcap","text":"Stops network traffic capture. If no traffic capture process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active traffic capture processes are running then the method returns an empty string.
"},{"location":"reference/execute-methods/#returned-result_26","title":"Returned Result","text":"Base64-encoded content of the traffic capture file (.pcap) or an empty string if no traffic capture has been started before. Netowrk capture files could be opened in Wireshark application.
"},{"location":"reference/execute-methods/#mobile-runxctest","title":"mobile: runXCTest","text":"Run a native XCTest script. Launches a subprocess that runs the XC Test and blocks until it is completed. Parses the stdout of the process and returns its result as an array. Facebook's IDB tool is required to run such tests.
"},{"location":"reference/execute-methods/#arguments_40","title":"Arguments","text":"Name Type Required Description Example testRunnerBundleId string yes Test app bundle io.appium.XCTesterAppUITests.xctrunner appUnderTestBundleId string yes App-under-test bundle com.mycompany.myapp xcTestBundleID string yes xctest bundle id io.appium.XCTesterAppUITests testType string no Test type. Eitherui
(the default one), app
or logic
app env map no Environment variables mapping to be passed to the test {'myvar': 'myvalue'} args array no Launch arguments to start the test with (see https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments for reference) ['-arg1', '--arg2'] timeout string or int no Timeout if session doesn't complete after given time (in milliseconds). 360000
ms by default 120000"},{"location":"reference/execute-methods/#returned-result_27","title":"Returned Result","text":"The API calls returns a map with the following entries:
0
value marks a successful execution.null
(e.g.: SIGTERM
)Installs an XCTest bundle to the device under test. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#arguments_41","title":"Arguments","text":"Name Type Required Description Example xctestBundle string yes Path to your xctest .app bundle. Could be an URL /path/to/my/bundle.app"},{"location":"reference/execute-methods/#mobile-listxctestbundles","title":"mobile: listXCTestBundles","text":"List XCTest bundles that are installed on device. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#returned-result_28","title":"Returned Result","text":"Array of XCTest bundles (e.g.: [\"XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance\"])
"},{"location":"reference/execute-methods/#mobile-listxctestsintestbundle","title":"mobile: listXCTestsInTestBundle","text":"List XCTests in a test bundle. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#arguments_42","title":"Arguments","text":"Name Type Required Description Example bundle string yes Bundle ID of the XCTest 'com.bundle.myapp'"},{"location":"reference/execute-methods/#returned-result_29","title":"Returned Result","text":"Array of xctests in the test bundle (e.g.: [ 'XCTesterAppUITests.XCTesterAppUITests/testExample', 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance' ]
)
Retrieves the viewport dimensions. The viewport is the device's screen size with status bar size subtracted if the latter is present/visible.
"},{"location":"reference/execute-methods/#returned-result_30","title":"Returned Result","text":"The response looks like {\"value\":{\"left\":0,\"top\":96,\"width\":828,\"height\":1696}}
.
left
and top
are distance from the left
of the screen and the top
of the screen. iOS Drawing Concepts could help about the relationship of coordinate.
width
and height
are the screen's width and height.
Takes a screenshot of the device viewport (see mobile: viewportRect
)
Unreliable
This method is unreliable. We recommend using getScreenshot
instead
Base64-encoded string, which represents the viewport screenshot.
"},{"location":"reference/execute-methods/#mobile-devicescreeninfo","title":"mobile: deviceScreenInfo","text":"Get information about screen.
"},{"location":"reference/execute-methods/#returned-result_32","title":"Returned Result","text":"The response looks like {\"value\":{\"statusBarSize\":{\"width\":414,\"height\":48},\"scale\":2}}
statusBarSize
contains status bar dimensions. It is the result of status bar. scale
is screen scale.
This gesture performs a simple \"swipe\" gesture on the particular screen element or on the application element, which is usually the whole screen. This method does not accept coordinates and simply emulates single swipe with one finger. It might be useful for such cases like album pagination, switching views, etc. More advanced cases may require to call mobile: dragFromToForDuration, where one can supply coordinates and duration.
"},{"location":"reference/execute-methods/#arguments_43","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to swipe on. Application element will be used instead if this argument is not provided fe50b60b-916d-420b-8728-ee2072ec53eb direction Either 'up', 'down', 'left' or 'right' yes The direction in which to swipe up velocity number no This argument is optional and is only supported since Appium server version 1.19 and Xcode SDK version 11.4+. The value is measured in pixels per second and same values could behave differently on different devices depending on their display density. Higher values make swipe gesture faster (which usually scrolls larger areas if we apply it to a list) and lower values slow it down. Only values greater than zero have effect. 250"},{"location":"reference/execute-methods/#examples","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\nMap<String, Object> params = new HashMap<>();\nparams.put(\"direction\", \"down\");\nparams.put(\"velocity\", 2500);\nparams.put(\"element\", ((RemoteWebElement) element).getId());\njs.executeScript(\"mobile: swipe\", params);\n
"},{"location":"reference/execute-methods/#references","title":"References","text":"Scrolls the element or the whole screen. Different scrolling strategies are supported. Arguments define the choosen strategy: either 'name', 'direction', 'predicateString' or 'toVisible' in that order. All strategies are exclusive and only one strategy can be applied at a single moment of time. Use \"mobile: scroll\" to emulate precise scrolling in tables or collection views, where it is already known to which element the scrolling should be performed. Although, there is one known limitation there: in case it is necessary to perform too many scroll gestures on parent container to reach the necessary child element (tens of them) then the method call may fail. Important: The implemntation of this extension relies on several undocumented XCTest features, which might not always be reliable. Thus it might not always work as expected.
"},{"location":"reference/execute-methods/#arguments_44","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to scroll on (e.g. the container). Application element will be used if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb name string no The accessibility id of the child element, to which scrolling is performed. The same result can be achieved by setting predicateString argument to 'name == accessibilityId'. Has no effect if elementId is not a container cell12 direction Either 'up', 'down', 'left' or 'right' yes The main difference from swipe call with the same argument is that scroll will try to move the current viewport exactly to the next/previous page (the term \"page\" means the content, which fits into a single device screen) down predicateString string no The NSPredicate locator of the child element, to which the scrolling should be performed. Has no effect if elementId is not a container label == \"foo\" toVisible boolean no If set to true then asks to scroll to the first visible elementId in the parent container. Has no effect if elementId is not set true"},{"location":"reference/execute-methods/#examples_1","title":"Examples","text":"# Python\ndriver.execute_script('mobile: scroll', {'direction': 'down'});\n
"},{"location":"reference/execute-methods/#mobile-pinch","title":"mobile: pinch","text":"Performs pinch gesture on the given element or on the application element.
"},{"location":"reference/execute-methods/#arguments_45","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to pinch on. Application element will be used instead if this parameter is not provided fe50b60b-916d-420b-8728-ee2072ec53eb scale number yes Pinch scale of type float. Use a scale between 0 and 1 to \"pinch close\" or zoom out and a scale greater than 1 to \"pinch open\" or zoom in. 0.5 velocity number yes The velocity of the pinch in scale factor per second (float value) 2.2"},{"location":"reference/execute-methods/#examples_2","title":"Examples","text":"# Ruby\nexecute_script 'mobile: pinch', scale: 0.5, velocity: 1.1, element: element.ref\n
"},{"location":"reference/execute-methods/#reference","title":"Reference","text":"pinchWithScale:velocity:
"},{"location":"reference/execute-methods/#mobile-doubletap","title":"mobile: doubleTap","text":"Performs double tap gesture on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_46","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no if x and y are set The internal element identifier (as hexadecimal hash string) to double tap on fe50b60b-916d-420b-8728-ee2072ec53eb x number no if elementId is set Screen x tap coordinate of type float. 100 y number no if elementId is set Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#examples_3","title":"Examples","text":"// javascript\ndriver.execute('mobile: doubleTap', {element: element.value.ELEMENT});\n
"},{"location":"reference/execute-methods/#mobile-touchandhold","title":"mobile: touchAndHold","text":"Performs long press gesture on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_47","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no if x and y are set The internal element identifier (as hexadecimal hash string) to long tap on fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes The float duration of press action in seconds 1.5 x number no if elementId is set Screen x tap coordinate of type float. 100 y number no if elementId is set Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#examples_4","title":"Examples","text":"// c#\nDictionary<string, object> tfLongTap = new Dictionary<string, object>();\ntfLongTap.Add(\"element\", element.Id);\ntfLongTap.Add(\"duration\", 2.0);\n((IJavaScriptExecutor)driver).ExecuteScript(\"mobile: touchAndHold\", tfLongTap);\n
"},{"location":"reference/execute-methods/#reference_1","title":"Reference","text":"pressForDuration:
"},{"location":"reference/execute-methods/#mobile-twofingertap","title":"mobile: twoFingerTap","text":"Performs two finger tap gesture on the given element or on the application element.
"},{"location":"reference/execute-methods/#arguments_48","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to tap on. Application element will be used instead if this parameter is not provided fe50b60b-916d-420b-8728-ee2072ec53eb"},{"location":"reference/execute-methods/#examples_5","title":"Examples","text":"// c#\nDictionary<string, object> tfTap = new Dictionary<string, object>();\ntfTap.Add(\"element\", element.Id);\n((IJavaScriptExecutor)driver).ExecuteScript(\"mobile: twoFingerTap\", tfTap);\n
"},{"location":"reference/execute-methods/#reference_2","title":"Reference","text":"twoFingerTap
"},{"location":"reference/execute-methods/#mobile-tap","title":"mobile: tap","text":"Performs tap gesture by coordinates on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_49","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to tap on. x and y tap coordinates will be calulated relatively to the current element position on the screen if this argument is provided. Otherwise they should be calculated relatively to the active application element. fe50b60b-916d-420b-8728-ee2072ec53eb x number yes Screen x tap coordinate of type float. 100 y number yes Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#mobile-dragfromtoforduration","title":"mobile: dragFromToForDuration","text":"Performs drag and drop gesture by coordinates. This can be done either on an element or on the screen
"},{"location":"reference/execute-methods/#arguments_50","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to perform drag on. All the coordinates will be calculated relatively this this element position on the screen. Absolute screen coordinates are expected if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes Float number of seconds in range [0.5, 60]. How long the tap gesture at starting drag point should be before to start dragging 5.3 fromX number yes The x coordinate of starting drag point 100 fromY number yes The y coordinate of starting drag point 100 toX number yes The x coordinate of ending drag point 200 toY number yes The y coordinate of ending drag point 200"},{"location":"reference/execute-methods/#examples_6","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\nMap<String, Object> params = new HashMap<>();\nparams.put(\"duration\", 1.0);\nparams.put(\"fromX\", 100);\nparams.put(\"fromY\", 100);\nparams.put(\"toX\", 200);\nparams.put(\"toY\", 200);\nparams.put(\"element\", ((RemoteWebElement) element).getId());\njs.executeScript(\"mobile: dragFromToForDuration\", params);\n
"},{"location":"reference/execute-methods/#reference_3","title":"Reference","text":"clickForDuration:thenDragToElement:
"},{"location":"reference/execute-methods/#mobile-dragfromtowithvelocity","title":"mobile: dragFromToWithVelocity","text":"Initiates a press-and-hold gesture, drags to another coordinate or an element with a velocity you specify, and holds for a duration you specify.
"},{"location":"reference/execute-methods/#arguments_51","title":"Arguments","text":"Name Type Required Description Example fromElementId string no The internal element identifier (as hexadecimal hash string) to start the drag gesture from. Absolute screen coordinates are expected if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb toElementId string no The internal element identifier (as hexadecimal hash string) to end the drag gesture on. This parameter is mandatory iffromElementId
is provided fe50b60b-916d-420b-8728-ee2072ec53eb pressDuration number yes Float number of seconds in range [0, 60]. How long the tap gesture at starting drag point should be before to start dragging 0.5 holdDuration number yes Float number of seconds in range [0, 60]. The duration for which to hold over the other coordinate or the given element after dragging 0.1 velocity number yes The speed at which to move from the initial press position to the other element or coordinate, expressed in pixels per second 400 fromX number no The x coordinate of starting drag point. Must be provided if fromElementId
is not defined 100 fromY number no The y coordinate of starting drag point. Must be provided if fromElementId
is not defined 100 toX number no The x coordinate of ending drag point. Must be provided if fromElementId
is not defined 200 toY number no The y coordinate of ending drag point. Must be provided if fromElementId
is not defined 200"},{"location":"reference/execute-methods/#references_1","title":"References","text":"pressForDuration:thenDragToElement:withVelocity:thenHoldForDuration: pressForDuration:thenDragToCoordinate:withVelocity:thenHoldForDuration:
"},{"location":"reference/execute-methods/#mobile-rotateelement","title":"mobile: rotateElement","text":"Performs rotate gesture on the given element.
"},{"location":"reference/execute-methods/#arguments_52","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string yes Internal element id (as hexadecimal hash string) to perform rotation on fe50b60b-916d-420b-8728-ee2072ec53eb rotation number yes The rotation of the gesture in radians Math.PI velocity number yes The velocity of the rotation gesture in radians per second Math.PI / 4"},{"location":"reference/execute-methods/#examples_7","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\njs.executeScript(\"mobile: rotateElement\", ImmutableMap.of(\n // rotate clockwise, 90 degrees\n \"rotation\", -Math.PI / 2,\n // in approximately two seconds\n \"velocity\", Math.PI / 4,\n \"element\", ((RemoteWebElement) element).getId()\n));\n
"},{"location":"reference/execute-methods/#reference_4","title":"Reference","text":"rotate:withVelocity:
"},{"location":"reference/execute-methods/#mobile-tapwithnumberoftaps","title":"mobile: tapWithNumberOfTaps","text":"Sends one or more taps with one or more touch points since Appium 1.17.1.
"},{"location":"reference/execute-methods/#arguments_53","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string yes The internal element identifier (as hexadecimal hash string) to perform one or more taps. fe50b60b-916d-420b-8728-ee2072ec53eb numberOfTaps number yes The number of taps 2 numberOfTouches number yes The number of touch points 2"},{"location":"reference/execute-methods/#examples_8","title":"Examples","text":"# Ruby\ne = @driver.find_element :id, 'target element'\n# Taps the element with a single touch point twice\n@driver.execute_script 'mobile: tapWithNumberOfTaps', {element: e.ref, numberOfTaps: 2, numberOfTouches: 1}\n
"},{"location":"reference/execute-methods/#reference_5","title":"Reference","text":"tapWithNumberOfTaps:numberOfTouches:
"},{"location":"reference/execute-methods/#mobile-forcepress","title":"mobile: forcePress","text":"Emulates force press on the given element/coordinates. An error is thrown if the target device does not support force press gesture.
"},{"location":"reference/execute-methods/#arguments_54","title":"Arguments","text":"Name Type Required Description Example elementId string no The internal element identifier (as hexadecimal hash string) to perform one or more taps. It is expected that both x and y are provided if this argument is ommitted. If the element identifier is provided without coordinates then the actual element's touch point will be calculated automatically by WebDriverAgent. fe50b60b-916d-420b-8728-ee2072ec53eb x number no x coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application. 100 y number no y coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application 100 duration number no The float number of seconds the force press action would take. If duration is provided then it is also expected that a custom pressure value is provided as well.0.5
by default. 2.5 pressure number no The float number defining how much pressure to apply. If pressure is provided then it is also expected that a custom duration value is provided as well. 1.0
by default 1.5"},{"location":"reference/execute-methods/#mobile-scrolltoelement","title":"mobile: scrollToElement","text":"Scrolls the current viewport to the given element. It is expected the destination element is inside a scrollable container and is hittable. The scroll direction is detected automatically. This API uses native XCTest calls, so it performs scrolling pretty fast. The same native call is implicitly performed by a vanilla click
API if the destination element is out of the current viewport. An exception is thrown if the scrolling action cannot be performed. This extension is available since the driver version 4.7.0.
Reset the location service on real device since Appium 1.22.0. It could delay a few seconds to reflect the location by the system. It raises an error if the device is simulator or an error occurred during the reset.
"},{"location":"reference/execute-methods/#mobile-enableconditioninducer","title":"mobile: enableConditionInducer","text":"Important: Device conditions are available for real devices running iOS 13.0 and later.
This API is going to throw an error if it is called while another condition inducer has been already enabled and is not explicitly disabled.
mobile: enableConditionInducer\nmobile: disableConditionInducer\nmobile: listConditionInducers\n
The above three extensions are available since the driver version 4.9.0.
You can create a condition on a connected device to test your app under adverse conditions, such as poor network connectivity or thermal constraints.
When you start a device condition, the operating system on the device behaves as if its environment has changed. The device condition remains active until you stop the device condition or disconnect the device. For example, you can start a device condition, run your app, monitor your app\u2019s energy usage, and then stop the condition.
Reference: Test under adverse device conditions (iOS)
Name Type Required Description Example conditionID string yes Get the conditionID parameter through the commandmobile: availableConditionInducer
SlowNetworkCondition profileID string yes Get the profileID parameter through the command mobile: availableConditionInducer
SlowNetwork100PctLoss"},{"location":"reference/execute-methods/#returned-result_33","title":"Returned Result","text":"Either true
or false
, where true
means enabling of the condition inducer has been successful
Get all condition inducer configuration profiles
"},{"location":"reference/execute-methods/#returned-result_34","title":"Returned Result","text":"The response looks like
[{\n \"profiles\": [\n {\n \"name\": \"100% packet loss\",\n \"identifier\": \"SlowNetwork100PctLoss\", // enableConditionInducer profileID\n \"description\": \"Name: 100% Loss Scenario\n Downlink Bandwidth: 0 Mbps\n Downlink Latency: 0 ms\n Downlink Packet Loss Ratio: 100%\n Uplink Bandwidth: 0 Mbps\n Uplink Latency: 0 ms\n Uplink Packet Loss Ratio: 100%\"\n },\n ],\n \"profilesSorted\": true,\n \"identifier\": \"SlowNetworkCondition\", // enableConditionInducer conditionID\n \"isDestructive\": false,\n \"isInternal\": false,\n \"activeProfile\": \"\",\n \"name\": \"Network Link\",\n \"isActive\": false\n}]\n
"},{"location":"reference/execute-methods/#mobile-disableconditioninducer","title":"mobile: disableConditionInducer","text":"Disable device condition inducer.
Usually a persistent connection is maintained after enable the condition inducer, and this method is only valid for this connection.
If the connection is disconnected, condition inducer will be automatically disabled
"},{"location":"reference/execute-methods/#returned-result_35","title":"Returned Result","text":"Either true
or false
, where true
means disabling of the condition inducer has been successful
Calibrates web to real coordinates translation. This API can only be called from Safari web context. It must load a custom page to the browser, and then restore the original one, so don't call it if you can potentially lose the current web app state. The outcome of this API is then used if nativeWebTap
capability/setting is enabled. The returned value could also be used to manually transform web coordinates to real device ones in client scripts.
It is adviced to call this API at least once before changing the device orientation or device screen layout as the recetly received value is cached for the session lifetime and may become obsolete.
It is advised to enable nativeWebTapStrict
capability/setting to speed up dynamic coordinates transformation if you use this extension.
An object with three properties used to properly shift Safari web element coordinates into native context: - offsetX
: Webview X offset in real coordinates - offsetY
: Webview Y offset in real coordinates - pixelRatioX
: Webview X pixel ratio - pixelRatioY
: Webview Y pixel ratio
The following formulas are used for coordinates translation: RealX = offsetX + webviewX * pixelRatioX
RealY = offsetY + webviewY * pixelRatioY
Updates preferences of Mobile Safari on Simulator
"},{"location":"reference/execute-methods/#arguments_56","title":"Arguments","text":"Name Type Required Description Example preferences map yes An object containing Mobile Safari preferences to be updated. The list of available setting names and their values could be retrieved by changing the corresponding Safari settings under Preferences->Safari and then inspectingLibrary/Preferences/com.apple.mobilesafari.plist
file inside of com.apple.mobilesafari
app container. The full path to the Mobile Safari's container could be retrieved from xcrun simctl get_app_container <sim_udid> com.apple.mobilesafari data
command output. Use the xcrun simctl spawn <sim_udid> defaults read <path_to_plist>
command to print the actual .plist content to the Terminal. { ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }"},{"location":"reference/execute-methods/#mobile-deeplink","title":"mobile: deepLink","text":"Opens the given URL with the default or the given application. This functionality is only available since xcuitest driver version 4.17. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
"},{"location":"reference/execute-methods/#arguments_57","title":"Arguments","text":"Name Type Required Description Example url string yes The URL to be opened. This parameter is manadatory. https://apple.com, myscheme:yolo bundleId string no The bundle identifier of an application to open the given url with. If not provided then the default application for the given url scheme is going to be used. com.myapp.yolo"},{"location":"reference/execute-methods/#mobile-getsimulatedlocation","title":"mobile: getSimulatedLocation","text":"Retrieves simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
"},{"location":"reference/execute-methods/#returned-result_37","title":"Returned Result","text":"This API returns a map with the following entries:
Name Type Description Example latitude number Measurement of distance north or south of the Equator.null
if mobile: setSimulatedLocation has not been called before or the simulated geolocation has been reset by mobile: resetSimulatedLocation. 50.08546 longitude number Measurement of distance east or west of the prime meridian. null
if mobile: setSimulatedLocation has not been called before or the simulated geolocation has been reset by mobile: resetSimulatedLocation. -20.12345"},{"location":"reference/execute-methods/#mobile-setsimulatedlocation","title":"mobile: setSimulatedLocation","text":"Sets simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
It is recommended for iOS 17+ real devices to simulate the device location.
"},{"location":"reference/execute-methods/#arguments_58","title":"Arguments","text":"Name Type Required Description Example latitude number yes Measurement of distance north or south of the Equator. 50.08546 longitude number yes Measurement of distance east or west of the prime meridian. -20.12345"},{"location":"reference/execute-methods/#mobile-resetsimulatedlocation","title":"mobile: resetSimulatedLocation","text":"Resets the previously set simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
Warning Do not forget to reset the simulated geolocation value after your automated test is finished. If the value is not reset explicitly then the simulated one will remain until the next device restart.
"},{"location":"reference/execute-methods/#mobile-getappstrings","title":"mobile: getAppStrings","text":"Retrieves string resources for the given app language. An error is thrown if strings cannot be fetched or no strings exist for the given language abbreviation
"},{"location":"reference/execute-methods/#arguments_59","title":"Arguments","text":"Name Type Required Description Example language string no The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned fr stringFile string no Relative path to the corresponding .strings file starting from the corresponding .lproj folder base/main.strings"},{"location":"reference/execute-methods/#returned-result_38","title":"Returned Result","text":"App strings map, where keys are resource identifiers.
"},{"location":"reference/execute-methods/#mobile-hidekeyboard","title":"mobile: hideKeyboard","text":"Tries to hide the on-screen keyboard. Throws an exception if the keyboard cannot be hidden. On non-tablet devices the keyboard might not have an explicit button to hide it. In such case this API won't work and the only way to close the keyboard would be to simulate the same action an app user would do to close it. For example, swipe from top to bottom or tap the screen somewhere at the area not covered by the keyboard.
"},{"location":"reference/execute-methods/#arguments_60","title":"Arguments","text":"Name Type Required Description Example keys string[] no One or more keyboard key names used to close/hide it. On tablet's such button is usually called 'done'."},{"location":"reference/execute-methods/#mobile-iskeyboardshown","title":"mobile: isKeyboardShown","text":"Checks if the system on-screen keyboard is visible.
"},{"location":"reference/execute-methods/#returned-result_39","title":"Returned Result","text":"true
if the keyboard is visible
Send keys to the given element or to the application under test. This API is only supported since Xcode 15/iOS 17. It is not supported on tvOS. The API only works on iPad. On iOS calling it has no effect.
"},{"location":"reference/execute-methods/#arguments_61","title":"Arguments","text":"Name Type Required Description Example elementId string no Unique identifier of the element to send the keys to. If unset then keys are sent to the current application under test. 21045BC8-013C-43BD-9B1E-4C6DC7AB0744 keys array yes Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's typeKey:modifierFlags: method and on XCUIKeyboardKey constants) or a dictionary withkey
and modifierFlags
entries, if the key should also be entered with modifiers. ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] or ['XCUIKeyboardKeyEscape'] Note
The modifierFlags
argument is of unsigned long
type and defines the bitmask with depressed modifier keys for the given key. XCTest defines the following possible bitmasks for modifier keys:
\ntypedef NS_OPTIONS(NSUInteger, XCUIKeyModifierFlags) {\n XCUIKeyModifierNone = 0,\n XCUIKeyModifierCapsLock = (1UL << 0),\n XCUIKeyModifierShift = (1UL << 1),\n XCUIKeyModifierControl = (1UL << 2),\n XCUIKeyModifierOption = (1UL << 3),\n XCUIKeyModifierCommand = (1UL << 4),\n XCUIKeyModifierFunction = (1UL << 5),\n // These values align with UIKeyModifierFlags and CGEventFlags.\n XCUIKeyModifierAlphaShift = XCUIKeyModifierCapsLock,\n XCUIKeyModifierAlternate = XCUIKeyModifierOption,\n};\n
So, for example, if you want Ctrl and Shift to be depressed while entering your key then modifierFlags
should be set to (1 << 1) | (1 << 2)
, where the first constant defines XCUIKeyModifierShift
and the seconds one - XCUIKeyModifierControl
. We apply the bitwise or (|
) operator between them to raise both bitflags in the resulting value. The left bitshift (<<
) operator defines the binary bitmask for the given modifier key. You may combine more keys using the same approach.
Lock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.
"},{"location":"reference/execute-methods/#arguments_62","title":"Arguments","text":"Name Type Required Description Example seconds number string no The number of seconds after which to unlock the device. Set to0
or leave it empty to require manual unlock (e.g. do not block and automatically unlock afterwards)."},{"location":"reference/execute-methods/#mobile-unlock","title":"mobile: unlock","text":"Unlocks the previously locked device. Only simple (e.g. without a password) locks are supported.
"},{"location":"reference/execute-methods/#mobile-islocked","title":"mobile: isLocked","text":"Determine whether the device is locked.
"},{"location":"reference/execute-methods/#returned-result_40","title":"Returned Result","text":"Either true
or false
Shakes the device. This functionality is only supported on simulators.
"},{"location":"reference/execute-methods/#mobile-backgroundapp","title":"mobile: backgroundApp","text":"Puts the app to the background and waits the given number of seconds. Then restores the app if necessary. The call is blocking.
"},{"location":"reference/execute-methods/#arguments_63","title":"Arguments","text":"Name Type Required Description Example seconds number no The amount of seconds to wait between putting the app to background and restoring it. Any negative value means to not restore the app after putting it to background (the default behavior). 5"},{"location":"reference/execute-methods/#mobile-performaccessibilityaudit","title":"mobile: performAccessibilityAudit","text":"Performs accessbility audit of the current application according to the given type or multiple types. Wraps the XCTest's performAccessibilityAuditWithAuditTypes API. Only available since Xcode 15/iOS 17.
"},{"location":"reference/execute-methods/#arguments_64","title":"Arguments","text":"Name Type Required Description Example auditTypes string[] no One or more type names to perform the audit for. The full list of available names could be found in the official XCTest API documentation. If no type if provided explicitly thenXCUIAccessibilityAuditTypeAll
is assumed. ['XCUIAccessibilityAuditTypeContrast', 'XCUIAccessibilityAuditTypeElementDetection']"},{"location":"reference/execute-methods/#returned-result_41","title":"Returned Result","text":"List of found issues or an empty list. Each list item is a map consisting of the following items:
Name Type Description Example detailedDescription string The detailed description of the found accessbility issue. Some longer issue description compactDescription string The compact description of the found accessbility issue. Some compact issue description auditType string or number The name of the audit type this issue belongs to. Could be a number if the type name is unknown. 'XCUIAccessibilityAuditTypeContrast' element string The description of the element this issue was found for. 'Yes' button elementDescription string The debug description of the element this issue was found for. Availble since driver version A long string describing the element itself and its position in the page tree hierarchy elementAttributes dict JSON object containing various attributes of the element. See the example below\"elementAttributes\":{\n \"isEnabled\":\"1\",\n \"isVisible\":\"1\",\n \"isAccessible\":\"0\",\n \"frame\":\"{{129, 65}, {135, 18}}\",\n \"isFocused\":\"0\",\n \"rect\":{\n \"y\":65,\n \"x\":129,\n \"width\":135,\n \"height\":18\n },\n \"value\":\"Some Button\",\n \"label\":\"Some Button\",\n \"type\":\"StaticText\",\n \"name\":\"Some Button\",\n \"rawIdentifier\":null\n}\n
"},{"location":"reference/ios-predicate/","title":"Predicate Locator Strategy","text":"The XCUITest driver supports searching elements using the predicate and class chain locator search strategies. They are powered by Apple XCTest, provide flexibility and are much faster than XPath. Predicates can be used to restrict a set of elements to select only those for which some condition evaluates to true.
Tip
In addition to the examples listed here, make sure to check the links in the More Information section below!
"},{"location":"reference/ios-predicate/#quick-examples","title":"Quick Examples","text":"Predicate StringClass Chain// java\ndriver.findElements(AppiumBy.iOSNsPredicateString(\"isVisible == 1\"));\n
// java\ndriver.findElements(AppiumBy.iOSClassChain(\"**/XCUIElementTypeWindow[`label LIKE '*yolo*'`]\"));\n
The predicate string example would select all visible elements on the page, while the class chain example would find all elements of type XCUIElementTypeWindow
whose label contains yolo
. Class chain queries allow to create much more complicated search expressions and may contain multiple predicates. Check the More Information section below for how to build such queries.
=
, ==
- The left-hand expression is equal to the right-hand expression:
// java\ndriver.findElements(AppiumBy.iOSNsPredicateString(\"label == 'Olivia'\"));\n\n// same in Xpath:\ndriver.findElements(AppiumBy.xpath(\"//*[@label = 'Olivia']\"));\n
>=
, =>
- The left-hand expression is greater than or equal to the right-hand expression.
<=
, =<
- The left-hand expression is less than or equal to the right-hand expression.
>
- The left-hand expression is greater than the right-hand expression.
<
- The left-hand expression is less than the right-hand expression.
!=
, <>
- The left-hand expression is not equal to the right-hand expression.
BETWEEN
- The left-hand expression is between, or equal to either of, the values specified in the right-hand side. The right-hand side is a two value array (an array is required to specify order) giving upper and lower bounds. For example, 1 BETWEEN { 0 , 33 }
, or $INPUT BETWEEN { $LOWER, $UPPER }
. In Objective-C, you could create a BETWEEN
predicate as shown in the following example:
driver.findElements(AppiumBy.iOSNsPredicateString(\"rect.x BETWEEN { 1, 100 }\"));\n
This creates a predicate that matches all elements whole left top coordinate is in range between 1 and 100.
TRUEPREDICATE
- A predicate that always evaluates to TRUE
.
FALSEPREDICATE
- A predicate that always evaluates to FALSE
.
AND
, &&
- Logical AND.
OR
, ||
- Logical OR.
NOT
, !
- Logical NOT.
String comparisons are by default case and diacritic sensitive. You can modify an operator using the key characters c
and d
within square braces to specify case and diacritic insensitivity respectively, for example, value BEGINSWITH[cd] 'bar'
.
BEGINSWITH
- The left-hand expression begins with the right-hand expression.
driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementTypeButton' AND name BEGINSWITH 'results toggle'\"));\n\n// same in Xpath:\ndriver.findElement(AppiumBy.xpath(\"//XCUIElementTypeButton[starts-with(@name, 'results toggle')]\"));\n
CONTAINS
- The left-hand expression contains the right-hand expression.
driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementCollectionView' AND name CONTAINS 'opera'\"));\n\n// same in Xpath:\ndriver.findElement(AppiumBy.xpath(\"//XCUIElementCollectionView[contains(@name, 'opera')]\"));\n
ENDSWITH
- The left-hand expression ends with the right-hand expression.
LIKE
- The left hand expression equals the right-hand expression: ?
and *
are allowed as wildcard characters, where ?
matches 1 character and *
matches 0 or more characters. In Mac OS X v10.4, wildcard characters do not match newline characters.
driver.findElement(AppiumBy.iOSNsPredicateString(\"name LIKE '*Total: $*'\"));\n\n// XPath1 does not have an alternative to the above expression\n
MATCHES
- The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
driver.findElement(AppiumBy.iOSNsPredicateString(\"value MATCHES '.*of [1-9]'\"));\n\n// XPath1 does not have an alternative to the above expression\n
IN
- Equivalent to an SQL IN operation, the left-hand side must appear in the collection specified by the right-hand side. For example, name IN { 'Ben', 'Melissa', 'Matthew' }
. The collection may be an array, a set, or a dictionary (in the case of a dictionary, its values are used).C style identifier - Any C style identifier that is not a reserved word.
#symbol - Used to escape a reserved word into a user identifier.
[\\]{octaldigit}{3} - Used to escape an octal number ( \\
followed by 3 octal digits).
[\\][xX]{hexdigit}{2} - Used to escape a hex number ( \\x
or \\X
followed by 2 hex digits).
[\\][uU]{hexdigit}{4} - Used to escape a Unicode number ( \\u
or \\U
followed by 4 hex digits).
Single and double quotes produce the same result, but they do not terminate each other. For example, \"abc\"
and 'abc'
are identical, whereas \"a'b'c\"
is equivalent to a space-separated concatenation of a, 'b', c
.
FALSE
, NO
- Logical false.
TRUE
, YES
- Logical true.
NULL
, NIL
- A null value.
SELF
- Represents the object being evaluated.
\"text\"
- A character string.
'text'
- A character string.
Comma-separated literal array - For example, { 'comma', 'separated', 'literal', 'array' }
.
Standard integer and fixed-point notations - For example, 1 , 27 , 2.71828 , 19.75
.
Floating-point notation with exponentiation - For example, 9.2e-5
.
0x
- Prefix used to denote a hexadecimal digit sequence.
0o
- Prefix used to denote an octal digit sequence.
0b
- Prefix used to denote a binary digit sequence.
The following keywords are reserved:
AND, OR, IN, NOT, ALL, ANY, SOME, NONE, LIKE, CASEINSENSITIVE, CI, MATCHES, CONTAINS, BEGINSWITH, ENDSWITH, BETWEEN, NULL, NIL, SELF, TRUE, YES, FALSE, NO, FIRST, LAST, SIZE, ANYKEY, SUBQUERY, CAST, TRUEPREDICATE, FALSEPREDICATE
Check the Element Attributes document to know all element attribute names and types that are available for usage in predicate locators.
"},{"location":"reference/ios-predicate/#more-information","title":"More Information","text":"The XCUITest driver supports several location strategies in the native context. The following table lists them in performance order (the first one is the fastest one):
Name Description ExampleclassName
Performs search by element's type
attribute. The full list of supported XCUIElement type names could be found in the official XCTest documentation on XCUIElementType XCUIElementTypeButton
id
, name
, accessibility id
All these locator types are synonyms and internally get transformed into search by element's name
attribute. my name
-ios predicate string
This strategy is mapped to the native XCTest predicate locator. Check the NSPredicate cheat sheet for more details on how to build effective predicate expressions. All the supported element attributes could be used in these expressions. (name == 'done' OR value == 'done') AND type IN {'XCUIElementTypeButton', 'XCUIElementTypeKey'}
-ios class chain
This strategy is mapped to the native XCTest predicate locator, but with respect to the actual element tree hierarchy. Such locators are basically a supertype of -ios predicate string
. Read Class Chain Queries Construction Rules for more details on how to build such locators. **/XCUIElementTypeCell[$name == 'done' OR value == 'done'$]/XCUIElementTypeButton[-1]
xpath
For elements lookup using the Xpath strategy the driver uses the same XML tree that is generated by the page source API. This means such locators are the slowest (sometimes up to 10x slower) in comparison to the ones above, which all depend on native XCTest primitives, but are the most flexible. Use Xpath locators only if there is no other way to locate the given element. Only Xpath 1.0 is supported. //XCUIElementTypeButton[@value=\\\"Regular\\\"]/parent::*
Also, consider checking the How To Achieve The Best Lookup Performance article.
"},{"location":"reference/scripts/","title":"Scripts","text":"Appium drivers can include scripts for executing specific actions. The following table lists the scripts bundled with the XCUITest driver. These scripts can be run as follows:
appium driver run xcuitest <script-name>\n
Script Name Description open-wda
Opens the WebDriverAgent project in Xcode build-wda
Builds the WebDriverAgent project using the first available iPhone simulator and the latest iOS supported by the current Xcode version"},{"location":"reference/security-flags/","title":"Security Feature Flags","text":"Some insecure driver features are disabled by default. They can be enabled upon launching Appium as follows:
appium --allow-insecure <feature-name>\n
or appium --relaxed-security\n
Feature Name Description shutdown_other_sims
Allow any session to use a capability to shutdown any running simulators on the host perf_record
Allow recording the system performance and other metrics of the simulator audio_record
Allow recording of host audio input(s) customize_result_bundle_path
Allow customizing the paths to result bundles, using the resultBundlePath
capability"},{"location":"reference/server-args/","title":"Appium Server Arguments","text":"Some driver arguments can be set when launching the Appium server. This can be done as follows:
appium --driver-xcuitest-[argName]=[argValue]\n
Argument Description Default Example webdriveragent-port
Local port used for communicating with WebDriverAgent 8100
--driver-xcuitest-webdriveragent-port=8200
"},{"location":"reference/settings/","title":"Settings","text":"The XCUITest driver supports Appium's Settings API. Along with the common settings, the following driver-specific settings are available:
Name Type DescriptionelementResponseAttributes
string
Comma-separated list of element attribute names to be included into findElement response. By default only element UUID is present there, but it is also possible to add the following items: name
, text
, rect
, enabled
, displayed
, selected
, attribute/<element_attribute_name>
. It is required that shouldUseCompactResponses
setting is set to false
in order for this one to apply. shouldUseCompactResponses
boolean
Used in combination with elementResponseAttributes
setting. If set to false
then the findElement response is going to include the items enumerated in elementResponseAttributes
setting. true
by default screenshotQuality
int
See the description of the corresponding capability. mjpegServerFramerate
int
The maximum count of screenshots per second taken by the MJPEG screenshots broadcaster. Must be in range 1..60. 10
by default mjpegScalingFactor
int
The percentage value used to apply downscaling on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. 100
is by default, which means that screenshots are not downscaled. mjpegServerScreenshotQuality
int
The percentage value used to apply lossy JPEG compression on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. 25
is by default, which means that screenshots are compressed to the quarter of their original quality. customSnapshotTimeout
(snapshotTimeout
before 1.19.1) float
Set how much time in float seconds is allowed to resolve a single accessibility snapshot with custom attributes. Snapshots are mainly used for page source generation, XML lookup and custom attributes retrieval (these are visibility and accessibility ones). It might be necessary to increase this value if the actual page source is very large and contains hundreds of UI elements. Defaults to 15 seconds. Since Appium 1.19.1 if this timeout expires and no custom snapshot could be made then WDA tries to calculate the missing attributes using its own algorithms, so setting this value to zero might speed up, for example, page source retrieval, but for the cost of preciseness of some element attributes. waitForIdleTimeout
float
Has the same meaning as corresponding capability (see above) animationCoolOffTimeout
float
The amount of time in float seconds to wait until the application under test does not have any active animations. This check is usually applied after each automation action that is supposed to change the state of the application under test, like click
one, and blocks XCTest until the transition of the tested application to a new state completes or the cool off timeout occurs. The default value is 2
(seconds). Setting it to zero disables animation checks completely. snapshotMaxDepth
int
Changes the value of maximum depth for traversing elements source tree. It may help to prevent out of memory or timeout errors while getting the elements source tree, but it might restrict the depth of source tree. Please consider restricting this value if you observed an error like Timed out snapshotting com.apple.testmanagerd... message or Cannot get 'xml' source of the current application in your Appium log since they are possibly timeout related. A part of elements source tree might be lost if the value was too small. Defaults to 50
useFirstMatch
boolean
Enabling this setting makes single element lookups faster, but there is the known problem related to nested elements lookup. Defaults to false
. reduceMotion
boolean
Changes the 'reduce motion' preference of accessibility feature. Defaults to false
defaultActiveApplication
string
Sets the hint for active application selection. This helps WebDriverAgent to select the current application if there are multiple items in the active applications list and the desired one is also one of them. The setting is particularly useful for split-screen apps automation. Defaults to auto
, which makes WebDriverAgent to select the application whose element is located at screenPoint
location or a single item from the active apps list if the length of this list is equal to one. activeAppDetectionPoint
string
Defines the coordinates of the current screen point. WebDriverAgent uses this point to detect the active application if multiple application are active on the screen. The format of this value is x,y
, where x and y are float or integer numbers representing valid screen coordinates. Setting this value to a point outside the actual screen coordinates might corrupt WebDriverAgent functionality. By default the screen point coordinates equal to 20% of the minimum screen dimension each, e.g. MIN(w, h) * 0.2, MIN(w, h) * 0.2
includeNonModalElements
boolean
Whether returns all of elements including no modal dialogs on iOS 13+. It fixes cannot find elements on nested modal presentations, but it might make visibility attributes unreliable. You could also enable shouldUseTestManagerForVisibilityDetection
setting (defaults to false
) or simpleIsVisibleCheck
capability to improve the visibility detection. This issue may happen between iOS 13.0 to 13.2 (Xcode 11.0 to 11.2). The query issued in includeNonModalElements
returns nil
with newer iOS/Xcode versions and Appium/WDA return proper elements three without this setting being used. Defaults to false
. acceptAlertButtonSelector
string
Allows to customize accept alert button selector. It helps you to handle an arbitrary element as accept button in accept alert
command. The selector should be a valid class chain expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: **/XCUIElementTypeButton[`label CONTAINS[c] 'accept'`]
dismissAlertButtonSelector
string
Allows to customize dismiss alert button selector. It helps you to handle an arbitrary element as dismiss button in dismiss alert
command. The selector should be a valid class chain expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: **/XCUIElementTypeButton[`label CONTAINS[c] 'dismiss'`]
screenshotOrientation
string
Adjust screenshot orientation for iOS. Appium tries to return a screenshot and adjust its orientation properly using internal heuristics, but sometimes it does not work, especially in landscape mode. The actual screenshot orientation depends on various factors such as OS versions, model versions and whether this is a real or simulator device. This option allows you to enforce the given image orientation. Acceptable values: auto
(default), portrait
, portraitUpsideDown
, landscapeRight
, landscapeLeft
. boundElementsByIndex
boolean
Whether to look up elements with allElementsBoundByAccessibilityElement
(default) or allElementsBoundByIndex
. This Stack Overflow topic explains the differences. Defaults to false
. keyboardAutocorrection
boolean
Changes the 'Auto-Correction' preference in Keyboards setting. Defaults to false
. keyboardPrediction
boolean
Changes the 'Predictive' preference in Keyboards setting. Defaults to false
. nativeWebTap
boolean
See the description of the corresponding capability. nativeWebTapStrict
boolean
See the description of the corresponding capability. nativeWebTapTabBarVisibility
enum
Bypass finding whether the existence of the tab bar before tapping on the element. It could make native web tap faster. If it's visible
, tab bar offset will be added without checking the existence of the tab bar. It's invisible
, the tab bar offset will be zero
. If you want to leave Appium to check and measure the tab bar offset, unset or set detect
. Only applicable if nativeWebTap
and nativeWebTapStrict
are enabled. Unset by default. nativeWebTapSmartAppBannerVisibility
enum
The same as nativeWebTapTabBarVisibility
, this keyword will bypass finding whether the existence of the smart app banner. safariTabBarPosition
string
Handle offset of Safari tab bar in nativeWebTap
enabled interactions. If platformVersion
was greater than or equal to 15 and iPhone device, the value is bottom
by default. Otherwise top
. When the value is top
, Appium considers offset as the bar length. iOS 15+ environment can customize the bar position in the settings app, so please adjust the offset with this. Acceptable values: bottom
, top
useJSONSource
boolean
See the description of the corresponding capability. pageSourceExcludedAttributes
string
One or more comma-separated attribute names to be excluded from the XML output. It might be sometimes helpful to exclude, for example, the visible
attribute, to significantly speed-up page source retrieval. This does not affect the XML output when useJSONSource
is enabled. Defaults to an empty string. Example: \"visible,accessible\"
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome","text":"Welcome to the Appium XCUITest Driver documentation! The XCUITest driver is a test automation framework for iOS, iPadOS and tvOS devices, enabling automated black-box testing of native, hybrid and WebKit web apps, on both emulators and real devices.
The XCUITest driver is part of the Appium test automation tool. For information on Appium itself, please visit the Appium documentation.
"},{"location":"#explore-the-documentation","title":"Explore the Documentation","text":"Contributions to this project are welcome! To start off, clone it from GitHub and run:
npm install\n
To watch changes during development:
npm run watch\n
To run unit/functional tests:
npm run test # unit \nnpm run e2e-test # functional\n
To develop documentation:
npm run install-docs-deps # install the dependencies (Python packages)\nnpm run dev:docs # serve the docs locally and watch for changes\n
There are also a number of environment variables that can be used when running the tests locally. These include:
REAL_DEVICE
- set to anything truthy, makes the tests use real device capabilities_FORCE_LOGS
- set to 1
to get the log output, not just specPLATFORM_VERSION
- change the version to run the tests against (defaults to 11.3
)XCCONFIG_FILE
- specify where the Xcode config file is for a real device run (if blank, and running a real device test, it will search for the first file in the root directory of the repo with the extension .xcconfig
)UICATALOG_REAL_DEVICE
- path to the real device build of UICatalog, in case the npm
installed one is not built for a real device* implemented but intentionally not supported
** not implemented handlers
"},{"location":"endpoints/","title":"Endpoints","text":""},{"location":"endpoints/#appium-ios-jsonwp-endpoints","title":"Appium iOS JSONWP Endpoints","text":""},{"location":"endpoints/#session-less-commands","title":"Session-less commands","text":"method endpoint req params opt params GET /status POST /session desiredCapabilities requiredCapabilities GET /sessions"},{"location":"endpoints/#session-commands","title":"Session commands","text":"method endpoint req params opt params GET /:sessionId DELETE /:sessionId POST /timeouts type, ms POST /timeouts/async_script ms POST /timeouts/implicit_wait ms GET /window_handle GET /window_handles GET /url POST /url url POST /forward none POST /back none POST /refresh none POST /execute script, args POST /execute_async script, args GET /screenshot POST /frame id POST /window name DELETE /window GET /window/:windowhandle/size GET /cookie POST /cookie cookie DELETE /cookie DELETE /cookie/:name GET /source GET /title POST /element using, value POST /elements using, value POST /element/active none POST /element/:elementId/element using, value POST /element/:elementId/elements using, value POST /element/:elementId/click none POST /element/:elementId/submit none GET /element/:elementId/text none POST /element/:elementId/value value POST /keys value GET /element/:elementId/name POST /element/:elementId/clear none GET /element/:elementId/selected GET /element/:elementId/enabled GET /element/:elementId/attribute/:name GET /element/:elementId/equals/:otherId GET /element/:elementId/displayed GET /element/:elementId/location GET /element/:elementId/location_in_view GET /element/:elementId/size GET /element/:elementId/css/:propertyName GET /orientation POST /orientation orientation GET /alert_text POST /alert_text text POST /accept_alert none POST /dismiss_alert none POST /click button POST /touch/click element POST /touch/flick element, xspeed, yspeed, xoffset, yoffset, speed GET /location POST /location location POST /log type GET /log/types GET /context POST /context name GET /contexts POST /touch/perform actions POST /touch/multi/perform actions elementId POST /receive_async_response status, value"},{"location":"endpoints/#appium-specific-commands","title":"Appium-specific commands","text":"method endpoint req params opt params POST /appium/device/shake none GET /appium/device/system_time POST /appium/device/lock seconds POST /appium/device/rotate x, y, radius, rotation, touchCount, duration element POST /appium/device/remove_app appId or bundleId POST /appium/device/hide_keyboard strategy, key, keyCode, keyName POST /appium/device/push_file path, data POST /appium/device/pull_file path POST /appium/device/pull_folder path POST /appium/simulator/touch_id match POST /appium/app/launch none POST /appium/app/close none POST /appium/app/background seconds POST /appium/app/strings language, stringFile POST /appium/element/:elementId/value value POST /appium/receive_async_response response"},{"location":"overview/","title":"Overview","text":"The XCUITest driver combines several different technologies to achieve its functionality:
appium-ios-device
libraryappium-ios-simulator
libraryThe XCUITest driver provides the appium:webDriverAgentUrl
capability to attach to a running WebDriverAgent (WDA) application. This works for real devices and simulators, but the primary usage is for real devices.
appium:webDriverAgentUrl
capabilityPlease read Manage WebDriverAgent by Yourself and Real Device Configuration about how to prepare WDA for a real device.
The appium:webDriverAgentUrl
value should be the WDA URL: http://<reachable ip address for the device>:8100
. If the environment has port-forward to the connected device, it can be http://localhost:8100
.
{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:udid\": \"<device udid>\",\n \"appium:deviceName\": \"iPhone\",\n \"appium:webDriverAgentUrl\": \"http://<reachable ip address for the device>:8100\"\n}\n
This method allows you to manage the WDA process by yourself. The XCUITest driver then simply attaches to the WDA process, which may improve the application performance.
Some XCUITest driver APIs (for example, mobile: calibrateWebToRealCoordinatesTranslation) might still require the port number of the remote device if it is a real device. Providing the appium:webDriverAgentUrl
capability might not be sufficient to recognize the remote port number, in case it is different from the local one. Consider settings the appium:wdaRemotePort
capability in such cases, to supply the driver with the appropriate data.
Appium XCUITest driver provides a possibility to record iOS audio stream and save it to a file, which could be then retrieved on the client side. Apple does not provide any API to directly retrieve the audio stream from a Simulator or a real device, but it is possible to redirect that stream to the host machine, where it could be captured.
mobile: startAudioRecording
mobile: stopAudioRecording
ffmpeg
installed and added to PATH. It can be installed via brew
: brew install ffmpeg
.For macOS 10.15+, applications recording Microphone audio need to be explicitly granted this permission. This can be done in the following settings menu:
Ensure that either ffmpeg
itself or the parent Appium process (e.g. Terminal) is present in that list.
As this is a potentially insecure feature, it must be explicitly allowed on the server side. See the Appium documentation on Security for more details. The feature name is audio_record
.
The following steps are necessary to setup iOS Simulator audio capture:
ffmpeg -f avfoundation -list_devices true -i \"\"
to get the identifier of the Soundflower (2ch)
device. This identifier prefixed with :
will be then used as audioInput
argument to mobile: startAudioRecording
call-i
argument value with the one you got from the previous step: ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n
After 5 seconds, a file named out.mp4
should be created on your desktop, containing the recorded audio stream.The following steps are necessary to setup iOS Real Device audio capture:
open -a /System/Applications/Utilities/Audio\\ MIDI\\ Setup.app
Enable
next to itffmpeg -f avfoundation -list_devices true -i \"\"
to get the identifier of your device in the AVFoundation audio devices
list. This identifier prefixed with :
will be then used as audioInput
argument to mobile: startAudioRecording
call-i
argument value with the value you got from the previous step: ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n
After 5 seconds, a file named out.mp4
should be created on your desktop, containing the recorded audio stream.Note
Apple does not allow phone calls to be redirected this way. You can only record application or system sounds.
"},{"location":"guides/audio-capture/#further-reading","title":"Further Reading","text":"Setting up the XCUITest driver in an automated environment brings a few challenges with it. Any scenario where user interaction is required must be automated or avoided altogether. For real device setup, you should first follow the Real Device Configuration tutorial.
"},{"location":"guides/ci-setup/#keychains","title":"Keychains","text":"One common scenario is a prompt asking for a keychain to be unlocked in order to sign the WebDriverAgent. There are multiple possible solutions for this:
It is recommended to go with the second or third option. The third one is the easiest and most reliable one to set up, at the cost of having to set the keychain password as an environment variable.
"},{"location":"guides/ci-setup/#xcode","title":"Xcode","text":"When setting up a new machine as a CI server, you are probably going to install Xcode, without executing it once, because you are not going to use it for development. Make sure to start Xcode at least once and do the initial set up and install the suggested extensions.
"},{"location":"guides/ci-setup/#linking-apple-account","title":"Linking Apple Account","text":"This only applies for real device set up. Make sure to link your 'Apple Developer Account' in the machine's system wide \"Account Panel\" when using the \"Basic Automatic Configuration\" described here.
"},{"location":"guides/ci-setup/#troubleshooting","title":"Troubleshooting","text":"Enable the appium:showXcodeLog
capability and check the Appium server output.
Working with the clipboard on real devices has an Apple security limitation, where the WebDriverAgentRunner application must be in foreground in order for the action to work. Otherwise an empty string is always returned, or it could raise an exception like this issue.
Consider using mobile: activateApp
and mobile: backgroundApp
to change the foreground application.
Applies to iOS 13+ real devices. You can also use mobile: getPasteboard
for simulators.
# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Get the clipboard content\ndriver.get_clipboard\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n
"},{"location":"guides/clipboard/#set-clipboard","title":"Set Clipboard","text":"Applies to iOS 15+ real devices. You can also use mobile: setPasteboard
for simulators.
# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Set the clipboard content\ndriver.set_clipboard(content: 'happy testing')\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n
"},{"location":"guides/file-transfer/","title":"File Transfer","text":"The XCUITest driver provides several extension commands for file transfer:
mobile: pullFolder
mobile: pullFile
mobile: pushFile
mobile: deleteFolder
mobile: deleteFile
This documentation aims to help to understand how they work on iOS.
"},{"location":"guides/file-transfer/#formats","title":"Formats","text":"All commands require a parameter with a path to the file/folder on the target device. There are 3 possible formats this path can take:
"},{"location":"guides/file-transfer/#format-1","title":"Format 1","text":"@<app-bundle-id>:<container-type>/<path-to-file-or-folder>\n
@<app-bundle-id>
is the application bundle identifier<container-type>
is the container typeapp
, data
, groups
, but a custom one can also be provideddocuments
. All others are treated as Format 2UIFileSharingEnabled
flag set to true
. You can use the mobile: listApps
extension to identify such apps.<path-to-file-or-folder>
is the target file or folder<container-type>
is set to documents
, this path will be mapped to On My iPhone/<app name>
in the Files app@<app-bundle-id>/<path-to-file-or-folder>\n
<container-type>
is set to app
.UIFileSharingEnabled
flag set to true
in their info.plist
can be mounted. You can use the mobile: listApps
extension to identify such apps.<path-to-file-or-folder>\n
This format is only supported on simulators. The implicit <container-type>
is set to app
. Eventually the whole simulator file system is available directly from the macOS Finder, so you may pull any file from there by providing a path to it relatively to the simulator's file system root.
pullFile
","text":"This example pulls a file present in Files -> On My iPhone -> Keynote:
Top On My iPhone Keynote JS (WebdriverIO)Rubylet data = driver.pullFile('@com.apple.Keynote:documents/Presentation.key');\nawait fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_file '@com.apple.Keynote:documents/Presentation.key'\nFile.open('presentation.key', 'wb') { |f| f<< file }\n
If the file is in deeper place like Keynote/Dir1/Dir2, then the path changes:
JS (WebdriverIO)Rubylet data = driver.pullFile('@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key');\nawait fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_file '@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key'\nFile.open('presentation.key', 'wb') { |f| f<< file }\n
Example for a simulator using Format 3:
// Java\n// Get AddressBook.sqlitedb in test app package ('app' container)\nbyte[] fileContent = driver.pullFile(\"Library/AddressBook/AddressBook.sqlitedb\");\nPath dstPath = Paths.get(new File(\"/local/path/AddressBook.sqlitedb\"));\nFiles.write(dstPath, fileContent);\n
"},{"location":"guides/file-transfer/#pullfolder","title":"pullFolder
","text":"You can pull folders similarly to files, but the path must end with a forward slash (/
).
let data = driver.pullFolder('@com.apple.Keynote:documents/');\nawait fs.writeFile('documents.zip', Buffer.from(data, 'base64'), 'binary');\n
file = @driver.pull_folder '@com.apple.Keynote:documents/'\nFile.open('documents.zip', 'wb') { |f| f<< file }\n
"},{"location":"guides/file-transfer/#pushfile","title":"pushFile
","text":"JS (WebdriverIO)Ruby driver.pushFile('@com.apple.Keynote:documents/text.txt', new Buffer(\"Hello World\").toString('base64'));\n
@driver.push_file '@com.apple.Keynote:documents/text.txt', (File.read 'path/to/file')\n
"},{"location":"guides/file-transfer/#references","title":"References","text":"iOS uses the Events concept to handle signals received from different input devices. An Event is an object generated in response to a signal from an input device. These objects are then delivered to the corresponding kernel subsystem, which processes them and notifies all listening processes about taps, key presses, swipes, etc. This means that in order to emulate a signal generated by an external device, such as a touch screen, it is necessary to just send Event objects with the same properties and in the same sequence as they would be generated by a real device.
"},{"location":"guides/input-events/#simulating-a-single-tap","title":"Simulating a Single Tap","text":"The Events API itself is a part of Apple private API, and it is neither open sourced nor documented. The XCTest framework also does not expose any public APIs for input events generation, although there is a possibility to perform events generation via XCTest private undocumented APIs.
In particular, we are interested in the XCPointerEventPath
and XCSynthesizedEventRecord
interfaces. These APIs allow to create chains of input events and supply them to the system kernel for execution.
In order to synthesize a single tap, it is necessary to:
XCPointerEventPath
instance and initialize it for touch at the starting pointliftUp
event at 0.125s
offset using liftUpAtOffset:
methodXCSynthesizedEventRecord
instance using addPointerEventPath:
methodsynthesizeWithError:
method of XCSynthesizedEventRecord
instance and control the returned errorThere are several limitations to these APIs:
XCPointerEventPath
instance can only be executed for a single action. If one tries to add, for example, two taps to a single path, then these are effectively ignoredXCPointerEventPath
instance can only be initialized for a particular pointer type: touch, mouse (since Xcode 10.2) or keyboard (since Xcode 10.2)XCPointerEventPath
instanceUnfortunately, because the API is private and has zero documentation, one can only figure out what it can do by playing with it and trying different input combinations.
It is known that providing multiple XCPointerEventPath
instances with overlapping timeouts will generate a multitouch action with the amount of fingers equal to the amount of the supplied event paths. So, in order to generate two-finger symmetric swipe we need to supply the following events:
XCPointerEventPath
instances and init them for touch at the starting pointmoveToPoint
event at 0.525s
offset using moveToPoint:
method to each pathliftUp
eventa at 0.525s
offset using liftUpAtOffset:
method to each pathXCSynthesizedEventRecord
instance using addPointerEventPath:
methodsynthesizeWithError:
method of XCSynthesizedEventRecord
instance and control the returned errorUnfortunately, there is no information on this topic at all (private API \u00af\\_(\u30c4)_/\u00af
). Consider visiting the following resources:
Unfortunately, Apple does not provide any command line options which can help to install self-signed certificate on a real device or simulator. However, there is over-the-air enrollment technology, which allows the deployment of several entity types, including such certificates, by simply downloading specially prepared configuration files with the built-in web browser. After the configuration is downloaded it can be installed and trusted by going through several simple wizard steps.
You can use the following extension methods to assist with this:
mobile: installCertificate
mobile: removeCertificate
If you have multiple Xcode installations, you may choose which toolset Appium should use with one of two ways:
"},{"location":"guides/multiple-xcode-versions/#xcode-select-tool","title":"xcode-select
tool","text":"Only available with sudo
privileges, affects the whole system.
Assuming you want to choose /Applications/Xcode13.app
:
sudo xcode-select -s /Applications/Xcode13.app/Contents/Developer\n
appium\n
No privileges needed, affects only the current shell, so Appium should be started within that shell.
Assuming you want to choose /Applications/Xcode12.app
:
DEVELOPER_DIR
environment variable export DEVELOPER_DIR=/Applications/Xcode12.app/Contents/Developer\n
appium\n
It is possible to execute tests in parallel using XCUITest driver. Appium allows to do this on a per-process (multiple server processes running on different ports managing single session) or a per-request basis (single server process managing multiple sessions, more preferable, uses less resources and ensures better control over running sessions).
Note
If you are not going to run your tests in parallel, consider enabling the --session-override
Appium server argument. It forces the server to close all pending sessions before a new one could be opened, which allows you to avoid possible issues with such sessions silently running/expiring in the background.
udid
must be a unique device UDID for each parallel session.wdaLocalPort
must be a unique port number for each parallel session. The default value is 8100
.derivedDataPath
set the unique derived data path root for each driver instance. This will help to avoid possible conflicts and to speed up the parallel execution.mjpegServerPort
must be a unique port number for each parallel session if you are going to record a video stream from it. The default value is 9100
.udid
, which is the unique simulator UDID for each parallel session (it could be retrieved from xcrun simctl list
command output), or a unique combination of deviceName
and platformVersion
capabilities to identify the appropriate simulator with the given name and version number for each parallel session.wdaLocalPort
must be a unique port number for each parallel session. The default value is 8100
.derivedDataPath
set the unique derived data path root for each driver instance. This will help to avoid possible conflicts and to speed up the parallel execution.mjpegServerPort
must be a unique port number for each parallel session if you are going to record a video stream from it. The default value is 9100
.The XCUITest driver runs xcodebuild
to build and install the WebDriverAgentRunner (WDA) app on the target device. You can manually run a modified version of this command in order to prebuild the WDA.
xcodebuild
Works","text":"By default, xcodebuild
is run with two commands: build-for-testing
and test-without-building
. build-for-testing
builds a test bundle package, whereas test-without-building
actually runs it.
For instance, XCUITest driver issues an xcodebuild
command like so:
xcodebuild build-for-testing test-without-building \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n
This translates to xcodebuild
building WebDriverAgent.xcodeproj
and running the resulting package on the specified device.
The command can be split into build-for-testing
and test-without-building
parts as follows:
xcodebuild build-for-testing \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n
xcodebuild test-without-building \\\n -xctestrun wda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\"\n
The build-for-testing
command generates two files: an .app
package and an .xctestrun
file, e.g.:
wda_build/Build/Products/Debug-iphonesimulator/WebDriverAgentRunner-Runner.app\nwda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun\n
The .xctestrun
file name depends on the -destination
preference. The file contains metadata about the package (the DependentProductPaths
key).
The test-without-building
command starts the WDA application for testing by referencing the provided .xctestrun
file. Once this is done, http://localhost:8100
will be able to receive commands for the target device.
The XCUITest driver provides two capabilities that allow skipping the build-for-testing
command, and executing only the test-without-building
command: appium:useXctestrunFile
and appium:bootstrapPath
(see Capabilities).
Note
These capabilities expect that the WDA files are already prebuild, so make sure to first run xcodebuild
to create the files.
This method can be used on both real devices and simulators, but real devices requires proper signing as described in Run Preinstalled WebDriverAgentRunner. We recommend using this method for real devices.
The capabilities can be used as follows:
{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:deviceName\": \"iPhone 12\",\n \"appium:useXctestrunFile\": true,\n \"appium:bootstrapPath\": \"/path/to/wda_build/Build/Products\"\n}\n
Not all combinations have been tested, but the target device can probably be anything.
The same thing can be achieved with the appium:derivedDataPath
and appium:usePrebuiltWDA
capabilities, but this may fail if xcodebuild
cannot find or handle the .xctestrun
file properly. The stability depends on Xcode.
The Appium WebDriverAgent GitHub page provides downloads for WebDriverAgent packages for real devices. They do not have embedded XCTest frameworks.
The Release and Building WebDriverAgent workflows may help with validating the build script.
"},{"location":"guides/run-preinstalled-wda/","title":"Run Preinstalled WebDriverAgentRunner","text":"The XCUITest driver can be configured to launch an already-installed WebDriverAgentRunner-Runner
application (WDA) on a real device. This allows you to start a session without the xcodebuild
command execution, improving the session startup performance.
Warning
This method currently does not work natively for iOS 17/tvOS 17 due to platform changes. Please use the default xcodebuild
approach or 3rd party tools such as pymobiledevice3
.
appium:usePreinstalledWDA
appium:updatedWDABundleId
appium:prebuiltWDAPath
Running a test for the WDA package in Xcode is the easiest way to prepare the device environment:
appium driver run xcuitest open-wda
if using XCUITest driver 4.13 or newerIf using a real device, you may need to change your bundle ID. Please check the Full Manual Provisioning Profile setup for details.
"},{"location":"guides/run-preinstalled-wda/#using-3rd-party-tools","title":"Using 3rd Party Tools","text":"Some 3rd party tools such as pymobiledevice3, ios-deploy, go-ios and tidevice can install the WebDriverAgent package.
The WDA app package (WebDriverAgentRunner-Runner.app
) can be generated in the derivedDataPath directory, as explained in Manual Configuration for a Generic Device. The app can then be installed without xcodebuild
using the 3rd party tools.
After installing the WebDriverAgentRunner-Runner
application, you can start the Appium server and launch an XCUITest driver session with the specified capabilities:
appium\n
# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:updatedWDABundleId\": \"com.appium.WebDriverAgentRunner\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n
If the <udid>
device has a WebDriverAgent package with com.appium.WebDriverAgentRunner.xctrunner
bundle ID, the session will launch the WebDriverAgent process without xcodebuild
.
Note
Please ensure that the WDA application is launchable before starting an XCUITest driver session. For example, check whether the provisioning profile is trusted.
"},{"location":"guides/run-preinstalled-wda/#set-appiumprebuiltwdapath","title":"Setappium:prebuiltWDAPath
","text":"If the appium:prebuiltWDAPath
capability is provided with a properly signed WebDriverAgentRunner-Runner.app
test bundle, the XCUITest driver will install the application and launch it every test session. Test bundles cannot be versioned using CFBundleVersion
as vanilla applications do, which is why it is necessary to (re)install them for every test session.
Usually you can find the WDA application bundle at the below location if you use Xcode to build it.
~/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\n
You can then set your Appium capabilities as follows:
# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:prebuiltWDAPath\": \"/path/to/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n
Note
As of iOS 17, the testmanagerd service name has changed from com.apple.testmanagerd
to com.apple.dt.testmanagerd.runner
. It causes an unexpected WDA process crash with embedded XCTest frameworks while running a single WebDriverAgent package on various OS environments without xcodebuild
.
Since WDA v5.10.0, the module can refer to the device's local XCTest frameworks. It lets the Appium/WebDriverAgent package use proper dependencies for the device with a single prebuilt WebDriverAgent package. To set this up, you should remove the package internal frameworks from WebDriverAgentRunner-Runner.app
with rm -rf WebDriverAgentRunner-Runner.app/Frameworks/XC*.framework
. The WDA package itself is available from https://github.com/appium/WebDriverAgent.
The XCUITest driver has the capability to simulate Touch ID.
Note
This functionality is only supported on simulators.
"},{"location":"guides/touch-id/#configuration","title":"Configuration","text":"To use Touch ID, the application that Appium launches from (Terminal, iTerm, etc.) must be added to the accessibility preferences on your Mac. Navigate to System Preferences -> Privacy & Security -> Accessibility and under Allow the apps below to control your computer add the application.
Why this is needed: The only way Appium can enable enrollment and toggling of Touch ID is to use system-level accessibility APIs to simulate mouse clicks on the simulator menus via AppleScript.
"},{"location":"guides/touch-id/#usage","title":"Usage","text":"appium:allowTouchIdEnroll
to true
.mobile: enrollBiometric
extensionNote
Remember that not all iOS devices have Touch ID, so your tests should handle cases where Touch ID is not supported.
"},{"location":"guides/troubleshooting/","title":"Troubleshooting","text":""},{"location":"guides/troubleshooting/#known-problems","title":"Known Problems","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).shake
is implemented via AppleScript and works only on Simulator due to lack of support from AppleThere 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:
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:
appium:app
and appium:bundleId
capabilitiesmobile: removeApp
for the target application's bundle idmobile: installApp
mobile: launchApp
or mobile: activateApp
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...\"\ndbug WebDriverAgent Device: Jul 26 13:20:42 iamPhone XCTRunner[240] <Warning>: Listening on USB\ndbug 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\ndbug 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\ndbug 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\n
"},{"location":"guides/troubleshooting/#command-takes-60-seconds","title":"Command Takes 60+ Seconds","text":"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.
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\nsecurity import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A\n
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.
When testing on simulators, the driver tries to leave the simulator state as it found it:
udid
is provided, the driver will create a new iOS simulator, run tests on it, and then delete the simulatorudid
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 downudid
is provided for a simulator that is running, the driver will connect to the existing simulator, run tests, and then leave the simulator runningYou 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.
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:
$HOME/Library/Logs/CoreSimulator/*\n$HOME/Library/Developer/Xcode/DerivedData/*\n
"},{"location":"guides/tvos/","title":"tvOS Support","text":"The XCUITest driver supports automation of the tvOS platform.
Warning
Apple TV 4K is not supported. This is because appium-ios-device
, which is used to support low-level communication with devices, only supports devices connected via USB.
You can run tests for tvOS by setting the platformName
capability to tvOS
:
{\n \"platformName\": \"tvOS\", // here\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"12.2\",\n \"appium:deviceName\": \"Apple TV\",\n ...\n}\n
Note
If using a simulator, make sure the tvOS simulator exists in your simulator list. You can run xcrun simctl list | grep \"com.apple.CoreSimulator.SimRuntime.tvOS\"
to verify this.
tvOS provides remote controller based actions. The XCUITest driver implements these actions using the mobile: pressButton
extension, with the following button values: menu
, up/down/left/right
, home
, playpause
and select
.
All actions are performed on the focused element (which has the focus
attribute set). The focused element is automatically changed after using mobile: pressButton
.
It is also possible to use the standard findElement
and click
methods. The XCUITest driver will automatically calculate the necessary sequence of up/down/left/right
and select
button presses, so you should not care about which keys should be pressed to reach an arbitrary element every time.
WebElement element = driver.findElementByAccessibilityId(\"element on the app\");\nelement.getAttribute(\"focused\"); // => 'true'\n// Appium moves the focus to the element by pressing the corresponding keys and clicking the element\nelement.click();\ndriver.queryAppState(\"test.package.name\"); // => :running_in_foreground\ndriver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Home\"));\ndriver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Up\"));\nelement = driver.switchTo().activeElement();\nelement.getAttribute(\"label\");\n
const element = $('~SomeAccessibilityId');\nelement.getAttribute('focused');\nelement.click();\ndriver.execute('mobile: pressButton', {name: 'Home'});\ndriver.execute('mobile: pressButton', {name: 'Up'});\nconst activeElement = driver.getActiveElement();\nactiveElement.getAttribute('label');\n
element = driver.find_element_by_accessibility_id('element on the app')\nelement.get_attribute('focused')\nelement.click()\ndriver.query_app_state('test.package.name')\ndriver.execute_script('mobile: pressButton', { 'name': 'Home' })\ndriver.execute_script('mobile: pressButton', { 'name': 'Up' })\nelement = driver.switch_to.active_element\nelement.get_attribute('label')\n
element = @driver.find_element :accessibility_id, 'element on the app'\nelement.focused\nelement.click\n@driver.app_state('test.package.name')\n@driver.execute_script 'mobile: pressButton', { name: 'Home' }\n@driver.execute_script 'mobile: pressButton', { name: 'Up' }\nelement = @driver.switch_to.active_element\nelement.label\n
"},{"location":"guides/tvos/#more-actions","title":"More Actions","text":"wait
methods, since tvOS also has animationmenu
button works as back for iOS context in tvOSThe XCUITest driver uses WebDriverAgent (WDA) as the automation backend. This backend is based on Apple's XCTest framework and shares all the known problems that are present in XCTest. For some of them we have workarounds, but there are some that are hardly possible to workaround (here is one example). The approach described in this article enables you to have full control over how WDA is built, managed, and run on the device. This way you may fine-tune your automated tests in a CI environment and make them more stable inlong-running perspective.
Note
In order to setup and launch WDA, please check the provided steps in the Run Preinstalled WDA documentation.
"},{"location":"guides/wda-custom-server/#wda-startup-via-code","title":"WDA Startup via Code","text":"WebDriverAgent application acts as a REST server, which proxies external API requests to native XCTest calls for your application under test. The server address will be localhost
if you run your tests on a simulator, or the actual phone IP address in case of real device. Appium uses appium-ios-device
to route network requests to a real device from localhost
via USB, which means one can use this tool to unify the WDA network addresses for a simulator and real device.
You can use appium-ios-device
to connect to a remote device by requiring the module from your JavaScript code. Alternatively, you can use iproxy
, go-ios
or tidevice
to handle the WDA process outside Appium, by installing and launching the WDA package. For instance, iproxy
can be installed using npm
: npm install -g iproxy
.
This helper class written in Java illustrates the main implementation details with iproxy
:
public class WDAServer {\n private static final Logger log = ZLogger.getLog(WDAServer.class.getSimpleName());\n\n private static final int MAX_REAL_DEVICE_RESTART_RETRIES = 1;\n private static final Timedelta REAL_DEVICE_RUNNING_TIMEOUT = Timedelta.ofMinutes(4);\n private static final Timedelta RESTART_TIMEOUT = Timedelta.ofMinutes(1);\n\n // These settings are needed to properly sign WDA for real device tests\n // See https://github.com/appium/appium-xcuitest-driver for more details\n private static final File KEYCHAIN = new File(String.format(\"%s/%s\",\n System.getProperty(\"user.home\"), \"/Library/Keychains/MyKeychain.keychain\"));\n private static final String KEYCHAIN_PASSWORD = \"******\";\n\n private static final File IPROXY_EXECUTABLE = new File(\"/usr/local/bin/iproxy\");\n private static final File XCODEBUILD_EXECUTABLE = new File(\"/usr/bin/xcodebuild\");\n private static final File WDA_PROJECT =\n new File(\"~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent\" +\n \"/WebDriverAgent.xcodeproj\");\n private static final String WDA_SCHEME = \"WebDriverAgentRunner\";\n private static final String WDA_CONFIGURATION = \"Debug\";\n private static final File XCODEBUILD_LOG = new File(\"/usr/local/var/log/appium/build.log\");\n private static final File IPROXY_LOG = new File(\"/usr/local/var/log/appium/iproxy.log\");\n\n private static final int PORT = 8100;\n public static final String SERVER_URL = String.format(\"http://127.0.0.1:%d\", PORT);\n\n private static final String[] IPROXY_CMDLINE = new String[]{\n IPROXY_EXECUTABLE.getAbsolutePath(),\n Integer.toString(PORT),\n Integer.toString(PORT),\n String.format(\"> %s 2>&1 &\", IPROXY_LOG.getAbsolutePath())\n };\n\n private static WDAServer instance = null;\n private final boolean isRealDevice;\n private final String deviceId;\n private final String platformVersion;\n private int failedRestartRetriesCount = 0;\n\n private WDAServer() {\n try {\n this.isRealDevice = !getIsSimulatorFromConfig(getClass());\n final String udid;\n if (isRealDevice) {\n udid = IOSRealDeviceHelpers.getUDID();\n } else {\n udid = IOSSimulatorHelpers.getId();\n }\n this.deviceId = udid;\n this.platformVersion = getPlatformVersionFromConfig(getClass());\n } catch (Exception e) {\n throw new RuntimeException(e);\n }\n ensureToolsExistence();\n ensureParentDirExistence();\n }\n\n public synchronized static WDAServer getInstance() {\n if (instance == null) {\n instance = new WDAServer();\n }\n return instance;\n }\n\n private boolean waitUntilIsRunning(Timedelta timeout) throws Exception {\n final URL status = new URL(SERVER_URL + \"/status\");\n try {\n if (timeout.asSeconds() > 5) {\n log.debug(String.format(\"Waiting max %s until WDA server starts responding...\", timeout));\n }\n new UrlChecker().waitUntilAvailable(timeout.asMillis(), TimeUnit.MILLISECONDS, status);\n return true;\n } catch (UrlChecker.TimeoutException e) {\n return false;\n }\n }\n\n private static void ensureParentDirExistence() {\n if (!XCODEBUILD_LOG.getParentFile().exists()) {\n if (!XCODEBUILD_LOG.getParentFile().mkdirs()) {\n throw new IllegalStateException(String.format(\n \"The script has failed to create '%s' folder for Appium logs. \" +\n \"Please make sure your account has correct access permissions on the parent folder(s)\",\n XCODEBUILD_LOG.getParentFile().getAbsolutePath()));\n }\n }\n }\n\n private void ensureToolsExistence() {\n if (isRealDevice && !IPROXY_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"%s tool is expected to be installed (`npm install -g iproxy`)\",\n IPROXY_EXECUTABLE.getAbsolutePath()));\n }\n if (!XCODEBUILD_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"xcodebuild tool is not detected on the current system at %s\",\n XCODEBUILD_EXECUTABLE.getAbsolutePath()));\n }\n if (!WDA_PROJECT.exists()) {\n throw new IllegalStateException(String.format(\"WDA project is expected to exist at %s\",\n WDA_PROJECT.getAbsolutePath()));\n }\n }\n\n private List<String> generateXcodebuildCmdline() {\n final List<String> result = new ArrayList<>();\n result.add(XCODEBUILD_EXECUTABLE.getAbsolutePath());\n result.add(\"clean build-for-testing test-without-building\");\n result.add(String.format(\"-project %s\", WDA_PROJECT.getAbsolutePath()));\n result.add(String.format(\"-scheme %s\", WDA_SCHEME));\n result.add(String.format(\"-destination id=%s\", deviceId));\n result.add(String.format(\"-configuration %s\", WDA_CONFIGURATION));\n result.add(String.format(\"IPHONEOS_DEPLOYMENT_TARGET=%s\", platformVersion));\n result.add(String.format(\"> %s 2>&1 &\", XCODEBUILD_LOG.getAbsolutePath()));\n return result;\n }\n\n private static List<String> generateKeychainUnlockCmdlines() throws Exception {\n final List<String> result = new ArrayList<>();\n result.add(String.format(\"/usr/bin/security -v list-keychains -s %s\", KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security -v unlock-keychain -p %s %s\",\n KEYCHAIN_PASSWORD, KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security set-keychain-settings -t 3600 %s\", KEYCHAIN.getAbsolutePath()));\n return result;\n }\n\n public synchronized void restart() throws Exception {\n if (isRealDevice && failedRestartRetriesCount >= MAX_REAL_DEVICE_RESTART_RETRIES) {\n throw new IllegalStateException(String.format(\n \"WDA server cannot start on the connected device with udid %s after %s retries. \" +\n \"Reboot the device manually and try again\", deviceId, MAX_REAL_DEVICE_RESTART_RETRIES));\n }\n\n final String hostname = InetAddress.getLocalHost().getHostName();\n log.info(String.format(\"Trying to (re)start WDA server on %s:%s...\", hostname, PORT));\n UnixProcessHelpers.killProcessesGracefully(IPROXY_EXECUTABLE.getName(), XCODEBUILD_EXECUTABLE.getName());\n\n final File scriptFile = File.createTempFile(\"script\", \".sh\");\n try {\n final List<String> scriptContent = new ArrayList<>();\n scriptContent.add(\"#!/bin/bash\");\n if (isRealDevice && isRunningInJenkinsNetwork()) {\n scriptContent.add(String.join(\"\\n\", generateKeychainUnlockCmdlines()));\n }\n if (isRealDevice) {\n scriptContent.add(String.join(\" \", IPROXY_CMDLINE));\n }\n final String wdaBuildCmdline = String.join(\" \", generateXcodebuildCmdline());\n log.debug(String.format(\"Building WDA with command line:\\n%s\\n\", wdaBuildCmdline));\n scriptContent.add(wdaBuildCmdline);\n try (Writer output = new BufferedWriter(new FileWriter(scriptFile))) {\n output.write(String.join(\"\\n\", scriptContent));\n }\n new ProcessBuilder(\"/bin/chmod\", \"u+x\", scriptFile.getCanonicalPath())\n .redirectErrorStream(true).start().waitFor(5, TimeUnit.SECONDS);\n final ProcessBuilder pb = new ProcessBuilder(\"/bin/bash\", scriptFile.getCanonicalPath());\n final Map<String, String> env = pb.environment();\n // This is needed for Jenkins\n env.put(\"BUILD_ID\", \"dontKillMe\");\n // This line is important. If USE_PORT environment variable is not set then WDA\n // takes port number zero by default and won't accept any incoming requests\n env.put(\"USE_PORT\", Integer.toString(PORT));\n log.info(String.format(\"Waiting max %s for WDA to be (re)started on %s:%s...\", RESTART_TIMEOUT.toString(),\n hostname, PORT));\n final Timedelta started = Timedelta.now();\n pb.redirectErrorStream(true).start().waitFor(RESTART_TIMEOUT.asMillis(), TimeUnit.MILLISECONDS);\n if (!waitUntilIsRunning(RESTART_TIMEOUT)) {\n ++failedRestartRetriesCount;\n throw new IllegalStateException(\n String.format(\"WDA server has failed to start after %s timeout on server '%s'.\\n\"\n + \"Please make sure that iDevice is properly connected and you can build \"\n + \"WDA manually from XCode.\\n\"\n + \"Xcodebuild logs:\\n\\n%s\\n\\n\\niproxy logs:\\n\\n%s\\n\\n\\n\",\n RESTART_TIMEOUT, hostname,\n getLog(XCODEBUILD_LOG).orElse(\"EMPTY\"), getLog(IPROXY_LOG).orElse(\"EMPTY\"))\n );\n }\n\n log.info(String.format(\"WDA server has been successfully (re)started after %s \" +\n \"and now is listening on %s:%s\", Timedelta.now().diff(started).toString(), hostname, PORT));\n } finally {\n scriptFile.delete();\n }\n }\n\n public boolean isRunning() throws Exception {\n if (!isProcessRunning(XCODEBUILD_EXECUTABLE.getName())\n || (isRealDevice && !isProcessRunning(IPROXY_EXECUTABLE.getName()))) {\n return false;\n }\n return waitUntilIsRunning(isRealDevice ? REAL_DEVICE_RUNNING_TIMEOUT : Timedelta.ofSeconds(3));\n }\n\n public Optional<String> getLog(File logFile) {\n if (logFile.exists()) {\n try {\n return Optional.of(new String(Files.readAllBytes(logFile.toPath()), Charset.forName(\"UTF-8\")));\n } catch (IOException e) {\n e.printStackTrace();\n }\n }\n return Optional.empty();\n }\n}\n
The following piece of code should then be called before starting the XCUITest driver:
if (!WDAServer.getInstance().isRunning()) {\n WDAServer.getInstance().restart();\n}\n
It is important to set the appium:webDriverAgentUrl
capability for the driver to let it know that WDA is ready for use:
capabilities.setCapability(\"webDriverAgentUrl\", WDAServer.SERVER_URL);\n
"},{"location":"guides/wda-custom-server/#important-notes","title":"Important Notes","text":"xcodebuild
and iproxy
processes are killed before restart to make sure compilation succeeds, in case the processes are frozenbash
script is used to detach the iproxy
/xcodebuild
processes, so they can continue running in background even after the actual code execution is finished. This is extremely important if multiple tests/suites are executed on the same machine/node in automation lab, which requires minimum human interactionBUILD_ID
environment variable is changed to avoid the CI agent killing the background process after the job is finishedisRunning
check is done by verifying the actual network endpointsystem_profiler SPUSBDataType
outputxcrun simctl list
outputUrlChecker
class is imported from the org.openqa.selenium.net
packageInfo
Before installing, make sure to check the System Requirements.
Use the Appium extension CLI to add this driver to your Appium install:
appium driver install xcuitest\n
Alternatively, if you are running a Node.js project, you can include appium-xcuitest-driver
as one of your dependencies.
To activate the driver, simply launch the Appium server. By default, Appium will load all the installed drivers:
appium\n
You should see some output that includes a line like this:
[Appium] XCUITestDriver has been successfully loaded in 0.789s\n
Once you have installed the driver and confirmed it works, you should continue with device preparation.
"},{"location":"installation/requirements/","title":"System Requirements","text":""},{"location":"installation/requirements/#main-dependencies","title":"Main Dependencies","text":"Like all Appium drivers, the XCUITest driver requires Appium to be installed. Refer to the Appium documentation for its requirements and prerequisites.
Note
Since version 4.0.0, the XCUITest driver has dropped support for Appium 1, and is only compatible with Appium 2.
In addition to Appium system requirements, the XCUITest driver expects the following prerequisites:
xcpretty
can be used to make Xcode output easier to read. It can be installed by running gem install xcpretty
.ffmpeg
is used for test video recording. It can be installed using brew
: brew install ffmpeg
idb
, go-ios
and tidevice
can be used to improve device interactionspy-ios-device
is required in several mobile:
extensions, and can improve the general testing experience for real devicesSince driver version 5.13.0, you can automate the validation for the most of the above requirements as well as various optional ones needed by driver extensions by running the appium driver doctor xcuitest
command.
The XCUITest driver functionality relies on the XCTest framework, and changes in the XCTest API are published in new Xcode and iOS versions. Many major and even some minor Xcode/iOS versions include breaking changes in this API, which require updating the driver code. Similarly, maintaining compatibility with older Xcode/iOS versions often requires workarounds, which are eventually dropped in order to simplify the code and use newer XCTest features.
Generally, the driver aims to support at least two latest major Xcode and iOS versions.
The following table lists the minimum driver versions required for specific Xcode/iOS versions:
Xcode/iOS version Minimum required XCUITest driver version Xcode 13 / iOS 15 3.48.0 Xcode 14-beta.3 / iOS 16 Beta 4.7.4 Xcode 14.3 / iOS 16.4 4.21.7 Xcode 15 / iOS 17 4.35.0The following table lists the last driver versions that are compatible with older Xcode versions:
Xcode version Last supported XCUITest driver version Xcode 8 2.95.0 Xcode 9 2.133.1 Xcode 10-10.1 3.31.1 Xcode 10.2 3.56.3 Xcode 11 4.3.2 Xcode 12 4.27.2The following table lists the last driver versions that are compatible with older iOS versions:
iOS version Last supported XCUITest driver version iOS < 15 4.27.2"},{"location":"preparation/","title":"Device Preparation","text":"Before using the XCUITest driver with a simulator or real device, some device preparation is required.
"},{"location":"preparation/#automatic-adjustments","title":"Automatic Adjustments","text":"The XCUITest driver automatically adjusts some device preferences for testing purposes.
"},{"location":"preparation/#keyboard-configuration","title":"Keyboard Configuration","text":"Some keyboard preferences are changed in order to make test runs more stable. You can change some of them via the Settings API.
Unfortunately, not all configuration can be done automatically, and some changes must be applied manually.
"},{"location":"preparation/#accessibility-settings","title":"Accessibility Settings","text":"WKWebView
and/or JSContext
component must have the isInspectable
property set to true
. Please read the WebKit documentation page for more details on this property.get-task-allow
entitlement present as true
in the application manifest.Some settings are enabled by default on simulators, but need to be manually changed for real devices. See the Real Device Configuration document for details.
"},{"location":"preparation/prov-profile-basic-auto/","title":"Basic Automatic Configuration","text":"If you have a paid Apple Developer account, the easiest way to create the provisioning profile is to use the automatic configuration strategy. There are two ways to do this:
xcodeOrgId
and xcodeSigningId
capabilities: {\n \"appium:xcodeOrgId\": \"<Team ID>\",\n \"appium:xcodeSigningId\": \"Apple Developer\"\n}\n
.xcconfig
file somewhere on your file system and add the following to it: DEVELOPMENT_TEAM = <Team ID>\nCODE_SIGN_IDENTITY = Apple Developer\n
Then use the xcodeConfigFile
capability to specify the path to this file: {\n \"appium:xcodeConfigFile\": \"/path/to/xcconfig/file\"\n}\n
Note that these are mutually exclusive strategies; use either the xcodeConfigFile
capability or the combination of xcodeOrgId
and xcodeSigningId
.
xcodeOrgId
/ DEVELOPMENT_TEAM
is a unique 10-character string generated by Apple that is assigned to your team.xcodeSigningId
/ CODE_SIGN_IDENTITY
is usually either Apple Developer
or iPhone Developer
.Once this configuration is done, you should specify your real device UDID with the udid
desired capability, after which you should be able to start your test. Proceed with Validating the WDA Install for the next steps.
There are many cases in which the basic automatic configuration is not enough. Often this happens when the development account being used is a \"Free\" one, in which case it is not possible to create a wildcard provisioning profile.
You can confirm this by opening the WDA project in Xcode. The issue will manifest as something like an error that Xcode failed to create provisioning profile:
The easiest way around this is to create a new project:
The type does not matter, other than it being \"iOS\". \"Single View Application\" is the easiest:
The important part is to use a unique \"Product Name\" and \"Organization Name\". Also, at this point, specify your \"Team\".
You can confirm that the provisioning profile was created by looking at the \"Project\" tab:
Or by going into your account preferences and seeing the provisioning profile:
At this point you have a valid provisioning profile. Make note of the bundle identifier you associated with it, and add that in the updatedWDABundleId
capability for your tests. Then follow the initial instructions for automatic configuration.
The provisioning profile can also be manually associated with the WDA project. Keep in mind that this will have to be done each time WDA is updated (such as when updating the XCUITest driver), and is not recommended:
mkdir -p Resources/WebDriverAgent.bundle\n
WebDriverAgent.xcodeproj
in Xcode. This will likely open a screen with an empty editor.Check Automatically manage signing, and then select your Team (you may need to first sign into Xcode). The outcome should be similar to the following:
Xcode will likely fail to create a provisioning profile due to an invalid bundle identifier:
Change the Bundle Identifier from com.facebook.WebDriverAgentRunner
to something that Xcode will accept. You can also do this in the Build Settings tab:
Note
Versions of Xcode older than 11 have a different naming convention. This feature may not work for a package which is built by Xcode versions below 12.
If your bundle identifier is accepted, you should see that Xcode has created a provisioning profile and all is well:
Finally, you can verify that everything works:
Proceed with Validating the WDA Install for the next steps!
"},{"location":"preparation/prov-profile-generic-manual/","title":"Manual Configuration for a Generic Device","text":"It is possible to build WebDriverAgentRunner
for a generic iOS/iPadOS/tvOS device, and install the generated .app
package to a real device.
# iOS/iPadOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_ios -scheme WebDriverAgentRunner -destination generic/platform=iOS CODE_SIGNING_ALLOWED=YES\n\n# tvOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_tvos -scheme WebDriverAgentRunner_tvOS -destination generic/platform=tvOS CODE_SIGNING_ALLOWED=YES\n
On successful completion the resulting package WebDriverAgentRunner-Runner.app
should be located in the Build/Products/Debug-iphoneos/
subfolder under WebDriverAgent sources root, or in the path provided as derivedDataPath
argument.
Note
If the build fails, please make sure WebDriverAgent.xcodeproj
has codesigning properties configured properly. For example, you may need to change the bundle id for the provisioning profile.
The WebDriverAgentRunner-Runner.app
can now be installed to any real device as allowed by the provisioning profile.
You can install the package with 3rd party tools and manage it separately as explained in How To Set Up And Customize WebDriverAgent Server. Note that if the codesigning was not correct, the installation will fail.
As a more advanced method, you can generate the package with CODE_SIGNING_ALLOWED=NO
and do codesign
by yourself. This would make the device management more flexible, but you would need to know about advanced codesign usage scenarios.
Note
The Appium team distributes generic builds with CODE_SIGNING_ALLOWED=NO
at https://github.com/appium/WebDriverAgent/releases. It is recommended to sign packages with a wildcard (*
) provisioning profile, although such profiles require a paid Apple Developer account. In case of a free account, you may need to update the bundle id before building the WebDriverAgent package.
In order to communicate with the device under test, the XCUITest driver automatically installs the WebDriverAgentRunner-Runner
(WDA) application on it, using Xcode's command-line utility xcodebuild
. Unlike simulators, real devices have several security restrictions that need to be manually configured, before this can work:
devmodectl streaming
CLI on macOS 13+ and installing development signed apps also help enabling the mode.Finally, the WDA application must have a valid provisioning profile, which includes signing the app and linking it to a development team.
"},{"location":"preparation/real-device-config/#provisioning-profile-setup","title":"Provisioning Profile Setup","text":"Generally, unless your device under test already has WDA installed, or you already have a prebuilt WDA on your local system, you will need an Apple ID to be able to sign the app.
Once you have an Apple ID, there are several approaches you can take.
If the automatic configuration did not work or does not apply to you, you will need to follow one of the manual configuration approaches. All of these involve the WDA Xcode project, so at the very least, you must know the local path to the project file - WebDriverAgent.xcodeproj
:
appium-webdriveragent
, which is installed as a dependency of the XCUITest driver. You can therefore find the project file in /path/to/xcuitest/driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj
. By default, drivers are installed in ~/.appium
, so the project would be located at ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj
.appium driver run xcuitest open-wda
driver script to directly open WebDriverAgent.xcodeproj
in Xcode.The WDA project file can now be used in the manual configuration approaches:
xcodebuild
to build WDA, then manually install itOnce you have configured the WDA project or have the app ready, you can try installing it. It is possible that you may encounter some errors:
xcodebuild exited with code '65' and signal 'null'
This usually happens when attempting the automatic configuration, and it means that the necessary code signing is not set up correctly. Follow the steps in any of the manual configuration approaches to fix this.
Unable to launch <your-bundle-id>.WebDriverAgentRunner-Runner because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.
This means that the developer is not trusted on the device. If you manually try to open the WDA app on the device, you will see a popup message:
To fix this, you need to open Settings -> General -> VPN & Device Management on the device, then select your development team and trust it. Afterwards you should be able to open/launch the app. See Apple documentation for more information.
For other issues, please refer to the Troubleshooting page
Since iOS 16, Apple requires a device to have a live internet connection for validating the code signing. It is possible to set up an offline enabled provisiong profile, which allows you to avoid the limitation. Please read this issue regarding detailed configuration steps.
"},{"location":"reference/capabilities/","title":"Capabilities","text":"This page lists various capabilities used and implemented by the XCUITest driver. To learn more about capabilities, refer to the Appium documentation.
"},{"location":"reference/capabilities/#general","title":"General","text":"Capability DescriptionplatformName
Could be set to ios
. Appium itself is not strict about this capability value if automationName
is provided, so feel free to assign it to any supported platform name if this is needed, for example, to make Selenium Grid working. browserName
The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read Automating hybrid apps for more details. Usually equals to safari
. appium:automationName
Must always be set to xcuitest
. Values of automationName
are compared case-insensitively. appium:deviceName
The name of the device under test. Consider setting udid
for real devices and use this one for Simulator selection instead appium:platformVersion
The platform version of an emulator or a real device. This capability is used for device autodetection if udid
is not provided appium:udid
UDID of the device to be tested. Could be retrieved from Xcode->Window->Devices and Simulators window. Always set this capability if you run parallel tests or use a real device to run your tests. appium:noReset
Prevents the device to be reset before the session startup if set to true
. This means that the application under test is not going to be terminated neither its data cleaned. false
by default appium:fullReset
Being set to true
always enforces the application under test to be fully uninstalled before starting a new session. The application data might be cached on real devices under particular circumstances. Please check troubleshooting for more details regarding obsolete application data cleanup on real devices. false
by default appium:printPageSourceOnFindFailure
Enforces the server to dump the actual XML page source into the log if any error happens. false
by default. appium:includeDeviceCapsToSessionInfo
Whether to include screen information as the result of Get Session Capabilities. It includes pixelRatio
, statBarHeight
and viewportRect
, but it causes an extra API call to WDA which may increase the response time like this issue. Defaults to true
. This capability has no effect since driver version 5 appium:resetLocationService
Whether reset the location service in the session deletion on real device. Defaults to false
. appium:customSSLCert
Adds a root SSL certificate to IOS Simulators and real devices. Real devices only work if py-ios-device tool is available on the server machine. The certificate content must be provided in PEM format, e.g. -----BEGIN CERTIFICATE-----MIIFWjCCBEKg...-----END CERTIFICATE-----
"},{"location":"reference/capabilities/#app","title":"App","text":"Capability Description appium:bundleId
Bundle identifier of the app under test, for example com.mycompany.myapp
. The capability value is calculated automatically if app
is provided. If neither app
or bundleId
capability is provided then XCUITest driver starts from the Home screen. appium:app
Full path to the application to be tested (the app must be located on the same machine where the server is running). .ipa
and .app
application extensions are supported. Zipped .app
bundles are supported as well. Could also be an URL to a remote location. If neither of the app
or bundleId
capabilities are provided then the driver starts from the Home screen and expects the test to know what to do next. Do not provide both app
and browserName
capabilities at once. appium:enforceAppInstall
If set to false
it will make xcuitest driver to verify whether the app version currently installed on the device under test is older than the one, which is provided as appium:app
value. No app reinstall is going to happen if the candidate app has the same or older version number than the already installed copy of it. The version number used for comparison must be provided as CFBundleVersion Semantic Versioning-compatible value in the application's Info.plist. No validation is performed by default, e.g. the provided app is always (re)installed, which could potentially slow down your test suites. The application data might be cached on real devices under particular circumstances when appium:enforceAppInstall
is true
if the application under test remained on the device under a certain situation. Please check troubleshooting for more details regarding obsolete application data cleanup on real devices. Available since XCUITest driver 4.19.0. appium:localizableStringsDir
Where to look for localizable strings in the application bundle. Defaults to en.lproj
appium:otherApps
App or list of apps (as a JSON array) to install prior to running tests. For example: [\"http://appium.github.io/appium/assets/TestApp9.4.app.zip\", \"/path/to/app-b.app\"]
appium:language
Language to set for iOS app, for example fr
. Please read Language IDs to get more details about available values for this capability. If a test is executed on a Simulator then UI language is changed as well. You can also change Simulator language in runtime using mobile: configureLocalization extension. appium:locale
Locale to set for iOS app, for example fr_CA
. Please read Locale IDs to get more details about available values for this capability. If a test is executed on a Simulator then UI locale is changed as well. You can also change Simulator locale in runtime using mobile: configureLocalization extension. appium:calendarFormat
Calendar format to set for iOS Simulator, for example gregorian
or persian
. Can only be set in conjunction with appium:locale
. appium:appPushTimeout
The timeout for application upload in milliseconds. Works for real devices only. The default value is 30000
ms appium:appInstallStrategy
Select application installation strategy for real devices. The following strategies are supported:serial
(default) - pushes app files to the device in a sequential order; this is the least performant strategy, although the most reliableparallel
- pushes app files simultaneously; this is usually the the most performant strategy, but sometimes could not be very stableios-deploy
- tells the driver to use a third-party tool ios-deploy to install the app; obviously the tool must be installed separately first and must be present in PATH before it could be used."},{"location":"reference/capabilities/#webdriveragent","title":"WebDriverAgent","text":"Capability Description Example appium:xcodeOrgId
Apple developer team identifier string. Must be used in conjunction with xcodeSigningId
to take effect. JWL241K123
appium:xcodeSigningId
String representing a signing certificate. Must be used in conjunction with xcodeOrgId
. This is usually just Apple Development
or iPhone Developer
, so the default (if not included) is iPhone Developer
Apple Developer
appium:xcodeConfigFile
Full path to an optional Xcode configuration file that specifies the code signing identity and team for running the WebDriverAgent
on the real device. /path/to/myconfig.xcconfig
appium:updatedWDABundleId
Bundle id to update WDA to before building and launching on real devices. This bundle id must be associated with a valid provisioning profile. io.appium.WebDriverAgentRunner
appium:keychainPath
Full path to the private development key exported from the system keychain. Used in conjunction with keychainPassword
when testing on real devices. /path/to/MyPrivateKey.p12
appium:keychainPassword
Password for unlocking keychain specified in keychainPath
. super awesome password
appium:derivedDataPath
Use along with usePrebuiltWDA capability and choose where to search for the existing WDA app. If the capability is not set then Xcode will store the derived data in the default root taken from preferences. appium:webDriverAgentUrl
If provided, Appium will connect to an existing WebDriverAgent
instance at this URL instead of starting a new one. http://localhost:8100
appium:useNewWDA
If true
, forces uninstall of any existing WebDriverAgent
app on device. Set it to true
if you want to apply different startup options for WebDriverAgent
for each session. Although, it is only guaranteed to work stable on Simulator. Real devices require WebDriverAgent
client to run for as long as possible without reinstall/restart to avoid issues like https://github.com/facebook/WebDriverAgent/issues/507. The false
value (the default behaviour since driver version 2.35.0) will try to detect currently running WDA listener executed by previous testing session(s) and reuse it if possible, which is highly recommended for real device testing and to speed up suites of multiple tests in general. A new WDA session will be triggered at the default URL (http://localhost:8100) if WDA is not listening and webDriverAgentUrl
capability is not set. The negative/unset value of useNewWDA
capability has no effect prior to xcuitest driver version 2.35.0. true
appium:wdaLaunchTimeout
Time, in ms, to wait for WebDriverAgent
to be pingable. Defaults to 60000ms. 30000
appium:wdaConnectionTimeout
Timeout, in ms, for waiting for a response from WebDriverAgent
. Defaults to 240000ms. 1000
appium:wdaStartupRetries
Number of times to try to build and launch WebDriverAgent
onto the device. Defaults to 2. 4
appium:wdaStartupRetryInterval
Time, in ms, to wait between tries to build and launch WebDriverAgent
. Defaults to 10000ms. 20000
appium:wdaLocalPort
This value if specified, will be used to forward traffic from Mac host to real ios devices over USB. Default value is same as port number used by WDA on device. 8100
appium:wdaRemotePort
This value if specified, will be used as the port number to start WDA HTTP server on the remote device. This is only relevant for real devices, because Simulator shares ports with its host. If webDriverAgentUrl
is provided then it might be used to provide a hint for the remote port number if it differs from the default one. Default value is 8100. 8100
appium:wdaBaseUrl
This value if specified, will be used as a prefix to build a custom WebDriverAgent
url. It is different from webDriverAgentUrl
, because if the latter is set then it expects WebDriverAgent
to be already listening and skips the building phase. Defaults to http://localhost
http://192.168.1.100
appium:showXcodeLog
Whether to display the output of the Xcode command used to run the tests. If this is true
, there will be lots of extra logging at startup. Defaults to false
true
appium:iosInstallPause
Time in milliseconds to pause between installing the application and starting WebDriverAgent
on the device. Used particularly for larger applications. Defaults to 0
8000
appium:usePrebuiltWDA
Skips the build phase of running the WDA app. Building is then the responsibility of the user. Only works for Xcode 8+. Defaults to false
. true
appium:prebuiltWDAPath
The path to a WebDriverAgentRunner application package to be installed with appium:usePreinstalledWDA
capability for real devices. The package's bundle id will be used over appium:updatedWDABundleId
. /path/to/WebDriverAgentRunner-Runner.app
appium:usePreinstalledWDA
Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client (via com.apple.instruments
service) instead of running xcodebuild
for real devices. If appium:prebuiltWDAPath
is provided, XCUITest driver will install it before launching the application. The preinstalled WebDriverAgent package must have been built by Xcode 12+. The default target bundle identifier is com.facebook.WebDriverAgentRunner.xctrunner
. If appium:updatedWDABundleId
is provided, <appium:updatedWDABundleId>.xctrunner
will be launched. Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to false
. true
or false
appium:shouldUseSingletonTestManager
Use default proxy for test management within WebDriverAgent
. Setting this to false
sometimes helps with socket hangup problems. Defaults to true
. false
appium:waitForIdleTimeout
The amount of time in float seconds to wait until the application under test is idling. XCTest requires the app's main thread to be idling in order to execute any action on it, so WDA might not even start/freeze if the app under test is constantly hogging the main thread. The default value is 10
(seconds). Setting it to zero disables idling checks completely (not recommended) and has the same effect as setting waitForQuiescence
to false
. Available since Appium 1.20.0. 1
appium:useXctestrunFile
Use Xctestrun file to launch WDA. It will search for such file in bootstrapPath
. Expected name of file is WebDriverAgentRunner_iphoneos<sdkVersion>-arm64.xctestrun
for real device and WebDriverAgentRunner_iphonesimulator<sdkVersion>-x86_64.xctestrun
for simulator. One can do build-for-testing
for WebDriverAgent
project for simulator and real device and then you will see Product Folder like this and you need to copy content of this folder at bootstrapPath
location. Since this capability expects that you have already built WDA
project, it neither checks whether you have necessary dependencies to build WDA
nor will it try to build project. Defaults to false
. Tips: Xcodebuild
builds for the target platform version. We'd recommend you to build with minimal OS version which you'd like to run as the original WDA module. e.g. If you build WDA for 12.2, the module cannot run on iOS 11.4 because of loading some module error on simulator. A module built with 11.4 can work on iOS 12.2. (This is xcodebuild's expected behaviour.) true
appium:useSimpleBuildTest
Build with build
and run test with test
in xcodebuild for all Xcode version if this is true
, or build with build-for-testing
and run tests with test-without-building
for over Xcode 8 if this is false
. Defaults to false
. true
or false
appium:wdaEventloopIdleDelay
Delays the invocation of -[XCUIApplicationProcess setEventLoopHasIdled:]
by the number of seconds specified with this capability. This can help quiescence apps that fail to do so for no obvious reason (and creating a session fails for that reason). This increases the time for session creation because -[XCUIApplicationProcess setEventLoopHasIdled:]
is called multiple times. If you enable this capability start with at least 3
seconds and try increasing it, if creating the session still fails. Defaults to 0
. 5
appium:processArguments
Process arguments and environment which will be sent to the WebDriverAgent
server in a new session request. Please use mobile: launchApp to launch an application with process arguments in the middle of a session. { args: [\"a\", \"b\", \"c\"] , env: { \"a\": \"b\", \"c\": \"d\" } }
or '{\"args\": [\"a\", \"b\", \"c\"], \"env\": { \"a\": \"b\", \"c\": \"d\" }}'
appium:autoLaunch
When set to false
, prevents the application under test from being launched automatically as a part of the new session startup process. The launch become the responsibility of the user. Defaults to true
. true
or false
appium:allowProvisioningDeviceRegistration
Allow xcodebuild
to register your destination device on the developer portal if necessary. Requires a developer account to have been added in Xcode's Accounts preference pane. Defaults to false
. true
or false
appium:resultBundlePath
Specify the path to the result bundle path as xcodebuild
argument for WebDriverAgent
build under a security flag (Please check Opt-in Features section below). WebDriverAgent
process must start/stop every time to pick up changed value of this property. Specifying useNewWDA
to true
may help there. Please read man xcodebuild
for more details. /path/to/resultbundle
appium:resultBundleVersion
Specify the version of result bundle as xcodebuild
argument for WebDriverAgent
build. The default value depends on your Xcode version. Please read man xcodebuild
for more details. /path/to/resultbundle
appium:maxTypingFrequency
Maximum frequency of keystrokes for typing and clear. If your tests are failing because of typing errors, you may want to adjust this. Defaults to 60 keystrokes per minute. 30
appium:simpleIsVisibleCheck
Use native methods for determining visibility of elements. In some cases this takes a long time. Setting this capability to false
will cause the system to use the position and size of elements to make sure they are visible on the screen. This can, however, lead to false results in some situations. Defaults to false
. true
, false
appium:waitForQuiescence
It allows to turn on/off waiting for application quiescence in WebDriverAgent
, while performing queries. The default value is true
. You can avoid this kind of issues if you turn it off. Consider using waitForIdleTimeout
capability instead for this purpose since Appium 1.20.0 false
appium:mjpegServerPort
The port number on which WDA broadcasts screenshots stream encoded into MJPEG format from the device under test. It might be necessary to change this value if the default port is busy because of other tests running in parallel. Default value: 9100
12000
appium:screenshotQuality
Changes the initial quality of display screenshots. This capability affects the screenshoting speed and the actual quality of resulting screenshots. Before version 5.4.0 of WebDriverAgent possible values were: 0
, 1
(default), 2
, where 0
abbreviates lossless PNG, 1
is a high-quality JPEG and 2
is a low-quality JPEG. In the version 5.4.0 one more mode has been added (3
), which is now the default one. It abbreviates lossless HEIC with fallback to PNG if the device does not support hardware-accelerated HEIC encoding. You can also change the value of screenshotQuality in settings. 2
appium:autoAcceptAlerts
Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is false
. true
or false
appium:autoDismissAlerts
Dismiss all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is false
. true
or false
appium:disableAutomaticScreenshots
Disable automatic screenshots taken by XCTest at every interaction. Default is up to WebDriverAgent
's config to decide, which currently defaults to true
. true
or false
appium:shouldTerminateApp
Specify if the app should be terminated on session end. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is true
unless noReset
capability is set to true
. true
or false
appium:forceAppLaunch
Specify if the app should be forcefully restarted if it is already running on session startup. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is true
unless noReset
capability is set to true
. true
or false
appium:useNativeCachingStrategy
Set this capability to false
in order to use the custom elements caching strategy. This might help to avoid stale element exception on property change. By default the native XCTest cache resolution is used (true
) for all native locators (e.g. all, but xpath). Check the corresponding WebDriverAgent pull request for more details. true
or false
"},{"location":"reference/capabilities/#simulator","title":"Simulator","text":"Capability Description Example appium:orientation
Start a test session in a certain orientation. Note, that Simulator may ignore this capability if the simulated device itself does not support orientation change in its current state. For example, iPhones only allow orientation change to landscape if an app that declares landscape support in its manifest is running. Thus changing the orientation from portrait to something else being on home screen won't have any effect. LANDSCAPE
or PORTRAIT
appium:scaleFactor
Simulator scale factor. This is useful to have if the default resolution of simulated device is greater than the actual display resolution, so you can scale the simulator to see the whole device screen without scrolling. Must be a string containing a positive float value. '2.0'
appium:connectHardwareKeyboard
Set this option to true
in order to enable hardware keyboard in Simulator. The preference works only when XCUITest driver launches a simulator instance with this value. It is set to false
by default, because this helps to workaround some XCTest bugs. connectHardwareKeyboard: true
makes forceSimulatorSoftwareKeyboardPresence: false
if no explicit value is set for forceSimulatorSoftwareKeyboardPresence
capability since Appium 1.22.0. true
or false
appium:forceSimulatorSoftwareKeyboardPresence
Set this option to true
in order to turn software keyboard on and turn hardware keyboard off in Simulator since Appium 1.22.0. This option helps to avoid Keyboard is not present
error. It is set to true
by default. XCUITest driver respects preset simulator software/hardware keyboard preference when this value is false
, so connectHardwareKeyboard: false
and forceSimulatorSoftwareKeyboardPresence: false
means for XCUITest driver to keep the current Simulator keyboard preferences. This option has priority over connectHardwareKeyboard
. true
or false
appium:skipSyncUiDialogTranslation
Set this option to true
in order to skip synchronizing UI dialogs translation. While this option might leave some system UI alerts untranslated, it helps to avoid unexpected side effects (see this issue for more details). It is set to false
by default. true
or false
Deprecated appium:calendarAccessAuthorized
This capability is obsolete. Please use appium:permissions
one instead with the calendar
key. true
or false
appium:isHeadless
Set this capability to true
if automated tests are running on Simulator and the device display is not needed to be visible. This only has an effect since Xcode9 and only for simulators. All running instances of Simulator UI are going to be automatically terminated if headless test is started. false
is the default value. true
appium:simulatorWindowCenter
Allows to explicitly set the coordinates of Simulator window center for Xcode9+ SDK. This capability only has an effect if Simulator window has not been opened yet for the current session before it started. Must be a tuple containing floats or integers, with no spaces. {-100.0,100.0}
appium:simulatorStartupTimeout
Allows to change the default timeout for Simulator startup. By default this value is set to 120000ms (2 minutes), although the startup could take longer on a weak hardware or if other concurrent processes use much system resources during the boot up procedure. 300000
appium:simulatorTracePointer
Whether to highlight pointer moves in the Simulator window. The Simulator UI client must be shut down before the session startup in order for this capability to be applied properly. false
by default. true
appium:shutdownOtherSimulators
If this capability set to true
and the current device under test is an iOS Simulator then Appium will try to shutdown all the other running Simulators before to start a new session. This might be useful while executing webview tests on different devices, since only one device can be debugged remotely at once due to an Apple bug. The capability only has an effect if --relaxed-security
command line argument is provided to the server. Defaults to false
. true
appium:enforceFreshSimulatorCreation
Creates a new simulator in session creation and deletes it in session deletion. Defaults to false
. true
or false
appium:keepKeyChains
Set the capability to true
in order to preserve Simulator keychains folder after full reset. This feature has no effect on real devices. Defaults to false
true
appium:keychainsExcludePatterns
This capability accepts comma-separated path patterns, which are going to be excluded from keychains restore while full reset is being performed on Simulator. It might be useful if you want to exclude only particular keychain types from being restored, like the applications keychain. This feature has no effect on real devices. *keychain*.db*
appium:reduceMotion
It allows to turn on/off reduce motion accessibility preference. Setting reduceMotion on
helps to reduce flakiness during tests. Only on simulators true
appium:reduceTransparency
It allows you to turn on/off reduce transparency accessibility preference. Setting reduceTransparency on
helps to reduce screenshot image distortion during tests. Only on simulators true
appium:autoFillPasswords
It allows you to turn on/off autofill passwords function when text field is foccused. Works only with iOS16.4+ simulators true
appium:permissions
Allows to set permissions for the specified application bundle on Simulator only. The capability value is expected to be a valid JSON string with {\"<bundleId1>\": {\"<serviceName1>\": \"<serviceStatus1>\", ...}, ...}
format. Since Xcode SDK 11.4 Apple provides native APIs to interact with application settings. Check the output of xcrun simctl privacy booted
command to get the list of available permission names. Use yes
, no
and unset
as values in order to grant
, revoke
or reset
the corresponding permission. Below Xcode SDK 11.4 it is required that applesimutils
package is installed and available in PATH. The list of available service names and statuses can be found at https://github.com/wix/AppleSimulatorUtils. {\"com.apple.mobilecal\": {\"calendar\": \"YES\"}}
appium:iosSimulatorLogsPredicate
Set the --predicate
flag in the ios simulator logs 'process != \"locationd\" AND process != \"DTServiceHub\"' AND process != \"mobileassetd\"
appium:simulatorPasteboardAutomaticSync
Handle the -PasteboardAutomaticSync
flag when simulator process launches. It could improve launching simulator performance not to sync pasteboard with the system when this value is off
. on
forces the flag enabled. system
does not provide the flag to the launching command. on
, off
, or system
is available. They are case insensitive. Defaults to off
system
appium:simulatorDevicesSetPath
This capability allows to set an alternative path to the simulator devices set in case you have multiple sets deployed on your local system. Such feature could be useful if you, for example, would like to save disk space on the main system volume. /MyVolume/Devices
appium:webkitResponseTimeout
(Real device only) Set the time, in ms, to wait for a response from WebKit in a Safari session. Defaults to 5000
10000
appium:safariGlobalPreferences
Allows changing of Mobile Safari's preferences at the session startup. Check the documentation on arguments of mobile: updateSafariPreferences extension to get more details on the value type requirements. { ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }
"},{"location":"reference/capabilities/#web-context","title":"Web Context","text":"Capability Description Example appium:absoluteWebLocations
This capability will direct the Get Element Location
command, when used within webviews, to return coordinates which are relative to the origin of the page, rather than relative to the current scroll offset. This capability has no effect outside of webviews. Default false
. true
appium:safariGarbageCollect
Turns on/off Web Inspector garbage collection when executing scripts on Safari. Turning on may improve performance. Defaults to false
. true
or false
appium:includeSafariInWebviews
Add Safari web contexts to the list of contexts available during a native/webview app test. This is useful if the test opens Safari and needs to be able to interact with it. Defaults to false
. true
or false
appium:safariLogAllCommunication
Log all plists sent to and received from the Web Inspector, as plain text. For some operations this can be a lot of data, so it is recommended to be used only when necessary. Defaults to false
. true
or false
appium:safariLogAllCommunicationHexDump
Log all communication sent to and received from the Web Inspector, as raw hex dump and printable characters. This logging is done before any data manipulation, and so can elucidate some communication issues. Like appium:safariLogAllCommunication
, this can produce a lot of data in some cases, so it is recommended to be used only when necessary. Defaults to false
. true
or false
appium:safariSocketChunkSize
The size, in bytes, of the data to be sent to the Web Inspector on iOS 11+ real devices. Some devices hang when sending large amounts of data to the Web Inspector, and breaking them into smaller parts can be helpful in those cases. Defaults to 16384
(also the maximum possible) 1000
appium:safariWebInspectorMaxFrameLength
The maximum size in bytes of a single data frame for the Web Inspector. Too high values could introduce slowness and/or memory leaks. Too low values could introduce possible buffer overflow exceptions. Defaults to 20MB (20*1024*1024
) 1024
, 100*1024*1024
appium:additionalWebviewBundleIds
Array (or JSON array) of possible bundle identifiers for webviews. This is sometimes necessary if the Web Inspector is found to be returning a modified bundle identifier for the app. If the value includes *
, XCUITest driver will return all available webview contexts on the device. Defaults to []
[\"io.appium.modifiedId', 'ABCDEF\"]
, [\"*\"]
appium:webviewConnectTimeout
The time to wait, in ms
, for the initial presence of webviews in MobileSafari or hybrid apps. Defaults to 0
5000
appium:safariIgnoreWebHostnames
Provide a list of hostnames (comma-separated) that the Safari automation tools should ignore. This is to provide a workaround to prevent a webkit bug where the web context is unintentionally changed to a 3rd party website and the test gets stuck. The common culprits are search engines (yahoo, bing, google) and about:blank
'www.yahoo.com, www.bing.com, www.google.com, about:blank'
appium:nativeWebTap
Enable native, non-javascript-based taps being in web context mode. Defaults to false
. Warning: sometimes the preciseness of native taps could be broken, because there is no reliable way to map web element coordinates to native ones. true
appium:nativeWebTapStrict
Enabling this capability would skip the additional logic that tries to match web view elements to native ones by using their textual descriptions. Depending on the actual web view content this algorithm might sometimes be not very reliable and will slow down each click as we anyway fallback to the usual coordinates transformation flow if it fails. It is advised to enable strict tap if you use mobile: calibrateWebToRealCoordinatesTranslation extension. Only applicable if nativeWebTap
is enabled. false
by default true
appium:safariInitialUrl
Initial safari url, default is a local welcome page. Setting it to an empty string will skip the initial navigation. https://www.github.com
appium:safariAllowPopups
(Simulator only) Allow javascript to open new windows in Safari. Default keeps current sim setting. true
or false
appium:safariIgnoreFraudWarning
(Simulator only) Prevent Safari from showing a fraudulent website warning. Default keeps current sim setting. true
or false
appium:safariOpenLinksInBackground
(Simulator only) Whether Safari should allow links to open in new windows. Default keeps current sim setting. true
or false
appium:webviewConnectRetries
Number of times to send connection message to remote debugger, to get webview. Default: 8
12
appium:webkitResponseTimeout
(Real device only) Set the time, in ms, to wait for a response from WebKit in a Safari session. Defaults to 5000
10000
appium:enableAsyncExecuteFromHttps
Capability to allow simulators to execute asynchronous JavaScript on pages using HTTPS. Defaults to false
true
or false
appium:fullContextList
Returns the detailed information on contexts for the Get Contexts command. If this capability is enabled, then each item in the returned contexts list would additionally include WebView title, full URL and the bundle identifier. Defaults to false
. true
or false
appium:enablePerformanceLogging
Enable Safari's performance logging (default false
) true
, false
appium:autoWebview
Move directly into Webview context if available. Default false
true
, false
appium:skipTriggerInputEventAfterSendkeys
If this capability is set to true
, then whenever you call the Send Keys method in a web context, the driver will not fire an additional input
event on the input field used for the call. This event, turned on by default, helps in situations where JS frameworks (like React) do not respond to the input events that occur by default when the underlying Selenium atom is executed. Default false
true
, false
"},{"location":"reference/capabilities/#other","title":"Other","text":"Capability Description Example appium:resetOnSessionStartOnly
Whether to perform reset on test session finish (false
) or not (true
). Keeping this variable set to true
and Simulator running (the default behaviour since version 1.6.4) may significantly shorten the duration of test session initialization. Defaults to true
true
or false
appium:commandTimeouts
Custom timeout(s) in milliseconds for WDA backend commands execution. This might be useful if WDA backend freezes unexpectedly or requires too much time to fail and blocks automated test execution. The value is expected to be of type string and can either contain max milliseconds to wait for each WDA command to be executed before terminating the session forcefully or a valid JSON string, where keys are internal Appium command names (you can find these in logs, look for \"Executing command 'command_name'\" records) and values are timeouts in milliseconds. You can also set the 'default' key to assign the timeout for all other commands not explicitly enumerated as JSON keys. '120000'
, '{\"findElement\": 40000, \"findElements\": 40000, \"setValue\": 20000, \"default\": 120000}'
appium:useJSONSource
Get JSON source from WDA and transform it to XML on the Appium server side. Defaults to false
. true
appium:skipLogCapture
Skips to start capturing logs such as crash, system, safari console and safari network. It might improve performance such as network. Log related commands will not work. Defaults to false
. true
or false
appium:launchWithIDB
Launch WebDriverAgentRunner with idb instead of xcodebuild. This could save a significant amout of time by skiping the xcodebuild process, although the idb might not be very reliable, especially with fresh Xcode SDKs. Check the idb repository for more details on possible compatibility issues. Defaults to false
true
or false
appium:showIOSLog
Whether to show any logs captured from a device in the appium logs. Default false
true
or false
appium:clearSystemFiles
Whether to clean temporary XCTest files (for example logs) when a testing session is closed. false
by default true
or false
appium:newCommandTimeout
How long (in seconds) the driver should wait for a new command from the client before assuming the client has stopped sending requests. After the timeout the session is going to be deleted. 60
seconds by default. Setting it to zero disables the timer. 100
"},{"location":"reference/commands/","title":"Commands","text":"The driver comes with a set of many available commands, in addition to the commands included in the Appium base driver. Refer to the documentation of your Appium client for the exact syntax to call these commands.
Please note that most of the driver-specific functionality is available using Execute Methods instead.
Info
Check the Appium base driver documentation for commands inherited by the XCUITest driver
"},{"location":"reference/commands/#getclipboard","title":"getClipboard
","text":"POST
/session/:sessionId/appium/device/get_clipboard
Gets the content of the primary clipboard on the device under test. See Get/Set Clipboard for more details
"},{"location":"reference/commands/#arguments","title":"Arguments","text":"Name TypecontentType?
any
"},{"location":"reference/commands/#returned-result","title":"Returned Result","text":"string
The actual clipboard content encoded into base64 string. An empty string is returned if the clipboard contains no data.
"},{"location":"reference/commands/#setclipboard","title":"setClipboard
","text":"POST
/session/:sessionId/appium/device/set_clipboard
Sets the primary clipboard's content on the device under test. See Get/Set Clipboard for more details
"},{"location":"reference/commands/#arguments_1","title":"Arguments","text":"Name Type Descriptioncontent
any
- contentType?
any
- label?
string
The content to be set as base64 encoded string."},{"location":"reference/commands/#returned-result_1","title":"Returned Result","text":"null
getGeoLocation
","text":"GET
/session/:sessionId/location
Returns the location of the device under test. Location Services for WebDriverAgent must be set to 'Always' to get the location data correctly.
The 'latitude', 'longitude' and 'altitude' could be zero even if the Location Services are set to 'Always', because the device may need some time to update the location data.
Throws
If the device under test returns an error message. i.e.: tvOS returns unsupported error
"},{"location":"reference/commands/#returned-result_2","title":"Returned Result","text":"Promise
<altitude
: number
, latitude
: number
, longitude
: number
>
setGeoLocation
","text":"POST
/session/:sessionId/location
Set location of the device under test.
For iOS 17+ real devices, this method will call the mobile: setSimulatedLocation
extension.
location
Location
An object with latitude
and longitude
values"},{"location":"reference/commands/#returned-result_3","title":"Returned Result","text":"Promise
<altitude
: number
, latitude
: number
, longitude
: number
>
startRecordingScreen
","text":"POST
/session/:sessionId/appium/start_recording_screen
Start recording the device screen. This functionality is available in the iOS Simulator since Xcode 9, and in real devices since iOS 11.
Screen activity is recorded to an MPEG-4 file. Note that audio is not recorded with the video file. If the screen recording has already been started, this command will force stop it and start a new recording. The previously recorded video file will also be deleted.
Info
This command requires the ffmpeg
utility to be installed (brew install ffmpeg
)
Throws
If the screen recording has failed to start.
"},{"location":"reference/commands/#arguments_3","title":"Arguments","text":"Name Typeoptions?
any
"},{"location":"reference/commands/#returned-result_4","title":"Returned Result","text":"string
Base64-encoded content of the recorded media file if any screen recording is currently running, or an empty string.
"},{"location":"reference/commands/#stoprecordingscreen","title":"stopRecordingScreen
","text":"POST
/session/:sessionId/appium/stop_recording_screen
Stop an ongoing screen recording and return the video. This functionality is available in the iOS Simulator since Xcode 9, and in real devices since iOS 11.
If no screen recording process is running, the command will attempt to retrieve the most recently recorded file. If no previously recorded file is found, the method will return an empty string.
Throws
If there was an error while getting the name of a media file, or the file content cannot be uploaded to the remote location.
"},{"location":"reference/commands/#arguments_4","title":"Arguments","text":"Name Typeoptions?
any
"},{"location":"reference/commands/#returned-result_5","title":"Returned Result","text":"null
| string
Base64-encoded content of the recorded media file if remotePath
parameter is empty or null, or an empty string.
getSize
","text":"GET
/session/:sessionId/element/:elementId/size
Get the size of an element
"},{"location":"reference/commands/#returned-result_6","title":"Returned Result","text":"Size
The positions of the element
"},{"location":"reference/commands/#submit","title":"submit
","text":"POST
/session/:sessionId/element/:elementId/submit
Submit the form an element is in
"},{"location":"reference/commands/#returned-result_7","title":"Returned Result","text":"null
background
","text":"Note
We recommend using the mobile: backgroundApp
extension instead
POST
/session/:sessionId/appium/app/background
Close app (simulate device home button). It is possible to restore the app after the timeout or keep it minimized based on the parameter value.
"},{"location":"reference/commands/#arguments_5","title":"Arguments","text":"Name Typeseconds
any
"},{"location":"reference/commands/#returned-result_8","title":"Returned Result","text":"unknown
queryAppState
","text":"Note
We recommend using the mobile: queryAppState
extension instead
POST
/session/:sessionId/appium/device/app_state
Get the running state of an app
"},{"location":"reference/commands/#returned-result_9","title":"Returned Result","text":"AppState
A number representing the state. 0
means not installed, 1
means not running, 2
means running in background but suspended, 3
means running in the background, and 4
means running in the foreground
isLocked
","text":"Note
We recommend using the mobile: isLocked
extension instead
POST
/session/:sessionId/appium/device/is_locked
Determine whether the device is locked
"},{"location":"reference/commands/#returned-result_10","title":"Returned Result","text":"boolean
true
if the device is locked, false
otherwise
lock
","text":"Note
We recommend using the mobile: lock
extension instead
POST
/session/:sessionId/appium/device/lock
Lock the device (and optionally unlock the device after a certain amount of time)
Default Value
0
"},{"location":"reference/commands/#arguments_6","title":"Arguments","text":"Name Typeseconds?
any
"},{"location":"reference/commands/#returned-result_11","title":"Returned Result","text":"null
unlock
","text":"Note
We recommend using the mobile: unlock
extension instead
POST
/session/:sessionId/appium/device/unlock
Unlock the device
"},{"location":"reference/commands/#returned-result_12","title":"Returned Result","text":"null
mobileShake
","text":"Note
We recommend using the mobile: shake
extension instead
POST
/session/:sessionId/appium/device/shake
Shake the device
"},{"location":"reference/commands/#returned-result_13","title":"Returned Result","text":"null
getStrings
","text":"Note
We recommend using the mobile: getAppStrings
extension instead
POST
/session/:sessionId/appium/app/strings
Return the language-specific strings for an app
"},{"location":"reference/commands/#arguments_7","title":"Arguments","text":"Name Type Default value Descriptionlanguage?
any
undefined
- stringFile?
string
null
The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned"},{"location":"reference/commands/#returned-result_14","title":"Returned Result","text":"StringRecord
<string
>
A record of localized keys to localized text
"},{"location":"reference/commands/#click","title":"click
","text":"Deprecated
This method is deprecated. Please use the mobile: tap
extension instead
POST
/session/:sessionId/touch/click
Click/tap an element
See
https://w3c.github.io/webdriver/#element-click
"},{"location":"reference/commands/#arguments_8","title":"Arguments","text":"Name Typeelement
any
"},{"location":"reference/commands/#returned-result_15","title":"Returned Result","text":"any
setValueImmediate
","text":"Deprecated
This method is deprecated
POST
/session/:sessionId/appium/element/:elementId/value
text
any
"},{"location":"reference/commands/#returned-result_16","title":"Returned Result","text":"null
keys
","text":"Deprecated
This method is deprecated. Please use setValue
instead
POST
/session/:sessionId/keys
Send keys to the app
"},{"location":"reference/commands/#arguments_10","title":"Arguments","text":"Name Typevalue
any
"},{"location":"reference/commands/#returned-result_17","title":"Returned Result","text":"null
receiveAsyncResponse
","text":"Deprecated
This method is deprecated
POST
/session/:sessionId/appium/receive_async_response
Collect the response of an async script execution
"},{"location":"reference/commands/#arguments_11","title":"Arguments","text":"Name Typeresponse
any
"},{"location":"reference/commands/#returned-result_18","title":"Returned Result","text":"null
toggleEnrollTouchId
","text":"Deprecated
This method is deprecated. Please use the mobile: enrollBiometric
extension instead
POST
/session/:sessionId/appium/simulator/toggle_touch_id_enrollment
Toggle whether the device is enrolled in the touch ID program
"},{"location":"reference/commands/#arguments_12","title":"Arguments","text":"Name Type Default valueenabled?
any
true
"},{"location":"reference/commands/#returned-result_19","title":"Returned Result","text":"null
touchId
","text":"Deprecated
This method is deprecated. Please use the mobile: sendBiometricMatch
extension instead
POST
/session/:sessionId/appium/simulator/touch_id
Trigger a touch/fingerprint match or match failure
"},{"location":"reference/commands/#arguments_13","title":"Arguments","text":"Name Type Default valuematch
any
true
"},{"location":"reference/commands/#returned-result_20","title":"Returned Result","text":"null
asyncScriptTimeout
","text":"Deprecated
This method is deprecated. Please use scriptTimeoutW3C
instead
POST
/session/:sessionId/timeouts/async_script
Alias for XCUITestDriver.scriptTimeoutW3C.
"},{"location":"reference/commands/#arguments_14","title":"Arguments","text":"Name Typems
any
"},{"location":"reference/commands/#returned-result_21","title":"Returned Result","text":"null
getLocation
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/element/:elementId/location
Get the position of an element on screen
"},{"location":"reference/commands/#returned-result_22","title":"Returned Result","text":"Position
The position of the element
"},{"location":"reference/commands/#getlocationinview","title":"getLocationInView
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/element/:elementId/location_in_view
Alias for getLocation
Position
The position of the element
"},{"location":"reference/commands/#getwindowsize","title":"getWindowSize
","text":"Deprecated
This method is deprecated. Please use getElementRect
instead
GET
/session/:sessionId/window/:windowhandle/size
Get the window size
"},{"location":"reference/commands/#returned-result_24","title":"Returned Result","text":"any
performMultiAction
","text":"Deprecated
This method is deprecated. Please use performActions
instead
POST
/session/:sessionId/touch/multi/perform
Perform a set of touch actions
"},{"location":"reference/commands/#arguments_15","title":"Arguments","text":"Name Typeactions
any
elementId?
any
"},{"location":"reference/commands/#returned-result_25","title":"Returned Result","text":"unknown
performTouch
","text":"Deprecated
This method is deprecated. Please use performActions
instead
POST
/session/:sessionId/touch/perform
Perform a set of touch actions
"},{"location":"reference/commands/#arguments_16","title":"Arguments","text":"Name Typeactions
any
"},{"location":"reference/commands/#returned-result_26","title":"Returned Result","text":"unknown
The XCUITest driver supports the following element attributes:
Name Description Examplename
Could contain either element's identifier or its label, depending on which one is available first. Could also be null
. It is recommended to prefer the usage of accessibilityIdentifier over accessibilityLabel for automation purposes, since the identifier
property is supposed to stay constant under different locales and does not affect accessibility services such as VoiceOver. hello
label
Element's label value. Could be null
. Since XCUITest driver 4.7.3 (WebDriverAgent 4.8.0), the behavior of this value was better aligned with XCTest, so it could include line breaks (\\n
). Before this version, line breaks were replaced by spaces. hello
, hello\\nworld
type
Element's type name XCUIElementTypeButton
visible
Whether the element is visible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer false
focused
Whether the element is focused. Before driver version 4.25.4, this was only available for tvOS. true
accessible
Whether the element is accessible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer true
enabled
Whether the element is enabled. false
selected
Whether the element is selected false
index
Element's index in the hierarchy relatively to its parent. Only available since Appium 1.20.0. Indexing starts from 0
. 2
rect
Element's rectangle. The actual data of this attribute is based on element's frame. {'x': 0, 'y': 0, 'width': 100, 'height': 100}
value
Element's value. This is a complex attribute, whose calculation algorithm depends on the actual element type. Check WebDriverAgent sources to know more about how it is compiled (method - (NSString *)wdValue
). Could be null
hello
hittable
Whether the element is hittable. This attribute is not included into the XML page source due to performance reasons, although you can use it in element locators or fetch its value using getAttribute API. Available since driver version 4.35. true
"},{"location":"reference/execute-methods/","title":"Execute Methods","text":"In addition to standard W3C APIs, the driver provides many custom command extensions for executing platform-specific scenarios. Use the following examples in order to invoke them from your client code:
JavaJS (WebdriverIO)PythonRubyC#var result = driver.executeScript(\"mobile: <methodName>\", Map.ofEntries(\n Map.entry(\"arg1\", \"value1\"),\n Map.entry(\"arg2\", \"value2\")\n // you may add more pairs if needed or skip providing the map completely\n // if all arguments are defined as optional\n));\n
const result = await driver.executeScript('mobile: <methodName>', [{\n arg1: \"value1\",\n arg2: \"value2\",\n}]);\n
result = driver.execute_script('mobile: <methodName>', {\n 'arg1': 'value1',\n 'arg2': 'value2',\n})\n
result = @driver.execute_script 'mobile: <methodName>', {\n arg1: 'value1',\n arg2: 'value2',\n}\n
object result = driver.ExecuteScript(\"mobile: <methodName>\", new Dictionary<string, object>() {\n {\"arg1\", \"value1\"},\n {\"arg2\", \"value2\"}\n}));\n
"},{"location":"reference/execute-methods/#mobile-selectpickerwheelvalue","title":"mobile: selectPickerWheelValue","text":"Performs selection of the next or previous picker wheel value. This might be useful if these values are populated dynamically, so you don't know which one to select or value selection suing sendKeys
API does not work because of an XCTest bug. The method throws an exception if it fails to change the current picker value.
element
before version 1.22) string yes PickerWheel's internal element id (as hexadecimal hash string) to perform value selection on. The element must be of type XCUIElementTypePickerWheel abcdef12-1111-2222-3333-444444 order string yes Either next
to select the value next to the current one from the target picker wheel or previous
to select the previous one. next offset number no The value in range [0.01, 0.5]. It defines how far from picker wheel's center the click should happen. The actual distance is calculated by multiplying this value to the actual picker wheel height. Too small offset value may not change the picker wheel value and too high value may cause the wheel to switch two or more values at once. Usually the optimal value is located in range [0.15, 0.3]. 0.2
by default 0.15 value string no If provided WDA will try to automatically scroll in the given direction until the actual picker value reaches the expected one or the amount of scrolling attempts is exceeded. myvalue maxAttempts number no The maximum number of scrolling attempts to reach value
before an error will be thrown. Only makes sense in combination with value
. 25 by default 50"},{"location":"reference/execute-methods/#mobile-alert","title":"mobile: alert","text":"Tries to apply the given action to the currently visible alert.
"},{"location":"reference/execute-methods/#arguments_1","title":"Arguments","text":"Name Type Required Description Example action string yes The actual action to apply. Could be either:accept
, dismiss
or getButtons
accept buttonLabel string no The name of the button used to perform the chosen alert action. Only makes sense if the action is accept
or dismiss
Accept"},{"location":"reference/execute-methods/#returned-result","title":"Returned Result","text":"The list of alert button names if the selected action is getButtons
Sets the Simulator's pasteboard content to the given value. Does not work for real devices.
"},{"location":"reference/execute-methods/#arguments_2","title":"Arguments","text":"Name Type Required Description Example content string yes The content to set hello encoding string no The content's encoding.utf8
by default ascii"},{"location":"reference/execute-methods/#mobile-getpasteboard","title":"mobile: getPasteboard","text":"Gets the Simulator's pasteboard content. Does not work for real devices.
"},{"location":"reference/execute-methods/#arguments_3","title":"Arguments","text":"Name Type Required Description Example encoding string no The expected encoding of the returned string.utf8
by default ascii"},{"location":"reference/execute-methods/#returned-result_1","title":"Returned Result","text":"The pasteboard content string.
"},{"location":"reference/execute-methods/#mobile-source","title":"mobile: source","text":"Allows to retrieve the source tree of the current page in different representation formats.
"},{"location":"reference/execute-methods/#arguments_4","title":"Arguments","text":"Name Type Required Description Example format string yes One of possible page tree source representation formats:xml
(the default value), description
and json
. The xml
format generates the output similar to what getPageSource
standard API returns. description
representation is how XCTest \"sees\" the page internally and is the same string as debugDescription API would return for the root application element. This source representation format is useful for debugging purposes and is the fastest one to fetch. json
representation is similar to xml
, but the tree hierarchy there is represented as JSON elements tree rather than as XML nodes. description excludedAttributes string no One or more comma-separated attribute names to be excluded from the XML output, thus only makes sense if format
is set to xml
. It might be sometimes helpful to exclude, for example, the visible
attribute, to significantly speed-up page source retrieval. visible,accessible"},{"location":"reference/execute-methods/#returned-result_2","title":"Returned Result","text":"The page source tree formatted according to the given format argument.
"},{"location":"reference/execute-methods/#mobile-getcontexts","title":"mobile: getContexts","text":"Retrieves the list of available contexts including the extended context information, like urls and page names. This is different from the standard getContexts
API, because the latter only has web view names without any additional information. In situation where multiple web views are available at once the client code would have to connect to each of them in order to detect the one, which needs to be interacted with. Although, this extra effort is not needed with the information provided by this extension.
5000
ms by default 10000"},{"location":"reference/execute-methods/#returned-result_3","title":"Returned Result","text":"The list of available context objects along with their properties:
null
null
Installs the given application to the device under test. Make sure the app is built for a correct architecture and is signed with a proper developer signature (for real devices) prior to install it.
"},{"location":"reference/execute-methods/#arguments_6","title":"Arguments","text":"Name Type Required Description Example app string yes See the description of theappium:app
capability /path/to/my.app timeoutMs number no The maximum time to wait until app install is finished in milliseconds on real devices. If not provided then the value of appium:appPushTimeout
capability is used. If the capability is not provided then equals to 240000ms 500000 strategy string no One of possible app installation strategies on real devices. This argument is ignored on simulators. If not provided then the value of appium:appInstallStrategy
is used. If the latter is also not provided then serial
is used. See the description of appium:appInstallStrategy
capability for more details on available values. parallel"},{"location":"reference/execute-methods/#mobile-isappinstalled","title":"mobile: isAppInstalled","text":"Checks whether the given application is installed on the device under test. Offloaded applications are handled as not installed.
"},{"location":"reference/execute-methods/#arguments_7","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be checked com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_4","title":"Returned Result","text":"Either true
or false
Removes the given application from the device under test. Offloaded application can also be removed.
For real devices, please also check how to explicitly clear the application local data.
"},{"location":"reference/execute-methods/#arguments_8","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be removed com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_5","title":"Returned Result","text":"Either true
if the app was successfully uninstalled, otherwise false
Executes the given app on the device under test. If the app is already running then it would be activated. If the app is not installed or cannot be launched then an exception is thrown.
"},{"location":"reference/execute-methods/#arguments_9","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be launched com.mycompany.myapp arguments string|array no One or more command line arguments for the app. If the app is already running then this argument is ignored. ['-s', '-m'] environment dict no Environment variables mapping for the app. If the app is already running then this argument is ignored. {'var': 'value'}"},{"location":"reference/execute-methods/#mobile-terminateapp","title":"mobile: terminateApp","text":"Terminates the given app on the device under test via XCTest's terminate API. If the app is not installed an exception is thrown. If the app is not running then nothing is done.
"},{"location":"reference/execute-methods/#arguments_10","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be terminated com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_6","title":"Returned Result","text":"Either true
if the app was successfully terminated, otherwise false
Kill the given app on the real device under test by instruments service. If the app is not running or failed to kill, then nothing is done.
XCUITest driver 4.4 and higher does not require py-ios-device. XCUITest driver 4.3 requires py-ios-device.
"},{"location":"reference/execute-methods/#arguments_11","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be terminated com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_7","title":"Returned Result","text":"Either true
if the app was successfully killed, otherwise false
Queries the state of an installed application from the device under test. An exception will be thrown if the app with given identifier is not installed.
"},{"location":"reference/execute-methods/#arguments_12","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be queried com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_8","title":"Returned Result","text":"An integer number is returned, which encodes the application state. Possible values are described in XCUIApplicationState XCTest documentation topic.
"},{"location":"reference/execute-methods/#mobile-activateapp","title":"mobile: activateApp","text":"Puts the given application to foreground if it is running in the background. An error is thrown if the app is not installed or is not running. Nothing is done if the app is already running in the foreground.
"},{"location":"reference/execute-methods/#arguments_13","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be activated com.mycompany.myapp"},{"location":"reference/execute-methods/#mobile-listapps","title":"mobile: listApps","text":"List applications installed on the real device under test. This extension throws an error if called for a Simulator device. Offload applications will not be in the result.
"},{"location":"reference/execute-methods/#arguments_14","title":"Arguments","text":"Name Type Required Description Example applicationType string no The type of applications to list. EitherSystem
or User
(the default one) System"},{"location":"reference/execute-methods/#returned-result_9","title":"Returned Result","text":"A list of apps, where each item is a map where keys are bundle identifiers and values are maps of platform-specific app properties. Having UIFileSharingEnabled
set to true
in the app properties map means this app supports files upload and download into its documents
container. Read the File Transfer guide for more details.
Deletes data files from the data container of an installed app, so it could start from the clean state next time it is launched. The destination app will be terminated if it is running when this API is invoked. Sometimes it might also be necessary to invoke the following APIs to fully reset the state of an installed app (make sure the app is not running while calling them): - mobile: clearKeychains - mobile: resetPermission
This API might not be 100% reliable for some apps. The only reliable method to fully reset an existing app that Apple supports is to uninstall it and then perform a fresh install of the same app.
This API only works on simulators. An exception is thrown if executed with real devices.
"},{"location":"reference/execute-methods/#arguments_15","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the application to be cleared com.mycompany.myapp"},{"location":"reference/execute-methods/#returned-result_10","title":"Returned Result","text":"true
if at least one item has been successfully deleted from the app data container.
Starts performance profiling for the device under test. Relaxing security is mandatory for simulators. It can always work for real devices. Since XCode 12 the method tries to use xctrace
tool to record performance stats. The instruments
developer utility is used as a fallback for this purpose if xctrace
is not available. It is possible to record multiple profiles at the same time. Read Instruments User Guide for more details. If the recording for the given profile is already running then nothing is done.
300000
ms by default (5 minutes) 600000
profileName string no The name of existing performance profile to apply. Can also contain the full path to the chosen template on the server file system. Note, that not all profiles are supported on mobile devices. Activity Monitor
by default. Time Profile
pid string or number no The ID of the process to measure the performance for. Set it to current
in order to measure the performance of the process, which belongs to the currently active application. All processes running on the device are measured if pid is unset (the default setting). current"},{"location":"reference/execute-methods/#mobile-stopperfrecord","title":"mobile: stopPerfRecord","text":"Stops the performance recording operation previosuly started by mobile: startPerfRecord
call. If the previous call has already been completed due to the timeout then its result is returned immediately. An error is thrown if the performance recording has failed to start and recorded no data.
Activity Monitor
by default. Time Profile
remotePath string no The path to the remote location, where the resulting zipped .trace file should be uploaded. The following protocols are supported: http/https, ftp Null or empty string value (the default setting) means the content of resulting file should be zipped, encoded as Base64 and passed as the endpoint response value. An exception will be thrown if the generated file is too big to fit into the available process memory. https://myserver/upload user string no The name of the user for the remote authentication. Only works if remotePath
is provided. myuser pass string no The password for the remote authentication. Only works if remotePath
is provided. mypassword method string no The http multipart upload method name. Only works if remotePath
is provided. PUT
by default POST headers dict no Additional headers mapping for multipart http(s) uploads {'User-Agent': 'Myserver 1.0'} fileFieldName string no The name of the form field, where the file content BLOB should be stored for http(s) uploads. file
by default payload formFields dict or array no Additional form fields for multipart http(s) uploads {'field2': 'value2'}"},{"location":"reference/execute-methods/#returned-result_11","title":"Returned Result","text":"The resulting file in .trace format can be either returned directly as base64-encoded zip archive or uploaded to a remote location (such files could be pretty large), depending on the remotePath
argument value. Afterwards it is possible to unarchive and open such file with Xcode Developer Tools.
Installs a custom certificate onto the device. Since Xcode SDK 11.4 Apple has added a dedicated simctl subcommand to quickly handle certificates on Simulator over CLI. On real devices the certificate could be installed via CLI if py-ios-device tool is available on the server machine. On simulators before Xcode 11.4 SDK Apple provides no official way to do it via the command line. In such case (and also as a fallback if CLI setup fails) this method tries to wrap the certificate into .mobileconfig format and then deploys the wrapped file to the internal HTTP server, so one can open it via mobile Safari. Then the algorithm goes through the profile installation procedure by clicking the necessary buttons using WebDriverAgent.
"},{"location":"reference/execute-methods/#arguments_18","title":"Arguments","text":"Name Type Required Description Example content string yes Base64-encoded content of the public certificate in PEM format a23234... commonName string no Common name of the certificate. If this is not set then the script will try to parse it from the given certificate content. com.myorg isRoot boolean no This option defines where the certificate should be installed to: either Trusted Root Store (true
, the default option) or the Keychain (false
). On environments other than Xcode 11.4+ Simulator this option is ignored. false"},{"location":"reference/execute-methods/#returned-result_12","title":"Returned Result","text":"The content of the generated .mobileconfig file as base64-encoded string. This config might be useful for debugging purposes. If the certificate has been successfully set via CLI then nothing is returned.
"},{"location":"reference/execute-methods/#mobile-removecertificate","title":"mobile: removeCertificate","text":"Removes installed certificate for real devices only if py-ios-device tool is available on the server machine since driver version 4.19.2.
"},{"location":"reference/execute-methods/#arguments_19","title":"Arguments","text":"Name Type Required Description Example name string yes Name of the profile com.orgname.profile.mdmprofile"},{"location":"reference/execute-methods/#returned-result_13","title":"Returned Result","text":"Returns status acknowledgment {'Status': 'Acknowledged'}
if successfully removed certificate or None
if unable to remove certificate.
Lists installed certificates for real devices only if py-ios-device tool is available on the server machine since driver version 4.10.0.
"},{"location":"reference/execute-methods/#returned-result_14","title":"Returned Result","text":"Returns map of certificates installed on the real device. The response looks like:
{\n 'OrderedIdentifiers': ['com.orgname.profile.mdmprofile'],\n 'ProfileManifest': {\n 'com.orgname.profile.mdmprofile': {\n 'Description': 'MDM Profile',\n 'IsActive': True\n }\n },\n 'ProfileMetadata': {\n 'com.orgname.profile.mdmprofile': {\n 'PayloadDescription': 'MDM Profile for testing,\n 'PayloadDisplayName': 'MDM Profile',\n 'PayloadOrganization': 'My Org, Inc.',\n 'PayloadRemovalDisallowed': False,\n 'PayloadUUID': '9ab3fa27-cc45-4c23-a94a-714686397a86',\n 'PayloadVersion': 1\n }\n },\n 'Status': 'Acknowledged'\n}\n
"},{"location":"reference/execute-methods/#mobile-startlogsbroadcast","title":"mobile: startLogsBroadcast","text":"Starts iOS system logs broadcast websocket on the same host and port where Appium server is running at /ws/session/:sessionId:/appium/syslog
endpoint. The method will return immediately if the web socket is already listening. Each connected webcoket listener will receive syslog lines as soon as they are visible to Appium. Read Using Mobile Execution Commands to Continuously Stream Device Logs with Appium Appium Pro article for more details on this feature.
Stops the syslog broadcasting wesocket server previously started by mobile: startLogsBroadcast
. This method will return immediately if no server is running.
Reads the battery information from the device under test. This endpoint only returns reliable result on real devices.
"},{"location":"reference/execute-methods/#returned-result_15","title":"Returned Result","text":"The actual battery info map, which consists of the following entries:
Returns the miscellaneous information about the device under test. It includes device information via lockdown in a real device since XCUITest driver 4.2.0.
"},{"location":"reference/execute-methods/#returned-result_16","title":"Returned Result","text":"Check the + (id<FBResponsePayload>)handleGetDeviceInfo:(FBRouteRequest *)request
method in FBCustomCommands.m for more details on the available map entries.
Returns the actual device time.
"},{"location":"reference/execute-methods/#arguments_20","title":"Arguments","text":"Name Type Required Description Example format string no The format specifier string. Read MomentJS documentation to get the full list of supported datetime format specifiers. The default format isYYYY-MM-DDTHH:mm:ssZ
, which complies to ISO-8601 YYYY-MM-DD HHss"},{"location":"reference/execute-methods/#returned-result_17","title":"Returned Result","text":"The retrieved datetime string formatted according to the given format specfier.
"},{"location":"reference/execute-methods/#mobile-activeappinfo","title":"mobile: activeAppInfo","text":"Returns information about the active application.
"},{"location":"reference/execute-methods/#returned-result_18","title":"Returned Result","text":"Check the + (id<FBResponsePayload>)handleActiveAppInfo:(FBRouteRequest *)request
method in FBCustomCommands.m for more details on the available map entries.
Emulates press action on the given physical device button. iOS is pressButton:, tvOS is pressButton: or pressButton:forDuration:. mobile: performIoHidEvent calls a more universal API to perform press with duration on any supported device.
"},{"location":"reference/execute-methods/#arguments_21","title":"Arguments","text":"Name Type Required Description Example name string yes The name of the button to be pressed. Supported button names for iOS-based devices are (case-insensitive):home
, volumeup
, volumedown
. For tvOS-based devices (case-insensitive): home
, up
, down
, left
, right
, menu
, playpause
, select
home durationSeconds number no Duration in float seconds for tvOS-based devices since Appium 1.22.0 10"},{"location":"reference/execute-methods/#mobile-pushnotification","title":"mobile: pushNotification","text":"Simulates push notification delivery to Simulator. Only application remote push notifications are supported. VoIP, Complication, File Provider, and other types are not supported. Check the output of xcrun simctl help push
command for more details.
Create the JSON Payload
topic of the official Apple documentation for more details on the payload creation. {\"aps\": {\"alert\": {\"title\": \"This is a simulated notification!\"}, \"badge\": 3, \"sound\": \"default\"} }
"},{"location":"reference/execute-methods/#mobile-expectnotification","title":"mobile: expectNotification","text":"Blocks until the expected notification is delivered. It is a thin wrapper over XCTNSNotificationExpectation and XCTDarwinNotificationExpectation entities. The extension call throws TimeoutError if the expected notification has not been delivered within the given timeout.
"},{"location":"reference/execute-methods/#arguments_23","title":"Arguments","text":"Name Type Required Description Example name string yes The name of the notification to expect com.example.fooAllDone type string no Which notification type to expect. Eitherplain
(the default value) to wait for a notification from the default notification center or darwin
to wait for a system notification. darwin timeoutSeconds number no For how long to wait until the notification is delivered in float seconds. 60 seconds by default 5.5"},{"location":"reference/execute-methods/#mobile-performiohidevent","title":"mobile: performIoHidEvent","text":"Emulates triggering of the given low-level IO HID device event. Constants for possible events are defined in HID Usage Tables. For example, in order to emulate single press on Home button the extension should be called with the following arguments: - page: 0x0C
(kHIDPage_Consumer
, select the Customer
page) - usage: 0x40
(kHIDUsage_Csmr_Menu
, the Csmr
prefix here means this usage is dedicated to the Customer
page) - durationSeconds: 0.005
(The event duration should be 5 milliseconds to be recognized as a single press by iOS)
Some popular constants:
Name Value Description kHIDPage_Consumer 0x0C The page containing all usages prefixed withkHIDUsage_Csmr_
kHIDUsage_Csmr_VolumeIncrement 0xE9 Volume Up kHIDUsage_Csmr_VolumeDecrement 0xEA Volume Down kHIDUsage_Csmr_Menu 0x40 Home kHIDUsage_Csmr_Power 0x30 Power/Lock kHIDUsage_Csmr_Snapshot 0x65 Power + Home"},{"location":"reference/execute-methods/#arguments_24","title":"Arguments","text":"Name Type Required Description Example page int yes The event page identifier. Look for constants perfixed with kHIDPage_
in the table above 0x0C usage int yes The event usage identifier (usages are defined per-page). Look for constants prefixed with kHIDUsage_
in the table above 0x40 durationSeconds number yes The event duration in float seconds. XCTest uses 0.005
for a single press event duration 2.5"},{"location":"reference/execute-methods/#mobile-enrollbiometric","title":"mobile: enrollBiometric","text":"Enrolls biometric authentication on Simulator.
"},{"location":"reference/execute-methods/#arguments_25","title":"Arguments","text":"Name Type Required Description Example isEnabled boolean no Whether to enable/disable biometric enrollment.true
by default. true"},{"location":"reference/execute-methods/#mobile-sendbiometricmatch","title":"mobile: sendBiometricMatch","text":"Emulates biometric match/non-match event on Simulator. The biometric feature is expected to be already enrolled before executing that.
"},{"location":"reference/execute-methods/#arguments_26","title":"Arguments","text":"Name Type Required Description Example type string no The biometric feature name. EithertouchId
or faceId
. touchId
by default. faceId match boolean no Whether to simulate biometric match (true
, the default value) or non-match (false
). true"},{"location":"reference/execute-methods/#mobile-isbiometricenrolled","title":"mobile: isBiometricEnrolled","text":"Checks whether biometric is currently enrolled or not on a Simulator device.
"},{"location":"reference/execute-methods/#returned-result_19","title":"Returned Result","text":"Either true
or false
Clears keychains on Simulator. An exception is thrown for real devices.
"},{"location":"reference/execute-methods/#mobile-getpermission","title":"mobile: getPermission","text":"Gets application permission state on Simulator. This method requires WIX applesimutils to be installed on the host where Appium server is running.
"},{"location":"reference/execute-methods/#arguments_27","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the destination app. com.mycompany.myapp service string yes One of available service names. The following services are supported:calendar
, camera
, contacts
, homekit
, microphone
, photos
, reminders
, medialibrary
, motion
, health
, siri
, speech
. true"},{"location":"reference/execute-methods/#returned-result_20","title":"Returned Result","text":"Either 'yes', 'no', 'unset' or 'limited'
"},{"location":"reference/execute-methods/#mobile-setpermission","title":"mobile: setPermission","text":"Set application permission state on Simulator.
location
and location-always
services are by xcrun simctl privacy
command since XCUITest driver version 5.11.0. The command will kill the bundleId
application process if it is running.
Other services such as contacts
are processed by WIX applesimutils, which will not kill the bundleId
application process. WIX applesimutils needs to be installed on the host where Appium server is running.
all
(Apply the action to all services), calendar
(Allow access to calendar), contacts-limited
(Allow access to basic contact info), contacts
(Allow access to full contact details), location
(Allow access to location services when app is in use), location-always
(Allow access to location services at all times), photos-add
(Allow adding photos to the photo library), photos
(Allow full access to the photo library), media-library
(Allow access to the media library), microphone
(Allow access to audio input), motion
(Allow access to motion and fitness data), reminders
(Allow access to reminders), siri
(Allow use of the app with Siri.). The following values are supported: yes
(To grant the permission), no
(To revoke the permission), unset
(To reset the permission) {'all': 'yes'}"},{"location":"reference/execute-methods/#mobile-resetpermission","title":"mobile: resetPermission","text":"Resets the given permission for the active application under test. Works for both Simulator and real devices using Xcode SDK 11.4+
"},{"location":"reference/execute-methods/#arguments_29","title":"Arguments","text":"Name Type Required Description Example service string or int yes One of available service names. The supported service names are:calendar
, camera
, contacts
, health
, homekit
, keyboardnet
, location
, medialibrary
, microphone
, photos
, reminders
, systemroot
, userdesktop
, userdocuments
, userdownloads
, bluetooth
. This could also be an integer protected resource identifier taken from XCUIProtectedResource photos"},{"location":"reference/execute-methods/#mobile-getappearance","title":"mobile: getAppearance","text":"Get the device's UI appearance style.
"},{"location":"reference/execute-methods/#returned-result_21","title":"Returned Result","text":"An object, with the following entries: - style: The device's UI appearance value. This could be one of: light
, dark
, unknown
, unsupported
Set the device's UI appearance style.
"},{"location":"reference/execute-methods/#arguments_30","title":"Arguments","text":"Name Type Required Description Example style string yes Eitherlight
or dark
dark"},{"location":"reference/execute-methods/#mobile-siricommand","title":"mobile: siriCommand","text":"Presents the Siri UI, if it is not currently active, and accepts a string which is then processed as if it were recognized speech. Check the documentation on activateWithVoiceRecognitionText XCTest method for more details.
"},{"location":"reference/execute-methods/#arguments_31","title":"Arguments","text":"Name Type Required Description Example text string yes The actual command that will be passed to Siri service Hello Siri"},{"location":"reference/execute-methods/#mobile-pullfile","title":"mobile: pullFile","text":"Pulls a remote file from the device.
"},{"location":"reference/execute-methods/#arguments_32","title":"Arguments","text":"Name Type Required Description Example remotePath string yes The path to an existing remote file on the device. See the File Transfer guide for accepted formats. If the file with the given name does not exist an exception will be thrown. @com.mycompany.myapp:documents/myfile.txt"},{"location":"reference/execute-methods/#returned-result_22","title":"Returned Result","text":"Base64-encoded string, which represents the content of the remote file.
"},{"location":"reference/execute-methods/#mobile-pushfile","title":"mobile: pushFile","text":"Pushes a local file to the device.
"},{"location":"reference/execute-methods/#arguments_33","title":"Arguments","text":"Name Type Required Description Example remotePath string yes The path on the device to where the payload should be written. The value format is similar to the one used in pullFile extension. If the file with the same name already exists then it will be silently overridden. @com.mycompany.myapp:documents/myfile.txt payload string yes Base64-encoded content of the file to be pushed. QXBwaXVt"},{"location":"reference/execute-methods/#mobile-pullfolder","title":"mobile: pullFolder","text":"Pulls a remote folder from the device.
"},{"location":"reference/execute-methods/#arguments_34","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same as for pullFile extension, but should be pointing to a remote folder @com.mycompany.myapp:documents/myfolder/"},{"location":"reference/execute-methods/#returned-result_23","title":"Returned Result","text":"Base64-encoded string, which represents the zipped content of the remote folder.
"},{"location":"reference/execute-methods/#mobile-deletefile","title":"mobile: deleteFile","text":"Deletes the given file from the device under test.
"},{"location":"reference/execute-methods/#arguments_35","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same as for pullFile extension @com.mycompany.myapp:documents/myfile.txt"},{"location":"reference/execute-methods/#mobile-deletefolder","title":"mobile: deleteFolder","text":"Deletes the given folder from the device under test.
"},{"location":"reference/execute-methods/#arguments_36","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same value as formobile: deleteFile
except of the fact it should be pointing to a folder and should end with a single slash /
@com.mycompany.myapp:documents/myfolder/"},{"location":"reference/execute-methods/#mobile-configurelocalization","title":"mobile: configureLocalization","text":"Change localization settings on the currently booted Simulator. The changed settings are only applied for the newly started applications/activities. Currently running applications will stay unchanged. This means, for example, that the keyboard should be hidden and shown again in order to observe the changed layout, and corresponding apps must be restarted in order to observe their interface using the newly set locale/language. Also this method might leave some system UI alerts untranslated. Be careful while setting the actual arguments since their actual values are not strictly checked. This could lead to an unexpected behavior if an incorrect/unsupported language or locale abbreviation is provided.
"},{"location":"reference/execute-methods/#arguments_37","title":"Arguments","text":"Name Type Required Description Example keyboard map no On-screen keyboard properties. Thename
key is required and should be set to a valid locale abbreviation. The layout
key is also required. The hardware
key is optional and could be omitted or set to Automated
. You could switch the keyboard layout in system preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleKeyboards
to see possible combinations. {\"name\": \"de_CH\", \"layout\": \"QWERTZ\", \"hardware\": \"Automated\"}
language map no System language properties. The name
key is required and should be set to a valid language abbreviation. You could switch the system language in preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleLanguages
to see possible combinations. {\"name\": \"zh-Hant-CN\"}
locale map no System locale properties. The name
key is required and should be set to a valid language abbreviation. The calendar
key is optonal and could be set to a valid calendar format name. You could switch the system locale/calendar format in preferences of your booted simulator, run xcrun simctl spawn booted defaults read .GlobalPreferences.plist
, and inspect the value of AppleLocale
to see possible combinations. {\"name\": \"uk_UA\", \"calendar\": \"gregorian\"}
"},{"location":"reference/execute-methods/#returned-result_24","title":"Returned Result","text":"true
if any of settings has been successfully changed.
Records the given hardware audio input into an .mp4 file. You must allow the audio_record
security feature in order to use this extension. Also it is required that FFMpeg is installed on the machibe where Appium server is running.
ffmpeg -f avfoundation -list_devices true -i \"\"
Terminal command. 1 audioCodec string no The name of the audio codec. The Advanced Audio Codec (aac) is used by default. aac audioBitrate string no The bitrate of the resulting audio stream. 128k
by default. 256k audioChannels string or int no The count of audio channels in the resulting stream. Setting it to 1
will create a single channel (mono) audio stream. 2
By default 1 audioRate string or int no The sampling rate of the resulting audio stream. 44100 by default 22050 timeLimit string or int no The maximum recording time, in seconds. The default value is 180
, the maximum value is 43200
(12 hours). 60 forceRestart boolean no Whether to restart audio capture process forcefully when startRecordingAudio is called (true
) or ignore the call until the current audio recording is completed (false
, the default value). true"},{"location":"reference/execute-methods/#mobile-stopaudiorecording","title":"mobile: stopAudioRecording","text":"Stops recording of the audio input. If no audio recording process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active audio recording processes are running then the method returns an empty string.
"},{"location":"reference/execute-methods/#returned-result_25","title":"Returned Result","text":"Base64-encoded content of the recorded media file or an empty string if no audio recording has been started before.
"},{"location":"reference/execute-methods/#mobile-startpcap","title":"mobile: startPcap","text":"Start mobile device network traffic capture. This extension only works if py-ios-device utility is installed on the server machine and only supports real iOS devices.
"},{"location":"reference/execute-methods/#arguments_39","title":"Arguments","text":"Name Type Required Description Example timeLimitSec string or int no The maximum recording time, in seconds. The default value is180
, the maximum value is 43200
(12 hours). 60 forceRestart boolean no Whether to restart traffic capture process forcefully when startPcap is called (true
) or ignore the call until the current traffic capture is completed (false
, the default value). true"},{"location":"reference/execute-methods/#mobile-stoppcap","title":"mobile: stopPcap","text":"Stops network traffic capture. If no traffic capture process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active traffic capture processes are running then the method returns an empty string.
"},{"location":"reference/execute-methods/#returned-result_26","title":"Returned Result","text":"Base64-encoded content of the traffic capture file (.pcap) or an empty string if no traffic capture has been started before. Netowrk capture files could be opened in Wireshark application.
"},{"location":"reference/execute-methods/#mobile-runxctest","title":"mobile: runXCTest","text":"Run a native XCTest script. Launches a subprocess that runs the XC Test and blocks until it is completed. Parses the stdout of the process and returns its result as an array. Facebook's IDB tool is required to run such tests.
"},{"location":"reference/execute-methods/#arguments_40","title":"Arguments","text":"Name Type Required Description Example testRunnerBundleId string yes Test app bundle io.appium.XCTesterAppUITests.xctrunner appUnderTestBundleId string yes App-under-test bundle com.mycompany.myapp xcTestBundleID string yes xctest bundle id io.appium.XCTesterAppUITests testType string no Test type. Eitherui
(the default one), app
or logic
app env map no Environment variables mapping to be passed to the test {'myvar': 'myvalue'} args array no Launch arguments to start the test with (see https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments for reference) ['-arg1', '--arg2'] timeout string or int no Timeout if session doesn't complete after given time (in milliseconds). 360000
ms by default 120000"},{"location":"reference/execute-methods/#returned-result_27","title":"Returned Result","text":"The API calls returns a map with the following entries:
0
value marks a successful execution.null
(e.g.: SIGTERM
)Installs an XCTest bundle to the device under test. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#arguments_41","title":"Arguments","text":"Name Type Required Description Example xctestBundle string yes Path to your xctest .app bundle. Could be an URL /path/to/my/bundle.app"},{"location":"reference/execute-methods/#mobile-listxctestbundles","title":"mobile: listXCTestBundles","text":"List XCTest bundles that are installed on device. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#returned-result_28","title":"Returned Result","text":"Array of XCTest bundles (e.g.: [\"XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance\"])
"},{"location":"reference/execute-methods/#mobile-listxctestsintestbundle","title":"mobile: listXCTestsInTestBundle","text":"List XCTests in a test bundle. Facebook's IDB tool is required to for this API to work.
"},{"location":"reference/execute-methods/#arguments_42","title":"Arguments","text":"Name Type Required Description Example bundle string yes Bundle ID of the XCTest 'com.bundle.myapp'"},{"location":"reference/execute-methods/#returned-result_29","title":"Returned Result","text":"Array of xctests in the test bundle (e.g.: [ 'XCTesterAppUITests.XCTesterAppUITests/testExample', 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance' ]
)
Retrieves the viewport dimensions. The viewport is the device's screen size with status bar size subtracted if the latter is present/visible.
"},{"location":"reference/execute-methods/#returned-result_30","title":"Returned Result","text":"The response looks like {\"value\":{\"left\":0,\"top\":96,\"width\":828,\"height\":1696}}
.
left
and top
are distance from the left
of the screen and the top
of the screen. iOS Drawing Concepts could help about the relationship of coordinate.
width
and height
are the screen's width and height.
Takes a screenshot of the device viewport (see mobile: viewportRect
)
Unreliable
This method is unreliable. We recommend using getScreenshot
instead
Base64-encoded string, which represents the viewport screenshot.
"},{"location":"reference/execute-methods/#mobile-devicescreeninfo","title":"mobile: deviceScreenInfo","text":"Get information about screen.
"},{"location":"reference/execute-methods/#returned-result_32","title":"Returned Result","text":"The response looks like {\"value\":{\"statusBarSize\":{\"width\":414,\"height\":48},\"scale\":2}}
statusBarSize
contains status bar dimensions. It is the result of status bar. scale
is screen scale.
This gesture performs a simple \"swipe\" gesture on the particular screen element or on the application element, which is usually the whole screen. This method does not accept coordinates and simply emulates single swipe with one finger. It might be useful for such cases like album pagination, switching views, etc. More advanced cases may require to call mobile: dragFromToForDuration, where one can supply coordinates and duration.
"},{"location":"reference/execute-methods/#arguments_43","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to swipe on. Application element will be used instead if this argument is not provided fe50b60b-916d-420b-8728-ee2072ec53eb direction Either 'up', 'down', 'left' or 'right' yes The direction in which to swipe up velocity number no This argument is optional and is only supported since Appium server version 1.19 and Xcode SDK version 11.4+. The value is measured in pixels per second and same values could behave differently on different devices depending on their display density. Higher values make swipe gesture faster (which usually scrolls larger areas if we apply it to a list) and lower values slow it down. Only values greater than zero have effect. 250"},{"location":"reference/execute-methods/#examples","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\nMap<String, Object> params = new HashMap<>();\nparams.put(\"direction\", \"down\");\nparams.put(\"velocity\", 2500);\nparams.put(\"element\", ((RemoteWebElement) element).getId());\njs.executeScript(\"mobile: swipe\", params);\n
"},{"location":"reference/execute-methods/#references","title":"References","text":"Scrolls the element or the whole screen. Different scrolling strategies are supported. Arguments define the choosen strategy: either 'name', 'direction', 'predicateString' or 'toVisible' in that order. All strategies are exclusive and only one strategy can be applied at a single moment of time. Use \"mobile: scroll\" to emulate precise scrolling in tables or collection views, where it is already known to which element the scrolling should be performed. Although, there is one known limitation there: in case it is necessary to perform too many scroll gestures on parent container to reach the necessary child element (tens of them) then the method call may fail. Important: The implemntation of this extension relies on several undocumented XCTest features, which might not always be reliable. Thus it might not always work as expected.
"},{"location":"reference/execute-methods/#arguments_44","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to scroll on (e.g. the container). Application element will be used if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb name string no The accessibility id of the child element, to which scrolling is performed. The same result can be achieved by setting predicateString argument to 'name == accessibilityId'. Has no effect if elementId is not a container cell12 direction Either 'up', 'down', 'left' or 'right' yes The main difference from swipe call with the same argument is that scroll will try to move the current viewport exactly to the next/previous page (the term \"page\" means the content, which fits into a single device screen) down predicateString string no The NSPredicate locator of the child element, to which the scrolling should be performed. Has no effect if elementId is not a container label == \"foo\" toVisible boolean no If set to true then asks to scroll to the first visible elementId in the parent container. Has no effect if elementId is not set true"},{"location":"reference/execute-methods/#examples_1","title":"Examples","text":"# Python\ndriver.execute_script('mobile: scroll', {'direction': 'down'});\n
"},{"location":"reference/execute-methods/#mobile-pinch","title":"mobile: pinch","text":"Performs pinch gesture on the given element or on the application element.
"},{"location":"reference/execute-methods/#arguments_45","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to pinch on. Application element will be used instead if this parameter is not provided fe50b60b-916d-420b-8728-ee2072ec53eb scale number yes Pinch scale of type float. Use a scale between 0 and 1 to \"pinch close\" or zoom out and a scale greater than 1 to \"pinch open\" or zoom in. 0.5 velocity number yes The velocity of the pinch in scale factor per second (float value) 2.2"},{"location":"reference/execute-methods/#examples_2","title":"Examples","text":"# Ruby\nexecute_script 'mobile: pinch', scale: 0.5, velocity: 1.1, element: element.ref\n
"},{"location":"reference/execute-methods/#reference","title":"Reference","text":"pinchWithScale:velocity:
"},{"location":"reference/execute-methods/#mobile-doubletap","title":"mobile: doubleTap","text":"Performs double tap gesture on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_46","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no if x and y are set The internal element identifier (as hexadecimal hash string) to double tap on fe50b60b-916d-420b-8728-ee2072ec53eb x number no if elementId is set Screen x tap coordinate of type float. 100 y number no if elementId is set Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#examples_3","title":"Examples","text":"// javascript\ndriver.execute('mobile: doubleTap', {element: element.value.ELEMENT});\n
"},{"location":"reference/execute-methods/#mobile-touchandhold","title":"mobile: touchAndHold","text":"Performs long press gesture on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_47","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no if x and y are set The internal element identifier (as hexadecimal hash string) to long tap on fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes The float duration of press action in seconds 1.5 x number no if elementId is set Screen x tap coordinate of type float. 100 y number no if elementId is set Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#examples_4","title":"Examples","text":"// c#\nDictionary<string, object> tfLongTap = new Dictionary<string, object>();\ntfLongTap.Add(\"element\", element.Id);\ntfLongTap.Add(\"duration\", 2.0);\n((IJavaScriptExecutor)driver).ExecuteScript(\"mobile: touchAndHold\", tfLongTap);\n
"},{"location":"reference/execute-methods/#reference_1","title":"Reference","text":"pressForDuration:
"},{"location":"reference/execute-methods/#mobile-twofingertap","title":"mobile: twoFingerTap","text":"Performs two finger tap gesture on the given element or on the application element.
"},{"location":"reference/execute-methods/#arguments_48","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to tap on. Application element will be used instead if this parameter is not provided fe50b60b-916d-420b-8728-ee2072ec53eb"},{"location":"reference/execute-methods/#examples_5","title":"Examples","text":"// c#\nDictionary<string, object> tfTap = new Dictionary<string, object>();\ntfTap.Add(\"element\", element.Id);\n((IJavaScriptExecutor)driver).ExecuteScript(\"mobile: twoFingerTap\", tfTap);\n
"},{"location":"reference/execute-methods/#reference_2","title":"Reference","text":"twoFingerTap
"},{"location":"reference/execute-methods/#mobile-tap","title":"mobile: tap","text":"Performs tap gesture by coordinates on the given element or on the screen.
"},{"location":"reference/execute-methods/#arguments_49","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to tap on. x and y tap coordinates will be calulated relatively to the current element position on the screen if this argument is provided. Otherwise they should be calculated relatively to the active application element. fe50b60b-916d-420b-8728-ee2072ec53eb x number yes Screen x tap coordinate of type float. 100 y number yes Screen y tap coordinate of type float. 100"},{"location":"reference/execute-methods/#mobile-dragfromtoforduration","title":"mobile: dragFromToForDuration","text":"Performs drag and drop gesture by coordinates. This can be done either on an element or on the screen
"},{"location":"reference/execute-methods/#arguments_50","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no The internal element identifier (as hexadecimal hash string) to perform drag on. All the coordinates will be calculated relatively this this element position on the screen. Absolute screen coordinates are expected if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes Float number of seconds in range [0.5, 60]. How long the tap gesture at starting drag point should be before to start dragging 5.3 fromX number yes The x coordinate of starting drag point 100 fromY number yes The y coordinate of starting drag point 100 toX number yes The x coordinate of ending drag point 200 toY number yes The y coordinate of ending drag point 200"},{"location":"reference/execute-methods/#examples_6","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\nMap<String, Object> params = new HashMap<>();\nparams.put(\"duration\", 1.0);\nparams.put(\"fromX\", 100);\nparams.put(\"fromY\", 100);\nparams.put(\"toX\", 200);\nparams.put(\"toY\", 200);\nparams.put(\"element\", ((RemoteWebElement) element).getId());\njs.executeScript(\"mobile: dragFromToForDuration\", params);\n
"},{"location":"reference/execute-methods/#reference_3","title":"Reference","text":"clickForDuration:thenDragToElement:
"},{"location":"reference/execute-methods/#mobile-dragfromtowithvelocity","title":"mobile: dragFromToWithVelocity","text":"Initiates a press-and-hold gesture, drags to another coordinate or an element with a velocity you specify, and holds for a duration you specify.
"},{"location":"reference/execute-methods/#arguments_51","title":"Arguments","text":"Name Type Required Description Example fromElementId string no The internal element identifier (as hexadecimal hash string) to start the drag gesture from. Absolute screen coordinates are expected if this argument is not set fe50b60b-916d-420b-8728-ee2072ec53eb toElementId string no The internal element identifier (as hexadecimal hash string) to end the drag gesture on. This parameter is mandatory iffromElementId
is provided fe50b60b-916d-420b-8728-ee2072ec53eb pressDuration number yes Float number of seconds in range [0, 60]. How long the tap gesture at starting drag point should be before to start dragging 0.5 holdDuration number yes Float number of seconds in range [0, 60]. The duration for which to hold over the other coordinate or the given element after dragging 0.1 velocity number yes The speed at which to move from the initial press position to the other element or coordinate, expressed in pixels per second 400 fromX number no The x coordinate of starting drag point. Must be provided if fromElementId
is not defined 100 fromY number no The y coordinate of starting drag point. Must be provided if fromElementId
is not defined 100 toX number no The x coordinate of ending drag point. Must be provided if fromElementId
is not defined 200 toY number no The y coordinate of ending drag point. Must be provided if fromElementId
is not defined 200"},{"location":"reference/execute-methods/#references_1","title":"References","text":"pressForDuration:thenDragToElement:withVelocity:thenHoldForDuration: pressForDuration:thenDragToCoordinate:withVelocity:thenHoldForDuration:
"},{"location":"reference/execute-methods/#mobile-rotateelement","title":"mobile: rotateElement","text":"Performs rotate gesture on the given element.
"},{"location":"reference/execute-methods/#arguments_52","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string yes Internal element id (as hexadecimal hash string) to perform rotation on fe50b60b-916d-420b-8728-ee2072ec53eb rotation number yes The rotation of the gesture in radians Math.PI velocity number yes The velocity of the rotation gesture in radians per second Math.PI / 4"},{"location":"reference/execute-methods/#examples_7","title":"Examples","text":"// Java\nJavascriptExecutor js = (JavascriptExecutor) driver;\njs.executeScript(\"mobile: rotateElement\", ImmutableMap.of(\n // rotate clockwise, 90 degrees\n \"rotation\", -Math.PI / 2,\n // in approximately two seconds\n \"velocity\", Math.PI / 4,\n \"element\", ((RemoteWebElement) element).getId()\n));\n
"},{"location":"reference/execute-methods/#reference_4","title":"Reference","text":"rotate:withVelocity:
"},{"location":"reference/execute-methods/#mobile-tapwithnumberoftaps","title":"mobile: tapWithNumberOfTaps","text":"Sends one or more taps with one or more touch points since Appium 1.17.1.
"},{"location":"reference/execute-methods/#arguments_53","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string yes The internal element identifier (as hexadecimal hash string) to perform one or more taps. fe50b60b-916d-420b-8728-ee2072ec53eb numberOfTaps number yes The number of taps 2 numberOfTouches number yes The number of touch points 2"},{"location":"reference/execute-methods/#examples_8","title":"Examples","text":"# Ruby\ne = @driver.find_element :id, 'target element'\n# Taps the element with a single touch point twice\n@driver.execute_script 'mobile: tapWithNumberOfTaps', {element: e.ref, numberOfTaps: 2, numberOfTouches: 1}\n
"},{"location":"reference/execute-methods/#reference_5","title":"Reference","text":"tapWithNumberOfTaps:numberOfTouches:
"},{"location":"reference/execute-methods/#mobile-forcepress","title":"mobile: forcePress","text":"Emulates force press on the given element/coordinates. An error is thrown if the target device does not support force press gesture.
"},{"location":"reference/execute-methods/#arguments_54","title":"Arguments","text":"Name Type Required Description Example elementId string no The internal element identifier (as hexadecimal hash string) to perform one or more taps. It is expected that both x and y are provided if this argument is ommitted. If the element identifier is provided without coordinates then the actual element's touch point will be calculated automatically by WebDriverAgent. fe50b60b-916d-420b-8728-ee2072ec53eb x number no x coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application. 100 y number no y coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application 100 duration number no The float number of seconds the force press action would take. If duration is provided then it is also expected that a custom pressure value is provided as well.0.5
by default. 2.5 pressure number no The float number defining how much pressure to apply. If pressure is provided then it is also expected that a custom duration value is provided as well. 1.0
by default 1.5"},{"location":"reference/execute-methods/#mobile-scrolltoelement","title":"mobile: scrollToElement","text":"Scrolls the current viewport to the given element. It is expected the destination element is inside a scrollable container and is hittable. The scroll direction is detected automatically. This API uses native XCTest calls, so it performs scrolling pretty fast. The same native call is implicitly performed by a vanilla click
API if the destination element is out of the current viewport. An exception is thrown if the scrolling action cannot be performed. This extension is available since the driver version 4.7.0.
Reset the location service on real device since Appium 1.22.0. It could delay a few seconds to reflect the location by the system. It raises an error if the device is simulator or an error occurred during the reset.
"},{"location":"reference/execute-methods/#mobile-enableconditioninducer","title":"mobile: enableConditionInducer","text":"Important: Device conditions are available for real devices running iOS 13.0 and later.
This API is going to throw an error if it is called while another condition inducer has been already enabled and is not explicitly disabled.
mobile: enableConditionInducer\nmobile: disableConditionInducer\nmobile: listConditionInducers\n
The above three extensions are available since the driver version 4.9.0.
You can create a condition on a connected device to test your app under adverse conditions, such as poor network connectivity or thermal constraints.
When you start a device condition, the operating system on the device behaves as if its environment has changed. The device condition remains active until you stop the device condition or disconnect the device. For example, you can start a device condition, run your app, monitor your app\u2019s energy usage, and then stop the condition.
Reference: Test under adverse device conditions (iOS)
Name Type Required Description Example conditionID string yes Get the conditionID parameter through the commandmobile: availableConditionInducer
SlowNetworkCondition profileID string yes Get the profileID parameter through the command mobile: availableConditionInducer
SlowNetwork100PctLoss"},{"location":"reference/execute-methods/#returned-result_33","title":"Returned Result","text":"Either true
or false
, where true
means enabling of the condition inducer has been successful
Get all condition inducer configuration profiles
"},{"location":"reference/execute-methods/#returned-result_34","title":"Returned Result","text":"The response looks like
[{\n \"profiles\": [\n {\n \"name\": \"100% packet loss\",\n \"identifier\": \"SlowNetwork100PctLoss\", // enableConditionInducer profileID\n \"description\": \"Name: 100% Loss Scenario\n Downlink Bandwidth: 0 Mbps\n Downlink Latency: 0 ms\n Downlink Packet Loss Ratio: 100%\n Uplink Bandwidth: 0 Mbps\n Uplink Latency: 0 ms\n Uplink Packet Loss Ratio: 100%\"\n },\n ],\n \"profilesSorted\": true,\n \"identifier\": \"SlowNetworkCondition\", // enableConditionInducer conditionID\n \"isDestructive\": false,\n \"isInternal\": false,\n \"activeProfile\": \"\",\n \"name\": \"Network Link\",\n \"isActive\": false\n}]\n
"},{"location":"reference/execute-methods/#mobile-disableconditioninducer","title":"mobile: disableConditionInducer","text":"Disable device condition inducer.
Usually a persistent connection is maintained after enable the condition inducer, and this method is only valid for this connection.
If the connection is disconnected, condition inducer will be automatically disabled
"},{"location":"reference/execute-methods/#returned-result_35","title":"Returned Result","text":"Either true
or false
, where true
means disabling of the condition inducer has been successful
Calibrates web to real coordinates translation. This API can only be called from Safari web context. It must load a custom page to the browser, and then restore the original one, so don't call it if you can potentially lose the current web app state. The outcome of this API is then used if nativeWebTap
capability/setting is enabled. The returned value could also be used to manually transform web coordinates to real device ones in client scripts.
It is adviced to call this API at least once before changing the device orientation or device screen layout as the recetly received value is cached for the session lifetime and may become obsolete.
It is advised to enable nativeWebTapStrict
capability/setting to speed up dynamic coordinates transformation if you use this extension.
An object with three properties used to properly shift Safari web element coordinates into native context: - offsetX
: Webview X offset in real coordinates - offsetY
: Webview Y offset in real coordinates - pixelRatioX
: Webview X pixel ratio - pixelRatioY
: Webview Y pixel ratio
The following formulas are used for coordinates translation: RealX = offsetX + webviewX * pixelRatioX
RealY = offsetY + webviewY * pixelRatioY
Updates preferences of Mobile Safari on Simulator
"},{"location":"reference/execute-methods/#arguments_56","title":"Arguments","text":"Name Type Required Description Example preferences map yes An object containing Mobile Safari preferences to be updated. The list of available setting names and their values could be retrieved by changing the corresponding Safari settings under Preferences->Safari and then inspectingLibrary/Preferences/com.apple.mobilesafari.plist
file inside of com.apple.mobilesafari
app container. The full path to the Mobile Safari's container could be retrieved from xcrun simctl get_app_container <sim_udid> com.apple.mobilesafari data
command output. Use the xcrun simctl spawn <sim_udid> defaults read <path_to_plist>
command to print the actual .plist content to the Terminal. { ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }"},{"location":"reference/execute-methods/#mobile-deeplink","title":"mobile: deepLink","text":"Opens the given URL with the default or the given application. This functionality is only available since xcuitest driver version 4.17. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
"},{"location":"reference/execute-methods/#arguments_57","title":"Arguments","text":"Name Type Required Description Example url string yes The URL to be opened. This parameter is manadatory. https://apple.com, myscheme:yolo bundleId string no The bundle identifier of an application to open the given url with. If not provided then the default application for the given url scheme is going to be used. com.myapp.yolo"},{"location":"reference/execute-methods/#mobile-getsimulatedlocation","title":"mobile: getSimulatedLocation","text":"Retrieves simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
"},{"location":"reference/execute-methods/#returned-result_37","title":"Returned Result","text":"This API returns a map with the following entries:
Name Type Description Example latitude number Measurement of distance north or south of the Equator.null
if mobile: setSimulatedLocation has not been called before or the simulated geolocation has been reset by mobile: resetSimulatedLocation. 50.08546 longitude number Measurement of distance east or west of the prime meridian. null
if mobile: setSimulatedLocation has not been called before or the simulated geolocation has been reset by mobile: resetSimulatedLocation. -20.12345"},{"location":"reference/execute-methods/#mobile-setsimulatedlocation","title":"mobile: setSimulatedLocation","text":"Sets simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
It is recommended for iOS 17+ real devices to simulate the device location.
"},{"location":"reference/execute-methods/#arguments_58","title":"Arguments","text":"Name Type Required Description Example latitude number yes Measurement of distance north or south of the Equator. 50.08546 longitude number yes Measurement of distance east or west of the prime meridian. -20.12345"},{"location":"reference/execute-methods/#mobile-resetsimulatedlocation","title":"mobile: resetSimulatedLocation","text":"Resets the previously set simulated geolocation value. This functionality is only available since xcuitest driver version 4.18. Xcode must be at version 14.3+ and iOS must be at version 16.4+.
Warning Do not forget to reset the simulated geolocation value after your automated test is finished. If the value is not reset explicitly then the simulated one will remain until the next device restart.
"},{"location":"reference/execute-methods/#mobile-getappstrings","title":"mobile: getAppStrings","text":"Retrieves string resources for the given app language. An error is thrown if strings cannot be fetched or no strings exist for the given language abbreviation
"},{"location":"reference/execute-methods/#arguments_59","title":"Arguments","text":"Name Type Required Description Example language string no The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned fr stringFile string no Relative path to the corresponding .strings file starting from the corresponding .lproj folder base/main.strings"},{"location":"reference/execute-methods/#returned-result_38","title":"Returned Result","text":"App strings map, where keys are resource identifiers.
"},{"location":"reference/execute-methods/#mobile-hidekeyboard","title":"mobile: hideKeyboard","text":"Tries to hide the on-screen keyboard. Throws an exception if the keyboard cannot be hidden. On non-tablet devices the keyboard might not have an explicit button to hide it. In such case this API won't work and the only way to close the keyboard would be to simulate the same action an app user would do to close it. For example, swipe from top to bottom or tap the screen somewhere at the area not covered by the keyboard.
"},{"location":"reference/execute-methods/#arguments_60","title":"Arguments","text":"Name Type Required Description Example keys string[] no One or more keyboard key names used to close/hide it. On tablet's such button is usually called 'done'."},{"location":"reference/execute-methods/#mobile-iskeyboardshown","title":"mobile: isKeyboardShown","text":"Checks if the system on-screen keyboard is visible.
"},{"location":"reference/execute-methods/#returned-result_39","title":"Returned Result","text":"true
if the keyboard is visible
Send keys to the given element or to the application under test. This API is only supported since Xcode 15/iOS 17. It is not supported on tvOS. The API only works on iPad. On iOS calling it has no effect.
"},{"location":"reference/execute-methods/#arguments_61","title":"Arguments","text":"Name Type Required Description Example elementId string no Unique identifier of the element to send the keys to. If unset then keys are sent to the current application under test. 21045BC8-013C-43BD-9B1E-4C6DC7AB0744 keys array yes Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's typeKey:modifierFlags: method and on XCUIKeyboardKey constants) or a dictionary withkey
and modifierFlags
entries, if the key should also be entered with modifiers. ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] or ['XCUIKeyboardKeyEscape'] Note
The modifierFlags
argument is of unsigned long
type and defines the bitmask with depressed modifier keys for the given key. XCTest defines the following possible bitmasks for modifier keys:
\ntypedef NS_OPTIONS(NSUInteger, XCUIKeyModifierFlags) {\n XCUIKeyModifierNone = 0,\n XCUIKeyModifierCapsLock = (1UL << 0),\n XCUIKeyModifierShift = (1UL << 1),\n XCUIKeyModifierControl = (1UL << 2),\n XCUIKeyModifierOption = (1UL << 3),\n XCUIKeyModifierCommand = (1UL << 4),\n XCUIKeyModifierFunction = (1UL << 5),\n // These values align with UIKeyModifierFlags and CGEventFlags.\n XCUIKeyModifierAlphaShift = XCUIKeyModifierCapsLock,\n XCUIKeyModifierAlternate = XCUIKeyModifierOption,\n};\n
So, for example, if you want Ctrl and Shift to be depressed while entering your key then modifierFlags
should be set to (1 << 1) | (1 << 2)
, where the first constant defines XCUIKeyModifierShift
and the seconds one - XCUIKeyModifierControl
. We apply the bitwise or (|
) operator between them to raise both bitflags in the resulting value. The left bitshift (<<
) operator defines the binary bitmask for the given modifier key. You may combine more keys using the same approach.
Lock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.
"},{"location":"reference/execute-methods/#arguments_62","title":"Arguments","text":"Name Type Required Description Example seconds number string no The number of seconds after which to unlock the device. Set to0
or leave it empty to require manual unlock (e.g. do not block and automatically unlock afterwards)."},{"location":"reference/execute-methods/#mobile-unlock","title":"mobile: unlock","text":"Unlocks the previously locked device. Only simple (e.g. without a password) locks are supported.
"},{"location":"reference/execute-methods/#mobile-islocked","title":"mobile: isLocked","text":"Determine whether the device is locked.
"},{"location":"reference/execute-methods/#returned-result_40","title":"Returned Result","text":"Either true
or false
Shakes the device. This functionality is only supported on simulators.
"},{"location":"reference/execute-methods/#mobile-backgroundapp","title":"mobile: backgroundApp","text":"Puts the app to the background and waits the given number of seconds. Then restores the app if necessary. The call is blocking.
"},{"location":"reference/execute-methods/#arguments_63","title":"Arguments","text":"Name Type Required Description Example seconds number no The amount of seconds to wait between putting the app to background and restoring it. Any negative value means to not restore the app after putting it to background (the default behavior). 5"},{"location":"reference/execute-methods/#mobile-performaccessibilityaudit","title":"mobile: performAccessibilityAudit","text":"Performs accessbility audit of the current application according to the given type or multiple types. Wraps the XCTest's performAccessibilityAuditWithAuditTypes API. Only available since Xcode 15/iOS 17.
"},{"location":"reference/execute-methods/#arguments_64","title":"Arguments","text":"Name Type Required Description Example auditTypes string[] no One or more type names to perform the audit for. The full list of available names could be found in the official XCTest API documentation. If no type if provided explicitly thenXCUIAccessibilityAuditTypeAll
is assumed. ['XCUIAccessibilityAuditTypeContrast', 'XCUIAccessibilityAuditTypeElementDetection']"},{"location":"reference/execute-methods/#returned-result_41","title":"Returned Result","text":"List of found issues or an empty list. Each list item is a map consisting of the following items:
Name Type Description Example detailedDescription string The detailed description of the found accessbility issue. Some longer issue description compactDescription string The compact description of the found accessbility issue. Some compact issue description auditType string or number The name of the audit type this issue belongs to. Could be a number if the type name is unknown. 'XCUIAccessibilityAuditTypeContrast' element string The description of the element this issue was found for. 'Yes' button elementDescription string The debug description of the element this issue was found for. Availble since driver version A long string describing the element itself and its position in the page tree hierarchy elementAttributes dict JSON object containing various attributes of the element. See the example below\"elementAttributes\":{\n \"isEnabled\":\"1\",\n \"isVisible\":\"1\",\n \"isAccessible\":\"0\",\n \"frame\":\"{{129, 65}, {135, 18}}\",\n \"isFocused\":\"0\",\n \"rect\":{\n \"y\":65,\n \"x\":129,\n \"width\":135,\n \"height\":18\n },\n \"value\":\"Some Button\",\n \"label\":\"Some Button\",\n \"type\":\"StaticText\",\n \"name\":\"Some Button\",\n \"rawIdentifier\":null\n}\n
"},{"location":"reference/ios-predicate/","title":"Predicate Locator Strategy","text":"The XCUITest driver supports searching elements using the predicate and class chain locator search strategies. They are powered by Apple XCTest, provide flexibility and are much faster than XPath. Predicates can be used to restrict a set of elements to select only those for which some condition evaluates to true.
Tip
In addition to the examples listed here, make sure to check the links in the More Information section below!
"},{"location":"reference/ios-predicate/#quick-examples","title":"Quick Examples","text":"Predicate StringClass Chain// java\ndriver.findElements(AppiumBy.iOSNsPredicateString(\"isVisible == 1\"));\n
// java\ndriver.findElements(AppiumBy.iOSClassChain(\"**/XCUIElementTypeWindow[`label LIKE '*yolo*'`]\"));\n
The predicate string example would select all visible elements on the page, while the class chain example would find all elements of type XCUIElementTypeWindow
whose label contains yolo
. Class chain queries allow to create much more complicated search expressions and may contain multiple predicates. Check the More Information section below for how to build such queries.
=
, ==
- The left-hand expression is equal to the right-hand expression:
// java\ndriver.findElements(AppiumBy.iOSNsPredicateString(\"label == 'Olivia'\"));\n\n// same in Xpath:\ndriver.findElements(AppiumBy.xpath(\"//*[@label = 'Olivia']\"));\n
>=
, =>
- The left-hand expression is greater than or equal to the right-hand expression.
<=
, =<
- The left-hand expression is less than or equal to the right-hand expression.
>
- The left-hand expression is greater than the right-hand expression.
<
- The left-hand expression is less than the right-hand expression.
!=
, <>
- The left-hand expression is not equal to the right-hand expression.
BETWEEN
- The left-hand expression is between, or equal to either of, the values specified in the right-hand side. The right-hand side is a two value array (an array is required to specify order) giving upper and lower bounds. For example, 1 BETWEEN { 0 , 33 }
, or $INPUT BETWEEN { $LOWER, $UPPER }
. In Objective-C, you could create a BETWEEN
predicate as shown in the following example:
driver.findElements(AppiumBy.iOSNsPredicateString(\"rect.x BETWEEN { 1, 100 }\"));\n
This creates a predicate that matches all elements whole left top coordinate is in range between 1 and 100.
TRUEPREDICATE
- A predicate that always evaluates to TRUE
.
FALSEPREDICATE
- A predicate that always evaluates to FALSE
.
AND
, &&
- Logical AND.
OR
, ||
- Logical OR.
NOT
, !
- Logical NOT.
String comparisons are by default case and diacritic sensitive. You can modify an operator using the key characters c
and d
within square braces to specify case and diacritic insensitivity respectively, for example, value BEGINSWITH[cd] 'bar'
.
BEGINSWITH
- The left-hand expression begins with the right-hand expression.
driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementTypeButton' AND name BEGINSWITH 'results toggle'\"));\n\n// same in Xpath:\ndriver.findElement(AppiumBy.xpath(\"//XCUIElementTypeButton[starts-with(@name, 'results toggle')]\"));\n
CONTAINS
- The left-hand expression contains the right-hand expression.
driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementCollectionView' AND name CONTAINS 'opera'\"));\n\n// same in Xpath:\ndriver.findElement(AppiumBy.xpath(\"//XCUIElementCollectionView[contains(@name, 'opera')]\"));\n
ENDSWITH
- The left-hand expression ends with the right-hand expression.
LIKE
- The left hand expression equals the right-hand expression: ?
and *
are allowed as wildcard characters, where ?
matches 1 character and *
matches 0 or more characters. In Mac OS X v10.4, wildcard characters do not match newline characters.
driver.findElement(AppiumBy.iOSNsPredicateString(\"name LIKE '*Total: $*'\"));\n\n// XPath1 does not have an alternative to the above expression\n
MATCHES
- The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
driver.findElement(AppiumBy.iOSNsPredicateString(\"value MATCHES '.*of [1-9]'\"));\n\n// XPath1 does not have an alternative to the above expression\n
IN
- Equivalent to an SQL IN operation, the left-hand side must appear in the collection specified by the right-hand side. For example, name IN { 'Ben', 'Melissa', 'Matthew' }
. The collection may be an array, a set, or a dictionary (in the case of a dictionary, its values are used).C style identifier - Any C style identifier that is not a reserved word.
#symbol - Used to escape a reserved word into a user identifier.
[\\]{octaldigit}{3} - Used to escape an octal number ( \\
followed by 3 octal digits).
[\\][xX]{hexdigit}{2} - Used to escape a hex number ( \\x
or \\X
followed by 2 hex digits).
[\\][uU]{hexdigit}{4} - Used to escape a Unicode number ( \\u
or \\U
followed by 4 hex digits).
Single and double quotes produce the same result, but they do not terminate each other. For example, \"abc\"
and 'abc'
are identical, whereas \"a'b'c\"
is equivalent to a space-separated concatenation of a, 'b', c
.
FALSE
, NO
- Logical false.
TRUE
, YES
- Logical true.
NULL
, NIL
- A null value.
SELF
- Represents the object being evaluated.
\"text\"
- A character string.
'text'
- A character string.
Comma-separated literal array - For example, { 'comma', 'separated', 'literal', 'array' }
.
Standard integer and fixed-point notations - For example, 1 , 27 , 2.71828 , 19.75
.
Floating-point notation with exponentiation - For example, 9.2e-5
.
0x
- Prefix used to denote a hexadecimal digit sequence.
0o
- Prefix used to denote an octal digit sequence.
0b
- Prefix used to denote a binary digit sequence.
The following keywords are reserved:
AND, OR, IN, NOT, ALL, ANY, SOME, NONE, LIKE, CASEINSENSITIVE, CI, MATCHES, CONTAINS, BEGINSWITH, ENDSWITH, BETWEEN, NULL, NIL, SELF, TRUE, YES, FALSE, NO, FIRST, LAST, SIZE, ANYKEY, SUBQUERY, CAST, TRUEPREDICATE, FALSEPREDICATE
Check the Element Attributes document to know all element attribute names and types that are available for usage in predicate locators.
"},{"location":"reference/ios-predicate/#more-information","title":"More Information","text":"The XCUITest driver supports several location strategies in the native context. The following table lists them in performance order (the first one is the fastest one):
Name Description ExampleclassName
Performs search by element's type
attribute. The full list of supported XCUIElement type names could be found in the official XCTest documentation on XCUIElementType XCUIElementTypeButton
id
, name
, accessibility id
All these locator types are synonyms and internally get transformed into search by element's name
attribute. my name
-ios predicate string
This strategy is mapped to the native XCTest predicate locator. Check the NSPredicate cheat sheet for more details on how to build effective predicate expressions. All the supported element attributes could be used in these expressions. (name == 'done' OR value == 'done') AND type IN {'XCUIElementTypeButton', 'XCUIElementTypeKey'}
-ios class chain
This strategy is mapped to the native XCTest predicate locator, but with respect to the actual element tree hierarchy. Such locators are basically a supertype of -ios predicate string
. Read Class Chain Queries Construction Rules for more details on how to build such locators. **/XCUIElementTypeCell[$name == 'done' OR value == 'done'$]/XCUIElementTypeButton[-1]
xpath
For elements lookup using the Xpath strategy the driver uses the same XML tree that is generated by the page source API. This means such locators are the slowest (sometimes up to 10x slower) in comparison to the ones above, which all depend on native XCTest primitives, but are the most flexible. Use Xpath locators only if there is no other way to locate the given element. Only Xpath 1.0 is supported. //XCUIElementTypeButton[@value=\\\"Regular\\\"]/parent::*
Also, consider checking the How To Achieve The Best Lookup Performance article.
"},{"location":"reference/scripts/","title":"Scripts","text":"Appium drivers can include scripts for executing specific actions. The following table lists the scripts bundled with the XCUITest driver. These scripts can be run as follows:
appium driver run xcuitest <script-name>\n
Script Name Description open-wda
Opens the WebDriverAgent project in Xcode build-wda
Builds the WebDriverAgent project using the first available iPhone simulator and the latest iOS supported by the current Xcode version"},{"location":"reference/security-flags/","title":"Security Feature Flags","text":"Some insecure driver features are disabled by default. They can be enabled upon launching Appium as follows:
appium --allow-insecure <feature-name>\n
or appium --relaxed-security\n
Feature Name Description shutdown_other_sims
Allow any session to use a capability to shutdown any running simulators on the host perf_record
Allow recording the system performance and other metrics of the simulator audio_record
Allow recording of host audio input(s) customize_result_bundle_path
Allow customizing the paths to result bundles, using the resultBundlePath
capability"},{"location":"reference/server-args/","title":"Appium Server Arguments","text":"Some driver arguments can be set when launching the Appium server. This can be done as follows:
appium --driver-xcuitest-[argName]=[argValue]\n
Argument Description Default Example webdriveragent-port
Local port used for communicating with WebDriverAgent 8100
--driver-xcuitest-webdriveragent-port=8200
"},{"location":"reference/settings/","title":"Settings","text":"The XCUITest driver supports Appium's Settings API. Along with the common settings, the following driver-specific settings are available:
Name Type DescriptionelementResponseAttributes
string
Comma-separated list of element attribute names to be included into findElement response. By default only element UUID is present there, but it is also possible to add the following items: name
, text
, rect
, enabled
, displayed
, selected
, attribute/<element_attribute_name>
. It is required that shouldUseCompactResponses
setting is set to false
in order for this one to apply. shouldUseCompactResponses
boolean
Used in combination with elementResponseAttributes
setting. If set to false
then the findElement response is going to include the items enumerated in elementResponseAttributes
setting. true
by default screenshotQuality
int
See the description of the corresponding capability. mjpegServerFramerate
int
The maximum count of screenshots per second taken by the MJPEG screenshots broadcaster. Must be in range 1..60. 10
by default mjpegScalingFactor
int
The percentage value used to apply downscaling on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. 100
is by default, which means that screenshots are not downscaled. mjpegServerScreenshotQuality
int
The percentage value used to apply lossy JPEG compression on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. 25
is by default, which means that screenshots are compressed to the quarter of their original quality. customSnapshotTimeout
(snapshotTimeout
before 1.19.1) float
Set how much time in float seconds is allowed to resolve a single accessibility snapshot with custom attributes. Snapshots are mainly used for page source generation, XML lookup and custom attributes retrieval (these are visibility and accessibility ones). It might be necessary to increase this value if the actual page source is very large and contains hundreds of UI elements. Defaults to 15 seconds. Since Appium 1.19.1 if this timeout expires and no custom snapshot could be made then WDA tries to calculate the missing attributes using its own algorithms, so setting this value to zero might speed up, for example, page source retrieval, but for the cost of preciseness of some element attributes. waitForIdleTimeout
float
Has the same meaning as corresponding capability (see above) animationCoolOffTimeout
float
The amount of time in float seconds to wait until the application under test does not have any active animations. This check is usually applied after each automation action that is supposed to change the state of the application under test, like click
one, and blocks XCTest until the transition of the tested application to a new state completes or the cool off timeout occurs. The default value is 2
(seconds). Setting it to zero disables animation checks completely. snapshotMaxDepth
int
Changes the value of maximum depth for traversing elements source tree. It may help to prevent out of memory or timeout errors while getting the elements source tree, but it might restrict the depth of source tree. Please consider restricting this value if you observed an error like Timed out snapshotting com.apple.testmanagerd... message or Cannot get 'xml' source of the current application in your Appium log since they are possibly timeout related. A part of elements source tree might be lost if the value was too small. Defaults to 50
useFirstMatch
boolean
Enabling this setting makes single element lookups faster, but there is the known problem related to nested elements lookup. Defaults to false
. reduceMotion
boolean
Changes the 'reduce motion' preference of accessibility feature. Defaults to false
defaultActiveApplication
string
Sets the hint for active application selection. This helps WebDriverAgent to select the current application if there are multiple items in the active applications list and the desired one is also one of them. The setting is particularly useful for split-screen apps automation. Defaults to auto
, which makes WebDriverAgent to select the application whose element is located at screenPoint
location or a single item from the active apps list if the length of this list is equal to one. activeAppDetectionPoint
string
Defines the coordinates of the current screen point. WebDriverAgent uses this point to detect the active application if multiple application are active on the screen. The format of this value is x,y
, where x and y are float or integer numbers representing valid screen coordinates. Setting this value to a point outside the actual screen coordinates might corrupt WebDriverAgent functionality. By default the screen point coordinates equal to 20% of the minimum screen dimension each, e.g. MIN(w, h) * 0.2, MIN(w, h) * 0.2
includeNonModalElements
boolean
Whether returns all of elements including no modal dialogs on iOS 13+. It fixes cannot find elements on nested modal presentations, but it might make visibility attributes unreliable. You could also enable shouldUseTestManagerForVisibilityDetection
setting (defaults to false
) or simpleIsVisibleCheck
capability to improve the visibility detection. This issue may happen between iOS 13.0 to 13.2 (Xcode 11.0 to 11.2). The query issued in includeNonModalElements
returns nil
with newer iOS/Xcode versions and Appium/WDA return proper elements three without this setting being used. Defaults to false
. acceptAlertButtonSelector
string
Allows to customize accept alert button selector. It helps you to handle an arbitrary element as accept button in accept alert
command. The selector should be a valid class chain expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: **/XCUIElementTypeButton[`label CONTAINS[c] 'accept'`]
dismissAlertButtonSelector
string
Allows to customize dismiss alert button selector. It helps you to handle an arbitrary element as dismiss button in dismiss alert
command. The selector should be a valid class chain expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: **/XCUIElementTypeButton[`label CONTAINS[c] 'dismiss'`]
screenshotOrientation
string
Adjust screenshot orientation for iOS. Appium tries to return a screenshot and adjust its orientation properly using internal heuristics, but sometimes it does not work, especially in landscape mode. The actual screenshot orientation depends on various factors such as OS versions, model versions and whether this is a real or simulator device. This option allows you to enforce the given image orientation. Acceptable values: auto
(default), portrait
, portraitUpsideDown
, landscapeRight
, landscapeLeft
. boundElementsByIndex
boolean
Whether to look up elements with allElementsBoundByAccessibilityElement
(default) or allElementsBoundByIndex
. This Stack Overflow topic explains the differences. Defaults to false
. keyboardAutocorrection
boolean
Changes the 'Auto-Correction' preference in Keyboards setting. Defaults to false
. keyboardPrediction
boolean
Changes the 'Predictive' preference in Keyboards setting. Defaults to false
. nativeWebTap
boolean
See the description of the corresponding capability. nativeWebTapStrict
boolean
See the description of the corresponding capability. nativeWebTapTabBarVisibility
enum
Bypass finding whether the existence of the tab bar before tapping on the element. It could make native web tap faster. If it's visible
, tab bar offset will be added without checking the existence of the tab bar. It's invisible
, the tab bar offset will be zero
. If you want to leave Appium to check and measure the tab bar offset, unset or set detect
. Only applicable if nativeWebTap
and nativeWebTapStrict
are enabled. Unset by default. nativeWebTapSmartAppBannerVisibility
enum
The same as nativeWebTapTabBarVisibility
, this keyword will bypass finding whether the existence of the smart app banner. safariTabBarPosition
string
Handle offset of Safari tab bar in nativeWebTap
enabled interactions. If platformVersion
was greater than or equal to 15 and iPhone device, the value is bottom
by default. Otherwise top
. When the value is top
, Appium considers offset as the bar length. iOS 15+ environment can customize the bar position in the settings app, so please adjust the offset with this. Acceptable values: bottom
, top
useJSONSource
boolean
See the description of the corresponding capability. pageSourceExcludedAttributes
string
One or more comma-separated attribute names to be excluded from the XML output. It might be sometimes helpful to exclude, for example, the visible
attribute, to significantly speed-up page source retrieval. This does not affect the XML output when useJSONSource
is enabled. Defaults to an empty string. Example: \"visible,accessible\"
"}]}
\ No newline at end of file
diff --git a/5.14/sitemap.xml b/5.14/sitemap.xml
index 52e616cb6..7ee4ea158 100644
--- a/5.14/sitemap.xml
+++ b/5.14/sitemap.xml
@@ -2,192 +2,192 @@