From a7e612fa3704cd9bb7cf1058cdefe3330c1a119a Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 2 Apr 2024 16:17:40 +0000 Subject: [PATCH] docs: auto-build docs for appium-xcuitest-driver@7.9 --- 7.9/guides/run-prebuilt-wda/index.html | 18 +++--- 7.9/reference/capabilities/index.html | 9 ++- 7.9/search/search_index.json | 2 +- 7.9/sitemap.xml | 76 ++++++++++++------------- 7.9/sitemap.xml.gz | Bin 593 -> 592 bytes 5 files changed, 57 insertions(+), 48 deletions(-) diff --git a/7.9/guides/run-prebuilt-wda/index.html b/7.9/guides/run-prebuilt-wda/index.html index 28f9475ee..d58dbf3a6 100644 --- a/7.9/guides/run-prebuilt-wda/index.html +++ b/7.9/guides/run-prebuilt-wda/index.html @@ -1529,9 +1529,9 @@
  • - + - Capabilities for Prebuilt WDA with appium:useXctestrunFile + Capabilities for Prebuilt WDA with appium:useXctestrunFile, appium:usePrebuiltWDA or appium:prebuildWDA @@ -2065,9 +2065,9 @@
  • - + - Capabilities for Prebuilt WDA with appium:useXctestrunFile + Capabilities for Prebuilt WDA with appium:useXctestrunFile, appium:usePrebuiltWDA or appium:prebuildWDA @@ -2216,7 +2216,7 @@

    How xcodebuild WorksCapabilities for Prebuilt WDA with appium:useXctestrunFile

    +

    Capabilities for Prebuilt WDA with appium:useXctestrunFile, appium:usePrebuiltWDA or appium:prebuildWDA

    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).

    @@ -2239,9 +2239,13 @@

    Capabilities }

    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 +

    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.

    +

    appium:prebuildWDA lets the XCUITest driver build the WDA before running it, then the session +will be handled with appium:usePrebuiltWDA. +It might have additional building steps than with appium:derivedDataPath and appium:usePrebuiltWDA +combination, but it could help appium:usePrebuiltWDA to not manage the WDA project.

    Capabilities for Prebuilt WDA with appium:prebuiltWDAPath

    Run Preinstalled WebDriverAgentRunner provides appium:prebuiltWDAPath capability. It also achieves the same thing, but the appium:prebuiltWDAPath does not use xcodebuild. @@ -2276,7 +2280,7 @@

    Download Prebuilt WDA - 2024-03-27 + 2024-04-02 diff --git a/7.9/reference/capabilities/index.html b/7.9/reference/capabilities/index.html index 3b5e1b5d5..c0948988a 100644 --- a/7.9/reference/capabilities/index.html +++ b/7.9/reference/capabilities/index.html @@ -2535,8 +2535,13 @@

    WebDriverAgentOther& - 2024-03-31 + 2024-04-02 diff --git a/7.9/search/search_index.json b/7.9/search/search_index.json index 9513c2473..107ea3f6f 100644 --- a/7.9/search/search_index.json +++ b/7.9/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":"
    • Check out the Overview to learn how the driver works
    • Go through the Installation steps to get set up
    • Follow the Device Preparation instructions to configure your test device
    • Browse the Reference documentation for everything exposed by the driver
    • Read the different Guides for a variety of instructions, tips and tricks
    • For contributions to the driver, refer to the Contributing page
    "},{"location":"contributing/","title":"Contributing","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 spec
    • PLATFORM_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
    "},{"location":"endpoints-wda/","title":"Endpoints wda","text":""},{"location":"endpoints-wda/#webdriveragent-jsonwp-endpoints","title":"WebDriverAgent JSONWP Endpoints","text":""},{"location":"endpoints-wda/#session-less-commands","title":"Session-less commands","text":"method endpoint req params opt params POST /wda/homescreen GET /source accessible GET /inspector GET /inspector.js GET /screenshot POST /session desiredCapabilities GET /status GET /* ** POST /* ** PUT /* ** DELETE /* **"},{"location":"endpoints-wda/#session-commands","title":"Session commands","text":"method endpoint req params opt params GET /alert/text POST /alert/accept POST /alert/dismiss POST /wda/deactivateApp duration POST /timeouts * GET /source accessible GET /element/:uuid/enabled GET /element/:uuid/rect GET /element/:uuid/attribute/:name GET /element/:uuid/text GET /element/:uuid/displayed GET /wda/element/:uuid/accessible GET /element/:uuid/name POST /element/:uuid/value value POST /element/:uuid/click POST /element/:uuid/clear POST /wda/element/:uuid/doubleTap POST /wda/element/:uuid/touchAndHold duration POST /wda/element/:uuid/scroll name, direction, predicateString, toVisible POST /uiaElement/:uuid/value value POST /wda/element/:uuid/dragfromtoforduration fromX, fromY, toX, toY, duration POST /wda/tap/:uuid x, y POST /wda/keys value GET /window/size POST /element using, value POST /elements using, value GET /wda/uiaElement/:uuid/getVisibleCells POST /element/:uuid/element using, value POST /element/:uuid/elements using, value GET /orientation POST /orientation orientation GET /screenshot POST /wda/touch_id match

    * 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 GET /location POST /location location POST /log type GET /log/types GET /context POST /context name GET /contexts 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:

    • Native testing is based on Apple's XCTest framework and Appium's fork of Facebook's WebDriverAgent server (the original project is not supported anymore)
      • In native mode, the driver operates in scope of WebDriver W3C protocol with several platform-specific extensions
    • Webview communication is done via Webkit remote debugger protocol
      • In webview mode, the driver can only operate in scope of the obsolete JSONWP protocol
    • Real device communication is provided by the appium-ios-device library
    • Simulator communication is provided by the appium-ios-simulator library
    "},{"location":"guides/attach-to-running-wda/","title":"Attach to a Running WebDriverAgent","text":"

    The 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.

    "},{"location":"guides/attach-to-running-wda/#usage","title":"Usage","text":"
    1. Start a WebDriverAgent application on a device
    2. Start an XCUITest driver session with appium:webDriverAgentUrl capability

    Please 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.

    "},{"location":"guides/audio-capture/","title":"Audio Capture","text":"

    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
    "},{"location":"guides/audio-capture/#server-requirements","title":"Server Requirements","text":"
    • The host machine must have 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:

      • macOS < 13: System Preferences -> Security & Privacy -> Privacy -> Microphone
      • macOS 13+: System Settings -> Privacy & Security -> Microphone

      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.

    "},{"location":"guides/audio-capture/#simulator-setup","title":"Simulator Setup","text":"

    The following steps are necessary to setup iOS Simulator audio capture:

    • Install Soundflower
    • Redirect Simulator audio output to Soundflower: from the main Simulator menu, select I/O -> Audio Output -> Soundflower (2ch)
    • In terminal, run 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
    • Test that your setup works as expected. Run any audio playback in Simulator and execute the following command in Terminal, replacing the -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.
    "},{"location":"guides/audio-capture/#real-device-setup","title":"Real Device Setup","text":"

    The following steps are necessary to setup iOS Real Device audio capture:

    • Connect your device to the Mac host with a cable
    • Open the Audio MIDI Setup application
      • Via Finder: Applications -> Utilities -> Audio MIDI Setup
      • Via terminal: open -a /System/Applications/Utilities/Audio\\ MIDI\\ Setup.app
    • Find your phone in the list of devices there and click Enable next to it
    • In terminal, run ffmpeg -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
    • Test that your setup works as expected. Run any audio playback on the device and execute the following command in Terminal, replacing the -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":"
    • https://github.com/appium/appium-xcuitest-driver/pull/1207
    • https://www.macobserver.com/tips/quick-tip/iphone-audio-input-mac/
    • http://www.lorisware.com/blog/2012/04/28/recording-iphone-emulator-video-with-sound/
    "},{"location":"guides/ci-setup/","title":"Continuous Integration","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:

    1. Keychains can be set to have no timeout and be unlocked manually once. This can be done using the keychain access application. Sometimes keychains still lock themselves though and this approach is not recommended.
    2. It is possible to create a second keychain, which just stores the required certificate to sign the WebDriverAgent. The issue with this approach is that Codesign wants to unlock all listed keychains regardless of the specified keychain, thus leading to a password prompt. This can be avoided by setting the default keychain and basically hiding the login keychain at the start of the build. See this Stackoverflow article for how to utilize this approach. It is impractical when running other build jobs simultaneously.
    3. Stick with the existing keychains as in approach 1, but explicitly call unlock keychain before each build. This can be done using fastlane unlock_keychain or by using security unlock-keychain directly. The password can be saved as a CI variable/secret or on the machine itself.

    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.

    "},{"location":"guides/clipboard/","title":"Get/Set Clipboard","text":"

    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.

    "},{"location":"guides/clipboard/#get-clipboard","title":"Get Clipboard","text":"

    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 type
      • On simulators, common values are app, data, groups, but a custom one can also be provided
      • On real devices, the only accepted value is documents. All others are treated as Format 2
        • This value can only be specified for apps that have the UIFileSharingEnabled 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
      • On real devices, if <container-type> is set to documents, this path will be mapped to On My iPhone/<app name> in the Files app
    "},{"location":"guides/file-transfer/#format-2","title":"Format 2","text":"
    @<app-bundle-id>/<path-to-file-or-folder>\n
    • On simulators, the implicit <container-type> is set to app.
    • On real device, only apps with the UIFileSharingEnabled flag set to true in their info.plist can be mounted. You can use the mobile: listApps extension to identify such apps.
    "},{"location":"guides/file-transfer/#format-3","title":"Format 3","text":"
    <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.

    "},{"location":"guides/file-transfer/#examples","title":"Examples","text":""},{"location":"guides/file-transfer/#pullfile","title":"pullFile","text":"

    This example pulls a file present in Files -> On My iPhone -> Keynote:

    Top On My iPhone Keynote JS (WebdriverIO)Ruby
    let 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)Ruby
    let 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 (/).

    JS (WebdriverIO)Ruby
    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":"
    • https://stackoverflow.com/questions/1108076/where-does-the-iphone-simulator-store-its-data
    • https://stackoverflow.com/questions/48884248/how-can-i-add-files-to-the-ios-simulator
    • https://apple.stackexchange.com/questions/299413/how-to-allow-the-files-app-to-save-to-on-my-iphone-or-to-on-my-ipad-in-ios/299565#299565
    "},{"location":"guides/input-events/","title":"About iOS Input Events","text":""},{"location":"guides/input-events/#what-are-input-events","title":"What Are Input Events","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:

    • Create a new XCPointerEventPath instance and initialize it for touch at the starting point
    • Add a new liftUp event at 0.125s offset using liftUpAtOffset: method
    • Add the generated event path object to XCSynthesizedEventRecord instance using addPointerEventPath: method
    • Execute the events using synthesizeWithError: method of XCSynthesizedEventRecord instance and control the returned error

    There are several limitations to these APIs:

    • Each 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 ignored
    • Each XCPointerEventPath instance can only be initialized for a particular pointer type: touch, mouse (since Xcode 10.2) or keyboard (since Xcode 10.2)
    • Events can only be added with increasing offset values to an existing XCPointerEventPath instance
    "},{"location":"guides/input-events/#more-complicated-actions","title":"More Complicated Actions","text":"

    Unfortunately, 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:

    • Create a two XCPointerEventPath instances and init them for touch at the starting point
    • Add a moveToPoint event at 0.525s offset using moveToPoint: method to each path
    • Add a liftUp eventa at 0.525s offset using liftUpAtOffset: method to each path
    • Add the generated event paths to XCSynthesizedEventRecord instance using addPointerEventPath: method
    • Execute the events using synthesizeWithError: method of XCSynthesizedEventRecord instance and control the returned error
    "},{"location":"guides/input-events/#further-reading","title":"Further Reading","text":"

    Unfortunately, there is no information on this topic at all (private API \u00af\\_(\u30c4)_/\u00af). Consider visiting the following resources:

    • https://github.com/appium/WebDriverAgent/tree/master/PrivateHeaders/XCTest
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CMultiTouchActionsIntegrationTests.m
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m
    "},{"location":"guides/install-certificate/","title":"Self-Signed Certificates","text":"

    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
    "},{"location":"guides/multiple-xcode-versions/","title":"Managing Multiple Xcodes","text":"

    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:

    1. Set the default Xcode
      sudo xcode-select -s /Applications/Xcode13.app/Contents/Developer\n
    2. Run Appium
      appium\n
    "},{"location":"guides/multiple-xcode-versions/#environment-variable","title":"Environment variable","text":"

    No privileges needed, affects only the current shell, so Appium should be started within that shell.

    Assuming you want to choose /Applications/Xcode12.app:

    1. Set the DEVELOPER_DIR environment variable
      export DEVELOPER_DIR=/Applications/Xcode12.app/Contents/Developer\n
    2. Run Appium
      appium\n
    "},{"location":"guides/parallel-tests/","title":"Testing in Parallel","text":"

    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.

    "},{"location":"guides/parallel-tests/#important-real-device-capabilities","title":"Important Real Device Capabilities","text":"
    • 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.
    "},{"location":"guides/parallel-tests/#important-simulator-capabilities","title":"Important Simulator Capabilities","text":"
    • Either 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.
    "},{"location":"guides/run-prebuilt-wda/","title":"Run Prebuilt WebDriverAgentRunner","text":"

    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.

    "},{"location":"guides/run-prebuilt-wda/#how-xcodebuild-works","title":"How 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.

    "},{"location":"guides/run-prebuilt-wda/#capabilities-for-prebuilt-wda-with-appiumusexctestrunfile","title":"Capabilities for Prebuilt WDA with appium:useXctestrunFile","text":"

    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.

    "},{"location":"guides/run-prebuilt-wda/#capabilities-for-prebuilt-wda-with-appiumprebuiltwdapath","title":"Capabilities for Prebuilt WDA with appium:prebuiltWDAPath","text":"

    Run Preinstalled WebDriverAgentRunner provides appium:prebuiltWDAPath capability. It also achieves the same thing, but the appium:prebuiltWDAPath does not use xcodebuild. Please check the link for more details.

    "},{"location":"guides/run-prebuilt-wda/#download-prebuilt-wda","title":"Download Prebuilt WDA","text":"

    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.

    For simulator environment, the prebuilt packages available on Building WebDriverAgent may not work for all environment as different building environment. We recommend preparing the Build directory, which is generated by -derivedDataPath xcodebuild argument, on your test running environment and re-use it.

    "},{"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 and a simulator. This allows you to start a session without the xcodebuild command execution, improving the session startup performance.

    Warning

    iOS/tvOS 17+ speicic:

    This method currently works over devicectl for iOS 17+ with Xcode 15+ environment since XCUITest driver v7.5.0. This may not work for tvOS 17+. iOS/tvOS 16 and lower ones work over appium-ios-device directly.

    "},{"location":"guides/run-preinstalled-wda/#capabilities","title":"Capabilities","text":"
    • Required
      • appium:usePreinstalledWDA
    • Optional
      • appium:updatedWDABundleId
      • appium:updatedWDABundleIdSuffix
        • Since XCUITest driver v7.6.0
      • appium:prebuiltWDAPath
    "},{"location":"guides/run-preinstalled-wda/#install-webdriveragent","title":"Install WebDriverAgent","text":""},{"location":"guides/run-preinstalled-wda/#using-xcode","title":"Using Xcode","text":"

    Running a test for the WDA package in Xcode is the easiest way to prepare the device environment:

    1. Open WebDriverAgent project in Xcode
      • You can run appium driver run xcuitest open-wda if using XCUITest driver 4.13 or newer
    2. Select the WebDriverAgentRunner scheme
    3. Select the scheme as Product -> Scheme -> WebDriverAgentRunner (or WebDriverAgentRunner_tvOS for tvOS)
    4. Select your device in Product -> Destination
    5. Select Product -> Test to build and install the WDA app

    If 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, ios-app-signer can install the WebDriverAgent package.

    Some tools let you set an arbitrary bundle identifier (CFBundleIdentifier for the Info.plist) and sign it with the bundle identifier. It may not have .xctrunner as the bundle identifier. XCUITest driver automatically adds the .xctrunner suffix to the provided bundle identifier unless a different suffix is specified by the appium:updatedWDABundleIdSuffix capability. If the value is an empty string, then no suffix will be added to the provided bundle identifier.

    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.

    "},{"location":"guides/run-preinstalled-wda/#additional-requirement-for-ios-17tvos17","title":"Additional requirement for iOS 17+/tvOS17+","text":"

    To launch the WebDriverAgentRunner package with xcrun devicectl device process launch it should not have Frameworks/XC** files.

    For example, after building the WebDriverAgent with Xcode with proper sign, it generates /Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app. Then you can remove Frameworks/XC** in WebDriverAgentRunner-Runner.app like rm Frameworks/WebDriverAgentRunner-Runner.app/XC**.

    Configuring appium:prebuiltWDAPath to the /Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app would install the WebDriverAgentRunner-Runner.app, which has no Frameworks/XC** to the target device and launch it with devicectl command as part of appium:usePreinstalledWDA functionality.

    "},{"location":"guides/run-preinstalled-wda/#launch-the-session","title":"Launch the Session","text":"

    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.

    # Ruby\ncapabilities: {\n  \"platformName\": \"ios\",\n  \"appium:automationName\": \"xcuitest\",\n  \"appium:udid\": \"<udid>\",\n  \"appium:usePreinstalledWDA\": true,\n  \"appium:updatedWDABundleId\": \"io.appium.wda\"\n  \"appium:updatedWDABundleIdSuffix\": \"\"\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 io.appium.wda bundle ID (it does not have .xctrunner), the session will launch the WebDriverAgent process without xcodebuild.

    "},{"location":"guides/run-preinstalled-wda/#set-appiumprebuiltwdapath","title":"Set appium:prebuiltWDAPath","text":"

    If the appium:prebuiltWDAPath capability is provided with a 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 usually, which is why it is necessary to (re)install them for every test session. The test bundle should be signed properly for real devices.

    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.

    "},{"location":"guides/touch-id/","title":"Touch ID","text":"

    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":"
    • Set the capability appium:allowTouchIdEnroll to true.
    • When the Simulator starts, Touch ID enrollment will be enabled by default
    • You can toggle Touch ID enrollment by calling the mobile: enrollBiometric extension

    Note

    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":"
    • Real devices with iOS/iPadOS 15+ show an overlay with the text Automation Running Hold both volume buttons to stop while WebDriverAgent is running. This is a known limitation of the XCTest framework. Note that screenshotting functionality is not affected (i.e. the overlay is not visible on taken screenshots).
    • Real devices with iOS/iPadOS 15+ require passcode or Touch ID when starting a new session. A workaround for this is to disable passcode/Touch ID on the device.
    • After many failures on a real device, it could transition to a state where connections are no longer being accepted. Rebooting the device can help remedy this problem. Please read this issue for more details.
    • shake is implemented via AppleScript and works only on Simulator due to lack of support from Apple
    "},{"location":"guides/troubleshooting/#interact-with-dialogs-managed-by-comapplespringboard","title":"Interact with dialogs managed by com.apple.springboard","text":"

    System dialogs, such as permission dialogs, might not be interactable directly when the active application is not com.apple.springboard. Despite a similar look, dialogs belonging to the active session application (e.g. initially passed as appium:app or appium:bundleId capability value) do not require such adjustment.

    XCUITest driver offers a few methods to handle them.

    • Start a session without appium:app nor appium:bundleId. Then XCUITest driver attempts to get the current active application. This requires you to start an application after a new session request with mobile: installApp to install an app if needed and mobile: launchApp/mobile: activateApp, but it could automatically change the active application with com.apple.springboard or activated application on the top. (Note that the automatic detection could have a delay, thus each action could take more time.)
      • When a permission alert exists on the top, it could select the com.apple.springboard
      • When another application is on the top by accepting/denying the system alert, or mobile: activateApp, the application would be selected as an active application.
    • mobile: alert
    • defaultActiveApplication setting in Settings.
      • e.g. With the Appium Ruby client
        # Interacting with the test target\ndriver.settings.update({defaultActiveApplication: \"com.apple.springboard\"})\n# to accept the alert\ndriver.find_element(\"accessibility_id\", \"Allow Once\").click\ndriver.settings.update({defaultActiveApplication: \"auto\"})\n# keep interacting with the test target\n
    • Enable appium:autoAcceptAlerts/appium:autoDismissAlerts, or interact with alerts via User Prompts in WebDriver endpoints
      • e.g. driver.switch_to.alert.accept with the Appium Ruby client
      • It might be necessary to coordinate element selection via acceptAlertButtonSelector/dismissAlertButtonSelector settings in Settings
    • Activate com.apple.springboard with mobile: activateApp before interacting with dialogs

    mobile: activeAppInfo helps to understand what application (bundleId) is considered as active for the XCUITest driver.

    "},{"location":"guides/troubleshooting/#leftover-application-data-on-real-devices","title":"Leftover Application Data on Real Devices","text":"

    There might be a situation where application data is present on the real device, even if the application itself is not installed. This could happen if:

    • The app is in an offloaded state
    • The application state is cached
    • There was an unexpected failure while installing the app. An example of such failure is the ApplicationVerificationFailed which happens while installing an app signed with an invalid provisioning profile.

    In the above cases, the application identifier will not be listed in the output of mobile: listApps, and it will not be detected by mobile: isAppInstalled. Setting appium:fullReset or appium:enforceAppInstall capabilities to true also will not help clear this data.

    The only way to completely get rid of the cached application data is to call the mobile: removeApp command with the appropriate bundle identifier.

    The driver does automatically try to resolve application installs that failed because of the MismatchedApplicationIdentifierEntitlement error. However, in cases when the previously installed application's provisioning profile is different from what currently the driver is trying to install, and if you explicitly set the driver to not perform application uninstall, then consider calling mobile: removeApp before the MismatchedApplicationIdentifierEntitlement error occurs. Example steps can be as follows:

    1. Start a session without appium:app and appium:bundleId capabilities
    2. Call mobile: removeApp for the target application's bundle id
    3. Install the test target with mobile: installApp
    4. Launch the application with mobile: launchApp or mobile: activateApp
    "},{"location":"guides/troubleshooting/#weird-state","title":"Weird State","text":""},{"location":"guides/troubleshooting/#real-device-stops-responding","title":"Real Device Stops Responding","text":"

    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.

    "},{"location":"guides/troubleshooting/#real-device-security-settings","title":"Real Device Security Settings","text":"

    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.

    "},{"location":"guides/troubleshooting/#simulator-resetting","title":"Simulator Resetting","text":"

    When testing on simulators, the driver tries to leave the simulator state as it found it:

    • If no udid is provided, the driver will create a new iOS simulator, run tests on it, and then delete the simulator
    • If a specific udid is provided for a simulator that is not running, the driver will boot the specified simulator, run tests on it, and then shut the simulator down
    • If a specific udid is provided for a simulator that is running, the driver will connect to the existing simulator, run tests, and then leave the simulator running

    You can use the appium:noReset capability to adjust this behavior: setting it to true will leave the simulator running at the end of a test session.

    "},{"location":"guides/troubleshooting/#caching-issues-during-build","title":"Caching Issues During Build","text":"

    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.

    "},{"location":"guides/tvos/#setup","title":"Setup","text":"

    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.

    "},{"location":"guides/tvos/#basic-actions","title":"Basic Actions","text":"

    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.

    JavaJS (WebdriverIO)PythonRuby
    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":"
    • Consider using wait methods, since tvOS also has animation
    • The menu button works as back for iOS context in tvOS
    "},{"location":"guides/tvos/#known-limitations","title":"Known Limitations","text":"
    • Gesture commands do not work for tvOS. Some commands such as pasteboard do not work as well.
    "},{"location":"guides/tvos/#related-tickets","title":"Related Tickets","text":"
    • https://github.com/appium/appium/pull/12401
    • https://github.com/appium/appium-xcuitest-driver/pull/911
    • https://github.com/appium/appium-xcuitest-driver/pull/931
    • https://github.com/appium/appium-xcuitest-driver/pull/939
    • https://github.com/appium/WebDriverAgent/pull/163
    "},{"location":"guides/wda-custom-server/","title":"Manage WebDriverAgent by Yourself","text":"

    The 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

    • The steps below are not necessary if default Appium capabilities are used. The server will do everything for you, however, you will not have so much control over WDA.
    • It is mandatory to have SSH or physical access to the machine to which the device under test is connected.
    "},{"location":"guides/wda-custom-server/#wda-setup","title":"WDA Setup","text":"

    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":"
    • The process does not have direct access to keychain if it is executed by a continuous integration agent, so the keychain must be prepated before compiling WDA for real device, otherwise codesigning will fail. Check the CI Setup documentation for details.
    • The xcodebuild and iproxy processes are killed before restart to make sure compilation succeeds, in case the processes are frozen
    • A dedicated bash 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 interaction
    • The value of the BUILD_ID environment variable is changed to avoid the CI agent killing the background process after the job is finished
    • The isRunning check is done by verifying the actual network endpoint
    • The output of daemonized processes is logged, so it is possible to track errors and unexpected failures. The content of the log files is automatically added to the actual error message if the server fails to (re)start.
    • Real device id can be parsed from system_profiler SPUSBDataType output
    • Simulator id can be parsed from xcrun simctl list output
    • The UrlChecker class is imported from the org.openqa.selenium.net package
    "},{"location":"installation/","title":"Installation","text":"

    Info

    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:

    • Only macOS is supported as the host platform
    • Xcode and Xcode Developer Tools must be installed
      • The Appium team usually needs some time to add support for the most recent Xcode/iOS versions, especially beta versions (check the Xcode/iOS version support section)
    • If automating real devices, additional manual configuration is required. Please check the Real Device Configuration document for more details.
    • Webviews must be debuggable in order to test them. If it is not possible to connect to your webview(s) using Safari remote debugger, then the driver will not be able to identify them.
    "},{"location":"installation/requirements/#optional-dependencies","title":"Optional Dependencies","text":"
    • 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 interactions
    • WIX AppleSimulatorUtils can be used to improve some Simulator interactions
    • py-ios-device is required in several mobile: extensions, and can improve the general testing experience for real devices
    "},{"location":"installation/requirements/#validate-dependencies-using-doctor","title":"Validate Dependencies Using Doctor","text":"

    Since 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.

    "},{"location":"installation/requirements/#xcodeios-version-support","title":"Xcode/iOS Version Support","text":"

    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.0

    The 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.2

    The 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.

    • Settings -> General -> Keyboard -> Auto-Correction is turned OFF
    • Settings -> General -> Keyboard -> Predictive Text is turned OFF
    • The keyboard tutorial is marked as complete
    • (Simulator Only) Software keyboard is turned ON
    "},{"location":"preparation/#manual-adjustments","title":"Manual Adjustments","text":"

    Unfortunately, not all configuration can be done automatically, and some changes must be applied manually.

    "},{"location":"preparation/#accessibility-settings","title":"Accessibility Settings","text":"
    • To avoid miscalculation of element coordinates, please make sure the zoom preference is turned off in Settings -> Accessibility -> Zoom.
    • Some accessibility settings may expose additional view elements. Appium does not modify these settings automatically, since they could affect the way your application under test performs. Please change them manually if needed. Note that the available accessibility content depends on the OS version.
      • Settings -> Accessibility -> Spoken Content -> Speak Selection
    "},{"location":"preparation/#webview-testing","title":"Webview Testing","text":"
    • Webviews on iOS/iPadOS 16.4 or above may require additional configuration from the application developer. Specifically, the destination 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.
    • WebViews on iOS/iPadOS below version 16.4 must have the get-task-allow entitlement present as true in the application manifest.
    • Starting from iOS/iPadOS 16.4, the Google Chrome browser also supports webview testing. This feature requires Chrome version 115 or newer. Please read the Chrome Developer documentation page for details on the necessary configuration.
    "},{"location":"preparation/#real-devices","title":"Real Devices","text":"

    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:

    • Use the xcodeOrgId and xcodeSigningId capabilities:
      {\n  \"appium:xcodeOrgId\": \"<Team ID>\",\n  \"appium:xcodeSigningId\": \"Apple Developer\"\n}\n
    • Create a .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.
      • To find this string (your Team ID), sign in to developer.apple.com/account, and click Membership in the sidebar. Your Team ID appears in the Membership Information section under the team name. You can also find your Team ID listed under the \"Organizational Unit\" field in your iPhone Developer certificate in your keychain.
    • 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.

    "},{"location":"preparation/prov-profile-basic-manual/","title":"Basic Manual Configuration","text":"

    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.

    "},{"location":"preparation/prov-profile-full-manual/","title":"Full Manual Configuration","text":"

    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:

    • In the terminal, open the directory where WDA is located. Run the following to set the project up:
      mkdir -p Resources/WebDriverAgent.bundle\n
    • Open WebDriverAgent.xcodeproj in Xcode. This will likely open a screen with an empty editor.
    • In the file browser on the left side, select the root WebDriverAgent project, which will open it in the editor. Then, under Targets, select WebDriverAgentRunner (or WebDriverAgentRunner_tvOS for tvOS), and switch to the Signing & Capabilities tab.
    • 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:

      • Select the scheme as Product -> Scheme -> WebDriverAgentRunner
      • Select your real device in Product -> Destination
      • Select Product -> Test to build and install the WDA app

    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.

    "},{"location":"preparation/real-device-config/","title":"Real Device Configuration","text":"

    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:

    • Devices need to be trusted. This can be done by opening Xcode and afterwards physically connecting the device under test to the computer. The device should have a popup asking to trust the computer, which you should accept.
    • Devices using iOS/iPadOS 16 or above require enabling Developer Mode. Please read Apple's documentation on Developer Mode for more details. devmodectl streaming CLI on macOS 13+ and installing development signed apps also help enabling the mode.
    • After enabling Developer Mode (if applicable), please turn on Settings -> Developer -> Enable UI Automation
    • Webviews will not be testable unless the Safari Inspector is enabled. Please turn it on in Settings -> Safari -> Advanced -> Web Inspector. Similarly, you may want to turn on the adjacent option Settings -> Safari -> Advanced -> Remote Automation.

    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.

    • Basic Automatic Configuration: the easiest approach, but requires you to have a paid Apple Developer account

    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:

    • The WDA project is included in 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.
    • If using XCUITest driver v4.13.0 or newer, you can run the 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:

    • Basic Manual Configuration: create a new project, then use its provisioning profile and bundle ID
    • Full Manual Configuration: associate the provisioning profile directly with the WDA project
    • Manual Configuration for a Generic Device: manually run xcodebuild to build WDA, then manually install it
    "},{"location":"preparation/real-device-config/#validating-the-wda-install","title":"Validating the WDA Install","text":"

    Once 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

    "},{"location":"preparation/real-device-config/#create-an-offline-provisioning-profile","title":"Create an Offline Provisioning Profile","text":"

    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":"preparation/real-device-config/#tune-webdriveragent-to-improve-session-startup-performance","title":"Tune WebDriverAgent to improve session startup performance","text":"

    Running xcodebuild every time takes much longer time to complete a session startup. XCUITest driver offers a few methods to improve the performance with, or without using xcodebuild.

    Some might require deeper understanding of iOS development environment, but they help to improve speedup your test execution speed.

    • Run Preinstalled WebDriverAgentRunner
    • Run Prebuilt WebDriverAgentRunner
    • Attach to a Running WebDriverAgent
    "},{"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 Description platformName 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:initialDeeplinkUrl A deeplink URL used to run either the application assigned to appium:bundleId, or the default application assigned to handle the particular deeplink protocol if appium:bundleId is not set. If provided in combination with browserName=safari then makes Safari to start with the given URL preloaded, which speeds up the session startup. The value of appium:initialSafariUrl capability is ignored in such case. An error is thrown on session init if either the value of the capability is not a valid URL, or XCTest was not able to associate it with any existing app, or the actual iOS version is below 16.4 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 30000ms 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 it. This bundle id must be associated with a valid provisioning profile. The default value is com.facebook.WebDriverAgentRunner. 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 Overrides the folder that should be used for derived data when performing a source building with xCode. xCode stores all build and test artifacts under this file system root. Use this capability to set a unique path while running parallel tests or to have more control over built artifacts, for example if you'd like to use preinstalled or prebuilt WDA to reduce the session startup time. If the capability is not set then Xcode will store the derived data in the default root taken from preferences (usually a subfolder of /Users/<username>/Library/Developer/Xcode/DerivedData). /tmp/wda-861563ec 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 by xcodebuild. It does not work for webDriverAgentUrl and usePreinstalledWDA capabilities since they handle WebDriverAgent without the xcodebuild. Defaults to 2 for simulators and 1 for real devices. 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 full path to the prebuilt WebDriverAgent-Runner application package to be installed if appium:usePreinstalledWDA capability is enabled. The package's bundle identifier could be customized via appium:updatedWDABundleId capability. /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 or simulators via simctl tool (since driver version 7.4.0). If appium:prebuiltWDAPath is provided, XCUITest driver will install WebDriverAgent-Runner app from the given path before launching the application. The preinstalled WebDriverAgent package must be built by Xcode 12+. The default target bundle identifier is com.facebook.WebDriverAgentRunner.xctrunner, although it could be customized by providing the appium:updatedWDABundleId capability value (the .xctrunner suffix is added automatically). Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to false. true or false appium:updatedWDABundleIdSuffix Add suffix for the bundle id provided by the appium:updatedWDABundleId capability value in appium:usePreinstalledWDA capability usage since XCUITest driver v7.6.0. This is for an advanced usage that sets an arbitrary CFBundleIdentifier for prebuilt WebDriverAgent package to sign with the bundle identifier's certificate. For example, if you would need to sign a WebDriverAgent package with io.appium.wda bundle identifier's certificate, the WebDriverAgent's package must have the same bundle identifier as CFBundleIdentifier. Then, the WebDriverAgent package can be launched by io.appium.wda, which does not have .xctrunner. Then \"appium:updatedWDABundleIdSuffix\": \"\" (an empty string) helps. Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to .xctrunner. \"\", \".customsuffix\" 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 appium:appLaunchStateTimeoutSec Allows to set the timeout in float seconds for the application state change on the session startup in range (0, 240) exclusively. The default value for it in XCTest is 60 seconds, which means WDA would throw an exception if the application under test is not ready for accessibility interactions in 60s after its process has started. Important: The fact the application's user interface is visible does not necessarily mean it could be immediately interacted with by XCTest. The latter must ensure the app's main thread is also idling. Setting this capability to a lower value might help to avoid prolonged test startup with problematic apps taking too much time to be ready and fail fast. It is not advised to increase the capability value above 60 seconds, rather consider fixing the affected application itself. Too low values though may cause unexpected app startup failures. The capability does not have an effect if the app under test is not (re)started at the beginning of the session. 10.5"},{"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. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup for this capability to take effect on real devices. { 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:webviewAtomWaitTimeout The time to wait, in ms, for each atom execution timeout of webviews in MobileSafari or hybrid apps. Defaults to 120000. If the value was zero or less, the timeout keeps the default value. 20000 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 Allow javascript to open new windows in Safari. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. true or false appium:safariIgnoreFraudWarning Prevent Safari from showing a fraudulent website warning. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. true or false appium:safariOpenLinksInBackground Whether Safari should allow links to open in new windows. Default keeps the current sim setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. 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 Type contentType? 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 Description content 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

    "},{"location":"reference/commands/#getgeolocation","title":"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.

    For iOS 17+ simulators and real devices, this method will return the result of mobile: getSimulatedLocation extension if the simulated location was previously set by mobile: setSimulatedLocation.

    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>

    "},{"location":"reference/commands/#setgeolocation","title":"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":"reference/commands/#arguments_2","title":"Arguments","text":"Name Type Description 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>

    "},{"location":"reference/commands/#startrecordingscreen","title":"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 Type options? 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 Type options? 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.

    "},{"location":"reference/commands/#getsize","title":"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

    "},{"location":"reference/commands/#background","title":"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 Type seconds any"},{"location":"reference/commands/#returned-result_8","title":"Returned Result","text":"

    unknown

    "},{"location":"reference/commands/#queryappstate","title":"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

    "},{"location":"reference/commands/#islocked","title":"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

    "},{"location":"reference/commands/#lock","title":"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 Type seconds? any"},{"location":"reference/commands/#returned-result_11","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#unlock","title":"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

    "},{"location":"reference/commands/#mobileshake","title":"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

    "},{"location":"reference/commands/#getstrings","title":"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 Description language? 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/#setvalueimmediate","title":"setValueImmediate","text":"

    Deprecated

    This method is deprecated

    POST /session/:sessionId/appium/element/:elementId/value

    "},{"location":"reference/commands/#arguments_8","title":"Arguments","text":"Name Type text any"},{"location":"reference/commands/#returned-result_15","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#keys","title":"keys","text":"

    Deprecated

    This method is deprecated. Please use setValue instead

    POST /session/:sessionId/keys

    Send keys to the app

    "},{"location":"reference/commands/#arguments_9","title":"Arguments","text":"Name Type value any"},{"location":"reference/commands/#returned-result_16","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#receiveasyncresponse","title":"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_10","title":"Arguments","text":"Name Type response any"},{"location":"reference/commands/#returned-result_17","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#toggleenrolltouchid","title":"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_11","title":"Arguments","text":"Name Type Default value enabled? any true"},{"location":"reference/commands/#returned-result_18","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#touchid","title":"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_12","title":"Arguments","text":"Name Type Default value match any true"},{"location":"reference/commands/#returned-result_19","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#asyncscripttimeout","title":"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_13","title":"Arguments","text":"Name Type ms any"},{"location":"reference/commands/#returned-result_20","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#getlocation","title":"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_21","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

    "},{"location":"reference/commands/#returned-result_22","title":"Returned Result","text":"

    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_23","title":"Returned Result","text":"

    any

    "},{"location":"reference/element-attributes/","title":"Element Attributes","text":"

    The XCUITest driver supports the following element attributes:

    Name Description Example name 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.

    "},{"location":"reference/execute-methods/#arguments","title":"Arguments","text":"Name Type Required Description Example elementId (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-sendmemorywarning","title":"mobile: sendMemoryWarning","text":"

    Simulates sending of Low Memory warning to the target application. It might be useful to verify the didReceiveMemoryWarning API in the application under test. This feature only works on real devices running iOS 17+ with Xcode 15+ SDK. The target application must be running while this API is called.

    "},{"location":"reference/execute-methods/#arguments_1","title":"Arguments","text":"Name Type Required Description Example bundleId string yes Bundle identifier of the app to simulate the warning for com.great.app"},{"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_2","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

    "},{"location":"reference/execute-methods/#mobile-setpasteboard","title":"mobile: setPasteboard","text":"

    Sets the Simulator's pasteboard content to the given value. Does not work for real devices.

    "},{"location":"reference/execute-methods/#arguments_3","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_4","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_5","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.

    "},{"location":"reference/execute-methods/#arguments_6","title":"Arguments","text":"Name Type Required Description Example waitForWebviewMs number no Tells Appium for how long (in milliseconds) to wait for web view(s) to appear. 5000ms by default 10000"},{"location":"reference/execute-methods/#returned-result_3","title":"Returned Result","text":"

    The list of available context objects along with their properties:

    • id: The identifier of the context. The native context will be 'NATIVE_APP' and the webviews will be 'WEBVIEW_xxx'
    • title: The title associated with the webview content. Could be null
    • url: The url associated with the webview content. Could be null
    "},{"location":"reference/execute-methods/#mobile-installapp","title":"mobile: installApp","text":"

    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_7","title":"Arguments","text":"Name Type Required Description Example app string yes See the description of the appium: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 checkVersion bool no If set to true, 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 app value. No app install 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 and the app is installed if checkVersion was not provided or false, which is default behavior. true"},{"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_8","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

    "},{"location":"reference/execute-methods/#mobile-removeapp","title":"mobile: removeApp","text":"

    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_9","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

    "},{"location":"reference/execute-methods/#mobile-launchapp","title":"mobile: launchApp","text":"

    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_10","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_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_6","title":"Returned Result","text":"

    Either true if the app was successfully terminated, otherwise false

    "},{"location":"reference/execute-methods/#mobile-killapp","title":"mobile: killApp","text":"

    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_12","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

    "},{"location":"reference/execute-methods/#mobile-queryappstate","title":"mobile: queryAppState","text":"

    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_13","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_14","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_15","title":"Arguments","text":"Name Type Required Description Example applicationType string no The type of applications to list. Either System 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.

    "},{"location":"reference/execute-methods/#mobile-clearapp","title":"mobile: clearApp","text":"

    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_16","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.

    "},{"location":"reference/execute-methods/#mobile-startperfrecord","title":"mobile: startPerfRecord","text":"

    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.

    "},{"location":"reference/execute-methods/#arguments_17","title":"Arguments","text":"Name Type Required Description Example timeout number no The maximum count of milliseconds to record the profiling information. It is recommended to always limit the maximum duration of perf record operation, since the resulting logs are pretty huge and may easily exceed the free space on th local storage volume. 300000ms 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.

    "},{"location":"reference/execute-methods/#arguments_18","title":"Arguments","text":"Name Type Required Description Example profileName string no The name of existing performance profile to stop the recording for. Multiple recorders for different profile names could be executed at the same time. 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.

    "},{"location":"reference/execute-methods/#mobile-installcertificate","title":"mobile: installCertificate","text":"

    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_19","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_20","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.

    "},{"location":"reference/execute-methods/#mobile-listcertificates","title":"mobile: listCertificates","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-stoplogsbroadcast","title":"mobile: stopLogsBroadcast","text":"

    Stops the syslog broadcasting wesocket server previously started by mobile: startLogsBroadcast. This method will return immediately if no server is running.

    "},{"location":"reference/execute-methods/#mobile-batteryinfo","title":"mobile: batteryInfo","text":"

    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:

    • level: Battery level in range [0.0, 1.0], where 1.0 means 100% charge.
    • state: Battery state as an integer number. The following values are possible:
    • UIDeviceBatteryStateUnknown = 0
    • UIDeviceBatteryStateUnplugged = 1 // on battery, discharging
    • UIDeviceBatteryStateCharging = 2 // plugged in, less than 100%
    • UIDeviceBatteryStateFull = 3 // plugged in, at 100%
    "},{"location":"reference/execute-methods/#mobile-deviceinfo","title":"mobile: deviceInfo","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-getdevicetime","title":"mobile: getDeviceTime","text":"

    Returns the actual device time.

    "},{"location":"reference/execute-methods/#arguments_21","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 is YYYY-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.

    "},{"location":"reference/execute-methods/#mobile-pressbutton","title":"mobile: pressButton","text":"

    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_22","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.

    "},{"location":"reference/execute-methods/#arguments_23","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the target application com.apple.Preferences payload map yes Valid Apple Push Notification values. Read the 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_24","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. Either plain (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 with kHIDUsage_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_25","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_26","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_27","title":"Arguments","text":"Name Type Required Description Example type string no The biometric feature name. Either touchId 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

    "},{"location":"reference/execute-methods/#mobile-clearkeychains","title":"mobile: clearKeychains","text":"

    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_28","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.

    "},{"location":"reference/execute-methods/#arguments_29","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the destination app. com.mycompany.myapp access map yes One or more access rules to set. The following keys are supported: 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_30","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

    "},{"location":"reference/execute-methods/#mobile-setappearance","title":"mobile: setAppearance","text":"

    Set the device's UI appearance style.

    "},{"location":"reference/execute-methods/#arguments_31","title":"Arguments","text":"Name Type Required Description Example style string yes Either light 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_32","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_33","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_34","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_35","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_36","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_37","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same value as for mobile: 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_38","title":"Arguments","text":"Name Type Required Description Example keyboard map no On-screen keyboard properties. The name 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 calendarkey 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.

    "},{"location":"reference/execute-methods/#mobile-startaudiorecording","title":"mobile: startAudioRecording","text":"

    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.

    "},{"location":"reference/execute-methods/#arguments_39","title":"Arguments","text":"Name Type Required Description Example audioInput string or int yes The name of the corresponding audio input device to use for the capture. The full list of capture devices could be shown using 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_40","title":"Arguments","text":"Name Type Required Description Example timeLimitSec 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 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_41","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. Either ui (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). 360000ms by default 120000"},{"location":"reference/execute-methods/#returned-result_27","title":"Returned Result","text":"

    The API calls returns a map with the following entries:

    • results: The array of test results. Each item in this array conists of the following entries:
    • testName: Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')
    • passed: Did the tests pass?
    • crashed: Did the tests crash?
    • status: Test result status (e.g.: 'passed', 'failed', 'crashed')
    • duration: How long did the tests take (in seconds)
    • failureMessage: Failure message (if applicable)
    • location The geolocation of the test (if applicable)
    • code: The exit code of the process. 0 value marks a successful execution.
    • signal: The signal that terminated the process. Could be null (e.g.: SIGTERM)
    "},{"location":"reference/execute-methods/#mobile-installxctestbundle","title":"mobile: installXCTestBundle","text":"

    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_42","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_43","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' ])

    "},{"location":"reference/execute-methods/#mobile-viewportrect","title":"mobile: viewportRect","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-viewportscreenshot","title":"mobile: viewportScreenshot","text":"

    Takes a screenshot of the device viewport (see mobile: viewportRect)

    Unreliable

    This method is unreliable. We recommend using getScreenshot instead

    "},{"location":"reference/execute-methods/#returned-result_31","title":"Returned Result","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-swipe","title":"mobile: swipe","text":"

    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_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 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":"
    • swipeDown
    • swipeDownWithVelocity:
    • swipeUp
    • swipeUpWithVelocity:
    • swipeLeft
    • swipeLeftWithVelocity:
    • swipeRight
    • swipeRightWithVelocity:
    "},{"location":"reference/execute-methods/#mobile-scroll","title":"mobile: scroll","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_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 scroll on (e.g. the container). The active application element will be used instead if this parameter is not provided. 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_46","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. The active 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_47","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 double tap on. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb x number no Horizontal coordinate offset. 100 y number no Vertical coordinate offset. 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_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 long tap on. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes The float duration of press action in seconds 1.5 x number no Horizontal coordinate offset. 100 y number no Vertical coordinate offset. 100"},{"location":"reference/execute-methods/#examples_4","title":"Examples","text":"
    // c#\nDictionary<string, object> tfLongTap = new Dictionary<string, object>();\ntfLongTap.Add(\"elementId\", 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_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. The active 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(\"elementId\", 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_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 tap on. x and y tap coordinates will be calculated 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 Horizontal coordinate offset. 100 y number yes Vertical coordinate offset. 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_51","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(\"elementId\", ((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_52","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 if fromElementId 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_53","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no Internal element id (as hexadecimal hash string) to perform rotation on. The active application element will be used instead if this parameter is not provided. 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    \"elementId\", ((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_54","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 one or more taps. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb numberOfTaps number no The number of taps. 1 by default 2 numberOfTouches number no The number of touch points. 1 by default 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', {elementId: e.ref, numberOfTaps: 2, numberOfTouches: 1}\n
    • numberOfTaps=1, numberOfTouches=1 -> \"vanilla\" single tap
    • numberOfTaps=2, numberOfTouches=1 -> double tap
    • numberOfTaps=3, numberOfTouches=1 -> tripple tap
    • numberOfTaps=2, numberOfTouches=2 -> double tap with two fingers
    "},{"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_55","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.

    "},{"location":"reference/execute-methods/#arguments_56","title":"Arguments","text":"Name Type Required Description Example elementId string yes The internal element identifier (as hexadecimal hash string) to scroll to. The destination element must be located in a scrollable container and must be hittable. If the element is already present in the current viewport then no action is performed. fe50b60b-916d-420b-8728-ee2072ec53eb"},{"location":"reference/execute-methods/#mobile-resetlocationservice","title":"mobile: resetLocationService","text":"

    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 command mobile: 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

    "},{"location":"reference/execute-methods/#mobile-listconditioninducers","title":"mobile: listConditionInducers","text":"

    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

    "},{"location":"reference/execute-methods/#mobile-calibratewebtorealcoordinatestranslation","title":"mobile: calibrateWebToRealCoordinatesTranslation","text":"

    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.

    "},{"location":"reference/execute-methods/#returned-result_36","title":"Returned Result","text":"

    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

    "},{"location":"reference/execute-methods/#mobile-updatesafaripreferences","title":"mobile: updateSafariPreferences","text":"

    Updates preferences of Mobile Safari on Simulator

    "},{"location":"reference/execute-methods/#arguments_57","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 inspecting Library/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_58","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_59","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_60","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_61","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

    "},{"location":"reference/execute-methods/#mobile-keys","title":"mobile: keys","text":"

    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_62","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 with key 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.

    "},{"location":"reference/execute-methods/#mobile-lock","title":"mobile: lock","text":"

    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_63","title":"Arguments","text":"Name Type Required Description Example seconds number string no The number of seconds after which to unlock the device. Set to 0 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

    "},{"location":"reference/execute-methods/#mobile-shake","title":"mobile: shake","text":"

    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_64","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_65","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 then XCUIAccessibilityAuditTypeAll 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/execute-methods/#mobile-startxctestscreenrecording","title":"mobile: startXCTestScreenRecording","text":"

    Start a new screen recording via XCTest.

    Since this feature is based on the native implementation provided by Apple it provides the best quality for the least perfomance penalty in comparison to alternative implementations.

    Even though the feature is available for real devices there is no possibility to delete video files stored on the device yet, which may lead to internal storage overload. That is why it was put under the xctest_screen_record security feature flag if executed from a real device test.

    If the screen recording is already running this API is a noop.

    The feature is only available since Xcode 15/iOS 17.

    "},{"location":"reference/execute-methods/#arguments_66","title":"Arguments","text":"Name Type Required Description Example fps number no The Frames Per Second value for the resulting video. Providing higher values will create video files that are greater in size, but with smoother transitions. It is highly recommeneded to keep this value is range 1-60. 24 by default 60"},{"location":"reference/execute-methods/#returned-result_42","title":"Returned Result","text":"

    The API response consists of the following entries:

    Name Type Description Example uuid string Unique identifier of the video being recorded 1D988774-C7E2-4817-829D-3B835DDAA7DF fps numner FPS value 24 codec number The magic for the used codec. Value of zero means h264 video codec is being used 0 startedAt number The timestamp when the screen recording has started in float seconds since Unix epoch 1709826124.123"},{"location":"reference/execute-methods/#mobile-getxctestscreenrecordinginfo","title":"mobile: getXCTestScreenRecordingInfo","text":"

    Retrieves information about the current running screen recording. If no screen recording is running then null is returned.

    "},{"location":"reference/execute-methods/#returned-result_43","title":"Returned Result","text":"

    Same as for mobile: startXCTestScreenRecording

    "},{"location":"reference/execute-methods/#mobile-stopxctestscreenrecording","title":"mobile: stopXCTestScreenRecording","text":"

    Stops the current XCTest screen recording previously started by the mobile: startXctestScreenRecording API.

    An error is thrown if no screen recording is running.

    The resulting movie is returned as base-64 string or is uploaded to a remote location if corresponding options have been provided.

    The resulting movie is automatically deleted from the local file system FOR SIMULATORS ONLY. In order to clean it up from a real device it is necessary to properly shut down XCTest by calling POST /wda/shutdown API or by doing device factory reset.

    "},{"location":"reference/execute-methods/#arguments_67","title":"Arguments","text":"Name Type Required Description Example remotePath string no The path to the remote location, where the resulting .mov 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 encoded as Base64 and passed to 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_44","title":"Returned Result","text":"

    Same as for mobile: startXCTestScreenRecording plus the below entry:

    Name Type Description Example payload string Base64-encoded content of the recorded media file if remotePath parameter is empty/null or an empty string otherwise. The resulting media is expected to a be a valid QuickTime movie (.mov). YXBwaXVt...."},{"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.

    "},{"location":"reference/ios-predicate/#basic-comparisons","title":"Basic Comparisons","text":"
    • = , == - 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.

    "},{"location":"reference/ios-predicate/#boolean-value-predicates","title":"Boolean Value Predicates","text":"
    • TRUEPREDICATE - A predicate that always evaluates to TRUE .

    • FALSEPREDICATE - A predicate that always evaluates to FALSE.

    "},{"location":"reference/ios-predicate/#basic-compound-predicates","title":"Basic Compound Predicates","text":"
    • AND , && - Logical AND.

    • OR , || - Logical OR.

    • NOT , ! - Logical NOT.

    "},{"location":"reference/ios-predicate/#string-comparisons","title":"String Comparisons","text":"

    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
    "},{"location":"reference/ios-predicate/#aggregate-operations","title":"Aggregate Operations","text":"
    • 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).
    "},{"location":"reference/ios-predicate/#identifiers","title":"Identifiers","text":"
    • 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).

    "},{"location":"reference/ios-predicate/#literals","title":"Literals","text":"

    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.

    "},{"location":"reference/ios-predicate/#reserved-keywords","title":"Reserved Keywords","text":"

    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

    "},{"location":"reference/ios-predicate/#available-attributes","title":"Available Attributes","text":"

    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":"
    • Apple Developer documentation on Predicates
    • NSPredicate Cheat Sheet
    • Class Chain Queries Construction Rules
    "},{"location":"reference/locator-strategies/","title":"Locator Strategies","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 Example className 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 Description elementResponseAttributes 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":"
    • Check out the Overview to learn how the driver works
    • Go through the Installation steps to get set up
    • Follow the Device Preparation instructions to configure your test device
    • Browse the Reference documentation for everything exposed by the driver
    • Read the different Guides for a variety of instructions, tips and tricks
    • For contributions to the driver, refer to the Contributing page
    "},{"location":"contributing/","title":"Contributing","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 spec
    • PLATFORM_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
    "},{"location":"endpoints-wda/","title":"Endpoints wda","text":""},{"location":"endpoints-wda/#webdriveragent-jsonwp-endpoints","title":"WebDriverAgent JSONWP Endpoints","text":""},{"location":"endpoints-wda/#session-less-commands","title":"Session-less commands","text":"method endpoint req params opt params POST /wda/homescreen GET /source accessible GET /inspector GET /inspector.js GET /screenshot POST /session desiredCapabilities GET /status GET /* ** POST /* ** PUT /* ** DELETE /* **"},{"location":"endpoints-wda/#session-commands","title":"Session commands","text":"method endpoint req params opt params GET /alert/text POST /alert/accept POST /alert/dismiss POST /wda/deactivateApp duration POST /timeouts * GET /source accessible GET /element/:uuid/enabled GET /element/:uuid/rect GET /element/:uuid/attribute/:name GET /element/:uuid/text GET /element/:uuid/displayed GET /wda/element/:uuid/accessible GET /element/:uuid/name POST /element/:uuid/value value POST /element/:uuid/click POST /element/:uuid/clear POST /wda/element/:uuid/doubleTap POST /wda/element/:uuid/touchAndHold duration POST /wda/element/:uuid/scroll name, direction, predicateString, toVisible POST /uiaElement/:uuid/value value POST /wda/element/:uuid/dragfromtoforduration fromX, fromY, toX, toY, duration POST /wda/tap/:uuid x, y POST /wda/keys value GET /window/size POST /element using, value POST /elements using, value GET /wda/uiaElement/:uuid/getVisibleCells POST /element/:uuid/element using, value POST /element/:uuid/elements using, value GET /orientation POST /orientation orientation GET /screenshot POST /wda/touch_id match

    * 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 GET /location POST /location location POST /log type GET /log/types GET /context POST /context name GET /contexts 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:

    • Native testing is based on Apple's XCTest framework and Appium's fork of Facebook's WebDriverAgent server (the original project is not supported anymore)
      • In native mode, the driver operates in scope of WebDriver W3C protocol with several platform-specific extensions
    • Webview communication is done via Webkit remote debugger protocol
      • In webview mode, the driver can only operate in scope of the obsolete JSONWP protocol
    • Real device communication is provided by the appium-ios-device library
    • Simulator communication is provided by the appium-ios-simulator library
    "},{"location":"guides/attach-to-running-wda/","title":"Attach to a Running WebDriverAgent","text":"

    The 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.

    "},{"location":"guides/attach-to-running-wda/#usage","title":"Usage","text":"
    1. Start a WebDriverAgent application on a device
    2. Start an XCUITest driver session with appium:webDriverAgentUrl capability

    Please 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.

    "},{"location":"guides/audio-capture/","title":"Audio Capture","text":"

    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
    "},{"location":"guides/audio-capture/#server-requirements","title":"Server Requirements","text":"
    • The host machine must have 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:

      • macOS < 13: System Preferences -> Security & Privacy -> Privacy -> Microphone
      • macOS 13+: System Settings -> Privacy & Security -> Microphone

      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.

    "},{"location":"guides/audio-capture/#simulator-setup","title":"Simulator Setup","text":"

    The following steps are necessary to setup iOS Simulator audio capture:

    • Install Soundflower
    • Redirect Simulator audio output to Soundflower: from the main Simulator menu, select I/O -> Audio Output -> Soundflower (2ch)
    • In terminal, run 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
    • Test that your setup works as expected. Run any audio playback in Simulator and execute the following command in Terminal, replacing the -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.
    "},{"location":"guides/audio-capture/#real-device-setup","title":"Real Device Setup","text":"

    The following steps are necessary to setup iOS Real Device audio capture:

    • Connect your device to the Mac host with a cable
    • Open the Audio MIDI Setup application
      • Via Finder: Applications -> Utilities -> Audio MIDI Setup
      • Via terminal: open -a /System/Applications/Utilities/Audio\\ MIDI\\ Setup.app
    • Find your phone in the list of devices there and click Enable next to it
    • In terminal, run ffmpeg -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
    • Test that your setup works as expected. Run any audio playback on the device and execute the following command in Terminal, replacing the -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":"
    • https://github.com/appium/appium-xcuitest-driver/pull/1207
    • https://www.macobserver.com/tips/quick-tip/iphone-audio-input-mac/
    • http://www.lorisware.com/blog/2012/04/28/recording-iphone-emulator-video-with-sound/
    "},{"location":"guides/ci-setup/","title":"Continuous Integration","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:

    1. Keychains can be set to have no timeout and be unlocked manually once. This can be done using the keychain access application. Sometimes keychains still lock themselves though and this approach is not recommended.
    2. It is possible to create a second keychain, which just stores the required certificate to sign the WebDriverAgent. The issue with this approach is that Codesign wants to unlock all listed keychains regardless of the specified keychain, thus leading to a password prompt. This can be avoided by setting the default keychain and basically hiding the login keychain at the start of the build. See this Stackoverflow article for how to utilize this approach. It is impractical when running other build jobs simultaneously.
    3. Stick with the existing keychains as in approach 1, but explicitly call unlock keychain before each build. This can be done using fastlane unlock_keychain or by using security unlock-keychain directly. The password can be saved as a CI variable/secret or on the machine itself.

    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.

    "},{"location":"guides/clipboard/","title":"Get/Set Clipboard","text":"

    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.

    "},{"location":"guides/clipboard/#get-clipboard","title":"Get Clipboard","text":"

    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 type
      • On simulators, common values are app, data, groups, but a custom one can also be provided
      • On real devices, the only accepted value is documents. All others are treated as Format 2
        • This value can only be specified for apps that have the UIFileSharingEnabled 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
      • On real devices, if <container-type> is set to documents, this path will be mapped to On My iPhone/<app name> in the Files app
    "},{"location":"guides/file-transfer/#format-2","title":"Format 2","text":"
    @<app-bundle-id>/<path-to-file-or-folder>\n
    • On simulators, the implicit <container-type> is set to app.
    • On real device, only apps with the UIFileSharingEnabled flag set to true in their info.plist can be mounted. You can use the mobile: listApps extension to identify such apps.
    "},{"location":"guides/file-transfer/#format-3","title":"Format 3","text":"
    <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.

    "},{"location":"guides/file-transfer/#examples","title":"Examples","text":""},{"location":"guides/file-transfer/#pullfile","title":"pullFile","text":"

    This example pulls a file present in Files -> On My iPhone -> Keynote:

    Top On My iPhone Keynote JS (WebdriverIO)Ruby
    let 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)Ruby
    let 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 (/).

    JS (WebdriverIO)Ruby
    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":"
    • https://stackoverflow.com/questions/1108076/where-does-the-iphone-simulator-store-its-data
    • https://stackoverflow.com/questions/48884248/how-can-i-add-files-to-the-ios-simulator
    • https://apple.stackexchange.com/questions/299413/how-to-allow-the-files-app-to-save-to-on-my-iphone-or-to-on-my-ipad-in-ios/299565#299565
    "},{"location":"guides/input-events/","title":"About iOS Input Events","text":""},{"location":"guides/input-events/#what-are-input-events","title":"What Are Input Events","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:

    • Create a new XCPointerEventPath instance and initialize it for touch at the starting point
    • Add a new liftUp event at 0.125s offset using liftUpAtOffset: method
    • Add the generated event path object to XCSynthesizedEventRecord instance using addPointerEventPath: method
    • Execute the events using synthesizeWithError: method of XCSynthesizedEventRecord instance and control the returned error

    There are several limitations to these APIs:

    • Each 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 ignored
    • Each XCPointerEventPath instance can only be initialized for a particular pointer type: touch, mouse (since Xcode 10.2) or keyboard (since Xcode 10.2)
    • Events can only be added with increasing offset values to an existing XCPointerEventPath instance
    "},{"location":"guides/input-events/#more-complicated-actions","title":"More Complicated Actions","text":"

    Unfortunately, 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:

    • Create a two XCPointerEventPath instances and init them for touch at the starting point
    • Add a moveToPoint event at 0.525s offset using moveToPoint: method to each path
    • Add a liftUp eventa at 0.525s offset using liftUpAtOffset: method to each path
    • Add the generated event paths to XCSynthesizedEventRecord instance using addPointerEventPath: method
    • Execute the events using synthesizeWithError: method of XCSynthesizedEventRecord instance and control the returned error
    "},{"location":"guides/input-events/#further-reading","title":"Further Reading","text":"

    Unfortunately, there is no information on this topic at all (private API \u00af\\_(\u30c4)_/\u00af). Consider visiting the following resources:

    • https://github.com/appium/WebDriverAgent/tree/master/PrivateHeaders/XCTest
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CMultiTouchActionsIntegrationTests.m
    • https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m
    "},{"location":"guides/install-certificate/","title":"Self-Signed Certificates","text":"

    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
    "},{"location":"guides/multiple-xcode-versions/","title":"Managing Multiple Xcodes","text":"

    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:

    1. Set the default Xcode
      sudo xcode-select -s /Applications/Xcode13.app/Contents/Developer\n
    2. Run Appium
      appium\n
    "},{"location":"guides/multiple-xcode-versions/#environment-variable","title":"Environment variable","text":"

    No privileges needed, affects only the current shell, so Appium should be started within that shell.

    Assuming you want to choose /Applications/Xcode12.app:

    1. Set the DEVELOPER_DIR environment variable
      export DEVELOPER_DIR=/Applications/Xcode12.app/Contents/Developer\n
    2. Run Appium
      appium\n
    "},{"location":"guides/parallel-tests/","title":"Testing in Parallel","text":"

    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.

    "},{"location":"guides/parallel-tests/#important-real-device-capabilities","title":"Important Real Device Capabilities","text":"
    • 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.
    "},{"location":"guides/parallel-tests/#important-simulator-capabilities","title":"Important Simulator Capabilities","text":"
    • Either 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.
    "},{"location":"guides/run-prebuilt-wda/","title":"Run Prebuilt WebDriverAgentRunner","text":"

    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.

    "},{"location":"guides/run-prebuilt-wda/#how-xcodebuild-works","title":"How 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.

    "},{"location":"guides/run-prebuilt-wda/#capabilities-for-prebuilt-wda-with-appiumusexctestrunfile-appiumuseprebuiltwda-or-appiumprebuildwda","title":"Capabilities for Prebuilt WDA with appium:useXctestrunFile, appium:usePrebuiltWDA or appium:prebuildWDA","text":"

    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.

    appium:prebuildWDA lets the XCUITest driver build the WDA before running it, then the session will be handled with appium:usePrebuiltWDA. It might have additional building steps than with appium:derivedDataPath and appium:usePrebuiltWDA combination, but it could help appium:usePrebuiltWDA to not manage the WDA project.

    "},{"location":"guides/run-prebuilt-wda/#capabilities-for-prebuilt-wda-with-appiumprebuiltwdapath","title":"Capabilities for Prebuilt WDA with appium:prebuiltWDAPath","text":"

    Run Preinstalled WebDriverAgentRunner provides appium:prebuiltWDAPath capability. It also achieves the same thing, but the appium:prebuiltWDAPath does not use xcodebuild. Please check the link for more details.

    "},{"location":"guides/run-prebuilt-wda/#download-prebuilt-wda","title":"Download Prebuilt WDA","text":"

    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.

    For simulator environment, the prebuilt packages available on Building WebDriverAgent may not work for all environment as different building environment. We recommend preparing the Build directory, which is generated by -derivedDataPath xcodebuild argument, on your test running environment and re-use it.

    "},{"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 and a simulator. This allows you to start a session without the xcodebuild command execution, improving the session startup performance.

    Warning

    iOS/tvOS 17+ speicic:

    This method currently works over devicectl for iOS 17+ with Xcode 15+ environment since XCUITest driver v7.5.0. This may not work for tvOS 17+. iOS/tvOS 16 and lower ones work over appium-ios-device directly.

    "},{"location":"guides/run-preinstalled-wda/#capabilities","title":"Capabilities","text":"
    • Required
      • appium:usePreinstalledWDA
    • Optional
      • appium:updatedWDABundleId
      • appium:updatedWDABundleIdSuffix
        • Since XCUITest driver v7.6.0
      • appium:prebuiltWDAPath
    "},{"location":"guides/run-preinstalled-wda/#install-webdriveragent","title":"Install WebDriverAgent","text":""},{"location":"guides/run-preinstalled-wda/#using-xcode","title":"Using Xcode","text":"

    Running a test for the WDA package in Xcode is the easiest way to prepare the device environment:

    1. Open WebDriverAgent project in Xcode
      • You can run appium driver run xcuitest open-wda if using XCUITest driver 4.13 or newer
    2. Select the WebDriverAgentRunner scheme
    3. Select the scheme as Product -> Scheme -> WebDriverAgentRunner (or WebDriverAgentRunner_tvOS for tvOS)
    4. Select your device in Product -> Destination
    5. Select Product -> Test to build and install the WDA app

    If 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, ios-app-signer can install the WebDriverAgent package.

    Some tools let you set an arbitrary bundle identifier (CFBundleIdentifier for the Info.plist) and sign it with the bundle identifier. It may not have .xctrunner as the bundle identifier. XCUITest driver automatically adds the .xctrunner suffix to the provided bundle identifier unless a different suffix is specified by the appium:updatedWDABundleIdSuffix capability. If the value is an empty string, then no suffix will be added to the provided bundle identifier.

    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.

    "},{"location":"guides/run-preinstalled-wda/#additional-requirement-for-ios-17tvos17","title":"Additional requirement for iOS 17+/tvOS17+","text":"

    To launch the WebDriverAgentRunner package with xcrun devicectl device process launch it should not have Frameworks/XC** files.

    For example, after building the WebDriverAgent with Xcode with proper sign, it generates /Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app. Then you can remove Frameworks/XC** in WebDriverAgentRunner-Runner.app like rm Frameworks/WebDriverAgentRunner-Runner.app/XC**.

    Configuring appium:prebuiltWDAPath to the /Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app would install the WebDriverAgentRunner-Runner.app, which has no Frameworks/XC** to the target device and launch it with devicectl command as part of appium:usePreinstalledWDA functionality.

    "},{"location":"guides/run-preinstalled-wda/#launch-the-session","title":"Launch the Session","text":"

    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.

    # Ruby\ncapabilities: {\n  \"platformName\": \"ios\",\n  \"appium:automationName\": \"xcuitest\",\n  \"appium:udid\": \"<udid>\",\n  \"appium:usePreinstalledWDA\": true,\n  \"appium:updatedWDABundleId\": \"io.appium.wda\"\n  \"appium:updatedWDABundleIdSuffix\": \"\"\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 io.appium.wda bundle ID (it does not have .xctrunner), the session will launch the WebDriverAgent process without xcodebuild.

    "},{"location":"guides/run-preinstalled-wda/#set-appiumprebuiltwdapath","title":"Set appium:prebuiltWDAPath","text":"

    If the appium:prebuiltWDAPath capability is provided with a 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 usually, which is why it is necessary to (re)install them for every test session. The test bundle should be signed properly for real devices.

    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.

    "},{"location":"guides/touch-id/","title":"Touch ID","text":"

    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":"
    • Set the capability appium:allowTouchIdEnroll to true.
    • When the Simulator starts, Touch ID enrollment will be enabled by default
    • You can toggle Touch ID enrollment by calling the mobile: enrollBiometric extension

    Note

    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":"
    • Real devices with iOS/iPadOS 15+ show an overlay with the text Automation Running Hold both volume buttons to stop while WebDriverAgent is running. This is a known limitation of the XCTest framework. Note that screenshotting functionality is not affected (i.e. the overlay is not visible on taken screenshots).
    • Real devices with iOS/iPadOS 15+ require passcode or Touch ID when starting a new session. A workaround for this is to disable passcode/Touch ID on the device.
    • After many failures on a real device, it could transition to a state where connections are no longer being accepted. Rebooting the device can help remedy this problem. Please read this issue for more details.
    • shake is implemented via AppleScript and works only on Simulator due to lack of support from Apple
    "},{"location":"guides/troubleshooting/#interact-with-dialogs-managed-by-comapplespringboard","title":"Interact with dialogs managed by com.apple.springboard","text":"

    System dialogs, such as permission dialogs, might not be interactable directly when the active application is not com.apple.springboard. Despite a similar look, dialogs belonging to the active session application (e.g. initially passed as appium:app or appium:bundleId capability value) do not require such adjustment.

    XCUITest driver offers a few methods to handle them.

    • Start a session without appium:app nor appium:bundleId. Then XCUITest driver attempts to get the current active application. This requires you to start an application after a new session request with mobile: installApp to install an app if needed and mobile: launchApp/mobile: activateApp, but it could automatically change the active application with com.apple.springboard or activated application on the top. (Note that the automatic detection could have a delay, thus each action could take more time.)
      • When a permission alert exists on the top, it could select the com.apple.springboard
      • When another application is on the top by accepting/denying the system alert, or mobile: activateApp, the application would be selected as an active application.
    • mobile: alert
    • defaultActiveApplication setting in Settings.
      • e.g. With the Appium Ruby client
        # Interacting with the test target\ndriver.settings.update({defaultActiveApplication: \"com.apple.springboard\"})\n# to accept the alert\ndriver.find_element(\"accessibility_id\", \"Allow Once\").click\ndriver.settings.update({defaultActiveApplication: \"auto\"})\n# keep interacting with the test target\n
    • Enable appium:autoAcceptAlerts/appium:autoDismissAlerts, or interact with alerts via User Prompts in WebDriver endpoints
      • e.g. driver.switch_to.alert.accept with the Appium Ruby client
      • It might be necessary to coordinate element selection via acceptAlertButtonSelector/dismissAlertButtonSelector settings in Settings
    • Activate com.apple.springboard with mobile: activateApp before interacting with dialogs

    mobile: activeAppInfo helps to understand what application (bundleId) is considered as active for the XCUITest driver.

    "},{"location":"guides/troubleshooting/#leftover-application-data-on-real-devices","title":"Leftover Application Data on Real Devices","text":"

    There might be a situation where application data is present on the real device, even if the application itself is not installed. This could happen if:

    • The app is in an offloaded state
    • The application state is cached
    • There was an unexpected failure while installing the app. An example of such failure is the ApplicationVerificationFailed which happens while installing an app signed with an invalid provisioning profile.

    In the above cases, the application identifier will not be listed in the output of mobile: listApps, and it will not be detected by mobile: isAppInstalled. Setting appium:fullReset or appium:enforceAppInstall capabilities to true also will not help clear this data.

    The only way to completely get rid of the cached application data is to call the mobile: removeApp command with the appropriate bundle identifier.

    The driver does automatically try to resolve application installs that failed because of the MismatchedApplicationIdentifierEntitlement error. However, in cases when the previously installed application's provisioning profile is different from what currently the driver is trying to install, and if you explicitly set the driver to not perform application uninstall, then consider calling mobile: removeApp before the MismatchedApplicationIdentifierEntitlement error occurs. Example steps can be as follows:

    1. Start a session without appium:app and appium:bundleId capabilities
    2. Call mobile: removeApp for the target application's bundle id
    3. Install the test target with mobile: installApp
    4. Launch the application with mobile: launchApp or mobile: activateApp
    "},{"location":"guides/troubleshooting/#weird-state","title":"Weird State","text":""},{"location":"guides/troubleshooting/#real-device-stops-responding","title":"Real Device Stops Responding","text":"

    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.

    "},{"location":"guides/troubleshooting/#real-device-security-settings","title":"Real Device Security Settings","text":"

    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.

    "},{"location":"guides/troubleshooting/#simulator-resetting","title":"Simulator Resetting","text":"

    When testing on simulators, the driver tries to leave the simulator state as it found it:

    • If no udid is provided, the driver will create a new iOS simulator, run tests on it, and then delete the simulator
    • If a specific udid is provided for a simulator that is not running, the driver will boot the specified simulator, run tests on it, and then shut the simulator down
    • If a specific udid is provided for a simulator that is running, the driver will connect to the existing simulator, run tests, and then leave the simulator running

    You can use the appium:noReset capability to adjust this behavior: setting it to true will leave the simulator running at the end of a test session.

    "},{"location":"guides/troubleshooting/#caching-issues-during-build","title":"Caching Issues During Build","text":"

    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.

    "},{"location":"guides/tvos/#setup","title":"Setup","text":"

    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.

    "},{"location":"guides/tvos/#basic-actions","title":"Basic Actions","text":"

    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.

    JavaJS (WebdriverIO)PythonRuby
    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":"
    • Consider using wait methods, since tvOS also has animation
    • The menu button works as back for iOS context in tvOS
    "},{"location":"guides/tvos/#known-limitations","title":"Known Limitations","text":"
    • Gesture commands do not work for tvOS. Some commands such as pasteboard do not work as well.
    "},{"location":"guides/tvos/#related-tickets","title":"Related Tickets","text":"
    • https://github.com/appium/appium/pull/12401
    • https://github.com/appium/appium-xcuitest-driver/pull/911
    • https://github.com/appium/appium-xcuitest-driver/pull/931
    • https://github.com/appium/appium-xcuitest-driver/pull/939
    • https://github.com/appium/WebDriverAgent/pull/163
    "},{"location":"guides/wda-custom-server/","title":"Manage WebDriverAgent by Yourself","text":"

    The 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

    • The steps below are not necessary if default Appium capabilities are used. The server will do everything for you, however, you will not have so much control over WDA.
    • It is mandatory to have SSH or physical access to the machine to which the device under test is connected.
    "},{"location":"guides/wda-custom-server/#wda-setup","title":"WDA Setup","text":"

    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":"
    • The process does not have direct access to keychain if it is executed by a continuous integration agent, so the keychain must be prepated before compiling WDA for real device, otherwise codesigning will fail. Check the CI Setup documentation for details.
    • The xcodebuild and iproxy processes are killed before restart to make sure compilation succeeds, in case the processes are frozen
    • A dedicated bash 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 interaction
    • The value of the BUILD_ID environment variable is changed to avoid the CI agent killing the background process after the job is finished
    • The isRunning check is done by verifying the actual network endpoint
    • The output of daemonized processes is logged, so it is possible to track errors and unexpected failures. The content of the log files is automatically added to the actual error message if the server fails to (re)start.
    • Real device id can be parsed from system_profiler SPUSBDataType output
    • Simulator id can be parsed from xcrun simctl list output
    • The UrlChecker class is imported from the org.openqa.selenium.net package
    "},{"location":"installation/","title":"Installation","text":"

    Info

    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:

    • Only macOS is supported as the host platform
    • Xcode and Xcode Developer Tools must be installed
      • The Appium team usually needs some time to add support for the most recent Xcode/iOS versions, especially beta versions (check the Xcode/iOS version support section)
    • If automating real devices, additional manual configuration is required. Please check the Real Device Configuration document for more details.
    • Webviews must be debuggable in order to test them. If it is not possible to connect to your webview(s) using Safari remote debugger, then the driver will not be able to identify them.
    "},{"location":"installation/requirements/#optional-dependencies","title":"Optional Dependencies","text":"
    • 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 interactions
    • WIX AppleSimulatorUtils can be used to improve some Simulator interactions
    • py-ios-device is required in several mobile: extensions, and can improve the general testing experience for real devices
    "},{"location":"installation/requirements/#validate-dependencies-using-doctor","title":"Validate Dependencies Using Doctor","text":"

    Since 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.

    "},{"location":"installation/requirements/#xcodeios-version-support","title":"Xcode/iOS Version Support","text":"

    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.0

    The 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.2

    The 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.

    • Settings -> General -> Keyboard -> Auto-Correction is turned OFF
    • Settings -> General -> Keyboard -> Predictive Text is turned OFF
    • The keyboard tutorial is marked as complete
    • (Simulator Only) Software keyboard is turned ON
    "},{"location":"preparation/#manual-adjustments","title":"Manual Adjustments","text":"

    Unfortunately, not all configuration can be done automatically, and some changes must be applied manually.

    "},{"location":"preparation/#accessibility-settings","title":"Accessibility Settings","text":"
    • To avoid miscalculation of element coordinates, please make sure the zoom preference is turned off in Settings -> Accessibility -> Zoom.
    • Some accessibility settings may expose additional view elements. Appium does not modify these settings automatically, since they could affect the way your application under test performs. Please change them manually if needed. Note that the available accessibility content depends on the OS version.
      • Settings -> Accessibility -> Spoken Content -> Speak Selection
    "},{"location":"preparation/#webview-testing","title":"Webview Testing","text":"
    • Webviews on iOS/iPadOS 16.4 or above may require additional configuration from the application developer. Specifically, the destination 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.
    • WebViews on iOS/iPadOS below version 16.4 must have the get-task-allow entitlement present as true in the application manifest.
    • Starting from iOS/iPadOS 16.4, the Google Chrome browser also supports webview testing. This feature requires Chrome version 115 or newer. Please read the Chrome Developer documentation page for details on the necessary configuration.
    "},{"location":"preparation/#real-devices","title":"Real Devices","text":"

    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:

    • Use the xcodeOrgId and xcodeSigningId capabilities:
      {\n  \"appium:xcodeOrgId\": \"<Team ID>\",\n  \"appium:xcodeSigningId\": \"Apple Developer\"\n}\n
    • Create a .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.
      • To find this string (your Team ID), sign in to developer.apple.com/account, and click Membership in the sidebar. Your Team ID appears in the Membership Information section under the team name. You can also find your Team ID listed under the \"Organizational Unit\" field in your iPhone Developer certificate in your keychain.
    • 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.

    "},{"location":"preparation/prov-profile-basic-manual/","title":"Basic Manual Configuration","text":"

    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.

    "},{"location":"preparation/prov-profile-full-manual/","title":"Full Manual Configuration","text":"

    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:

    • In the terminal, open the directory where WDA is located. Run the following to set the project up:
      mkdir -p Resources/WebDriverAgent.bundle\n
    • Open WebDriverAgent.xcodeproj in Xcode. This will likely open a screen with an empty editor.
    • In the file browser on the left side, select the root WebDriverAgent project, which will open it in the editor. Then, under Targets, select WebDriverAgentRunner (or WebDriverAgentRunner_tvOS for tvOS), and switch to the Signing & Capabilities tab.
    • 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:

      • Select the scheme as Product -> Scheme -> WebDriverAgentRunner
      • Select your real device in Product -> Destination
      • Select Product -> Test to build and install the WDA app

    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.

    "},{"location":"preparation/real-device-config/","title":"Real Device Configuration","text":"

    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:

    • Devices need to be trusted. This can be done by opening Xcode and afterwards physically connecting the device under test to the computer. The device should have a popup asking to trust the computer, which you should accept.
    • Devices using iOS/iPadOS 16 or above require enabling Developer Mode. Please read Apple's documentation on Developer Mode for more details. devmodectl streaming CLI on macOS 13+ and installing development signed apps also help enabling the mode.
    • After enabling Developer Mode (if applicable), please turn on Settings -> Developer -> Enable UI Automation
    • Webviews will not be testable unless the Safari Inspector is enabled. Please turn it on in Settings -> Safari -> Advanced -> Web Inspector. Similarly, you may want to turn on the adjacent option Settings -> Safari -> Advanced -> Remote Automation.

    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.

    • Basic Automatic Configuration: the easiest approach, but requires you to have a paid Apple Developer account

    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:

    • The WDA project is included in 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.
    • If using XCUITest driver v4.13.0 or newer, you can run the 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:

    • Basic Manual Configuration: create a new project, then use its provisioning profile and bundle ID
    • Full Manual Configuration: associate the provisioning profile directly with the WDA project
    • Manual Configuration for a Generic Device: manually run xcodebuild to build WDA, then manually install it
    "},{"location":"preparation/real-device-config/#validating-the-wda-install","title":"Validating the WDA Install","text":"

    Once 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

    "},{"location":"preparation/real-device-config/#create-an-offline-provisioning-profile","title":"Create an Offline Provisioning Profile","text":"

    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":"preparation/real-device-config/#tune-webdriveragent-to-improve-session-startup-performance","title":"Tune WebDriverAgent to improve session startup performance","text":"

    Running xcodebuild every time takes much longer time to complete a session startup. XCUITest driver offers a few methods to improve the performance with, or without using xcodebuild.

    Some might require deeper understanding of iOS development environment, but they help to improve speedup your test execution speed.

    • Run Preinstalled WebDriverAgentRunner
    • Run Prebuilt WebDriverAgentRunner
    • Attach to a Running WebDriverAgent
    "},{"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 Description platformName 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:initialDeeplinkUrl A deeplink URL used to run either the application assigned to appium:bundleId, or the default application assigned to handle the particular deeplink protocol if appium:bundleId is not set. If provided in combination with browserName=safari then makes Safari to start with the given URL preloaded, which speeds up the session startup. The value of appium:initialSafariUrl capability is ignored in such case. An error is thrown on session init if either the value of the capability is not a valid URL, or XCTest was not able to associate it with any existing app, or the actual iOS version is below 16.4 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 30000ms 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 it. This bundle id must be associated with a valid provisioning profile. The default value is com.facebook.WebDriverAgentRunner. 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 Overrides the folder that should be used for derived data when performing a source building with xCode. xCode stores all build and test artifacts under this file system root. Use this capability to set a unique path while running parallel tests or to have more control over built artifacts, for example if you'd like to use preinstalled or prebuilt WDA to reduce the session startup time. If the capability is not set then Xcode will store the derived data in the default root taken from preferences (usually a subfolder of /Users/<username>/Library/Developer/Xcode/DerivedData). /tmp/wda-861563ec 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 by xcodebuild. It does not work for webDriverAgentUrl and usePreinstalledWDA capabilities since they handle WebDriverAgent without the xcodebuild. Defaults to 2 for simulators and 1 for real devices. 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:prebuildWDA Enables prebuilding if the WebDriverAgentRunner application before running the WDA app. With this capability, XCUITest driver builds the WDA project first, then it handles the session as appium:usePrebuiltWDA true behavior. Defaults to false. true appium:usePrebuiltWDA Skips the build phase of running the WDA app. Building is then the responsibility of the user. appium:derivedDataPath let the session use the path as -derivedDataPath argument for xcodebuild command. Defaults to false. true appium:prebuiltWDAPath The full path to the prebuilt WebDriverAgent-Runner application package to be installed if appium:usePreinstalledWDA capability is enabled. The package's bundle identifier could be customized via appium:updatedWDABundleId capability. /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 or simulators via simctl tool (since driver version 7.4.0). If appium:prebuiltWDAPath is provided, XCUITest driver will install WebDriverAgent-Runner app from the given path before launching the application. The preinstalled WebDriverAgent package must be built by Xcode 12+. The default target bundle identifier is com.facebook.WebDriverAgentRunner.xctrunner, although it could be customized by providing the appium:updatedWDABundleId capability value (the .xctrunner suffix is added automatically). Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to false. true or false appium:updatedWDABundleIdSuffix Add suffix for the bundle id provided by the appium:updatedWDABundleId capability value in appium:usePreinstalledWDA capability usage since XCUITest driver v7.6.0. This is for an advanced usage that sets an arbitrary CFBundleIdentifier for prebuilt WebDriverAgent package to sign with the bundle identifier's certificate. For example, if you would need to sign a WebDriverAgent package with io.appium.wda bundle identifier's certificate, the WebDriverAgent's package must have the same bundle identifier as CFBundleIdentifier. Then, the WebDriverAgent package can be launched by io.appium.wda, which does not have .xctrunner. Then \"appium:updatedWDABundleIdSuffix\": \"\" (an empty string) helps. Please read Run Preinstalled WebDriverAgentRunner for more details. Defaults to .xctrunner. \"\", \".customsuffix\" 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 appium:appLaunchStateTimeoutSec Allows to set the timeout in float seconds for the application state change on the session startup in range (0, 240) exclusively. The default value for it in XCTest is 60 seconds, which means WDA would throw an exception if the application under test is not ready for accessibility interactions in 60s after its process has started. Important: The fact the application's user interface is visible does not necessarily mean it could be immediately interacted with by XCTest. The latter must ensure the app's main thread is also idling. Setting this capability to a lower value might help to avoid prolonged test startup with problematic apps taking too much time to be ready and fail fast. It is not advised to increase the capability value above 60 seconds, rather consider fixing the affected application itself. Too low values though may cause unexpected app startup failures. The capability does not have an effect if the app under test is not (re)started at the beginning of the session. 10.5"},{"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. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup for this capability to take effect on real devices. { 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:webviewAtomWaitTimeout The time to wait, in ms, for each atom execution timeout of webviews in MobileSafari or hybrid apps. Defaults to 120000. If the value was zero or less, the timeout keeps the default value. 20000 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 Allow javascript to open new windows in Safari. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. true or false appium:safariIgnoreFraudWarning Prevent Safari from showing a fraudulent website warning. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. true or false appium:safariOpenLinksInBackground Whether Safari should allow links to open in new windows. Default keeps the current sim setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. 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 Type contentType? 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 Description content 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

    "},{"location":"reference/commands/#getgeolocation","title":"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.

    For iOS 17+ simulators and real devices, this method will return the result of mobile: getSimulatedLocation extension if the simulated location was previously set by mobile: setSimulatedLocation.

    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>

    "},{"location":"reference/commands/#setgeolocation","title":"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":"reference/commands/#arguments_2","title":"Arguments","text":"Name Type Description 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>

    "},{"location":"reference/commands/#startrecordingscreen","title":"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 Type options? 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 Type options? 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.

    "},{"location":"reference/commands/#getsize","title":"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

    "},{"location":"reference/commands/#background","title":"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 Type seconds any"},{"location":"reference/commands/#returned-result_8","title":"Returned Result","text":"

    unknown

    "},{"location":"reference/commands/#queryappstate","title":"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

    "},{"location":"reference/commands/#islocked","title":"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

    "},{"location":"reference/commands/#lock","title":"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 Type seconds? any"},{"location":"reference/commands/#returned-result_11","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#unlock","title":"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

    "},{"location":"reference/commands/#mobileshake","title":"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

    "},{"location":"reference/commands/#getstrings","title":"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 Description language? 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/#setvalueimmediate","title":"setValueImmediate","text":"

    Deprecated

    This method is deprecated

    POST /session/:sessionId/appium/element/:elementId/value

    "},{"location":"reference/commands/#arguments_8","title":"Arguments","text":"Name Type text any"},{"location":"reference/commands/#returned-result_15","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#keys","title":"keys","text":"

    Deprecated

    This method is deprecated. Please use setValue instead

    POST /session/:sessionId/keys

    Send keys to the app

    "},{"location":"reference/commands/#arguments_9","title":"Arguments","text":"Name Type value any"},{"location":"reference/commands/#returned-result_16","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#receiveasyncresponse","title":"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_10","title":"Arguments","text":"Name Type response any"},{"location":"reference/commands/#returned-result_17","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#toggleenrolltouchid","title":"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_11","title":"Arguments","text":"Name Type Default value enabled? any true"},{"location":"reference/commands/#returned-result_18","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#touchid","title":"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_12","title":"Arguments","text":"Name Type Default value match any true"},{"location":"reference/commands/#returned-result_19","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#asyncscripttimeout","title":"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_13","title":"Arguments","text":"Name Type ms any"},{"location":"reference/commands/#returned-result_20","title":"Returned Result","text":"

    null

    "},{"location":"reference/commands/#getlocation","title":"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_21","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

    "},{"location":"reference/commands/#returned-result_22","title":"Returned Result","text":"

    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_23","title":"Returned Result","text":"

    any

    "},{"location":"reference/element-attributes/","title":"Element Attributes","text":"

    The XCUITest driver supports the following element attributes:

    Name Description Example name 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.

    "},{"location":"reference/execute-methods/#arguments","title":"Arguments","text":"Name Type Required Description Example elementId (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-sendmemorywarning","title":"mobile: sendMemoryWarning","text":"

    Simulates sending of Low Memory warning to the target application. It might be useful to verify the didReceiveMemoryWarning API in the application under test. This feature only works on real devices running iOS 17+ with Xcode 15+ SDK. The target application must be running while this API is called.

    "},{"location":"reference/execute-methods/#arguments_1","title":"Arguments","text":"Name Type Required Description Example bundleId string yes Bundle identifier of the app to simulate the warning for com.great.app"},{"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_2","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

    "},{"location":"reference/execute-methods/#mobile-setpasteboard","title":"mobile: setPasteboard","text":"

    Sets the Simulator's pasteboard content to the given value. Does not work for real devices.

    "},{"location":"reference/execute-methods/#arguments_3","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_4","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_5","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.

    "},{"location":"reference/execute-methods/#arguments_6","title":"Arguments","text":"Name Type Required Description Example waitForWebviewMs number no Tells Appium for how long (in milliseconds) to wait for web view(s) to appear. 5000ms by default 10000"},{"location":"reference/execute-methods/#returned-result_3","title":"Returned Result","text":"

    The list of available context objects along with their properties:

    • id: The identifier of the context. The native context will be 'NATIVE_APP' and the webviews will be 'WEBVIEW_xxx'
    • title: The title associated with the webview content. Could be null
    • url: The url associated with the webview content. Could be null
    "},{"location":"reference/execute-methods/#mobile-installapp","title":"mobile: installApp","text":"

    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_7","title":"Arguments","text":"Name Type Required Description Example app string yes See the description of the appium: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 checkVersion bool no If set to true, 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 app value. No app install 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 and the app is installed if checkVersion was not provided or false, which is default behavior. true"},{"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_8","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

    "},{"location":"reference/execute-methods/#mobile-removeapp","title":"mobile: removeApp","text":"

    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_9","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

    "},{"location":"reference/execute-methods/#mobile-launchapp","title":"mobile: launchApp","text":"

    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_10","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_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_6","title":"Returned Result","text":"

    Either true if the app was successfully terminated, otherwise false

    "},{"location":"reference/execute-methods/#mobile-killapp","title":"mobile: killApp","text":"

    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_12","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

    "},{"location":"reference/execute-methods/#mobile-queryappstate","title":"mobile: queryAppState","text":"

    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_13","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_14","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_15","title":"Arguments","text":"Name Type Required Description Example applicationType string no The type of applications to list. Either System 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.

    "},{"location":"reference/execute-methods/#mobile-clearapp","title":"mobile: clearApp","text":"

    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_16","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.

    "},{"location":"reference/execute-methods/#mobile-startperfrecord","title":"mobile: startPerfRecord","text":"

    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.

    "},{"location":"reference/execute-methods/#arguments_17","title":"Arguments","text":"Name Type Required Description Example timeout number no The maximum count of milliseconds to record the profiling information. It is recommended to always limit the maximum duration of perf record operation, since the resulting logs are pretty huge and may easily exceed the free space on th local storage volume. 300000ms 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.

    "},{"location":"reference/execute-methods/#arguments_18","title":"Arguments","text":"Name Type Required Description Example profileName string no The name of existing performance profile to stop the recording for. Multiple recorders for different profile names could be executed at the same time. 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.

    "},{"location":"reference/execute-methods/#mobile-installcertificate","title":"mobile: installCertificate","text":"

    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_19","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_20","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.

    "},{"location":"reference/execute-methods/#mobile-listcertificates","title":"mobile: listCertificates","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-stoplogsbroadcast","title":"mobile: stopLogsBroadcast","text":"

    Stops the syslog broadcasting wesocket server previously started by mobile: startLogsBroadcast. This method will return immediately if no server is running.

    "},{"location":"reference/execute-methods/#mobile-batteryinfo","title":"mobile: batteryInfo","text":"

    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:

    • level: Battery level in range [0.0, 1.0], where 1.0 means 100% charge.
    • state: Battery state as an integer number. The following values are possible:
    • UIDeviceBatteryStateUnknown = 0
    • UIDeviceBatteryStateUnplugged = 1 // on battery, discharging
    • UIDeviceBatteryStateCharging = 2 // plugged in, less than 100%
    • UIDeviceBatteryStateFull = 3 // plugged in, at 100%
    "},{"location":"reference/execute-methods/#mobile-deviceinfo","title":"mobile: deviceInfo","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-getdevicetime","title":"mobile: getDeviceTime","text":"

    Returns the actual device time.

    "},{"location":"reference/execute-methods/#arguments_21","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 is YYYY-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.

    "},{"location":"reference/execute-methods/#mobile-pressbutton","title":"mobile: pressButton","text":"

    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_22","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.

    "},{"location":"reference/execute-methods/#arguments_23","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the target application com.apple.Preferences payload map yes Valid Apple Push Notification values. Read the 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_24","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. Either plain (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 with kHIDUsage_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_25","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_26","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_27","title":"Arguments","text":"Name Type Required Description Example type string no The biometric feature name. Either touchId 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

    "},{"location":"reference/execute-methods/#mobile-clearkeychains","title":"mobile: clearKeychains","text":"

    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_28","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.

    "},{"location":"reference/execute-methods/#arguments_29","title":"Arguments","text":"Name Type Required Description Example bundleId string yes The bundle identifier of the destination app. com.mycompany.myapp access map yes One or more access rules to set. The following keys are supported: 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_30","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

    "},{"location":"reference/execute-methods/#mobile-setappearance","title":"mobile: setAppearance","text":"

    Set the device's UI appearance style.

    "},{"location":"reference/execute-methods/#arguments_31","title":"Arguments","text":"Name Type Required Description Example style string yes Either light 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_32","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_33","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_34","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_35","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_36","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_37","title":"Arguments","text":"Name Type Required Description Example remotePath string yes Same value as for mobile: 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_38","title":"Arguments","text":"Name Type Required Description Example keyboard map no On-screen keyboard properties. The name 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 calendarkey 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.

    "},{"location":"reference/execute-methods/#mobile-startaudiorecording","title":"mobile: startAudioRecording","text":"

    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.

    "},{"location":"reference/execute-methods/#arguments_39","title":"Arguments","text":"Name Type Required Description Example audioInput string or int yes The name of the corresponding audio input device to use for the capture. The full list of capture devices could be shown using 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_40","title":"Arguments","text":"Name Type Required Description Example timeLimitSec 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 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_41","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. Either ui (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). 360000ms by default 120000"},{"location":"reference/execute-methods/#returned-result_27","title":"Returned Result","text":"

    The API calls returns a map with the following entries:

    • results: The array of test results. Each item in this array conists of the following entries:
    • testName: Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')
    • passed: Did the tests pass?
    • crashed: Did the tests crash?
    • status: Test result status (e.g.: 'passed', 'failed', 'crashed')
    • duration: How long did the tests take (in seconds)
    • failureMessage: Failure message (if applicable)
    • location The geolocation of the test (if applicable)
    • code: The exit code of the process. 0 value marks a successful execution.
    • signal: The signal that terminated the process. Could be null (e.g.: SIGTERM)
    "},{"location":"reference/execute-methods/#mobile-installxctestbundle","title":"mobile: installXCTestBundle","text":"

    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_42","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_43","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' ])

    "},{"location":"reference/execute-methods/#mobile-viewportrect","title":"mobile: viewportRect","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-viewportscreenshot","title":"mobile: viewportScreenshot","text":"

    Takes a screenshot of the device viewport (see mobile: viewportRect)

    Unreliable

    This method is unreliable. We recommend using getScreenshot instead

    "},{"location":"reference/execute-methods/#returned-result_31","title":"Returned Result","text":"

    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.

    "},{"location":"reference/execute-methods/#mobile-swipe","title":"mobile: swipe","text":"

    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_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 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":"
    • swipeDown
    • swipeDownWithVelocity:
    • swipeUp
    • swipeUpWithVelocity:
    • swipeLeft
    • swipeLeftWithVelocity:
    • swipeRight
    • swipeRightWithVelocity:
    "},{"location":"reference/execute-methods/#mobile-scroll","title":"mobile: scroll","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_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 scroll on (e.g. the container). The active application element will be used instead if this parameter is not provided. 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_46","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. The active 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_47","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 double tap on. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb x number no Horizontal coordinate offset. 100 y number no Vertical coordinate offset. 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_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 long tap on. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb duration number yes The float duration of press action in seconds 1.5 x number no Horizontal coordinate offset. 100 y number no Vertical coordinate offset. 100"},{"location":"reference/execute-methods/#examples_4","title":"Examples","text":"
    // c#\nDictionary<string, object> tfLongTap = new Dictionary<string, object>();\ntfLongTap.Add(\"elementId\", 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_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. The active 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(\"elementId\", 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_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 tap on. x and y tap coordinates will be calculated 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 Horizontal coordinate offset. 100 y number yes Vertical coordinate offset. 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_51","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(\"elementId\", ((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_52","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 if fromElementId 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_53","title":"Arguments","text":"Name Type Required Description Example elementId (\"element\" prior to Appium v 1.22) string no Internal element id (as hexadecimal hash string) to perform rotation on. The active application element will be used instead if this parameter is not provided. 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    \"elementId\", ((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_54","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 one or more taps. The active application element will be used instead if this parameter is not provided. fe50b60b-916d-420b-8728-ee2072ec53eb numberOfTaps number no The number of taps. 1 by default 2 numberOfTouches number no The number of touch points. 1 by default 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', {elementId: e.ref, numberOfTaps: 2, numberOfTouches: 1}\n
    • numberOfTaps=1, numberOfTouches=1 -> \"vanilla\" single tap
    • numberOfTaps=2, numberOfTouches=1 -> double tap
    • numberOfTaps=3, numberOfTouches=1 -> tripple tap
    • numberOfTaps=2, numberOfTouches=2 -> double tap with two fingers
    "},{"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_55","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.

    "},{"location":"reference/execute-methods/#arguments_56","title":"Arguments","text":"Name Type Required Description Example elementId string yes The internal element identifier (as hexadecimal hash string) to scroll to. The destination element must be located in a scrollable container and must be hittable. If the element is already present in the current viewport then no action is performed. fe50b60b-916d-420b-8728-ee2072ec53eb"},{"location":"reference/execute-methods/#mobile-resetlocationservice","title":"mobile: resetLocationService","text":"

    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 command mobile: 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

    "},{"location":"reference/execute-methods/#mobile-listconditioninducers","title":"mobile: listConditionInducers","text":"

    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

    "},{"location":"reference/execute-methods/#mobile-calibratewebtorealcoordinatestranslation","title":"mobile: calibrateWebToRealCoordinatesTranslation","text":"

    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.

    "},{"location":"reference/execute-methods/#returned-result_36","title":"Returned Result","text":"

    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

    "},{"location":"reference/execute-methods/#mobile-updatesafaripreferences","title":"mobile: updateSafariPreferences","text":"

    Updates preferences of Mobile Safari on Simulator

    "},{"location":"reference/execute-methods/#arguments_57","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 inspecting Library/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_58","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_59","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_60","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_61","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

    "},{"location":"reference/execute-methods/#mobile-keys","title":"mobile: keys","text":"

    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_62","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 with key 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.

    "},{"location":"reference/execute-methods/#mobile-lock","title":"mobile: lock","text":"

    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_63","title":"Arguments","text":"Name Type Required Description Example seconds number string no The number of seconds after which to unlock the device. Set to 0 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

    "},{"location":"reference/execute-methods/#mobile-shake","title":"mobile: shake","text":"

    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_64","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_65","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 then XCUIAccessibilityAuditTypeAll 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/execute-methods/#mobile-startxctestscreenrecording","title":"mobile: startXCTestScreenRecording","text":"

    Start a new screen recording via XCTest.

    Since this feature is based on the native implementation provided by Apple it provides the best quality for the least perfomance penalty in comparison to alternative implementations.

    Even though the feature is available for real devices there is no possibility to delete video files stored on the device yet, which may lead to internal storage overload. That is why it was put under the xctest_screen_record security feature flag if executed from a real device test.

    If the screen recording is already running this API is a noop.

    The feature is only available since Xcode 15/iOS 17.

    "},{"location":"reference/execute-methods/#arguments_66","title":"Arguments","text":"Name Type Required Description Example fps number no The Frames Per Second value for the resulting video. Providing higher values will create video files that are greater in size, but with smoother transitions. It is highly recommeneded to keep this value is range 1-60. 24 by default 60"},{"location":"reference/execute-methods/#returned-result_42","title":"Returned Result","text":"

    The API response consists of the following entries:

    Name Type Description Example uuid string Unique identifier of the video being recorded 1D988774-C7E2-4817-829D-3B835DDAA7DF fps numner FPS value 24 codec number The magic for the used codec. Value of zero means h264 video codec is being used 0 startedAt number The timestamp when the screen recording has started in float seconds since Unix epoch 1709826124.123"},{"location":"reference/execute-methods/#mobile-getxctestscreenrecordinginfo","title":"mobile: getXCTestScreenRecordingInfo","text":"

    Retrieves information about the current running screen recording. If no screen recording is running then null is returned.

    "},{"location":"reference/execute-methods/#returned-result_43","title":"Returned Result","text":"

    Same as for mobile: startXCTestScreenRecording

    "},{"location":"reference/execute-methods/#mobile-stopxctestscreenrecording","title":"mobile: stopXCTestScreenRecording","text":"

    Stops the current XCTest screen recording previously started by the mobile: startXctestScreenRecording API.

    An error is thrown if no screen recording is running.

    The resulting movie is returned as base-64 string or is uploaded to a remote location if corresponding options have been provided.

    The resulting movie is automatically deleted from the local file system FOR SIMULATORS ONLY. In order to clean it up from a real device it is necessary to properly shut down XCTest by calling POST /wda/shutdown API or by doing device factory reset.

    "},{"location":"reference/execute-methods/#arguments_67","title":"Arguments","text":"Name Type Required Description Example remotePath string no The path to the remote location, where the resulting .mov 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 encoded as Base64 and passed to 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_44","title":"Returned Result","text":"

    Same as for mobile: startXCTestScreenRecording plus the below entry:

    Name Type Description Example payload string Base64-encoded content of the recorded media file if remotePath parameter is empty/null or an empty string otherwise. The resulting media is expected to a be a valid QuickTime movie (.mov). YXBwaXVt...."},{"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.

    "},{"location":"reference/ios-predicate/#basic-comparisons","title":"Basic Comparisons","text":"
    • = , == - 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.

    "},{"location":"reference/ios-predicate/#boolean-value-predicates","title":"Boolean Value Predicates","text":"
    • TRUEPREDICATE - A predicate that always evaluates to TRUE .

    • FALSEPREDICATE - A predicate that always evaluates to FALSE.

    "},{"location":"reference/ios-predicate/#basic-compound-predicates","title":"Basic Compound Predicates","text":"
    • AND , && - Logical AND.

    • OR , || - Logical OR.

    • NOT , ! - Logical NOT.

    "},{"location":"reference/ios-predicate/#string-comparisons","title":"String Comparisons","text":"

    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
    "},{"location":"reference/ios-predicate/#aggregate-operations","title":"Aggregate Operations","text":"
    • 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).
    "},{"location":"reference/ios-predicate/#identifiers","title":"Identifiers","text":"
    • 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).

    "},{"location":"reference/ios-predicate/#literals","title":"Literals","text":"

    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.

    "},{"location":"reference/ios-predicate/#reserved-keywords","title":"Reserved Keywords","text":"

    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

    "},{"location":"reference/ios-predicate/#available-attributes","title":"Available Attributes","text":"

    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":"
    • Apple Developer documentation on Predicates
    • NSPredicate Cheat Sheet
    • Class Chain Queries Construction Rules
    "},{"location":"reference/locator-strategies/","title":"Locator Strategies","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 Example className 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 Description elementResponseAttributes 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/7.9/sitemap.xml b/7.9/sitemap.xml index 498b2ec98..300cdcc54 100644 --- a/7.9/sitemap.xml +++ b/7.9/sitemap.xml @@ -2,192 +2,192 @@ https://appium.github.io/appium-xcuitest-driver/7.9/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/contributing/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/endpoints-wda/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/endpoints/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/overview/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/attach-to-running-wda/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/audio-capture/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/ci-setup/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/clipboard/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/file-transfer/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/input-events/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/install-certificate/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/multiple-xcode-versions/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/parallel-tests/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/run-prebuilt-wda/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/run-preinstalled-wda/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/touch-id/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/troubleshooting/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/tvos/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/guides/wda-custom-server/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/installation/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/installation/requirements/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/prov-profile-basic-auto/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/prov-profile-basic-manual/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/prov-profile-full-manual/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/prov-profile-generic-manual/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/preparation/real-device-config/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/capabilities/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/commands/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/element-attributes/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/execute-methods/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/ios-predicate/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/locator-strategies/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/scripts/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/security-flags/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/server-args/ - 2024-03-31 + 2024-04-02 daily https://appium.github.io/appium-xcuitest-driver/7.9/reference/settings/ - 2024-03-31 + 2024-04-02 daily \ No newline at end of file diff --git a/7.9/sitemap.xml.gz b/7.9/sitemap.xml.gz index 0567e789ba0aacc9d65ab9673b20e2dcb29a923f..fa5f03d44061817465876c71df16e8d0f6e4f2b5 100644 GIT binary patch literal 592 zcmV-W0wmY4k`lD@a?`Fw5)3C@s8!+C6rpY)=%+hBWWp7*DRoo=gv z_p|GE4D3&6* zdfz4ml{J?#c9nvd)wYeqmLk}jB_dq4+8~=EA(?9zuuRPM`hpJ*3){?NjdLcrH@wSz+5K^49$LNmk);Z7(G zRV&)NVl-mJd3XIDfQEgTK!ck!8$*oCh-kxAa%5MVUS eV(pt8WXlv}ZN2{k{_86OctsqMY>hqf@ub0fqsLer(G!{hmqckv_g&=CE5J7o>RFKQ@Q`4x%HEaXjsR z{rq9R?O(fxW6hxe?__Z-r~Sm7zPIi9d~OOd%r=#V^4JzP$wg_m$@b8^?7N4ZjMc#V z*>xNPxo)*m#EeY|>)edUQ|%k1ZNgk!6+4BE&nO7nugyz)Y}Y4m4cWpo`R?iP^u-*W z&GVxy+2(GRxyi;6h77+uZ!x?b+nbqpgzYE9e+AZ2%WU0bm`tuQO0??>n-3<{BN=BC*924*YJbowOOEG~gy z*84gsh^(2Ep|2QNt+s6>wiE%cmIzaoY6EqO1ZS#!fHD#3>kB?OETl7!CE|^%g=v-| zDKFYodP`l)q6LbP%Zn;znDtc|vVE>q_TEQUg3X)za+$hWy+?oY+5iX&hO$fCe{mIav~$YnIYIw fF^jctGB#_bz-#OMAMjrf^1AL1j@9qIXdM6m!OI~h