{"id":28564144,"url":"https://github.com/appium/appium-espresso-driver","last_synced_at":"2026-04-23T07:00:36.920Z","repository":{"id":37548445,"uuid":"92194544","full_name":"appium/appium-espresso-driver","owner":"appium","description":"Espresso integration for Appium","archived":false,"fork":false,"pushed_at":"2026-04-18T07:12:06.000Z","size":18884,"stargazers_count":212,"open_issues_count":81,"forks_count":73,"subscribers_count":22,"default_branch":"master","last_synced_at":"2026-04-18T09:23:22.954Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appium.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"appium"}},"created_at":"2017-05-23T16:18:54.000Z","updated_at":"2026-04-18T07:12:07.000Z","dependencies_parsed_at":"2024-03-18T19:32:54.017Z","dependency_job_id":"a0da20ee-65aa-4e71-b285-85297a204223","html_url":"https://github.com/appium/appium-espresso-driver","commit_stats":{"total_commits":847,"total_committers":38,"mean_commits":"22.289473684210527","dds":0.7461629279811097,"last_synced_commit":"619d177700084c3916b569397bac922d00d0cf19"},"previous_names":[],"tags_count":322,"template":false,"template_full_name":null,"purl":"pkg:github/appium/appium-espresso-driver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fappium-espresso-driver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fappium-espresso-driver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fappium-espresso-driver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fappium-espresso-driver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appium","download_url":"https://codeload.github.com/appium/appium-espresso-driver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fappium-espresso-driver/sbom","scorecard":{"id":203610,"data":{"date":"2025-08-11","repo":{"name":"github.com/appium/appium-espresso-driver","commit":"e44af7ed18837ef8676027c0e189af459948adc4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.8,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":2,"reason":"Found 8/27 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"28 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/functional-test.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/gradle-wrapper-validation.yml:10","Warn: no topLevel permission defined: .github/workflows/pr-title.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/publish.js.yml:9","Warn: no topLevel permission defined: .github/workflows/unit-test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: espresso-server/gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/functional-test.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/functional-test.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/functional-test.yml:111: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:125: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/functional-test.yml:131: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/functional-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/gradle-wrapper-validation.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/gradle-wrapper-validation.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/gradle-wrapper-validation.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/gradle-wrapper-validation.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pr-title.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/pr-title.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.js.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/publish.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.js.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/publish.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.js.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/publish.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/unit-test.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/appium/appium-espresso-driver/unit-test.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/functional-test.yml:87","Warn: npmCommand not pinned by hash: .github/workflows/functional-test.yml:88","Warn: npmCommand not pinned by hash: .github/workflows/functional-test.yml:89","Warn: npmCommand not pinned by hash: .github/workflows/publish.js.yml:30","Warn: npmCommand not pinned by hash: .github/workflows/publish.js.yml:41","Warn: npmCommand not pinned by hash: .github/workflows/unit-test.yml:43","Warn: npmCommand not pinned by hash: .github/workflows/unit-test.yml:61","Info:   0 out of  17 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 third-party GitHubAction dependencies pinned","Info:   0 out of   7 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":9,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/appium/.github/SECURITY.md:1","Info: Found linked content: github.com/appium/.github/SECURITY.md:1","Warn: One or no descriptive hints of disclosure, vulnerability, and/or timelines in security policy","Info: Found text in security policy: github.com/appium/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.js.yml:14"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T23:15:09.516Z","repository_id":37548445,"created_at":"2025-08-16T23:15:09.516Z","updated_at":"2025-08-16T23:15:09.516Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32166781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T02:19:40.750Z","status":"ssl_error","status_checked_at":"2026-04-23T02:17:55.737Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-10T13:09:43.018Z","updated_at":"2026-04-23T07:00:36.904Z","avatar_url":"https://github.com/appium.png","language":"Kotlin","funding_links":["https://opencollective.com/appium"],"categories":[],"sub_categories":[],"readme":"# Appium Espresso Driver\n\n[![Build Status](https://dev.azure.com/AppiumCI/Appium%20CI/_apis/build/status/appium.appium-espresso-driver?branchName=master)](https://dev.azure.com/AppiumCI/Appium%20CI/_build/latest?definitionId=3\u0026branchName=master)\n\n[![NPM version](http://img.shields.io/npm/v/appium-espresso-driver.svg)](https://npmjs.org/package/appium-espresso-driver)\n[![Downloads](http://img.shields.io/npm/dm/appium-espresso-driver.svg)](https://npmjs.org/package/appium-espresso-driver)\n\n[![Release](https://github.com/appium/appium-espresso-driver/actions/workflows/publish.js.yml/badge.svg)](https://github.com/appium/appium-espresso-driver/actions/workflows/publish.js.yml)\n\nAppium's Espresso Driver is a test automation server for Android that uses [Espresso](https://developer.android.com/training/testing/espresso/) as the underlying test technology. The Espresso Driver is a part of the Appium framework. The driver operates in scope of [W3C WebDriver protocol](https://www.w3.org/TR/webdriver/) with several custom extensions to cover operating-system specific scenarios.\n\nThe Espresso package consists of two main parts:\n- The driver part (written in Node.js) ensures the communication between the Espresso server and Appium. Also includes several handlers that directly use ADB and/or other system tools without a need to talk to the server.\n- The server part (written in Kotlin with some parts of Java), which is running on the device under test and transforms REST API calls into low-level Espresso commands.\n\n\u003e [!IMPORTANT]\n\u003e Since major version *5.0.0*, this driver is only compatible with Appium 3. Use the `appium driver install espresso`\n\u003e command to add it to your distribution.\n\n\n## Comparison with UiAutomator2\n\nThe key difference between [UiAutomator2 Driver](https://github.com/appium/appium-uiautomator2-driver) and Espresso Driver is that UiAutomator2 is a black-box testing framework, and Espresso is a \"grey-box\" testing framework. The Espresso Driver itself is black-box (no internals of the code are exposed to the tester), but the Espresso framework itself has access to the internals of Android applications. This distinction has a few notable benefits. It can find elements that aren't rendered on the screen, it can identify elements by the Android View Tag, and it makes use of [IdlingResource](https://developer.android.com/reference/android/support/test/espresso/IdlingResource) which blocks the framework from running commands until the UI thread is free. There is a limited support of out-of-app areas automation via the [mobile: uiautomator](#mobile-uiautomator) command.\n\n## Requirements\n\nOn top of standard Appium requirements Espresso driver also expects the following prerequisites:\n\n- Windows, Linux and macOS are supported as hosts\n- [Android SDK Platform tools](https://developer.android.com/studio/releases/platform-tools) must be installed. [Android Studio IDE](https://developer.android.com/studio) also provides a convenient UI to install and manage the tools.\n- ANDROID_HOME or ANDROID_SDK_ROOT [environment variable](https://developer.android.com/studio/command-line/variables) must be set\n- Java JDK must be installed and [JAVA_HOME](https://www.baeldung.com/java-home-on-windows-7-8-10-mac-os-x-linux) environment variable must be set. Java major version must be 11 or newer.\n- [Emulator](https://developer.android.com/studio/run/managing-avds) platform image must be installed if you plan to run your tests on it. [Android Studio IDE](https://developer.android.com/studio) also provides a convenient UI to install and manage emulators.\n- Real Android devices must have [USB debugging enabled](https://developer.android.com/studio/debug/dev-options) and should be visible as `online` in `adb devices -l` output.\n- Since driver version 6.0.0 the minimum supported version of Android API must be 8.0 (API level 26). Older driver versions support Android API 5/level 21 (6.0 is recommended as version 5 has some known compatibility issues).\n- [Gradle](https://gradle.org/) must be installed in order to build Espresso server.\n- Both the server package and the application under test must be signed with the same digital signature. Appium does sign them automatically upon session creation, so this could only be an issue if one wants to test an application, which is already installed on the device (using `noReset=true` capability).\n- The package under test must not have mangled class names (e.g. [Proguard](https://developer.android.com/studio/build/shrink-code) must not be enabled for it)\n\n\n## Consuming Espresso Server as Library\n\nIf you have access to the source code of the application under test then it is\npossible to integrate Espresso server into your application and make it to a library.\nThis approach allows to simplify the dependency conflicts resolution\nas well as to optimize the session startup performance.\nRead the corresponding [article](./docs/as-library.md) from the driver\ndocumentation for more details.\n\n\n### Doctor\n\nSince driver version 2.31.0 you can automate the validation for the most of the above\nrequirements as well as various optional ones needed by driver extensions by running the\n`appium driver doctor espresso` server command.\n\n\n## Scripts\n\n- `appium driver run espresso print-espresso-path` prints the path to the Appium Espresso server root. You can modify the gradle file directly if [Espresso Build Config](#espresso-build-config) was not sufficient.\n- `appium driver run espresso build-espresso` builds the espresso server since driver version 2.18.0. It helps building the espresso server outside of the Appium process. Available environment variables are below:\n  - `SHOW_GRADLE_LOG` configures if the command shows the gradle task logs. `true` or `1`  sets it as enabled, but others set it as disabled. Defaults to disabled.\n  - `TEST_APP_PACKAGE` configures the target application to build the espresso server for.\n  - `ESPRESSO_BUILD_CONFIG` is an absolute path to the [Espresso Build Config](#espresso-build-config) as JSON format file.\n    - e.g. `SHOW_GRADLE_LOG=true TEST_APP_PACKAGE=your.test.pkg ESPRESSO_BUILD_CONFIG=/path/to/the/config.json appium driver run build-espresso`\n\n## Capabilities\n\n### General\n\nCapability Name | Description\n--- | ---\nplatformName | Could be set to `android`. 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.\nappium:automationName | Must always be set to `espresso`. Values of `automationName` are compared case-insensitively.\nappium:deviceName | The name of the device under test (actually, it is not used to select a device under test). Consider setting `udid` for real devices and `avd` for emulators instead\nappium:platformVersion | The platform version of an emulator or a real device. This capability is used for device autodetection if `udid` is not provided\nappium:udid | UDID of the device to be tested. Could ve retrieved from `adb devices -l` output. If unset then the driver will try to use the first connected device. Always set this capability if you run parallel tests.\nappium: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\nappium:fullReset | Being set to `true` always enforces the application under test to be fully uninstalled before starting a new session. `false` by default\nappium:printPageSourceOnFindFailure | Enforces the server to dump the actual XML page source into the log if any error happens. `false` by default.\n\n### Driver/Server\n\nCapability Name | Description\n--- | ---\nappium:systemPort | The number of the port the Espresso server is listening on. By default the first free port from 8300..8399 range is selected. It is recommended to set this value if you are running [parallel tests](docs/parallel-tests.md) on the same machine.\nappium:skipServerInstallation | Skip the Espresso Server component installation on the device under test and all the related checks if set to `true`. This could help to speed up the session startup if you know for sure the correct server version is installed on the device. In case the server is not installed or an incorrect version of it is installed then you may get an unexpected error later. Since driver version 3.3.0 the driver automatically verifies the compatibility with the server module on session startup by checking its `/status` response. An error is thrown if the returned server major version does not match to the driver's module major version or the target package name is different from the expected one. You may also skip the server version validation for a prebuilt server module by setting the [VERSION constant](./espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt) to a non-valid [semver](https://semver.org/) value. `false` by default\nappium:espressoServerLaunchTimeout | The maximum number of milliseconds to wait util Espresso server is listening on the device. `45000` ms by default\nappium:forceEspressoRebuild | Whether to always enforce Espresso server rebuild (`true`). By default Espresso caches the already built server apk and only rebuilds it when it is necessary, because rebuilding process needs extra time. `false` by default\nappium:espressoBuildConfig | Either the full path to build config JSON on the server file system or the JSON content itself serialized to a string. This config allows to customize several important properties of Espresso server. Refer to [Espresso Build Config](#espresso-build-config) for more information on how to properly construct such config.\nappium:showGradleLog | Whether to include Gradle log to the regular server logs while building Espresso server. `false` by default.\n\n### App\n\nCapability Name | Description\n--- | ---\nappium:app | Full path to the application to be tested (the app must be located on the same machine where the server is running). The `.apk` application extension is supported. Since driver version 2.1.0 `.aab` files are supported as well (they get converted to `.apk` format automatically if [bundletool.jar](https://github.com/google/bundletool/releases) could be found in your PATH). For older driver versions `.aab` files need to be [converted](https://stackoverflow.com/questions/53040047/generate-apk-file-from-aab-file-android-app-bundle) manually to `.apk` format using [bundletool](https://developer.android.com/studio/command-line/bundletool) first. Could also be an URL to a remote location. If neither of the `app` or `appPackage` capabilities are provided then the driver will fail to start a session. Also, if `app` capability is not provided it is expected that the app under test is already installed on the device under test and `noReset` is equal to `true`.\nappium:appPackage | Application package identifier to be started. If not provided then Espresso will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appActivity | Main application activity identifier. If not provided then Espresso will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appWaitActivity | Identifier of the first activity that the application invokes. If not provided then equals to `appium:appActivity`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appWaitPackage | Identifier of the first package that is invoked first. If not provided then equals to `appium:appPackage`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appWaitDuration | Maximum amount of milliseconds to wait until the application under test is started (e. g. an activity returns the control to the caller). `20000` ms by default. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:intentOptions | The mapping of custom options for the intent that is going to be passed to the main app activity. Check [Intent Options](#intent-options) for more details.\nappium:activityOptions | The mapping of custom options for the main app activity that is going to be started. Check [Activity Options](#activity-options) for more details.\nappium:androidInstallTimeout | Maximum amount of milliseconds to wait until the application under test is installed. `90000` ms by default\nappium:autoGrantPermissions | Whether to grant all the requested application permissions automatically when a test starts(`true`). The targetSdkVersion in the application manifest must be greater or equal to 23 and the Android version on the device under test must be greater or equal to Android 6 (API level 23) to grant permissions. Applications whose targetSdkVersion is lower than or equal to 22 must be reisntalled to grant permissions, for example, by setting the `appium:fullReset` capability as `true` for Android 6+ devices. `false` by default\nappium:otherApps | Allows to set one or more comma-separated paths to Android packages that are going to be installed along with the main application under test. This might be useful if the tested app has dependencies\nappium:uninstallOtherPackages | Allows to set one or more comma-separated package identifiers to be uninstalled from the device before a test starts\nappium:allowTestPackages | If set to `true` then it would be possible to use packages built with the test flag for the automated testing (literally adds `-t` flag to the `adb install` command). `false` by default\nappium:remoteAppsCacheLimit | Sets the maximum amount of application packages to be cached on the device under test. This is needed for devices that don't support streamed installs (Android 7 and below), because ADB must push app packages to the device first in order to install them, which takes some time. Setting this capability to zero disables apps caching. `10` by default.\nappium:enforceAppInstall | If set to `true` then the application under test is always reinstalled even if a newer version of it already exists on the device under test. `false` by default\n\n### App Localization\n\nCapability Name | Description\n--- | ---\nappium:localeScript | Canonical name of the locale to be set for the app under test, for example `Hans` in `zh-Hans-CN`. See https://developer.android.com/reference/java/util/Locale.html for more details.\nappium:language | Name of the language to extract application strings for. Strings are extracted for the current system language by default. Also sets the language for the app under test. See https://developer.android.com/reference/java/util/Locale.html for more details. Example: en, ja\nappium:locale | Sets the locale for the app under test. See https://developer.android.com/reference/java/util/Locale.html for more details. Example: EN, JA\nappium:appLocale | Sets the locale for the app under test. The main difference between this option and the above ones is that this option only changes the locale for the application under test and does not affect other parts of the system. Also, it only uses public APIs for its purpose. See https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers to get the list of available language abbreviations. Example: `{\"language\": \"zh\", \"country\": \"CN\", \"variant\": \"Hans\"}`\n\n### ADB\n\nCapability Name | Description\n--- | ---\nappium:adbPort | Number of the port where ADB is running. `5037` by default\nappium:remoteAdbHost | Address of the host where ADB is running (the value of `-H` ADB command line option). Unset by default\nappium:adbExecTimeout | Maximum number of milliseconds to wait until single ADB command is executed. `20000` ms by default\nappium:clearDeviceLogsOnStart | If set to `true` then Espresso deletes all the existing logs in the device buffer before starting a new test\nappium:buildToolsVersion | The version of Android build tools to use. By default Espresso driver uses the most recent version of build tools installed on the machine, but sometimes it might be necessary to give it a hint (let say if there is a known bug in the most recent tools version). Example: `28.0.3`\nappium:skipLogcatCapture | Being set to `true` disables automatic logcat output collection during the test run. `false` by default\nappium:suppressKillServer | Being set to `true` prevents the driver from ever killing the ADB server explicitly. Could be useful if ADB is connected wirelessly. `false` by default\nappium:ignoreHiddenApiPolicyError | Being set to `true` ignores a failure while changing hidden API access policies to [enable access to non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#how_can_i_enable_access_to_non-sdk_interfaces). Could be useful on some devices, where access to these policies has been locked by its vendor. `false` by default.\nappium:hideKeyboard | Being set to `true` hides the on-screen keyboard while the session is running. Use it instead of the legacy `appium:unicodeKeyboard` one (which will be dropped in the future). This effect is achieved by assigning a custom \"artificial\" [input method](https://developer.android.com/develop/ui/views/touch-and-input/creating-input-method). Only use this feature for special/exploratory cases as it violates the way your application under test is normally interacted with by a human. Setting this capability explicitly to `false` enforces `adb shell ime reset` call on session startup, which resets the currently selected/enabled IMEs to the default ones as if the device is initially booted with the current locale. `undefined` by default.\nappium:mockLocationApp | Sets the package identifier of the app, which is used as a system mock location provider since Appium 1.18.0+. This capability has no effect on emulators. If the value is set to `null` or an empty string, then Appium will skip the mocked location provider setup procedure. Defaults to Appium Setting package identifier (`io.appium.settings`).\nappium:logcatFormat | The log print format, where `format` is one of: `brief` `process` `tag` `thread` `raw` `time` `threadtime` `long`. `threadtime` is the default value.\nappium:logcatFilterSpecs | Series of `tag[:priority]` where `tag` is a log component tag (or * for all) and priority is: `V    Verbose`, `D    Debug`, `I    Info`, `W    Warn`, `E    Error`, `F    Fatal`, `S    Silent (suppress all output)`. '*' means '*:d' and `tag` by itself means `tag:v`. If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS. If no filterspec is found, filter defaults to '*:I'.\nappium:allowDelayAdb | Being set to `false` prevents emulator to use `-delay-adb` feature to detect its startup. See https://github.com/appium/appium/issues/14773 for more details.\nappium:adbListenAllNetwork | Being set to `true` adds `-a` ADB command line global option. Requires `uiautomator2:adb_listen_all_network` [security feature](https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/security.md) to be enabled. Unset by default. Available since the driver version 6.2.0.\n\n### Emulator (Android Virtual Device)\n\nCapability Name | Description\n--- | ---\nappium:avd | The name of Android emulator to run the test on. The names of currently installed emulators could be listed using `avdmanager list avd` command. If the emulator with the given name is not running then it is going to be started before a test\nappium:avdLaunchTimeout | Maximum number of milliseconds to wait until Android Emulator is started. `60000` ms by default\nappium:avdReadyTimeout | Maximum number of milliseconds to wait until Android Emulator is fully booted and is ready for usage. `60000` ms by default\nappium:avdArgs | Either a string or an array of emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline).\nappium:avdEnv | Mapping of emulator [environment variables](https://developer.android.com/studio/command-line/variables).\nappium:networkSpeed | Sets the desired network speed limit for the emulator. It is only applied if the emulator is not running before the test starts. See emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline) description for more details.\nappium:gpsEnabled | Sets whether to enable (`true`) or disable (`false`) GPS service in the Emulator. Unset by default, which means to not change the current value\nappium:isHeadless | If set to `true` then emulator starts in headless mode (e.g. no UI is shown). It is only applied if the emulator is not running before the test starts. `false` by default.\nappium:injectedImageProperties | Allows adjusting of injected image properties, like size, position or rotation. The image itself is expected to be injected by [mobile: injectEmulatorCameraImage](#mobile-injectemulatorcameraimage) extension. It is also mandatory to provide this capability if you are going to use the injection feature on a newly created/resetted emulator as it __enforces emulator restart__, so it could properly reload the modified image properties. The value itself is a map, where possible keys are `size`, `position` and `rotation`. All of them are optional. If any of values is not provided then the following defaults are used: `{size: {scaleX: 1, scaleY: 1}, position: {x: 0, y: 0, z: -1.5}, rotation: {x: 0, y: 0, z: 0}}`. The `size` value contains scale multipliers for X and Y axes. The `position` contains normalized coefficients for X/Y/Z axes, where `0` means it should be centered in the viewport. Values in the `rotation` are measured in degrees respectively for X, Y and Z axis. The capability is available since the driver version 2.43.0.\n\n### App Signing\n\nCapability Name | Description\n--- | ---\nappium:useKeystore | Whether to use a custom [keystore](https://developer.android.com/studio/publish/app-signing#certificates-keystores) to sign the app under test. `false` by default, which means apps are always signed with the default Appium debug certificate (unless canceled by `noSign` capability). This capability is used in combination with `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities.\nappium:keystorePath | The full path to the keystore file on the server filesystem. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:keystorePassword | The password to the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:keyAlias | The alias of the key in the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:keyPassword | The password of the key in the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:noSign | Set it to `true` in order to skip application signing. By default all apps are always signed with the default Appium debug signature. This capability cancels all the signing checks and makes the driver to use the application package as is. This capability does not affect `.apks` packages as these are expected to be already signed. Make sure that the server package is signed with the same signature as the application under test before disabling this capability.\n\n### Device Locking\n\nCapability Name | Description\n--- | ---\nappium:skipUnlock | Whether to skip the check for lock screen presence (`true`). By default Espresso driver tries to detect if the device's screen is locked before starting the test and to unlock that (which sometimes might be unstable). Note, that this operation takes some time, so it is recommended to set this capability to `false` and disable screen locking on devices under test. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockType | Set one of the possible types of Android lock screens to unlock. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockKey | Allows to set an unlock key. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockSuccessTimeout | Maximum number of milliseconds to wait until the device is unlocked. `2000` ms by default. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\n\n### Web Context\n\nCapability Name | Description\n--- | ---\nappium:autoWebview | If set to `true` then Espresso driver will try to switch to the first available web view after the session is started. `false` by default.\nappium:webviewDevtoolsPort | The local port number to use for devtools communication. By default the first free port from 10900..11000 range is selected. Consider setting the custom value if you are running parallel tests.\nappium:ensureWebviewsHavePages | Whether to skip web views that have no pages from being shown in `getContexts` output. The driver uses devtools connection to retrieve the information about existing pages. `true` by default since Appium 1.19.0, `false` if lower than 1.19.0.\nappium:enableWebviewDetailsCollection | Whether to retrieve extended web views information using devtools protocol. Enabling this capability helps to detect the necessary chromedriver version more precisely. `true` by default since Appium 1.22.0, `false` if lower than 1.22.0.\nappium:chromedriverPort | The port number to use for Chromedriver communication. Any free port number is selected by default if unset.\nappium:chromedriverPorts | Array of possible port numbers to assign for Chromedriver communication. If none of the port in this array is free then an error is thrown.\nappium:chromedriverArgs | Array of chromedriver [command line arguments](http://www.assertselenium.com/java/list-of-chrome-driver-command-line-arguments/). Note, that not all command line arguments that are available for the desktop browser are also available for the mobile one.\nappium:chromedriverExecutable | Full path to the chromedriver executable on the server file system.\nappium:chromedriverExecutableDir | Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled. Read [Automatic Chromedriver Discovery article](docs/hybrid-mode.md#automatic-discovery-of-compatible-chromedriver) for more details.\nappium:chromedriverChromeMappingFile | Full path to the chromedrivers mapping file. This file is used to statically map webview/browser versions to the chromedriver versions that are capable of automating them. Read [Automatic Chromedriver Discovery article](docs/hybrid-mode.md#automatic-discovery-of-compatible-chromedriver) for more details.\nappium:chromedriverUseSystemExecutable | Set it to `true` in order to enforce the usage of chromedriver, which gets downloaded by Appium automatically upon installation. This driver might not be compatible with the destination browser or a web view. `false` by default.\nappium:chromedriverDisableBuildCheck | Being set to `true` disables the compatibility validation between the current chromedriver and the destination browser/web view. Use it with care.\nappium:autoWebviewTimeout | Set the maximum number of milliseconds to wait until a web view is available if `autoWebview` capability is set to `true`. `2000` ms by default\nappium:recreateChromeDriverSessions | If this capability is set to `true` then chromedriver session is always going to be killed and then recreated instead of just suspending it on context switching. `false` by default\nappium:nativeWebScreenshot | Whether to use screenshoting endpoint provided by Espresso framework (`true`) rather than the one provided by chromedriver (`false`, the default value). Use it when you experience issues with the latter.\nappium:extractChromeAndroidPackageFromContextName | If set to `true`, tell chromedriver to attach to the android package we have associated with the context name, rather than the package of the application under test. `false` by default.\nappium:showChromedriverLog | If set to `true` then all the output from chromedriver binary will be forwarded to the Appium server log. `false` by default.\npageLoadStrategy | One of the available page load strategies. See https://www.w3.org/TR/webdriver/#capabilities\nappium:chromeOptions | A mapping, that allows to customize chromedriver options. See https://chromedriver.chromium.org/capabilities for the list of available entries.\n\n### Other\n\nCapability Name | Description\n--- | ---\nappium:disableSuppressAccessibilityService | Being set to `true` tells the instrumentation process to not suppress accessibility services during the automated test. This might be useful if your automated test needs these services. `false` by default\nappium:disableWindowAnimation | To avoid flakiness google [recommends](https://developer.android.com/training/testing/espresso/setup#set-up-environment) to disable the window animation of the Android device under test when running espresso test. Animation state is restored automatically after the session is stopped if it was enabled before it has started. The restore method may not work if the session ends unexpectedly. `true` by default\nappium:timeZone | Overrides the current device's time zone since the driver version 2.38.0. This change is preserved until the next override. The time zone identifier must be a valid name from the list of [available time zone identifiers](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), for example `Europe/Kyiv`\n\n\n## Settings API\n\nEspresso driver supports Appium [Settings API](https://appium.io/docs/en/advanced-concepts/settings/).\nAlong with the common settings the following driver-specific settings are currently available:\n\nName | Type | Description\n--- | --- | ---\ndriver | 'compose' or 'espresso' | The name of the subdriver to use for elements interactions. The default value is `espresso`. Switching the value to `compose` enables interactions with [Jetpack Compose](https://developer.android.com/jetpack/compose)-based application user interfaces. Read [Jetpack Compose Support](#jetpack-compose-support) for more details.\n\n\n## Jetpack Compose Support\n\n[Jetpack Compose](https://developer.android.com/jetpack/compose) is Android’s modern toolkit for building native UI. Espresso driver supports basic interactions with Compose-based applications since version *1.46.0*.\n\n[Appium UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver/) allows to interact with Jetpack Compose elements via the accessibility layer by providing [testTag](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.Modifier).testTag(kotlin.String)) modifier attribute or the displayed text, but this Espresso driver allows you to access Jetpack Compose elements directly.\n\n\n### Interaction With Compose Elements\n\nEspresso driver has the concept of subdrivers. This works quite similarly to the concept of contexts, while contexts are used to switch between native and web, and subdrivers are still\nunder the native one. Each subdriver operates its own elements cache, so it is not be possible\nto mix Espresso and Compose elements.\n\nIn order to change between subdrivers use the [driver](#settings-api) setting. Setting its value to `compose` modifies driver behavior in the way it interacts with Compose elements rather that with classic Android views. It is possible to switch between `espresso` and `compose` modes at any point of time. When `compose` mode is active the the following webdriver commands behave differently (as of driver version *1.50.0*):\n- findElement(s): Element finding commands only support Compose-based locators. Read [Compose Elements Location](#compose-elements-location) for more details.\n- getPageSource: The returned page source is retrieved from Compose and all elements there contain [Compose-specific](#compose-element-attributes) attributes.\n- click, isDisplayed, isEnabled, clear, getText, sendKeys, getElementRect, getValue, isSelected: These commands should properly support compose elements.\n- getAttribute: Accepts and returns Compose-specific element attributes. See [Compose Element Attributes](#compose-element-attributes) for the full list of supported Compose element attributes.\n- getElementScreenshot: Fetches a screenshot of the given Compose element. Available since driver version *2.14.0*\n- `mobile: swipe`: Performs swipe gesture on the given element in the given direction.\nThe `swiper` argument is not supported in Compose mode. Available since driver version *2.15.0*\n\nCalling other driver element-specific APIs not listed above would most likely throw an exception as Compose and Espresso elements are being stored in completely separated internal caches and must not be mixed.\n\nYou could also check end-to-end tests for more examples on how to setup test capabilities and\non the Compose usage in general:\n- https://github.com/appium/appium-espresso-driver/blob/master/test/functional/commands/jetpack-componse-element-values-e2e-specs.js\n- https://github.com/appium/appium-espresso-driver/blob/master/test/functional/commands/jetpack-compose-attributes-e2e-specs.js\n- https://github.com/appium/appium-espresso-driver/blob/master/test/functional/commands/jetpack-compose-e2e-specs.js\n- https://github.com/appium/appium-espresso-driver/blob/master/test/functional/commands/jetpack-compose-e2e-specs.js\n\n\n## Espresso Build Config\n\nEspresso server is in tight connection with the application under test. That is why it is important that the server uses the same versions of common dependencies and there are no conflicts. Espresso driver allows to configure several build options via `espressoBuildConfig` capability. The configuration JSON supports the following entries:\n\n### composeSupport\n\nWhen set to `false`, the Espresso server is built **without** Jetpack Compose UI test dependencies (smaller test APK and no Compose on the classpath). The default is `true` when this key is omitted. If Compose support is disabled, setting the `driver` setting to `compose` or using Compose-only flows returns a clear server error; rebuild with `composeSupport` enabled (or remove the key) to use Compose.\n\n### toolsVersions\n\nThis entry allows to explicitly set the versions of different server components. The following map entries are supported:\n\nName | Description | Example\n--- | --- | ---\ngradle | The Gradle version to use for Espresso server building. | '6.3'\nandroidGradlePlugin | The Gradle plugin version to use for Espresso server building. By default the version from the [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/build.gradle.kts) is used | '4.1.1'\ncompileSdk | Android SDK version to compile the server for. By default the version from the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) is used | 28\nbuildTools | Target Android build tools version to compile the server with. By default the version from the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) is used | '28.0.3'\nminSdk | Minimum Android SDK version to compile the server for. By default the version from the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) is used | 18\ntargetSdk | Target Android SDK version to compile the server for. By default the version from the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) is used | 28\nkotlin | Kotlin version to compile the server for. By default the version from the [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/build.gradle.kts) is used | '1.3.72'\ncomposeVersion | The version for the Jetpack Compose dependencies to use for Espresso server building. By default the version from the [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/build.gradle.kts) is used | '1.1.1'\nespressoVersion | The version for the Espresso dependencies to use for Espresso server building. By default the version from the [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/build.gradle.kts) is used | '3.5.0'\nsourceCompatibility | The minimum version of JVM the project sources are compatible with. The default value is `VERSION_1_8` | VERSION_12\ntargetCompatibility | The target version of JVM the project sources are compatible with. The default value is `VERSION_1_8` | VERSION_12\njvmTarget | Target version of the generated JVM bytecode as a string. The default value is `1_8` | `1_10`\nannotationVersion | The target version of `androidx.annotation:annotation` package. By default the version from the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) is used | '1.2.0'\n\n### additionalAppDependencies\n\nThe value of this entry must be a non empty array of dependent module names with their versions. The scripts adds all these items as `api` lines of `dependencies` category in the library [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/library/build.gradle.kts) script. Example: `[\"xerces.xercesImpl:2.8.0\", \"xerces.xmlParserAPIs:2.6.2\"]`\n\n### additionalAndroidTestDependencies\n\nThe value of this entry must be a non empty array of dependent module names with their versions. The scripts adds all these items as `androidTestImplementation` lines of `dependencies` category in the app [build.gradle.kts](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/build.gradle.kts) script. Example: `[\"xerces.xercesImpl:2.8.0\", \"xerces.xmlParserAPIs:2.6.2\"]`\n\n### Full JSON Example\n\n```json\n{\n  \"composeSupport\": false,\n  \"toolsVersions\": {\n    \"androidGradlePlugin\": \"4.0.0\"\n  },\n  \"additionalAndroidTestDependencies\": [\"xerces.xercesImpl:2.8.0\", \"xerces.xmlParserAPIs:2.6.2\"]\n}\n```\n\n\n## Intent Options\n\nBy default Espresso creates the following intent to start the app activity:\n\n```json\n{\n  \"action\": \"ACTION_MAIN\",\n  \"flags\": \"ACTIVITY_NEW_TASK\",\n  \"className\": \"\u003cfullyQualifiedAppActivity\u003e\"\n}\n```\n\nAlthough, it is possible to fully customize these options by providing the `intentOptions` capability. Read [Intent documentation](https://developer.android.com/reference/android/content/Intent) for more details on this topic. The value of this capability is expected to be a map with the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\naction | string | An action name. Application-specific actions should be prefixed with the vendor's package name. | ACTION_MAIN\ndata | string | Intent data URI | content://contacts/people/1\ntype | string | Intent MIME type | image/png\ncategories | string | One or more comma-separated Intent categories | android.intent.category.APP_CONTACTS\ncomponent | string | Component name with package name prefix to create an explicit intent | com.example.app/.ExampleActivity\nintFlags | string | Single string value, which represents intent flags set encoded into an integer. Could also be provided in hexadecimal format. Check [setFlags method documentation](https://developer.android.com/reference/android/content/Intent.html#setFlags(int)) for more details. | 0x0F\nflags | Comma-separated string of intent flag names | 'FLAG_GRANT_READ_URI_PERMISSION, ACTIVITY_CLEAR_TASK' (the 'FLAG_' prefix could be omitted)\nclassName | The name of a class inside of the application package that will be used as the component for this Intent | com.example.app.MainActivity\ne or es | `Map\u003cstring, string\u003e` | Intent string parameters | {'foo': 'bar'}\nesn | `Array\u003cstring\u003e` | Intent null parameters | ['foo', 'bar']\nez | `Map\u003cstring, boolean\u003e` | Intent boolean parameters | {'foo': true, 'bar': false}\nei | `Map\u003cstring, int\u003e` | Intent integer parameters | {'foo': 1, 'bar': 2}\nel | `Map\u003cstring, long\u003e` | Intent long integer parameters | {'foo': 1L, 'bar': 2L}\nef | `Map\u003cstring, float\u003e` | Intent float parameters | {'foo': 1.ff, 'bar': 2.2f}\neu | `Map\u003cstring, string\u003e` | Intent URI-data parameters | {'foo': 'content://contacts/people/1'}\necn | `Map\u003cstring, string\u003e` | Intent component name parameters | {'foo': 'com.example.app/.ExampleActivity'}\nesa | `Map\u003cstring, List\u003cstring\u003e\u003e` | Intent string array parameters | {'foo': ['bar1','bar2','bar3','bar4']}\neia | `Map\u003cstring, string\u003e` | Intent integer array parameters | {'foo': '1,2,3,4'}\nela | `Map\u003cstring, string\u003e` | Intent long array parameters | {'foo': '1L,2L,3L,4L'}\nefa | `Map\u003cstring, string\u003e` | Intent float array parameters | {'foo': '1.1,2.2,3.2,4.4'}\n\n\n## Activity Options\n\nEspresso driver allows to customize several activity startup options using `activityOptions` capability. The capability value is expected to be a map with the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nlaunchDisplayId | string or int | Display id which you want to assign to launch the main app activity on. This might be useful if the device under test supports multiple displays | 1\n\n\n## Espresso Element Attributes\n\nEspresso driver supports the following element attributes in `espresso` subdriver:\n\nName | Description | Example\n--- | --- | ---\ncheckable | Whether the element is checkable or not | 'true'\nchecked | Whether the element is checked. Always `false` if the element is not checkable | 'false'\nclass | The full name of the element's class. Could be `null` for some elements | 'android.view.View'\nclickable | Whether the element could be clicked | 'false'\ncontent-desc | The content-description attribute of the accessible element | 'foo'\nenabled | Whether the element could be clicked | 'true'\nfocusable | Whether the element could be focused | 'true'\nfocused | Whether the element could is focused. Always `false` if the element is not focusable | 'false'\nlong-clickable | Whether the element accepts long clicks | 'false'\npackage | Identifier of the package the element belongs to | 'com.mycompany'\npassword | Whether the element is a password input field | 'true'\nresource-id | Element's resource identifier. Could be `null` | 'com.mycompany:id/resId'\nscrollable | Whether the element is scrollable | 'true'\nselected | Whether the element is selected | 'false'\ntext | The element's text. It never equals to `null` | 'my text'\nhint | The element's hint. Could be `null` | 'my hint text'\nbounds | The element's visible frame (`[left, top][right, bottom]`) | `[0,0][100,100]`\nno-multiline-buttons | Whether the element's view hierarchy does not contain multiline buttons | 'true'\nno-overlaps | Whether element's descendant objects assignable to TextView or ImageView do not overlap each other | 'true'\nno-ellipsized-text | Whether the element's view hierarchy does not contain ellipsized or cut off text views | 'false'\nvisible | Whether the element is visible to the user | 'true'\nview-tag | The tag value assigned to the element. Could be `null` | 'my tag'\n\n\n## Compose Element Attributes\n\nEspresso driver supports the following element attributes in `compose` subdriver:\n\nName | Description | Example\n--- | --- | ---\nbounds | The element's visible frame (`[left, top][right, bottom]`) | `[0,0][100,100]`\nchecked | Whether the element is checked. Always `false` if the element is not checkable | 'false'\nclass | The full name of the element's class. Could be `ComposeNode` for some elements | 'ComposeNode'\nclickable | Whether the element could be clicked | 'false'\ncontent-desc | The content-description attribute of the accessible element | 'foo'\nenabled | Whether the element could be clicked | 'true'\nfocused | Whether the element could is focused. Always `false` if the element is not focusable | 'false'\nindex | Element's index in the tree hierarchy | `0`\npassword | Whether the element is a password input field | 'true'\nresource-id | Element's resource identifier. Could be `null` | 'com.mycompany:id/resId'\nscrollable | Whether the element is scrollable | 'true'\nselected | Whether the element is selected | 'false'\ntext | The element's text | 'my text'\nview-tag | The [testTag](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.Modifier).testTag(kotlin.String)) element's value. Could be `null` | 'my tag'\n\n\n## Espresso Elements Location\n\nEspresso driver supports the following location strategies in `espresso` subdriver:\n\nName | Description | Speed Ranking | Example\n--- | --- | --- | ---\nid | This strategy is mapped to the native Espresso `withId` [matcher](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers#withId(org.hamcrest.Matcher%3Cjava.lang.Integer%3E)) (exact match of element's resource id). Package identifier prefix is added automatically if unset and is equal to the identifier of the current application under test. | `⭐⭐⭐⭐⭐` | 'com.mycompany:id/resourceId'\naccessibility id | This strategy is mapped to the native Espresso `withContentDescription` [matcher](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers#withcontentdescription_1) (exact match of element's content description). | `⭐⭐⭐⭐⭐` | 'my description'\nclass name | This strategy is mapped to the native Espresso `withClassName` [matcher](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers#withClassName(org.hamcrest.Matcher%3Cjava.lang.String%3E)) (exact match of element's class name). | `⭐⭐⭐⭐⭐` | 'android.view.View'\ntext | This strategy is mapped to the native Espresso `withText` [matcher](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers#withText(org.hamcrest.Matcher%3Cjava.lang.String%3E)) (exact match of element's text). | `⭐⭐⭐⭐⭐` | 'my text'\n`-android viewtag` or `tag name` | This strategy is mapped to the native Espresso `withTagValue` [matcher](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers#withtagvalue) (exact match of element's tag value). | `⭐⭐⭐⭐⭐` | 'my tag'\n-android datamatcher | This strategy allows to create Espresso [data interaction](https://developer.android.com/reference/android/support/test/espresso/DataInteraction) selectors which can quickly and reliably scroll to the necessary elements. Read [Espresso DataMatcher Selector](docs/espresso-datamatcher-selector.md) to know more on how to construct these locators. Also check the [Unlocking New Testing Capabilities with Espresso Driver by Daniel Graham](https://www.youtube.com/watch?v=gU9EEUV5n9U) presentation video from Appium Conf 2019. | `⭐⭐⭐⭐` | {\"name\": \"hasEntry\", \"args\": [\"title\", \"WebView3\"]}\n-android viewmatcher | This strategy allows constructing of Espresso [view matchers](https://developer.android.com/reference/androidx/test/espresso/matcher/ViewMatchers) based on the given JSON representation of them. The representation is expected to contain the following fields: `name`: _mandatory_ matcher function name; `args`: _optional_ matcher function arguments, each argument could also be a function; `class`: _optional_ full qualified class name of the corresponding matcher (if not provided then [org.hamcrest.Matchers](https://hamcrest.org/JavaHamcrest/javadoc/2.2/org/hamcrest/Matchers.html) one is used), `scope` (since Espresso driver 2.11.0): _optional_ JSON representation of a [RootMatchers](https://developer.android.com/reference/androidx/test/espresso/matcher/RootMatchers) method. Check [unit tests](https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/HamcrestMatcherTest.kt) for more examples. | `⭐⭐⭐⭐` | {\"name\": \"withText\", \"args\": [{\"name\": \"containsString\", \"args\": \"getExternalStoragePublicDirectory\", \"class\": \"org.hamcrest.Matchers\"}], \"class\": \"androidx.test.espresso.matcher.ViewMatchers\"}\nxpath | For elements lookup Xpath strategy the driver uses the same XML tree that is generated by page source API. Only Xpath 1.0 is supported. | `⭐⭐⭐` | By.xpath(\"//android.view.View[@text=\\\"Regular\\\" and @checkable=\\\"true\\\"]\")\n\n\n## Compose Elements Location\n\nEspresso driver supports the following location strategies in `compose` subdriver:\n\nName | Description | Speed Ranking | Example\n--- | --- | --- | ---\naccessibility id | This strategy is mapped to the native Espresso `hasContentDescription` [matcher](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/package-summary#hasContentDescription(kotlin.String,kotlin.Boolean,kotlin.Boolean)) (exact match of element's content description). | `⭐⭐⭐⭐⭐` | 'my description'\n`-android viewtag` or `tag name` | This strategy is mapped to the native Compose `hasTestTag` [matcher](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/package-summary#hasTestTag(kotlin.String)) (exact match of element's tag value). | `⭐⭐⭐⭐⭐` | 'my tag'\n`text` or `link text` | This strategy is mapped to the native Compose `hasText` [matcher](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/package-summary#hasText(kotlin.String,kotlin.Boolean,kotlin.Boolean)) (exact match of element's text). | `⭐⭐⭐⭐⭐` | 'my text'\nxpath | For elements lookup Xpath strategy the driver uses the same XML tree that is generated by page source API. Only Xpath 1.0 is supported. | `⭐⭐⭐` | By.xpath(\"//ComposeNode[@text=\\\"Regular\\\" and @selected=\\\"true\\\"]\")\n\n\n## Platform-Specific Extensions\n\nBeside of standard W3C APIs the driver provides the below custom command extensions to execute platform specific scenarios. Use the following source code examples in order to invoke them from your client code:\n\n```java\n// Java 11+\nvar result = driver.executeScript(\"mobile: \u003cmethodName\u003e\", Map.of(\n    \"arg1\", \"value1\",\n    \"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```\n\n```js\n// WebdriverIO\nconst result = await driver.executeScript('mobile: \u003cmethodName\u003e', [{\n    arg1: \"value1\",\n    arg2: \"value2\",\n}]);\n```\n\n```python\n# Python\nresult = driver.execute_script('mobile: \u003cmethodName\u003e', {\n    'arg1': 'value1',\n    'arg2': 'value2',\n})\n```\n\n```ruby\n# Ruby\nresult = @driver.execute_script 'mobile: \u003cmethodName\u003e', {\n    arg1: 'value1',\n    arg2: 'value2',\n}\n```\n\n```csharp\n// Dotnet\nobject result = driver.ExecuteScript(\"mobile: \u003cmethodName\u003e\", new Dictionary\u003cstring, object\u003e() {\n    {\"arg1\", \"value1\"},\n    {\"arg2\", \"value2\"}\n});\n```\n\n### mobile: shell\n\nExecutes the given shell command on the device under test via ADB connection. This extension exposes a potential security risk and thus is only enabled when explicitly activated by the `espresso:adb_shell` server command line feature specifier\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | Shell command name to execute, for example `echo` or `rm` | echo\nargs | `Array\u003cstring\u003e` | no | Array of command arguments | `['-f', '/sdcard/myfile.txt']`\ntimeout | number | no | Command timeout in milliseconds. If the command blocks for longer than this timeout then an exception is going to be thrown. The default timeout is `20000` ms | 100000\nincludeStderr | boolean | no | Whether to include stderr stream into the returned result. `false` by default | true\n\n#### Returns\n\nDepending on the `includeStderr` value this API could either return a string, which is equal to the `stdout` stream content of the given command or a dictionary whose elements are `stdout` and `stderr` and values are contents of the corresponding outgoing streams. If the command exits with a non-zero return code then an exception is going to be thrown. The exception message will be equal to the command stderr.\n\n### mobile: execEmuConsoleCommand\n\nExecutes a command through emulator telnet console interface and returns its output.\nThe `emulator_console` server feature must be enabled in order to use this method.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | The actual command to execute. See [Android Emulator Console Guide](https://developer.android.com/studio/run/emulator-console) for more details on available commands | help-verbose\nexecTimeout | number | no | Timeout used to wait for a server reply to the given command in milliseconds. `60000` ms by default | 100000\nconnTimeout | boolean | no | Console connection timeout in milliseconds. `5000` ms by default | 10000\ninitTimeout | boolean | no | Telnet console initialization timeout in milliseconds (the time between the connection happens and the command prompt). `5000` ms by default | 10000\n\n#### Returns\n\nThe actual command output. An error is thrown if command execution fails.\n\n### mobile: performEditorAction\n\nPerforms IME action on the _currently focused_ edit element.\n\nVery often Android developers use [onEditorAction](https://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html#onEditorAction(android.widget.TextView,%20int,%20android.view.KeyEvent)) callback with `actionId` argument to implement actions handling, for example, when `Search` or `Done` button is pressed on the on-screen keyboard. This mobile extension is supposed to emulate the invocation of such callback on the focused element.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | string | yes | The name or an integer code of the editor action to be executed. The following action names are supported: `normal, unspecified, none, go, search, send, next, done, previous`. Read [EditorInfo](https://developer.android.com/reference/android/view/inputmethod/EditorInfo) for more details on this topic. | search\n\n#### Examples\n\n```java\n// Java\ndriver.executeScript(\"mobile: performEditorAction\", ImmutableMap.of(\"action\", \"Go\"));\n```\n\n```python\n# Python\ndriver.execute_script('mobile: performEditorAction', {'action': 'previous'})\n```\n\n### mobile: changePermissions\n\nChanges package permissions in runtime.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npermissions | string or `Array\u003cstring\u003e` | yes | The full name of the permission to be changed or a list of permissions. Mandatory argument. | `['android.permission.ACCESS_FINE_LOCATION', 'android.permission.BROADCAST_SMS']`\nappPackage | string | no | The application package to set change permissions on. Defaults to the package name under test | com.mycompany.myapp\naction | string | no | Either `grant` (the default action) or `revoke` | grant\n\n### mobile: getPermissions\n\nGets runtime permissions list for the given application package.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntype | string | no | One of possible permission types to get. Can be one of: `denied`, `granted` or `requested` (the default value). | granted\nappPackage | string | no | The application package to get permissions from. Defaults to the package name under test | com.mycompany.myapp\n\n#### Returns\n\nArray of strings, where each string is a permission name. the array could be empty.\n\n### mobile: startScreenStreaming\n\nStarts device screen broadcast by creating MJPEG server. Multiple calls to this method have no effect unless the previous streaming session is stopped. This method only works if the `adb_screen_streaming` feature is enabled on the server side. It is also required that [GStreamer](https://gstreamer.freedesktop.org/) with `gst-plugins-base`, `gst-plugins-good` and `gst-plugins-bad` packages is installed and available in PATH on the server machine.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwidth | number | no | The scaled width of the device's screen. If unset then the script will assign it to the actual screen width measured in pixels. | 768\nheight | number | no | The scaled height of the device's screen. If unset then the script will assign it to the actual screen height measured in pixels. | 1024\nbitRate | number | no | The video bit rate for the video, in bits per second. The default value is 4000000 (4 Mb/s). You can increase the bit rate to improve video quality, but doing so results in larger movie files. | 1024000\nhost | string | no | The IP address/host name to start the MJPEG server on. You can set it to `0.0.0.0` to trigger the broadcast on all available network interfaces. `127.0.0.1` by default | 0.0.0.0\npathname | string | no | The HTTP request path the MJPEG server should be available on. If unset then any pathname on the given `host`/`port` combination will work. Note that the value should always start with a single slash: `/` | /myserver\ntcpPort | number | no | The port number to start the internal TCP MJPEG broadcast on. This type of broadcast always starts on the loopback interface (`127.0.0.1`). `8094` by default | 5024\nport | number | no | The port number to start the MJPEG server on. `8093` by default | 5023\nquality | number | no | The quality value for the streamed JPEG images. This number should be in range [1, 100], where 100 is the best quality. `70` by default | 80\nconsiderRotation | boolean | no | If set to `true` then GStreamer pipeline will increase the dimensions of the resulting images to properly fit images in both landscape and portrait orientations. Set it to `true` if the device rotation is not going to be the same during the broadcasting session. `false` by default | false\nlogPipelineDetails | boolean | no | Whether to log GStreamer pipeline events into the standard log output. Might be useful for debugging purposes. `false` by default | true\n\n### mobile: stopScreenStreaming\n\nStop the previously started screen streaming. If no screen streaming server has been started then nothing is done.\n\n### mobile: deviceInfo\n\nRetrieves the information about the device under test, like the device model, serial number, network connectivity info, etc.\n\n#### Returns\n\nThe extension returns a dictionary whose entries are the device properties. Check https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetDeviceInfo.kt to get the full list of returned keys and their corresponding values.\n\n### mobile: swipe\n\nPerform swipe action. Invokes Espresso [swipe action](https://developer.android.com/reference/android/support/test/espresso/action/Swipe) under the hood.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | The UDID of the element to perform the swipe on. | 123456-7890-3453-24234243\ndirection | string | no | Swipe direction. Either this argument or `swiper` must be provided, but not both. The following values are supported: `up`, `down`, `left`, `right` | down\nswiper | string | no | Swipe speed. Either this argument or `direction` must be provided, but not both. Either `FAST` (Swipes quickly between the co-ordinates) or `SLOW` (Swipes deliberately slowly between the co-ordinates, to aid in visual debugging) | SLOW\nstartCoordinates | string | no | The starting coordinates for the action. The following values are supported: `TOP_LEFT`, `TOP_CENTER`, `TOP_RIGHT`, `CENTER_LEFT`, `CENTER`, `CENTER_RIGHT`, `BOTTOM_LEFT`, `BOTTOM_CENTER` (the default value), `BOTTOM_RIGHT`, `VISIBLE_CENTER` | CENTER_LEFT\nendCoordinates | string | no | The ending coordinates for the action. The following values are supported: `TOP_LEFT`, `TOP_CENTER` (the default value), `TOP_RIGHT`, `CENTER_LEFT`, `CENTER`, `CENTER_RIGHT`, `BOTTOM_LEFT`, `BOTTOM_CENTER`, `BOTTOM_RIGHT`, `VISIBLE_CENTER` | TOP_LEFT\nprecisionDescriber | string | no | Defines the actual swipe precision. The following values are supported: `PINPOINT` (1px), `FINGER` (average width of the index finger is 16 – 20 mm), `THUMB` (average width of an adult thumb is 25 mm or 1 inch, the default value) | FINGER\n\n### mobile: isToastVisible\n\nChecks whether a toast notification with the given text is currently visible.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntext | string | yes | The actual toast test or a part of it | 'toast text'\nisRegexp | boolean | no | Whether the `text` value should be parsed as a regular expression (`true`) or as a raw text (`false`, the default value) | false\n\n#### Returns\n\nEither `true` or `false`\n\n### mobile: openDrawer\n\nOpens the DrawerLayout drawer with the gravity. This method blocks until the drawer is fully open. No operation if the drawer is already open.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | UDID of the element to perform the action on. | 123456-7890-3453-24234243\ngravity | int | no | See [GravityCompat](https://developer.android.com/reference/kotlin/androidx/core/view/GravityCompat) and [Gravity](https://developer.android.com/reference/android/view/Gravity) classes documentation | `0x00800000 \u003cbitwise_or\u003e 0x00000003`\n\n### mobile: closeDrawer\n\nCloses the DrawerLayout drawer with the gravity. This method blocks until the drawer is fully closed. No operation if the drawer is already closed.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | UDID of the element to perform the action on. | 123456-7890-3453-24234243\ngravity | int | no | See [GravityCompat](https://developer.android.com/reference/kotlin/androidx/core/view/GravityCompat) and [Gravity](https://developer.android.com/reference/android/view/Gravity) classes documentation | `0x00800000 \u003cbitwise_or\u003e 0x00000005`\n\n### mobile: scrollToPage\n\nPerform scrolling to the given page. Invokes one of the [ViewPagerActions](https://developer.android.com/reference/androidx/test/espresso/contrib/ViewPagerActions) under the hood. Which action is invoked depends on the given arguments.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | UDID of the element to perform the action on. | 123456-7890-3453-24234243\nscrollTo | string | no if `scrollToPage` is provided | Shifts ViewPager to the given page. Supported values are: `first`, `last`, `left`, `right` | last\nscrollToPage | int | no if `scrollTo` is provided | Moves ViewPager to a specific page number (numbering starts from zero). | 1\nsmoothScroll | boolean | no | Whether to perform smooth (but slower) scrolling (`true`). The default value is `false` | true\n\n### mobile: navigateTo\n\nInvokes [navigateTo](https://developer.android.com/reference/androidx/test/espresso/contrib/NavigationViewActions#navigateto) action under the hood.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | UDID of the element to perform the action on. View constraints: View must be a child of a DrawerLayout; View must be of type NavigationView; View must be visible on screen; View must be displayed on screen | 123456-7890-3453-24234243\nmenuItemId | int | yes | The resource id of the destination menu item | 123\n\n### mobile: clickAction\n\nPerform [general click action](https://developer.android.com/reference/androidx/test/espresso/action/GeneralClickAction).\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | The UDID of the element to perform the click on. | 123456-7890-3453-24234243\ntapper | string | no | Tapper type. Supported types are: `SINGLE` (the default value), `LONG`, `DOUBLE` | `LONG`\ncoordinatesProvider | string | no | The coordinates for the action. The following values are supported: `TOP_LEFT`, `TOP_CENTER`, `TOP_RIGHT`, `CENTER_LEFT`, `CENTER`, `CENTER_RIGHT`, `BOTTOM_LEFT`, `BOTTOM_CENTER`, `BOTTOM_RIGHT`, `VISIBLE_CENTER` (the default value) | CENTER_LEFT\nprecisionDescriber | string | no | Defines the actual click precision. The following values are supported: `PINPOINT` (1px), `FINGER` (average width of the index finger is 16 – 20 mm, the default value), `THUMB` (average width of an adult thumb is 25 mm or 1 inch) | PINPOINT\ninputDevice | int | no | Input device identifier, `0` by default | 1\nbuttonState | int | no | Button state id, `0` by default | 1\n\n### mobile: getContexts\n\nRetrieves a WebViews mapping based on CDP endpoints\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwaitForWebviewMs | number | no | Tells Espresso driver for how long (in milliseconds) to wait for web view(s) to appear since Espresso driver v2.30.0. If a Chrome process running on the device under test fails to create a connection to the devtools socket, then the chromedriver will rise an error similar to `failed to connect to socket 'localabstract:chrome_devtools_remote'` in Espresso driver. It could cause no WebViews found result, although a couple of retrials may fix it. This argument helps to keep trying to get WebView(s) up to the given time milliseconds as one command call. This issue tends to occur Chrome v115 and over so far. [issues#19251](https://github.com/appium/appium/issues/19251) contains more details. If set to `0`ms (the default value), then Espresso driver only checks the WebView(s) availability once. | 10000\n\n#### Returns\n\nThe following json demonstrates the example of WebviewsMapping object.\nNote that `description` in `page` can be an empty string most likely when it comes to Mobile Chrome)\n\n```json\n {\n   \"proc\": \"@webview_devtools_remote_22138\",\n   \"webview\": \"WEBVIEW_22138\",\n   \"info\": {\n     \"Android-Package\": \"io.appium.settings\",\n     \"Browser\": \"Chrome/74.0.3729.185\",\n     \"Protocol-Version\": \"1.3\",\n     \"User-Agent\": \"Mozilla/5.0 (Linux; Android 10; Android SDK built for x86 Build/QSR1.190920.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.185 Mobile Safari/537.36\",\n     \"V8-Version\": \"7.4.288.28\",\n     \"WebKit-Version\": \"537.36 (@22955682f94ce09336197bfb8dffea991fa32f0d)\",\n     \"webSocketDebuggerUrl\": \"ws://127.0.0.1:10900/devtools/browser\"\n   },\n   \"pages\": [\n     {\n       \"description\": \"{\\\"attached\\\":true,\\\"empty\\\":false,\\\"height\\\":1458,\\\"screenX\\\":0,\\\"screenY\\\":336,\\\"visible\\\":true,\\\"width\\\":1080}\",\n       \"devtoolsFrontendUrl\": \"http://chrome-devtools-frontend.appspot.com/serve_rev/@22955682f94ce09336197bfb8dffea991fa32f0d/inspector.html?ws=127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F\",\n       \"id\": \"27325CC50B600D31B233F45E09487B1F\",\n       \"title\": \"Releases · appium/appium · GitHub\",\n       \"type\": \"page\",\n       \"url\": \"https://github.com/appium/appium/releases\",\n       \"webSocketDebuggerUrl\": \"ws://127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F\"\n     }\n   ],\n   \"webviewName\": \"WEBVIEW_com.io.appium.setting\"\n }\n```\n\n### mobile: getNotifications\n\nRetrieves Android notifications via Appium Settings helper. Appium Settings app itself must be *manually* granted to access notifications under device Settings in order to make this feature working. Appium Settings helper keeps all the active notifications plus notifications that appeared while it was running in the internal buffer, but no more than 100 items altogether. Newly appeared notifications are always added to the head of the notifications array. The `isRemoved` flag is set to `true` for notifications that have been removed.\nSee https://developer.android.com/reference/android/service/notification/StatusBarNotification and https://developer.android.com/reference/android/app/Notification.html for more information on available notification properties and their values.\n\n#### Returns\n\nThe example output is:\n```json\n{\n   \"statusBarNotifications\":[\n     {\n       \"isGroup\":false,\n       \"packageName\":\"io.appium.settings\",\n       \"isClearable\":false,\n       \"isOngoing\":true,\n       \"id\":1,\n       \"tag\":null,\n       \"notification\":{\n         \"title\":null,\n         \"bigTitle\":\"Appium Settings\",\n         \"text\":null,\n         \"bigText\":\"Keep this service running, so Appium for Android can properly interact with several system APIs\",\n         \"tickerText\":null,\n         \"subText\":null,\n         \"infoText\":null,\n         \"template\":\"android.app.Notification$BigTextStyle\"\n       },\n       \"userHandle\":0,\n       \"groupKey\":\"0|io.appium.settings|1|null|10133\",\n       \"overrideGroupKey\":null,\n       \"postTime\":1576853518850,\n       \"key\":\"0|io.appium.settings|1|null|10133\",\n       \"isRemoved\":false\n     }\n   ]\n}\n```\n\n### mobile: listSms\n\nRetrieves the list of the most recent SMS properties list via Appium Settings helper. Messages are sorted by date in descending order.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nmax | number | no | The maximum count of recent messages to retrieve. `100` by default | 10\n\n#### Returns\n\nThe example output is:\n```json\n {\n   \"items\":[\n     {\n       \"id\":\"2\",\n       \"address\":\"+123456789\",\n       \"person\":null,\n       \"date\":\"1581936422203\",\n       \"read\":\"0\",\n       \"status\":\"-1\",\n       \"type\":\"1\",\n       \"subject\":null,\n       \"body\":\"\\\"text message2\\\"\",\n       \"serviceCenter\":null\n     },\n     {\n       \"id\":\"1\",\n       \"address\":\"+123456789\",\n       \"person\":null,\n       \"date\":\"1581936382740\",\n       \"read\":\"0\",\n       \"status\":\"-1\",\n       \"type\":\"1\",\n       \"subject\":null,\n       \"body\":\"\\\"text message\\\"\",\n       \"serviceCenter\":null\n     }\n   ],\n   \"total\":2\n }\n```\n\n### mobile: sensorSet\n\nEmulate changing of sensor values on the connected emulator.\nThis extension does not work on real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nsensorType | string | yes | The set of all supported sensor types could be found in [adb-emu-commands.js](https://github.com/appium/appium-adb/blob/master/lib/tools/adb-emu-commands.js) (look for *SENSORS* object values). Check the output of `sensor status` command in the [emulator console](https://developer.android.com/studio/run/emulator-console) to see more details on the available sensor types | light\nvalue | string | yes | Check the output of `sensor get \u003csensorType\u003e` command in the [emulator console](https://developer.android.com/studio/run/emulator-console) to see the acceptable value format for the given sensor type | 50\n\n### mobile: refreshGpsCache\n\nSends a request to refresh the GPS cache on the device under test.\nBy default the location tracking is configured for\n[low battery consumption](https://github.com/appium/io.appium.settings/blob/master/app/src/main/java/io/appium/settings/LocationTracker.java),\nso you might need to call this extension periodically to get the updated geo\nlocation if the actual (or mocked) device location is changed too frequently.\nThe feature only works if the device under test has Google Play Services installed.\nIn case the vanilla\n[LocationManager](https://developer.android.com/reference/android/location/LocationManager)\nis used the device API level must be at version 30 (Android R) or higher.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntimeoutMs | number | no | The maximum number of milliseconds to block until GPS cache is refreshed. If the API call does not receive a confirmation about successful cache refresh within this timeout then an error is thrown. Providing zero or a negative value to it skips waiting completely and does not check for any errors. 20000 ms by default. | 60000\n\n### mobile: setGeolocation\n\nSets emulated geolocation coordinates on the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nlatitude | number | yes | [Latitude](https://en.wikipedia.org/wiki/Latitude) value | 32.456\nlongitude | number | yes | [longitude](https://en.wikipedia.org/wiki/Longitude) value | 32.456\naltitude | number | no | [Altitude](https://en.wikipedia.org/wiki/Altitude) value. Zero by default | 5.678\nsatellites | number | no | Number of satellites being tracked (1-12). Available for emulators. | 2\nspeed | number | no | [Set the speed](https://developer.android.com/reference/android/location/Location#setSpeed(float)) in meters per second. Valid value is `0.0` or greater. | 30.0\nbearing | number | no | [Set the bearing](https://developer.android.com/reference/android/location/Location#setBearing(float)) at the time of this location, in degrees. Available for real devices. Valid values should be in range `[0, 360)`. | 10\naccuracy | number | no | [Set the horizontal accuracy](https://developer.android.com/reference/android/location/Location#setAccuracy(float)) in meters of this location. Available for real devices. Valid value is `0.0` or greater. | 10.0\n\n### mobile: getGeolocation\n\nRetrieves current geolocation coordinates from the device under test. If coordinates are mocked/emulated\nthen these coordinates would be returned.\n\n#### Returned Result\n\nA map with the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nlatitude | number | [Latitude](https://en.wikipedia.org/wiki/Latitude) value | 32.456\nlongitude | number | [longitude](https://en.wikipedia.org/wiki/Longitude) value | 32.456\naltitude | number | [Altitude](https://en.wikipedia.org/wiki/Altitude) value | 5.678\n\n### mobile: resetGeolocation\n\nResets mocked geolocation provider to the default/system one. Only works for real devices.\n\n### mobile: pullFile\n\nPulls a remote file from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The full path to the remote file or a specially formatted path, which points to an item inside an app bundle, for example `@my.app.id/my/path`. It is mandatory for the app bundle to have [debugging enabled](https://developer.android.com/studio/debug) in order to use the latter remotePath format. If the file with the given name does not exist then an exception will be thrown. | /sdcard/foo.bar\n\n#### Returned Result\n\nBase64-encoded string, which represents the content of the remote file.\n\n### mobile: pushFile\n\nPushes a local file to the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | 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](#mobile-pullfile) extension. If the file with the same name already exists then it will be silently overridden. | /sdcard/foo.bar\npayload | string | yes | Base64-encoded content of the file to be pushed. | QXBwaXVt\n\n### mobile: pullFolder\n\nPulls a remote folder from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | Same as for [pullFile](#mobile-pullfile) extension, but should be pointing to a remote folder | /sdcard/yolo/\n\n#### Returned Result\n\nBase64-encoded string, which represents the zipped content of the remote folder.\n\n### mobile: deleteFile\n\nDeletes a file on the remote device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The full path to the remote file or a file inside an application bundle | `/sdcard/myfile.txt` or `@my.app.id/path/in/bundle`\n\n### mobile: isAppInstalled\n\nVerify whether an application is installed on the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be checked | `my.app.id`\nuser | number or string | no | The user ID for which the package is installed. The `current` user is used by default | 1006\n\n#### Returned Result\n\nTrue or false\n\n### mobile: listApps\n\nLists all installed packages on the Android device, optionally filtered by user.\nAn exception will be thrown on devices running Android API below level 26.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nuser | number or string | no | The user ID for which the package is installed. The `current` user is used by default | 1006\n\n#### Returned Result\n\nA map where keys are packageName and values are maps of platform-specific app properties since Espresso driver v7.0.0.\nEspresso driver v6.4.0 was a list of installed package names.\n\n### mobile: queryAppState\n\nQueries the current state of the app.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be checked | `my.app.id`\n\n#### Returned Result\n\nThe following numbers could returned:\n- The app is not installed: `0`\n- The app is installed and is not running: `1`\n- The app is running in background: `3`\n- The app is running in foreground: `4`\n\n### mobile: activateApp\n\nActivates the given application or launches it if necessary.\nThe action literally simulates\nclicking the corresponding application icon on the dashboard.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be activated | `my.app.id`\n\n### mobile: removeApp\n\nRemove the corresponding application if is installed.\nThe call is ignored if the app is not installed.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be removed | `my.app.id`\ntimeout | number | no | The count of milliseconds to wait until the app is terminated. 20000ms by default. | 1500, 0\nkeepData | boolean | no | Set to true in order to keep the application data and cache folders after uninstall. | true\n\n#### Returned Result\n\nTrue is the app has been found on the device and successfully removed. Otherwise false.\n\n### mobile: terminateApp\n\nTerminates the app and waits until the app is terminated up to the given timeout\nby checking the app state to ensure if the app process is actually stopped.\n\nThe app state check can be skipped if the given timeout is lower or equal to zero since Espresso driver 2.13.0.\nThe skip helps when you want to terminate the app process but do not want to check the process existence\nbecause the app under test may, for example, restart it automatically.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be terminated | `my.app.id`\ntimeout | number | no | The count of milliseconds to wait until the app is terminated. 500ms by default. | 1500, 0\n\n#### Returned Result\n\nTrue if the app has been successfully terminated.\n\n### mobile: installApp\n\nInstalls the given application package to the device under test.\nIt might raise the `INSTALL_FAILED_VERSION_DOWNGRADE` error if the installation was a version downgrade.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappPath | string | yes | The local .apk(s) path on the server filesystem or a remote url. | `/app/path.apk`\ntimeout | number | no | The count of milliseconds to wait until the app is installed.. 6000ms by default. | 120000\nallowTestPackages | boolean | no | Set to true in order to allow test packages installation. false by default | true\nuseSdcard | boolean | no | Set to true to install the app on sdcard instead of the device memory. false by default | true\ngrantPermissions | boolean | no | Set to true in order to grant all the permissions requested in the application's manifest automatically after the installation is completed under Android 6+. The targetSdkVersion in the application manifest must be greater or equal to 23 and the Android version on the device under test must be greater or equal to Android 6 (API level 23) to grant permissions. Applications whose targetSdkVersion is lower than or equal to 22 must be reisntalled to grant permissions for Android 6+ devices. false by default | true\nreplace | boolean | no | Set it to false if you don't want the application to be upgraded/reinstalled if it is already present on the device, but throw an error instead. true by default | false\ncheckVersion | boolean | no | Set to true, in order to skip the application installation if the device under test has a greater or equal to the application version. It may help to avoid `INSTALL_FAILED_VERSION_DOWNGRADE` error and unnecessary installation. | true\n\n### mobile: clearApp\n\nDeletes all data associated with a package. Calls `adb shell pm clear` under the hood.\nThe app should be accessible, should not be running,\nand should exist on the device under test for this extension to work properly.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be cleared | `my.app.id`\n\n#### Returned Result\n\nStdout of the corresponding adb command.\n\n### mobile: startActivity\n\nStarts the given activity with intent options, activity options and locale. Activity could only be executed in scope of the current app package.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappActivity | string | yes | Application activity identifier to start | `com.myapp.myacitivty`\nlocale | object | no | Sets the locale for the app under test. It only uses public APIs for its purpose. See https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers to get the list of available language abbreviations. | `{\"language\": \"zh\", \"country\": \"CN\", \"variant\": \"Hans\"}`\noptionalIntentArguments | object | no | The mapping of custom options for the intent that is going to be passed to the main app activity. Check [Intent Options](#intent-options) for more details. | `{ 'flags': 'ACTIVITY_NEW_TASK', 'action': '\u003cintent_action\u003e', 'className': '\u003cfullyQualifiedAppActivity\u003e', 'es': {'foo': 'bar'} }`\noptionalActivityArguments | object | no | The mapping of custom options for the main app activity that is going to be started. Check [Activity Options](#activity-options) for more details. | `{ 'launchDisplayId': 1 }`\n\n### mobile: startService\n\nStarts the given service intent.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | yes | The name of the service intent to start. Only services in the app's under test scope could be started. | `com.some.package.name/.YourServiceSubClassName`\nuser | number or string | no | The user ID for which the service is started. The `current` user id is used by default | 1006\nforeground | boolean | no | Set it to `true` if your service must be started as foreground service. | false\n\n### mobile: stopService\n\nStops the given service intent.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | yes | The name of the service intent to stop. Only services in the app's under test scope could be stopped. | `com.some.package.name/.YourServiceSubClassName`\nuser | number or string | no | The user ID for which the service is started. The `current` user id is used by default | 1006\n\n### mobile: broadcast\n\nSend a broadcast Intent. Invokes `am broadcast` command under the hood.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | no | The full name of the intent to broadcast | `com.some.package.name/.YourIntentClassName`\nuser | number or string | no | Specify which user to send to; if not specified then send to all users. Possible values are `all`/`current`/`\u003cnumeric user id\u003e` | current\nreceiverPermission | string | no | Require receiver to hold the given permission | android.permission.READ_PROFILE\nallowBackgroundActivityStarts | boolean | no | The receiver may start activities even if in the background if set to `true` | false\naction | string | no | Action name. The actual value for the Activity Manager's `-a` argument. | android.intent.action.MAIN\nuri | string | no | Unified resource identifier. The actual value for the Activity Manager's `-d` argument. | https://appium.io\nmimeType | string | no | Mime type. The actual value for the Activity Manager's `-t` argument. | application/json\nidentifier | string | no | Optional identifier. The actual value for the Activity Manager's `-i` argument. | my_identifier\ncategories | string or Array\u0026lt;string\u0026gt; | no | One or more category names. The actual value(s) for the Activity Manager's `-c` argument. | android.intent.category.LAUNCHER\ncomponent | string | no | Component name. The actual value for the Activity Manager's `-n` argument. | com.myapp/com.myapp.SplashActivity\npackage | string | no | Package name. The actual value for the Activity Manager's `-p` argument. | com.myapp\nextras | Array\u0026lt;Array\u0026lt;string\u0026gt;\u0026gt; | no | Optional intent arguments. Must be represented as an array of arrays, where each subarray item contains two (only in case it no value is required for the given type) or three string items: value type, key (variable name) and the value itself. Supported value types are: `s`: string. Value must be a valid string; `sn`: null. Value is ignored for this type; `z`: boolean. Value must be either `true` or `false`; `i`: integer. Value must be a valid 4-byte integer number; `l`: long. Value must be a valid 8-byte long number; `f`: float: Value must be a valid float number; `u`: uri. Value must be a valid uniform resource identifier string; `cn`: component name. Value must be a valid component name string; `ia`: Integer[]. Value must be a string of comma-separated integers; `ial`: List\u0026lt;Integer\u0026gt;. Value must be a string of comma-separated integers; `la`: Long[]. Value must be a string of comma-separated long numbers; `lal`: List\u0026lt;Long\u0026gt;. Value must be a string of comma-separated long numbers; `fa`: Float[]. Value must be a string of comma-separated float numbers; `fal`: List\u0026lt;Float\u0026gt;. Value must be a string of comma-separated float numbers; `sa`: String[]. Value must be comma-separated strings. To embed a comma into a string escape it using \"\\,\"; `sal`: List\u0026lt;String\u0026gt;. Value must be comma-separated strings. To embed a comma into a string, escape it using \"\\,\" | [['s', 'varName1', 'My String1'], ['s', 'varName2', 'My String2'], ['ia', 'arrName', '1,2,3,4']]\nflags | string | no | Intent startup-specific flags as a hexadecimal string. Check [Intent documentation](https://developer.android.com/reference/android/content/Intent.html) for the list of available flag values (constants starting with `FLAG_ACTIVITY_`). Flag values could be merged using the logical 'or' operation. | 0x10200000 is the combination of two flags: 0x10000000 `FLAG_ACTIVITY_NEW_TASK` `|` 0x00200000 `FLAG_ACTIVITY_RESET_TASK_IF_NEEDED`\n\n#### Returned Result\n\nThe actual stdout of the downstream `am` command.\n\n### mobile: getDeviceTime\n\nRetrieves the current device's timestamp.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nformat | string | no | The set of format specifiers. Read https://momentjs.com/docs/ 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-DDTHH:mm:ssZ\n\n#### Returns\n\nThe device timestamp string formatted according to the given specifiers\n\n### mobile: setDate\n\nSet the given date for a picker control. Invokes https://developer.android.com/reference/androidx/test/espresso/contrib/PickerActions#setdate under the hood.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nyear | int | yes | The year to set | 2020\nmonthOfYear | int | yes | The number of the month to set | 3\ndayOfMonth | int | yes | The number of the day to set | 20\n\n### mobile: setTime\n\nSet the given time for a picker control. Invokes https://developer.android.com/reference/androidx/test/espresso/contrib/PickerActions#settime under the hood.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nhours | int | yes | Hour to set in range 0..23 | 14\nminutes | int | yes | Minute to set in range 0..59 | 15\n\n### mobile: flashElement\n\nHighlights the given element in the UI by adding flashing to it\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (element before v2.29) | string | yes | UDID of the element to perform the action on. | 123456-7890-3453-24234243\ndurationMillis | int | no | Duration of single flashing sequence, 30 ms by default | 50\nrepeatCount | int | no | Count of repeats, 15 times by default | 10\n\n### mobile: dismissAutofill\n\nDismisses [autofill](https://developer.android.com/guide/topics/text/autofill) picker if it is visible on the screen.\n\n### mobile: backdoor\n\nGives a possibility to invoke methods from your application under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | yes if `target` is set to `element` | UDID of the element to perform the action on. | 123456-7890-3453-24234243\ntarget | string | yes | Select a target for the backdoor method execution: `activity`, `application`, `element` | activity\nmethods | `Array\u003cMap\u003e` | yes | Methods chain to execute | See [Backdoor Extension Usage](#backdoor-extension-usage)\n\n#### Returns\n\nThe result of the last method in the chain\n\n### mobile: uiautomator\n\nAllows to execute a limited set of [UiAutomator](https://developer.android.com/training/testing/ui-automator) commands to allow out-of-app interactions with accessibility elements.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nstrategy | string | yes | UiAutomator element location strategy. The following strategies are supported: \"clazz\", \"res\", \"text\", \"textContains\", \"textEndsWith\", \"textStartsWith\", \"desc\", \"descContains\", \"descEndsWith\", \"descStartsWith\", \"pkg\" | desc\nlocator | string | yes | Valid UiObject2 locator value for the given strategy | 'my description'\naction | string | yes | The action name to perform on the found element. The following actions are supported: \"click\", \"longClick\", \"getText\", \"getContentDescription\", \"getClassName\",  \"getResourceName\", \"getVisibleBounds\", \"getVisibleCenter\", \"getApplicationPackage\", \"getChildCount\", \"clear\", \"isCheckable\", \"isChecked\", \"isClickable\", \"isEnabled\", \"isFocusable\", \"isFocused\", \"isLongClickable\", \"isScrollable\", \"isSelected\" | isEnabled\nindex | int | no | If the given locator matches multiple elements then only the element located by this index will be selected for the interaction, otherwise the method will be applied to all found elements.  Indexing starts from zero | 1\n\n#### Returns\n\nThe result of the selected action applied to found elements. If index is provided then the array will only contain one item. If the index is greater than the count of found elements then an exception will be thrown.\n\n### mobile: uiautomatorPageSource\n\nAllows to retrieve accessibility elements hierarchy tree with [UiAutomator](https://developer.android.com/training/testing/ui-automator) framework. The extension calls [dumpWindowHierarchy](https://developer.android.com/reference/androidx/test/uiautomator/UiDevice#dumpwindowhierarchy_1) under the hood.\n\n#### Returns\n\nThe UI accessibility hierarchy represented as XML document.\n\n### mobile: webAtoms\n\nAllows to run a chain of [Espresso web atoms](https://developer.android.com/training/testing/espresso/web) on a web view element.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwebviewEl | string | yes | The UDID of the destination web view element | 123456-7890-3453-24234243\nforceJavascriptEnabled | boolean | yes | If webview disables javascript then webatoms won't work. Setting this argument to `true` enforces javascript to be enabled. | true\nmethodChain | `Array\u003cMap\u003e` | yes | Chain of atoms to execute. Each item in the chain must have the following properties: `name` (must be one of [WebInteraction](https://developer.android.com/reference/androidx/test/espresso/web/sugar/Web.WebInteraction) action names) and `atom`. `atom` is a map with two entries: `name` (must be one of [DriverAtoms](https://developer.android.com/reference/androidx/test/espresso/web/webdriver/DriverAtoms) method names) and `args` (must be an array of the corresponding method values). | `[{\"name\": \"methodName\", \"atom\": {\"name\": \"atomName\", \"args\": [\"arg1\", \"arg2\", ...]}}, ...]`\n\n#### Returns\n\nChain items are executed sequentially and the next item is executed on the result of the previous item. The final result is returned to the caller.\n\n### mobile: registerIdlingResources\n\nRegisters one or more [idling resources](https://developer.android.com/training/testing/espresso/idling-resource).\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nclassNames | string | yes | Comma-separated list of idling resources class names. Each name must be a full-qualified java class name. Each class in the app source must implement a singleton pattern and have a static `getInstance()` method returning the class instance, which implements `androidx.test.espresso.IdlingResource` interface. Read [Integrate Espresso Idling Resources in your app to build flexible UI tests](https://android.jlelse.eu/integrate-espresso-idling-resources-in-your-app-to-build-flexible-ui-tests-c779e24f5057) for more details on how to design and use idling resources concept in Espresso. | `io.appium.espressoserver.lib.MyIdlingResource`\n\n### mobile: unregisterIdlingResources\n\nUnregisters one or more [idling resources](https://developer.android.com/training/testing/espresso/idling-resource).\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nclassNames | string | yes | Comma-separated list of idling resources class names. Each name must be a full-qualified java class name. Each class in the app source must implement a singleton pattern and have a static `getInstance()` method returning the class instance, which implements `androidx.test.espresso.IdlingResource` interface. Read [Integrate Espresso Idling Resources in your app to build flexible UI tests](https://android.jlelse.eu/integrate-espresso-idling-resources-in-your-app-to-build-flexible-ui-tests-c779e24f5057) for more details on how to design and use idling resources concept in Espresso. | `io.appium.espressoserver.lib.MyIdlingResource`\n\n### mobile: listIdlingResources\n\nLists all the previously registered [idling resources](https://developer.android.com/training/testing/espresso/idling-resource).\n\n#### Returns\n\nList of fully qualified class names of currently registered idling resources or an empty list if no resources have been registered yet.\n\n### mobile: waitForUIThread\n\n- Wait for the UI thread to become idle, in other words, wait for the APP to become [idle](https://developer.android.com/reference/androidx/test/espresso/UiController#loopMainThreadUntilIdle()).\n- Use case: On compose and native combination screens, it's possible for the Espresso API to block the UI thread, which can cause the app to freeze. To resolve this issue, it's recommended to explicitly call the `mobile:waitForUIThread` API, which can help to unfreeze the UI thread.\n\n### mobile: unlock\n\nUnlocks the device if it is locked. Noop if the device's screen is not locked.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nkey | string | yes | The unlock key. See the documentation on [appium:unlockKey](#device-locking) capability for more details | 12345\ntype | string | yes | The unlock type. See the documentation on [appium:unlockType](#device-locking) capability for more details | password\ntimeoutMs | number | no | Unlock timeout. See the documentation on [appium:unlockSuccessTimeout](#device-locking) capability for more details | 5000\n\n### mobile: isLocked\n\nDetermine whether the device is locked.\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: lock\n\nLock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nseconds | 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). | 5\n\n### mobile: startMediaProjectionRecording\n\nStarts a new recording of the device activity using [Media Projection](https://developer.android.com/reference/android/media/projection/MediaProjection) API. This API is available since Android 10 (API level 29) and allows to record device screen and audio in high quality. Video and audio encoding is done by Android itself.\nThe recording is done by [Appium Settings helper](https://github.com/appium/io.appium.settings#internal-audio--video-recording).\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nresolution | string | no | The resolution of the resulting video, which usually equals to Full HD 1920x1080 on most phones, however you could change it to one of the following supported resolutions: \"1920x1080\", \"1280x720\", \"720x480\", \"320x240\", \"176x144\" | 1280x720\nmaxDurationSec | number | no | The maximum number of seconds allowed for the recording to run. 900 seconds by default (15 minutes) | 300\npriority | string | no | Recording thread priority is set to maximum (`high`) by default. However if you face performance drops during testing with recording enabled, you could reduce the recording priority to `normal` or `low`. | low\nfilename | string | no | You can type recording video file name as you want, but recording currently supports only \"mp4\" format so your filename must end with \".mp4\". An invalid file name will fail to start the recording. If not provided then the current timestamp will be used as file name. | screen.mp4\n\n#### Returned Result\n\n`true` if a new recording has successfully started. `false` if another recording is currently running.\n\n### mobile: isMediaProjectionRecordingRunning\n\nCheck if a media projection recording is currently running\n\n#### Returned Result\n\n`true` if a recording is running.\n\n### mobile: stopMediaProjectionRecording\n\nStops a recording and retrieves the recently recorded media. If no recording has been started before then an error is thrown. If the recording has been already finished before this API has been called then the most recent recorded media is returned.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | no | The path to the remote location, where the resulting video 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 as the endpoont response value. An exception will be thrown if the generated media file is too big to fit into the available process memory. | https://myserver.com/upload\nuser | string | no | The name of the user f","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappium%2Fappium-espresso-driver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappium%2Fappium-espresso-driver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappium%2Fappium-espresso-driver/lists"}