<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: WasiqBhamla</title>
    <description>The latest articles on DEV Community by WasiqBhamla (@wasiqbhamla).</description>
    <link>https://dev.to/wasiqbhamla</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F990896%2F09d9af25-fde9-43f3-a559-99993264f1aa.jpeg</url>
      <title>DEV Community: WasiqBhamla</title>
      <link>https://dev.to/wasiqbhamla</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wasiqbhamla"/>
    <language>en</language>
    <item>
      <title>A Complete Tutorial to Appium Capabilities for Mobile Automation</title>
      <dc:creator>WasiqBhamla</dc:creator>
      <pubDate>Thu, 17 Aug 2023 08:54:56 +0000</pubDate>
      <link>https://dev.to/testmuai/a-complete-tutorial-to-appium-capabilities-for-mobile-automation-3cmi</link>
      <guid>https://dev.to/testmuai/a-complete-tutorial-to-appium-capabilities-for-mobile-automation-3cmi</guid>
      <description>&lt;p&gt;Capabilities are a set of parameters that describes the device on which the Appium test should run, along with the application to be used for testing. These capabilities must be provided to the Appium Server while creating the session. With these capabilities, the Appium Server parses them and creates the session with the target device described in the capabilities, and installs or launches the target application on the device before our test starts executing.&lt;/p&gt;

&lt;p&gt;Before we go into more detail with capabilities, let’s first understand Appium. &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium&lt;/a&gt; is an open-source &lt;a href="https://www.lambdatest.com/blog/best-mobile-app-testing-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile application testing framework&lt;/a&gt; and a complete ecosystem to help automate Android and iOS applications categorized across different mobile-based applications, like Native, Web, and Hybrid. It also supports automating Smart TV and Windows and macOS-based desktop applications.&lt;/p&gt;

&lt;p&gt;Appium consists of two core components. The first is the Appium Server command line library, a NodeJS-based library that completely manages the Appium session created with the device. The second component is the Appium Client, which is available in multiple programming languages like Java, Python, JavaScript, etc. The client is responsible for communicating with the Appium Server and providing it with instructions about how to communicate with the application on the target device and test it.&lt;/p&gt;

&lt;p&gt;Capabilities are used with these Appium Clients, which consume the capabilities provided to them and pass on these capabilities to the Appium Server, which in turn understands them and starts the mobile device session based on these capabilities.&lt;/p&gt;

&lt;p&gt;In addition to leveraging Appium’s capabilities for interactions and validations, integrating &lt;a href="https://www.lambdatest.com/appium-visual-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium Visual Testing&lt;/a&gt; allows you to extend your testing horizon to include visual regressions. By automatically capturing and comparing UI screenshots between baseline and current versions, Appium Visual Testing helps identify even the subtlest visual discrepancies that might impact user satisfaction. This comprehensive approach not only ensures that your app functions as intended but also maintains its visual integrity across iterations.&lt;/p&gt;

&lt;p&gt;In this blog on Appium Capabilities, we will be using Appium 2.0. To understand what changes Appium 2.0 brings in from Appium 1.x, it has decoupled Appium drivers from its command line tool. Earlier, it used to install all the available drivers when you installed the Appium command line tool. But with Appium 2.0, only the command line tool will be installed, while you can install only those drivers you want to use.&lt;/p&gt;

&lt;p&gt;If you are using Appium 1.x and want to learn more about Appium 2.x or even switch to it, you can go through this &lt;a href="https://www.lambdatest.com/blog/appium-2-migration-guide/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium 2 migration guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this tutorial on Appium Capabilities, we will cover different types of capabilities for Android and iOS platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Common Appium capabilities, which are common irrespective of the target platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Platform-specific Appium capabilities, which are platform-specific, like Android has its own set of capabilities, and iOS has its own.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver-specific Appium capabilities, which are driver-specific, like the UiAutomator2 driver will have different capabilities than the Espresso driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud platform-specific Appium capabilities, which are cloud provider specific and will differ from one cloud provider to another.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Appium Client libraries for different languages have different options classes created, which helps set many of these capabilities directly by exposing descriptive methods representing the corresponding capability name. So most of the time, you will call the respective method and pass the required value for the capability directly to that method. Once all the Appium capabilities are set, you will pass the options object instance to the corresponding driver class while creating the driver instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;It’s crucial to debug websites for Safari before pushing them live. In this article, we look at how to debug websites using&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/debug-websites-using-safari-developer-tools/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Dev tools in Safari&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Appium Capabilities
&lt;/h3&gt;

&lt;p&gt;The common capabilities are the ones that can be used for any platform you are automating with Appium. Let’s see the commonly used Appium capabilities irrespective of your working platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;While looking into these Appium capabilities, we will use the&lt;/em&gt; &lt;a href="https://github.com/appium/java-client/blob/master/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java" rel="noopener noreferrer"&gt;&lt;em&gt;UiAutomator2Options&lt;/em&gt;&lt;/a&gt; &lt;em&gt;class for examples of how to set these capabilities in the test. However, when you work on any particular platform, you will use the corresponding options class depending on your working platform.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  platformName
&lt;/h3&gt;

&lt;p&gt;In this capability, you will give the target platform name, which can be Android or iOS, depending on which platform is being automated. This capability is mandatory and must be provided to Appium.&lt;/p&gt;

&lt;p&gt;If you use any of the available option classes and initialize it, this capability will be automatically set under the hood along with the &lt;em&gt;automationName&lt;/em&gt; capability, so you don’t need to set it explicitly.&lt;/p&gt;

&lt;p&gt;Following is the table which lists all the option classes along with their corresponding platform and automation name values which are automatically set when you use the option class:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;OPTION CLASS&lt;/td&gt;
        &lt;td&gt;PLATFORM NAME&lt;/td&gt;
        &lt;td&gt;AUTOMATION NAME &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;UiAutomator2Options&lt;/td&gt;
        &lt;td&gt;Android&lt;/td&gt;
        &lt;td&gt;UiAutomator2 &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;EspressoOptions&lt;/td&gt;
        &lt;td&gt;Android&lt;/td&gt;
        &lt;td&gt;Espresso &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;XCUITestOptions&lt;/td&gt;
        &lt;td&gt;iOS&lt;/td&gt;
        &lt;td&gt;XCUITest &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Mac2Options&lt;/td&gt;
        &lt;td&gt;Mac&lt;/td&gt;
        &lt;td&gt;Mac2 &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;WindowsOptions&lt;/td&gt;
        &lt;td&gt;Windows&lt;/td&gt;
        &lt;td&gt;Windows&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:automationName
&lt;/h3&gt;

&lt;p&gt;This capability instructs Appium which Appium driver it must use to automate the application. It is a mandatory capability and must be set to run the tests. This capability is automatically set along with &lt;em&gt;platformName&lt;/em&gt; when you use any available option classes, as explained earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this article, we take a look at some aspects of simulation and discuss some ways through which we can use&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/iphone-simulators-for-windows/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;ios emulator for pc&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:platformVersion
&lt;/h3&gt;

&lt;p&gt;This capability holds the target platform version number. It is an optional capability. If provided, it will help Appium narrow the search for the correct device. Check out the following code snippet on how to set the platform version capability using the option class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setPlatformVersion ("12");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, in the case of Android, you can mention any Android version you want to automate, like 12 or 11. In the case of iOS, you can mention the exact version, like 16.2.&lt;/p&gt;

&lt;h3&gt;
  
  
  browserName
&lt;/h3&gt;

&lt;p&gt;If you want to automate a web application, you can use this capability to set on which browser you want to test that web application. If you use this capability, you can avoid using &lt;em&gt;appium:app&lt;/em&gt; capability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.withBrowserName (Browser.CHROME.browserName ());
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;IOS&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/mobile-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;emulators online&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;from LambdaTest allows you to seamlessly test your mobile applications, websites,and web apps on mobile browsers and mobile devices.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:app
&lt;/h3&gt;

&lt;p&gt;If you want to automate a native or a hybrid application, you can use this capability to set the path to the &lt;em&gt;.apk file on your machine for Android,&lt;/em&gt; .ipa file path for iOS real device or &lt;em&gt;.&lt;/em&gt;&lt;a href="http://app.zip" rel="noopener noreferrer"&gt;&lt;em&gt;app.zip&lt;/em&gt;&lt;/a&gt; &lt;em&gt;/&lt;/em&gt; .app file path for iOS simulator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static final String USER_DIR = getProperty ("user.dir");


var options = new UiAutomator2Options ();
options.setApp (Path.of (USER_DIR, "src/test/resources/apps/wdio-demo.apk").toString ());
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:deviceName
&lt;/h3&gt;

&lt;p&gt;This capability is where you would give the device name on which you will be testing your application. This capability is not used internally for Android. However, it is used to find the target device in the case of iOS. So you must make sure you give the correct device name for iOS.&lt;/p&gt;

&lt;p&gt;For example, you may give the iPhone 14 Pro device name for the iOS device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setDeviceName ("Pixel_6_Pro");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:noReset
&lt;/h3&gt;

&lt;p&gt;If this capability is set with the value as &lt;em&gt;true&lt;/em&gt;, it will indicate the driver to skip its clean-up and reset logic from being applied at the start of the session. By default, the value is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setNoReset (true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:fullReset
&lt;/h3&gt;

&lt;p&gt;If this capability is set with the value as &lt;em&gt;true&lt;/em&gt;, it will instruct the Appium Server to do a complete reset of the device by deleting whatever temporary data which was created due to the previous executions including the applications which were installed before along with cleaning up any previous logs which are there on the device.&lt;/p&gt;

&lt;p&gt;Full reset does not mean that Appium will simply wipe out the complete data of the device. It will only delete the files created by Appium when the test is executed. This ensures maximum environmental reproductivity. By default, the value is set as &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Get started with this complete&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/selenium?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Selenium&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;automation testing tutorial. Learn what Selenium is, its architecture, advantages and more for automated cross browser testing. Read more.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setFullReset (true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:eventTimings
&lt;/h3&gt;

&lt;p&gt;If this capability is set as &lt;em&gt;true&lt;/em&gt;, it will instruct Appium to collect all the event timings each event takes to execute. By default, the value is set as &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When this capability is enabled, you can get details of all the events and commands executed by Appium, along with the timings each of those events and commands took to execute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setEventTimings (true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this capability is enabled, you can get event details using the following code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.getEvents ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:printPageSourceOnFindFailure
&lt;/h3&gt;

&lt;p&gt;If the capability is set as &lt;em&gt;true&lt;/em&gt;, it will instruct to print the complete page source when Appium fails to find any element. By default, the value is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setPrintPageSourceOnFindFailure (true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:udid (optional, default: null)
&lt;/h3&gt;

&lt;p&gt;This capability takes in the unique device ID of the target device on which you will be executing your test. For Android, you can get the UDID of the device by running adb devices -l on your terminal, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2Aij9p8JZzHeoyZgWv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2Aij9p8JZzHeoyZgWv.png" alt="image" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For iOS, you can get it from Xcode &amp;gt; Windows &amp;gt; Devices and Simulators &amp;gt; Simulators (see the reference screenshot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABsE1LvRgWA76XB59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABsE1LvRgWA76XB59.png" alt="image" width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This capability is optional. If not provided, it will automatically find the device matching other Appium capabilities you have provided. But this capability must be provided if there is more than one real device with the same iOS versions connected to the machine. Appium will try finding the particular device matching the provided unique ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUdid ("emulator-5554");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:settings[ &amp;lt; setting-name &amp;gt; ]
&lt;/h3&gt;

&lt;p&gt;With this capability, you can apply any of the available Appium settings which you would otherwise use &lt;em&gt;driver.setSetting (“settingName”, “settingValue”)&lt;/em&gt;; after the session is started. Using this capability, you can replace the &lt;em&gt;&amp;lt; setting-name &amp;gt;&lt;/em&gt; with the actual setting name and assign the value of that setting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setCapability ("appium:settings[ignoreUnimportantViews]", true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get all the list of supported settings from the following driver documentations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/appium/appium-uiautomator2-driver#settings-api" rel="noopener noreferrer"&gt;UiAutomator2 driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/appium/appium-espresso-driver#settings-api" rel="noopener noreferrer"&gt;Espresso driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://appium.github.io/appium-xcuitest-driver/4.28/settings/" rel="noopener noreferrer"&gt;XCUITest driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.lambdatest.com/learning-hub/black-box-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Black Box testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;? Don’t worry; we will be covering what is Black box testing, merits, demerits, types &amp;amp; techniques.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:enforceAppInstall
&lt;/h3&gt;

&lt;p&gt;If this capability is set to &lt;em&gt;true&lt;/em&gt;, then the application under test is always reinstalled even if a newer version of it already exists on the device under test. This is set to &lt;em&gt;false&lt;/em&gt; by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.enforceAppInstall ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:language
&lt;/h3&gt;

&lt;p&gt;This capability sets the application language based on the format of the ISO-639 code for alpha-2 or alpha-3 language code. To illustrate, when configuring the application language to French, you should set the capability as “fr,” while for English, it will be “en.” The device’s system language will be utilized by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setLanguage ("fr");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:locale
&lt;/h3&gt;

&lt;p&gt;This capability sets the application language based on the format of ISO-3166 two-letter country code or three-digit country code. By default, the device system locale will be used. For example, if you want to set the &lt;em&gt;locale&lt;/em&gt; to France, you must set the value as &lt;em&gt;FR&lt;/em&gt; or &lt;em&gt;250&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setLocale ("FR");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:otherApps
&lt;/h3&gt;

&lt;p&gt;You can provide a comma-separated list of one or more applications that you want to install before you run your test because they are the dependent applications on which the application under test relies on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static final String USER_DIR = getProperty ("user.dir");


var otherApp1 = Path.of (USER_DIR, "src/test/resources/apps/otherApp1.apk").toString ();
var otherApp2 = Path.of (USER_DIR, "src/test/resources/apps/otherApp2.apk").toString ();
var options = new UiAutomator2Options ();
options.setOtherApps (otherApp1 + "," + otherApp2);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:isHeadless
&lt;/h3&gt;

&lt;p&gt;If you want to run your test in a headless mode on any virtual device, whether it’s on Android Emulator or iOS Simulator, then you must set this capability as &lt;em&gt;true&lt;/em&gt;. By default, this capability is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.headless ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:skipLogCapture
&lt;/h3&gt;

&lt;p&gt;If you want to enforce Appium to skip capturing the logs during the test execution, then you must set this capability as &lt;em&gt;true&lt;/em&gt;. This would improve network performance. If this capability is enabled, then any log-related commands will not work. By default, this capability is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.skipLogcatCapture ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/learning-hub/system-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;System testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;tutorial, learn why System testing is important and all the intricacies of the System testing process.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:newCommandTimeout
&lt;/h3&gt;

&lt;p&gt;Maximum amount of time in seconds should Appium driver wait for a command from the client to get executed before assuming that the client is no longer active. By default, 60sec is set for this capability. This capability is not supported by the Android Espresso driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setNewCommandTimeout (Duration.ofSeconds (10));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:mjpegServerPort
&lt;/h3&gt;

&lt;p&gt;The number of the port the Appium server starts the MJPEG server on. If not provided, then the screenshots broadcasting service on the remote device does not get exposed to a local port (e.g., no adb port forwarding is happening). This capability is not supported by the Android Espresso driver. You can learn more about it through this blog on &lt;a href="https://www.lambdatest.com/blog/adb-commands/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;ADB commands&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setMjpegServerPort (9200);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Platform-Specific Appium Capabilities
&lt;/h3&gt;

&lt;p&gt;Apart from the common capabilities seen earlier, some platform-specific Appium capabilities are common throughout that platform. Let’s check out all these capabilities for each of the platforms.&lt;/p&gt;

&lt;p&gt;Following are Android-specific capabilities that are commonly supported irrespective of the driver you might be using whether &lt;em&gt;UiAutomator2&lt;/em&gt; or &lt;em&gt;Espresso&lt;/em&gt; drivers.&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:systemPort
&lt;/h3&gt;

&lt;p&gt;This is the port number on which the corresponding Android driver listens. By default, any of the 8200–8299 free port numbers will be used. But if you want to execute your tests in parallel, you must ensure that you provide a unique &lt;em&gt;systemPort&lt;/em&gt; number capability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setSystemPort (8250);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:skipServerInstallation
&lt;/h3&gt;

&lt;p&gt;If you set this capability as &lt;em&gt;true&lt;/em&gt;, then the driver will skip the server component installation on the device along with any related checks. This will help speed up the test execution only when you are sure your target device already has the correct server component installed.&lt;/p&gt;

&lt;p&gt;In case you are running for the first on any device, you must keep this capability disabled to make sure all the required Appium server components get installed. By default, the value is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.skipServerInstallation ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:appPackage
&lt;/h3&gt;

&lt;p&gt;This capability will try to launch the application with the same package name as provided to the capability. If this capability is not provided, Appium will find the application package name from the &lt;em&gt;appium:app&lt;/em&gt; capability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAppPackage ("packageName");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:appActivity
&lt;/h3&gt;

&lt;p&gt;Appium will try to launch the application activity which matches the provided capability. If not provided, Appium will automatically identify the main activity from the &lt;em&gt;appium:app&lt;/em&gt; capability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAppActivity ("activityName");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:appWaitActivity
&lt;/h3&gt;

&lt;p&gt;The activity name for which Appium should wait till it gets launched. If not provided, then by default &lt;em&gt;appium:appActivity&lt;/em&gt; value is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAppWaitActivity ("activityName");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:appWaitPackage
&lt;/h3&gt;

&lt;p&gt;The package name for which Appium should wait till it gets launched. If not provided, then by default &lt;em&gt;appium:appPackage&lt;/em&gt; value is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAppWaitPackage ("packageName");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:appWaitDuration
&lt;/h3&gt;

&lt;p&gt;The wait timeout in milliseconds for which Appium should wait until the application under test gets launched. By default, 20000 ms is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAppWaitDuration (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:androidInstallTimeout
&lt;/h3&gt;

&lt;p&gt;This is the maximum amount of time Appium will wait till the application under test is installed on the device. By default, Appium will wait till 90000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAndroidInstallTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;This article on the Best&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/top-ui-automated-testing-tools/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;UI Automation Testing Tools&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;cover what is UI automated testing, challenges while performing UI testing, and top tools that can help you perform UI testing.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:autoGrantPermissions
&lt;/h3&gt;

&lt;p&gt;If this capability is set to &lt;em&gt;true&lt;/em&gt;, then Appium will automatically grant any permissions which the application under test may request when it is first installed and launched, else, you will see the permissions pop-up whenever the application under test starts for the first time. By default, this is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.autoGrantPermissions ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:uninstallOtherPackages
&lt;/h3&gt;

&lt;p&gt;You can provide a comma-separated list of one or more applications you want to uninstall before you run your test on that target device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUninstallOtherPackages ("package1,package2");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:allowTestPackages
&lt;/h3&gt;

&lt;p&gt;If you set this capability to &lt;em&gt;true&lt;/em&gt;, then it would be possible to use packages built with the test flag for automated testing, which means it adds &lt;em&gt;-t&lt;/em&gt; flag to the &lt;code&gt;adb install&lt;/code&gt; command. This is set as &lt;em&gt;false&lt;/em&gt; by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.allowTestPackages ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:remoteAppsCacheLimit
&lt;/h3&gt;

&lt;p&gt;This capability 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, for example, Android 7 and below, because adb must push app packages to the device first to install them, which takes some time. Setting this capability to 0 disables app caching, which is not required for Android 8 and above because that supports streamed installation. By default, this capability is set as 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setRemoteAppsCacheLimit (10);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:adbPort
&lt;/h3&gt;

&lt;p&gt;This capability sets the port number on which ADB is running. By default, Appium will listen on the 5037 port number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAdbPort (8400);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:remoteAdbHost
&lt;/h3&gt;

&lt;p&gt;This is the host address on which ADB will be running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setRemoteAdbHost ("http://localhost:9300");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:adbExecTimeout
&lt;/h3&gt;

&lt;p&gt;This will be the maximum amount of time in milliseconds Appium will wait for a single ADB command to get executed. By default, this capability value is set as 20000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAdbExecTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:clearDeviceLogsOnStart
&lt;/h3&gt;

&lt;p&gt;If this capability is set as &lt;em&gt;true&lt;/em&gt;, then the corresponding Appium driver will clear all the logs from the device buffer before the test gets executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.clearDeviceLogsOnStart ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:suppressKillServer
&lt;/h3&gt;

&lt;p&gt;If this capability is &lt;em&gt;true&lt;/em&gt;, then the Appium driver will not explicitly kill the ADB server. This capability is useful to be enabled when you have connected your target device via WiFi. By default, this capability is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.suppressKillServer ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:avd
&lt;/h3&gt;

&lt;p&gt;You can set the name of the Android emulator to run the test on. The names of currently created emulators could be listed using the &lt;code&gt;emulator -list-avds&lt;/code&gt; command. If the emulator with the given name is not running, it will be launched on automated session startup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAvd ("Pixel_6_Pro");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:avdLaunchTimeout
&lt;/h3&gt;

&lt;p&gt;You can set the maximum amount of time in milliseconds Appium should wait for the Android Emulator to launch. By default, the capability is set to 60000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAvdLaunchTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:avdReadyTimeout
&lt;/h3&gt;

&lt;p&gt;You can set the maximum amount of time in milliseconds Appium should wait for the Android Emulator to be fully loaded and ready for running the tests. By default, the capability is set to 60000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setAvdReadyTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:avdArgs
&lt;/h3&gt;

&lt;p&gt;You can pass the Android emulator arguments to this capability. Appium will use these &lt;a href="https://developer.android.com/studio/run/emulator-commandline#startup-options" rel="noopener noreferrer"&gt;arguments&lt;/a&gt; while starting the Emulator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final var args = new ArrayList&amp;lt;String&amp;gt; ();
args.add ("-gpu swiftshader_indirect");


var options = new UiAutomator2Options ();
options.setAvdArgs (args);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;We can speed up the software validation process and boost testing coverage by adopting automated testing. However, there are a lot of challenges in applying test automation. In this article on the top 9&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/challenges-in-automation-testing/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;challenges in automation testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;, we look at the various obstacles and how to deal with them.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:chromedriverPort
&lt;/h3&gt;

&lt;p&gt;This capability sets the port number on which Appium will listen for Chrome driver communications. By default, this capability is unset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setChromedriverPort (9300);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:chromedriverExecutableDir
&lt;/h3&gt;

&lt;p&gt;This capability will contain a full path to the folder where the downloaded Chrome driver executable is stored when Appium automatically downloads the driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setChromedriverExecutableDir ("/path/to/driver/exe/folder");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:chromedriverExecutable
&lt;/h3&gt;

&lt;p&gt;This capability will contain the complete path to the Chrome driver executable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setChromedriverExecutable ("/path/to/driver/exe");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:chromedriverArgs
&lt;/h3&gt;

&lt;p&gt;You can provide the Chrome driver-specific &lt;a href="https://peter.sh/experiments/chromium-command-line-switches/" rel="noopener noreferrer"&gt;arguments&lt;/a&gt; by using this capability which Appium will use when launching the browser on the device. This capability is an array of Chrome driver arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final var chromeArgs = new ArrayList&amp;lt;String&amp;gt; ();
chromeArgs.add ("some-args");


var options = new UiAutomator2Options ();
options.setChromedriverArgs (chromeArgs);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:chromeOptions
&lt;/h3&gt;

&lt;p&gt;This capability takes a map of Chrome options to customize the Chrome driver. Check out &lt;a href="https://chromedriver.chromium.org/capabilities" rel="noopener noreferrer"&gt;this documentation&lt;/a&gt; for a complete list of supported Chrome options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final var chromeOptions = new ChromeOptions ();
chromeOptions.setBinary ("/path/to/chrome/exe");


var options = new UiAutomator2Options ();
options.setChromeOptions (chromeOptions.asMap ());
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:skipUnlock
&lt;/h3&gt;

&lt;p&gt;When this capability is set to &lt;em&gt;true&lt;/em&gt;, then Appium will not check if the device screen is currently locked. By default, it’s set as &lt;em&gt;false&lt;/em&gt;, which means, Appium checks if the device is locked and tries to unlock the device if it’s locked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.skipUnlock ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:unlockType
&lt;/h3&gt;

&lt;p&gt;You can provide the unlock type your device uses to unlock. This value can be any one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;pin:&lt;/em&gt; It is a numeric pin code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;password:&lt;/em&gt; It is an alphanumeric password&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;pattern:&lt;/em&gt; It is a finger gesture pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;fingerprint:&lt;/em&gt; It is a fingerprint biometric&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;pinWithKeyEvent:&lt;/em&gt; It is a numeric pin code which is entered using a key event&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUnlockType ("pin");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:unlockKey
&lt;/h3&gt;

&lt;p&gt;You can set the unlock key which Appium can use to unlock the device with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUnlockKey ("123456");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:unlockSuccessTimeout
&lt;/h3&gt;

&lt;p&gt;This is the maximum time in milliseconds Appium will wait for the device under test to get unlocked. By default, this value is set as 2000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUnlockSuccessTimeout (Duration.ofSeconds (20));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:disableWindowAnimation
&lt;/h3&gt;

&lt;p&gt;If this capability is set to &lt;em&gt;true&lt;/em&gt;, the device window animation will be disabled. By default, this capability is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.disableWindowAnimation ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:noSign
&lt;/h3&gt;

&lt;p&gt;When this capability is set to &lt;em&gt;true&lt;/em&gt;, Appium will skip signing the application under test with the default Appium debug signature. You can disable the application signing if you want to test your application as is without any modification. By default, this capability is set as &lt;em&gt;true&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.noSign ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following are the capabilities specific to the iOS platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this Selenium with Java tutorial, you will learn everything you need to know to kick start your journey in Selenium&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/selenium-with-java/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;automation testing with Java&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:updatedWDABundleId
&lt;/h3&gt;

&lt;p&gt;You can provide a bundle id to this capability, which Appium will use to update WDA before building and launching it on real devices. This bundle id must be associated with a valid provisioning profile. For example, you can set its value as &lt;em&gt;io.appium.WebDriverAgentRunner&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setUpdatedWdaBundleId ("io.appium.WebDriverAgentRunner");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:xcodeOrgId
&lt;/h3&gt;

&lt;p&gt;This capability will take the Apple developer team identifier, which is a 10-character long string. This capability must be used in conjunction with &lt;em&gt;appium:xcodeSigningId&lt;/em&gt; to take effect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setCapability (IOSMobileCapabilityType.XCODE_ORG_ID, "XXXXXXXXXX");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:xcodeSigningId
&lt;/h3&gt;

&lt;p&gt;This capability is the string representing a signing certificate. It must be used in conjunction with &lt;em&gt;appium:xcodeOrgId.&lt;/em&gt; This is usually just iPhone Developer, so the default (if not provided) is iPhone Developer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setCapability (IOSMobileCapabilityType.XCODE_SIGNING_ID, "iPhone Developer");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:webDriverAgentUrl
&lt;/h3&gt;

&lt;p&gt;If you provide this capability a value, then Appium will connect to an existing &lt;em&gt;WebDriverAgent&lt;/em&gt; instance at this URL instead of starting a new one. By default, &lt;a href="http://localhost:8100" rel="noopener noreferrer"&gt;http://localhost:8100&lt;/a&gt; is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWebDriverAgentUrl ("http://localhost:8100");
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:useNewWDA
&lt;/h3&gt;

&lt;p&gt;If this capability is set to &lt;em&gt;true&lt;/em&gt;, Appium will uninstall any existing &lt;em&gt;WebDriverAgent&lt;/em&gt; application installed on the device and build and install the new instance of WDA.&lt;/p&gt;

&lt;p&gt;For real devices, it is required for the &lt;em&gt;WebDriverAgent&lt;/em&gt; client to run for as long as possible without reinstalling/restarting to avoid any issues. The &lt;em&gt;false&lt;/em&gt; value, the default behavior, will try to detect the currently running WDA listener executed by previous testing sessions and reuse it if possible, which is highly recommended for real device testing and to speed up suites of multiple tests in general.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.useNewWDA ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:wdaLaunchTimeout
&lt;/h3&gt;

&lt;p&gt;This capability takes time, in milliseconds, which Appium will wait until &lt;em&gt;WebDriverAgent&lt;/em&gt; is launched. By default, Appium uses 60000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWdaLaunchTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:wdaConnectionTimeout
&lt;/h3&gt;

&lt;p&gt;This is the timeout in milliseconds which Appium will wait for the response from &lt;em&gt;WebDriverAgent&lt;/em&gt; to respond. By default, 240000 ms is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWdaConnectionTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:wdaStartupRetries
&lt;/h3&gt;

&lt;p&gt;This is the number of times the Appium server will try to build and start up the WDA on the device before failing the test execution. By default, 2 is set for this capability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWdaStartupRetries (5);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:wdaStartupRetryInterval
&lt;/h3&gt;

&lt;p&gt;This is the time interval between the retries for building and launching the WDA on the device in milliseconds. By default, 10000 ms is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWdaStartupRetryInterval (Duration.ofSeconds (2));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:wdaLocalPort
&lt;/h3&gt;

&lt;p&gt;If you specify this capability value, Appium will use it to forward traffic from Mac host to real iOS devices over USB. By default, the value is the same as the port number used by WDA on the device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWdaLocalPort (8102);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:usePrebuiltWDA
&lt;/h3&gt;

&lt;p&gt;If this capability is set to &lt;em&gt;true&lt;/em&gt;, then Appium will not build the &lt;em&gt;WebDriverAgent&lt;/em&gt;. It will be your responsibility to build the WDA manually. This feature is available for XCode v8 or above. By default, this capability is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.usePrebuiltWda ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:waitForIdleTimeout
&lt;/h3&gt;

&lt;p&gt;This capability takes in the time in seconds in a floating number to wait until the application under test is getting idle. Since XCTest requires the main thread to be idle for the next command to get executed. The WDA will not even start or freeze if the application under test is constantly hogging the main thread. By default, Appium will use 10 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setWaitForIdleTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Learn why Python is the top choice for automation testing. This comprehensive tutorial provides a step-by-step guide to&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/python-automation-testing/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Python automation testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;to help you streamline your testing process.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:maxTypingFrequency
&lt;/h3&gt;

&lt;p&gt;The maxing keystrokes for typing or clearing the text in the element. If your test fails due to incorrect typing, you can try changing this capability. By default, this capability is set to 60 keystrokes per minute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setMaxTypingFrequency (40);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:autoAcceptAlerts
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, will instruct Appium to accept all the iOS alerts when they pop up automatically. This also includes all the privacy access permissions pop-ups. By default, this capability is set to &lt;em&gt;false.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.autoAcceptAlerts ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:autoDismissAlerts
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, will instruct Appium to dismiss any iOS alerts when they pop up automatically. This also includes all the privacy access permissions pop-ups. By default, this capability is set to &lt;em&gt;false.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Following is the example code snippet on how to disable this capability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.autoDismissAlerts ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:connectHardwareKeyboard
&lt;/h3&gt;

&lt;p&gt;If you set this capability to &lt;em&gt;true&lt;/em&gt;, then Appium will connect with the hardware keyboard on the Simulator. By default, this capability is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.connectHardwareKeyboard ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:simulatorStartupTimeout
&lt;/h3&gt;

&lt;p&gt;You can set the timeout value in milliseconds which Appium will wait for the simulator to start up completely. By default, this capability is set as 120000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.setSimulatorStartupTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:simulatorTracePointer
&lt;/h3&gt;

&lt;p&gt;You can enable a pointer tracker on the simulator to see any touch or swipe gestures happening on the screen of the simulator by setting this capability to &lt;em&gt;true&lt;/em&gt;. You must ensure that the simulator is shut down before applying this change, else this change will not reflect on the simulator. By default, this capability is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.simulatorTracePointer ();
// ... Other capabilities

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:permissions
&lt;/h3&gt;

&lt;p&gt;You can provide any permissions your application under tests might need during your test execution. You must provide the value for this capability in the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "&amp;lt;bundle_id_1&amp;gt;": {
    "&amp;lt;service_name_1&amp;gt;": "YES",
      // other services...
  },
  //other bundle ids if available...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check what service names you must use, then run this &lt;code&gt;xcrun simctl privacy booted&lt;/code&gt; on your terminal to get the supported service names.&lt;/p&gt;

&lt;p&gt;You must set the corresponding service value by providing yes, no, or unset as values to grant, revoke or reset its corresponding permissions.&lt;/p&gt;

&lt;p&gt;For example, you can set this capability value as &lt;em&gt;{“&lt;/em&gt;&lt;a href="http://com.apple" rel="noopener noreferrer"&gt;&lt;em&gt;com.apple&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.yourapp”: {“calendar”: “YES”}}&lt;/em&gt; to provide calendar permissions to your application under test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var permissions = new HashMap&amp;lt;String, String&amp;gt; ();
permissions.put ("calendar", "YES");
permissions.put ("contacts", "YES");


var options = new XCUITestOptions ();
options.setPermissions (new Permissions ().withAppPermissions ("com.domain.app", permissions));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:launchWithIDB
&lt;/h3&gt;

&lt;p&gt;You can prefer to use IDB to launch &lt;em&gt;WebDriverAgentRunner&lt;/em&gt; instead of the Xcode build tool by setting this capability to &lt;em&gt;true&lt;/em&gt;. This will help improve the startup time because the Xcode build will be skipped. By default, this capability is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.launchWithIdb ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:clearSystemFiles
&lt;/h3&gt;

&lt;p&gt;If you set this capability as &lt;em&gt;true&lt;/em&gt;, then Appium will clear all the temporary files created by XCTest during the &lt;a href="https://www.lambdatest.com/learning-hub/test-execution?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;test execution&lt;/a&gt;, including logs. By default, this value is set to &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new XCUITestOptions ();
options.clearSystemFiles ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Driver-Specific Appium Capabilities
&lt;/h3&gt;

&lt;p&gt;There are some capabilities in Appium specific to a particular driver type. Let’s check out all of these capabilities.&lt;/p&gt;

&lt;p&gt;For Android, there are currently two drivers supported by Appium, these are &lt;em&gt;UiAutomator2&lt;/em&gt; and &lt;em&gt;Espresso&lt;/em&gt; driver.&lt;/p&gt;

&lt;p&gt;Following are the Appium capabilities specific to the &lt;em&gt;UiAutomator2&lt;/em&gt; driver:&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:uiautomator2ServerLaunchTimeout
&lt;/h3&gt;

&lt;p&gt;This is the maximum number of time in milliseconds Appium will wait for the &lt;em&gt;UiAutomator2&lt;/em&gt; server to launch on the device. By default, this capability is set as 30000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUiautomator2ServerLaunchTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:uiautomator2ServerInstallTimeout
&lt;/h3&gt;

&lt;p&gt;This is the maximum number of time in milliseconds Appium will wait for the &lt;em&gt;UiAutomator2&lt;/em&gt; server to be installed on the target device. By default, this capability is set as 20000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUiautomator2ServerInstallTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:uiautomator2ServerReadTimeout
&lt;/h3&gt;

&lt;p&gt;This is the maximum number of time in milliseconds Appium will wait for HTTP response to come from the &lt;em&gt;UiAutomator2&lt;/em&gt; server which is installed on the target device. By default, this value is set as 240000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setUiautomator2ServerReadTimeout (Duration.ofSeconds (30));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:skipDeviceInitialization
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, then Appium will skip all the device checks and initialization steps. If you are sure that the initialization steps have already run properly before, then you can enable this capability to speed up the session creation step by skipping the device initialization step. By default, this value is set as &lt;em&gt;false&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.skipDeviceInitialization ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:autoLaunch
&lt;/h3&gt;

&lt;p&gt;This capability, if set to &lt;em&gt;false&lt;/em&gt;, will restrict Appium from launching the application under test when starting a new session on the device. By default, this capability is set as &lt;em&gt;true.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new UiAutomator2Options ();
options.setCapability (AndroidMobileCapabilityType.AUTO_LAUNCH, true);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following are the Appium capabilities that are specific to the &lt;em&gt;Espresso&lt;/em&gt; driver:&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:espressoServerLaunchTimeout
&lt;/h3&gt;

&lt;p&gt;This capability is the maximum time in milliseconds Appium will wait for the Espresso server to get launched on the device under test. By default, this value is set as 45000 ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new EspressoOptions ();
options.setCapability ("appium:espressoServerLaunchTimeout", 40000);
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:forceEspressoRebuild
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, then Appium will rebuild the Espresso server .apk file every time the session is created. By default, this capability is set as &lt;em&gt;false&lt;/em&gt;, which means Appium will only rebuild the Espresso server APK file when required or use the server APK from the cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new EspressoOptions ();
options.forceEspressoRebuild ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this Selenium&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/automation-testing-with-selenium-javascript/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;JavaScript for automation testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;tutorial, as we deep dive into the basic concepts, explained the best practices and executed automation scripts with JavaScript on cloud-based Selenium Grid.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  appium:espressoBuildConfig
&lt;/h3&gt;

&lt;p&gt;This capability would contain the full path of JSON config containing the &lt;a href="https://www.lambdatest.com/espresso" rel="noopener noreferrer"&gt;Espresso&lt;/a&gt; config, or it can contain the JSON string itself with &lt;a href="https://github.com/appium/appium-espresso-driver#espresso-build-config" rel="noopener noreferrer"&gt;Espresso Build configs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new EspressoOptions ();
options.setEspressoBuildConfig (new EspressoBuildConfig ().withBuildToolsVersion ("28.0"));
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  appium:showGradleLog
&lt;/h3&gt;

&lt;p&gt;When this capability is set to &lt;em&gt;true&lt;/em&gt;, then Appium server logs will also contain Espresso Gradle logs. By default, this capability is set to &lt;em&gt;false.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var options = new EspressoOptions ();
options.showGradleLog ();
// ... Other capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cloud-Specific Appium Capabilities
&lt;/h3&gt;

&lt;p&gt;In today’s world, numerous cloud providers offer unique custom Appium capabilities that you must configure to run tests on devices hosted on their platforms. In this blog, we’ll focus on the LambdaTest cloud — an AI-powered test orchestration and execution platform that lets you perform &lt;a href="https://www.lambdatest.com/mobile-app-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;mobile app testing&lt;/a&gt; using the Appium framework on a &lt;a href="https://www.lambdatest.com/real-device-cloud?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;real device cloud&lt;/a&gt;. They provide a convenient &lt;a href="https://www.lambdatest.com/capabilities-generator/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Automation Capabilities Generator&lt;/a&gt; for generating all their supported capabilities, which can be customized per your needs.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/7dczd7AfPFs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Subscribe to the &lt;a href="https://www.youtube.com/c/LambdaTest?sub_confirmation=1" rel="noopener noreferrer"&gt;LambdaTest YouTube Channel&lt;/a&gt; and stay up to date with the latest tutorials around &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Selenium testing&lt;/a&gt;, &lt;a href="https://www.lambdatest.com/cypress-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Cypress testing&lt;/a&gt;, and more.&lt;/p&gt;

&lt;p&gt;To get started with Appium for mobile automation, visit the documentation &lt;a href="https://www.lambdatest.com/support/docs/getting-started-with-appium-testing/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=support_doc" rel="noopener noreferrer"&gt;Appium testing on LambdaTest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s explore some of their frequently used Appium capabilities that will simplify running your mobile tests on their devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  w3c
&lt;/h3&gt;

&lt;p&gt;This capability, when set as &lt;em&gt;true&lt;/em&gt;, indicates to LambdaTest that you want to use the W3C protocol for your &lt;a href="https://www.lambdatest.com/learning-hub/automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;test automation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("w3c", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  platformName
&lt;/h3&gt;

&lt;p&gt;This capability will set the platform name on which your test will run. For example, Android when you want to run on an Android device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("platformName", "Android");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  deviceName
&lt;/h3&gt;

&lt;p&gt;This capability will set the device name on which the test will get executed. For example, if you were to run your test on a Google Pixel device, you can set this capability as Pixel 6.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("deviceName", "Pixel 6");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  platformVersion
&lt;/h3&gt;

&lt;p&gt;This capability will set the platform version on which you want to run your test. For example, if you want to run on the Android 12 platform, you can set this capability as 12.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Learn why Python is the top choice for automation testing. This comprehensive tutorial provides a step-by-step guide to&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/python-automation-testing/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Python for automation testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;to help you streamline your testing process.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  app
&lt;/h3&gt;

&lt;p&gt;This capability will set the LambdaTest application URL, which points to the application under the test you want to install on the target device. The format of the value for this capability is &lt;em&gt;lt://&amp;lt; hash-id &amp;gt;.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("app", "lt://&amp;lt;unique-hash-id&amp;gt;");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  project
&lt;/h3&gt;

&lt;p&gt;This capability sets the project name, which categorizes the test session on the LambdaTest platform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("project", "Project Name");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  build
&lt;/h3&gt;

&lt;p&gt;This capability sets the build name, which categorizes the test session on the LambdaTest platform under the project name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("build", "Build Name");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  name
&lt;/h3&gt;

&lt;p&gt;This capability sets the test execution session name, which gets categorized under the project and build names that are set by the earlier capabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("name", "Test Name");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  devicelog
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, will enable device-specific logs capturing, which you can view on the LamdaTest dashboard once the test execution is completed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("devicelog", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  visual
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, will capture screenshots on each step of the test execution, which you can view on the LambdaTest dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("visual", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  network
&lt;/h3&gt;

&lt;p&gt;This capability, when set to &lt;em&gt;true&lt;/em&gt;, will enable capturing network calls happening from the application under test, which you can view on the LambdaTest dashboard once the test execution has been completed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("network", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  video
&lt;/h3&gt;

&lt;p&gt;This capability when set to &lt;em&gt;true&lt;/em&gt;, will enable capturing video recording of your test execution which can be viewed on the dashboard once the test execution has completed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("video", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  deviceOrientation
&lt;/h3&gt;

&lt;p&gt;This capability can be used to set the device orientation for the test session. Possible values which can be used for this capability are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;portrait&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;landscape&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("deviceOrientation", "portrait");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  geoLocation
&lt;/h3&gt;

&lt;p&gt;This capability can be used to set the geographical location of the device under test to whatever country in the world. You can provide &lt;a href="https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes" rel="noopener noreferrer"&gt;ISO country code&lt;/a&gt; alpha 2 code. You can learn more about it through this blog on &lt;a href="https://www.lambdatest.com/blog/gps-geolocation-vs-ip-geolocation/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;GPS Geolocation vs IP Geolocation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("geoLocation", "AU");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  location
&lt;/h3&gt;

&lt;p&gt;This capability can be used to set the exact location of the device under test. You can provide the latitude and longitude to set the device location. You can learn more about it through this blog on &lt;a href="https://www.lambdatest.com/blog/geolocation-testing-with-selenium-using-examples/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Geolocation testing&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var locationObj = new HashMap &amp;lt;String, String&amp;gt; ();
locationObj.put ("lat", "100");
locationObj.put ("long", "100");


var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("location", locationObj);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  isRealMobile
&lt;/h3&gt;

&lt;p&gt;You can set this capability to &lt;em&gt;true&lt;/em&gt; if you want to run on a real cloud device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("isRealMobile", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  autoGrantPermissions
&lt;/h3&gt;

&lt;p&gt;You can set this capability to &lt;em&gt;true&lt;/em&gt;, then it will automatically grant permissions to all the permissions required by the application under test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("autoGrantPermissions", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  autoAcceptAlerts
&lt;/h3&gt;

&lt;p&gt;You can set this capability to &lt;em&gt;true&lt;/em&gt;, then it will automatically accept the alert pop-ups which may occur in the application under test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("autoAcceptAlerts", true);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  idleTimeout
&lt;/h3&gt;

&lt;p&gt;You can set this capability to an integer to set the idle timeout in seconds. LambdaTest will wait for this idle timeout before canceling a test session if there is no activity happening in that session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("idleTimeout", 30);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  queueTimeout
&lt;/h3&gt;

&lt;p&gt;You can set this capability to an integer to set the queue timeout in seconds. LambdaTest will wait for this idle timeout before canceling a test session in the queue but not getting executed until the timeout occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("queueTimeout", 30);
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  language
&lt;/h3&gt;

&lt;p&gt;You can set the language to any other language for the application under test. You can provide &lt;a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" rel="noopener noreferrer"&gt;ISO language code&lt;/a&gt; of 2 char code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("language", "en");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  locale
&lt;/h3&gt;

&lt;p&gt;You can set the locale for the application under test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ltOptions = new HashMap &amp;lt;String, Object&amp;gt; ();
ltOptions.put ("locale", "en");
// ... Other capabilities


var options = new UiAutomator2Options ();
options.setCapability ("lt:options", ltOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  That’s a wrap!
&lt;/h3&gt;

&lt;p&gt;I would like to thank you for reading here. I tried my best to cover all the useful capabilities you can use in your daily work while working with Appium.&lt;/p&gt;

&lt;p&gt;I hope this blog on Appium capabilities helps you improve while performing &lt;a href="https://www.lambdatest.com/appium?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_17&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium automation&lt;/a&gt; and gain more knowledge and confidence so you know exactly why you use a particular capability in your Appium test.&lt;/p&gt;

&lt;p&gt;If you liked the blog on desired capabilities in Appium, share it with your friends so they can also benefit from it and know what capabilities Appium supports.&lt;/p&gt;

</description>
      <category>appium</category>
      <category>mobileautomation</category>
      <category>automationtesting</category>
    </item>
    <item>
      <title>Appium 2 Migration Guide: Migrating From Appium 1.x To Appium 2.x</title>
      <dc:creator>WasiqBhamla</dc:creator>
      <pubDate>Tue, 01 Aug 2023 08:59:25 +0000</pubDate>
      <link>https://dev.to/testmuai/appium-2-migration-guide-migrating-from-appium-1x-to-appium-2x-242p</link>
      <guid>https://dev.to/testmuai/appium-2-migration-guide-migrating-from-appium-1x-to-appium-2x-242p</guid>
      <description>&lt;p&gt;Appium is the most popular open-source library which helps automate various platforms such as Android, iOS, tvOS, Mac, Windows, etc. It also supports automating applications such as Native, Hybrid, and Web. &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium&lt;/a&gt; has been around for almost a decade, and its very first version, 0.0.1, was released ten years ago.&lt;/p&gt;

&lt;p&gt;The maintainers of Appium had supported Appium 1.x for almost eight years before they suggested using Appium 2.x beta versions. Even the very first 2.0.0 beta version was released almost three years ago.&lt;/p&gt;

&lt;p&gt;As everyone is aware, whenever a major version is released for any library, there must be a migration guide for the existing users to help them transition from the older version to the newer major version. In this Appium 2 migration guide, this is exactly what you will be learning. With this &lt;a href="https://www.lambdatest.com/appium?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium tutorial&lt;/a&gt;, you will understand exactly what you must do to easily migrate from 1.x to 2.x version of Appium.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Need a great solution for&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/safari-browser-for-windows?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Safari browser testing on Windows&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;? Forget about emulators or simulators — use real online browsers. Try LambdaTest for free.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many breaking changes were introduced in Appium 2.x. Let’s check out all the breaking changes and understand each.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Server Base Path
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, when the server was started, it would accept different Appium commands by default on the URL &lt;a href="http://localhost:4723/wd/hub" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:4723/wd/hub&lt;/code&gt;&lt;/a&gt;. This base path of &lt;code&gt;/wd/hub&lt;/code&gt; was hardcoded in the Appium Server, and you could not change this path.&lt;/p&gt;

&lt;p&gt;But with Appium 2.x, this base path is now configurable. By default, the base path is set &lt;code&gt;as/if&lt;/code&gt; no base path is provided to the server using the &lt;code&gt;--base-path&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;For example, you can run the following command to set the base path for the Appium Server instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appium --base-path /wd/hub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking to perform &lt;a href="https://www.lambdatest.com/mobile-app-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;mobile app testing&lt;/a&gt; using Appium? LambdaTest, a digital experience testing platform, lets you perform &lt;a href="https://www.lambdatest.com/app-test-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;app test automation&lt;/a&gt; using Appium on a &lt;a href="https://www.lambdatest.com/real-device-cloud?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;real device cloud&lt;/a&gt; to automate your mobile applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Perform manual or automated cross&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;browser testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;on 3000+ browsers online. Deploy and scale faster with the most powerful cross browser testing tool online.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Drivers Decoupled
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, when you installed the Appium command line tool, it installed all the available drivers supported by Appium. This meant that you would get many files installed on your machine even when you did not require those drivers.&lt;/p&gt;

&lt;p&gt;With Appium 2.x, now this behavior has been changed. When you install the Appium command line tool, only the Appium server component will get installed. You now have more control over which driver you want to use; accordingly, you can install only those you want to work with.&lt;/p&gt;

&lt;p&gt;You can install these drivers or check out which drivers are available in Appium. For example, you can execute the following command to list down the available drivers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appium driver list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, run the following command to install any of the drivers you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appium driver install &amp;lt;driver-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also mention the driver name when you are installing the Appium command line tool itself by using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --global appium --drivers=uiautomator2,xcuitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is also highly recommended to uninstall all the early installations of Appium 1.x by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm uninstall --global appium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Appium Driver Installation Path
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, when you installed the command line tool, all the Appium drivers would get installed simultaneously somewhere in the &lt;code&gt;node_modules&lt;/code&gt; folder in the main Appium Server binary folder. For example, all the drivers would be available in the &lt;code&gt;/path/to/appium/node_modules&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;With Appium 2.x, the default path for installing the Appium driver is now set to the &lt;code&gt;APPIUM_HOME&lt;/code&gt;, which is &lt;code&gt;~/.appium&lt;/code&gt;. So, when you install any Appium driver, it will get saved in &lt;code&gt;$APPIUM_HOME/node_modules/&amp;lt; driver-name &amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Test your native, hybrid, and web apps across all legacy and latest mobile operating systems on the most powerful&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/android-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;online emulator android&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Chrome Driver Installation Flags
&lt;/h3&gt;

&lt;p&gt;With Appium 1.x, you were able to use the following command line flags while installing the Appium server to control how the Chrome driver would get installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--chromedriver-skip-install&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--chromedriver-version&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--chromedriver-cdnurl&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Appium 2.x, all these command line flags have been removed because all these flags are now implemented as NPM config flags. Now, you can use the following environment variables instead of the earlier flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;APPIUM_SKIP_CHROMEDRIVER_INSTALL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CHROMEDRIVER_VERSION&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CHROMEDRIVER_CDNURL&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use these environment variables as shown in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPIUM_SKIP_CHROMEDRIVER_INSTALL=1 appium driver install uiautomator2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you are skipping Chrome driver installation by setting &lt;code&gt;APPIUM_SKIP_CHROMEDRIVER_INSTALL&lt;/code&gt; as 1, which indicates true.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Driver Command Line Options
&lt;/h3&gt;

&lt;p&gt;With Appium 1.x, many command line options were specific to a particular driver and were available with the main Appium Server. So, for example, if you wanted to set the Chrome driver location, you would use the &lt;code&gt;--chromedriver-executable&lt;/code&gt; flag with the Appium command.&lt;/p&gt;

&lt;p&gt;With Appium 2.x, all these command line options have been moved to the individual driver commands from the main Appium Server command. Also, there are a few commands that those drivers have completely removed and instead introduced capabilities you can leverage to set those options.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;--chromedriver-executable&lt;/code&gt; command line option has been removed from the &lt;code&gt;uiautomator2&lt;/code&gt; driver and replaced with &lt;code&gt;appium:chromedriverExecutable&lt;/code&gt; capability, which you can use and set the Chrome driver executable path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run your&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/playwright?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Playwright&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;test scripts instantly on 50+ browser and OS combinations using the LambdaTest cloud. Read more.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Driver Automation Commands
&lt;/h3&gt;

&lt;p&gt;With Appium 1.x, when any Appium commands were not implemented by the corresponding driver, it would throw a &lt;code&gt;501 Not Yet Implemented&lt;/code&gt; exception. This error in Appium 2.x has been replaced with &lt;code&gt;404 Not Found&lt;/code&gt; when you call this command from the driver, which does not implement the command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Driver Updates
&lt;/h3&gt;

&lt;p&gt;With Appium 1.x, whenever you wanted to update the drivers, you had to wait for the actual Appium library to roll out the new version to update all the outdated drivers.&lt;/p&gt;

&lt;p&gt;With Appium 2.x, since you now have a separate driver command, you have more control over when to update which driver without worrying about the main Appium Server version.&lt;/p&gt;

&lt;p&gt;For example, you can execute the following command to see which driver has a new update available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appium driver list --updates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when you want to update any driver, you can simply run the following command to update it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appium driver list [driver-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;[driver-name]&lt;/code&gt; is the driver’s name you want to update.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protocol Update
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, Appium API supported MJSONWP (Mobile JSON wire protocol) and W3C WebDriver protocol. But with Appium 2.x, it now only supports W3C WebDriver protocol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;A comprehensive&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/learning-hub/end-to-end-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;end-to-end Testing&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;tutorial that covers what E2E Testing is, its importance, benefits, and how to perform it with real-time examples.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Capabilities Updates
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, the capabilities were used as is without vendor prefixes. However, with Appium 2.x, only the &lt;code&gt;browserName&lt;/code&gt; and &lt;code&gt;platformName&lt;/code&gt; capabilities will not have the vendor prefix, and all the other capabilities will have the vendor prefix. The vendor prefix is the name of the vendor and capability name separated by a colon, for example, &lt;code&gt;appium:&amp;lt; capability-name &amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This format is specific to W3C protocol specification. If the vendor prefix is not required, it will be explicitly mentioned in the documentation.&lt;/p&gt;

&lt;p&gt;This approach is automatically handled in the Appium client bindings in different programming languages. Also, the new Appium Inspector version has this feature to automatically add the vendor prefix to the respective capability name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing Appium Commands
&lt;/h3&gt;

&lt;p&gt;There may be many Appium commands that may not have been moved to the respective drivers, or plugins will be removed in the Appium clients first from the Appium Server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Image Comparison
&lt;/h3&gt;

&lt;p&gt;Image comparison commands were available in Appium 1.x, which has been moved to a separate plugin called &lt;code&gt;images&lt;/code&gt;, which you can install separately using the Appium plugin command.&lt;/p&gt;

&lt;p&gt;For example, you can install this plugin by running the &lt;code&gt;appium plugin install images&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And you can use this plugin in your Appium session by providing &lt;code&gt;--use-plugins=images&lt;/code&gt; to the Appium Server command while starting the server session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Execute Driver Script Command
&lt;/h3&gt;

&lt;p&gt;The execute driver script command, available in Appium 1.x has been moved to a separate plugin called &lt;code&gt;execute-driver&lt;/code&gt;, which you can install separately using the Appium plugin command.&lt;/p&gt;

&lt;p&gt;For example, you can install this plugin by running the &lt;code&gt;appium plugin install execute-driver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And you can use this plugin in your Appium session by providing &lt;code&gt;--use-plugins=execute-driver&lt;/code&gt; to the Appium Server command while starting the server session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Server Port Must Not Be Zero
&lt;/h3&gt;

&lt;p&gt;With Appium 1.x, you could start the Appium Server with a port set as 0. This meant that Appium would identify any available free port to start the Appium session.&lt;/p&gt;

&lt;p&gt;But with Appium 2.x, this is not allowed. The port number should be greater than 0. This means that you must know beforehand which port number you want to start the Appium session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Renamed Internal Packages
&lt;/h3&gt;

&lt;p&gt;Many internal packages were renamed. For example, &lt;code&gt;appium-base-driver&lt;/code&gt; is now named &lt;code&gt;@appium/base-driver&lt;/code&gt;. This change will not impact the users, but it will impact those who maintain code that directly works with Appium code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removed Old Drivers
&lt;/h3&gt;

&lt;p&gt;All the old drivers, like &lt;code&gt;UIAutomator1&lt;/code&gt;, which were part of Appium 1.x have been removed. It also removed other related tools like &lt;code&gt;authorize-ios&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appium Desktop Deprecated
&lt;/h3&gt;

&lt;p&gt;In Appium 1.x, you would use Appium Desktop with &lt;a href="https://www.lambdatest.com/blog/appium-inspector-for-apps/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium Inspector&lt;/a&gt; integrated inside it. But with Appium 2.x, the Appium Desktop has been deprecated and does not support the new version. Instead, Appium Inspector has been made as a standalone desktop application that you can use to inspect the elements.&lt;/p&gt;

&lt;p&gt;Appium Inspector also comes in a web application form which you can access from the web by going to &lt;a href="https://inspector.appiumpro.com" rel="noopener noreferrer"&gt;https://inspector.appiumpro.com&lt;/a&gt; URL. The only thing to remember here is to provide the &lt;code&gt;--allow-cors&lt;/code&gt; flag while starting the Appium server on your machine to connect the web Appium Inspector to the local Appium Server session.&lt;/p&gt;

&lt;h3&gt;
  
  
  New features
&lt;/h3&gt;

&lt;p&gt;There were a few new major features that have been introduced with Appium 2.x, which are described below:&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Now it is possible to create Appium plugins. Plugins are a feature that helps extend and modify the Appium behavior as required. You can install, update or uninstall the plugin as you require.&lt;/p&gt;

&lt;h3&gt;
  
  
  Drivers
&lt;/h3&gt;

&lt;p&gt;You can now install any Appium driver using the driver commands. You can also create a new driver to support a new platform that Appium currently does not support.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration file
&lt;/h3&gt;

&lt;p&gt;With Appium 2.x, you can now create an Appium config file with commonly used Appium Server flags configured in this config file. This config file can be in any of the following formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;YML&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;It is a comprehensive guide for test automation with&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/learning-hub/selenium-ide?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=aug_01&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Selenium IDE&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;, covering various topics and techniques for effective web testing.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;That’s all in this short Appium 2 migration guide on how to move from using Appium 1.x to Appium 2.x and what things you must keep in mind. Share this Appium 2 migration guide with your network to help them transition to the new Appium version.&lt;/p&gt;

</description>
      <category>appium</category>
      <category>appiumtesting</category>
      <category>automationtesting</category>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>How To Automate Android Apps Using Appium</title>
      <dc:creator>WasiqBhamla</dc:creator>
      <pubDate>Fri, 03 Mar 2023 07:35:00 +0000</pubDate>
      <link>https://dev.to/testmuai/how-to-automate-android-apps-using-appium-5fa8</link>
      <guid>https://dev.to/testmuai/how-to-automate-android-apps-using-appium-5fa8</guid>
      <description>&lt;p&gt;In this age where new technologies are coming up rapidly, it’s very important to keep up with speed and ensure the highest application quality is delivered to the customers. If we see the user base of different operating systems, we can see that Android is currently the market leader worldwide. Let’s see this market trend:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F0%2AHS_JSFl-nTj1tgRX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2400%2F0%2AHS_JSFl-nTj1tgRX.png" alt="image1" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many companies want a mobile version of their web applications or even directly create mobile applications for their customers. Therefore, it must be tested thoroughly to ensure customers get quality applications.&lt;/p&gt;

&lt;p&gt;When I started with &lt;a href="https://www.lambdatest.com/mobile-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;mobile automation testing&lt;/a&gt; in 2017, I explored many &lt;a href="https://www.lambdatest.com/blog/automation-testing-tools/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;automation testing tools&lt;/a&gt;, like, Calabash with Ruby, Selendroid, and Appium, but out of those, I found Appium is one of the most popular automation tools, and it was relatively easy to get started because of the similarities it had with &lt;a href="https://www.lambdatest.com/learning-hub/webdriver?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt;. Also, it had support with many different programming languages like Java, JavaScript, C#, Python, Ruby, etc., which gave more flexibility to everyone who could use Appium in the language of their choice.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://www.lambdatest.com/learning-hub/webdriver?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;mobile app testing tutorial&lt;/a&gt; on how to automate Android apps will help you know everything to get started with &lt;a href="https://www.lambdatest.com/android-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Android automation testing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Appium?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium&lt;/a&gt; is an open-source &lt;a href="https://www.lambdatest.com/blog/best-mobile-app-testing-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile app testing framework&lt;/a&gt; and an ecosystem to help automate Android apps and iOS apps categorized across different mobile-based applications, like native, web, and hybrid. It also supports automating smart TV and Windows/macOS-based desktop applications.&lt;/p&gt;

&lt;p&gt;Since Appium came up with the new version 2.0.0, it has introduced many new changes which further enhanced the overall functionality of Appium. To mention a few recent changes, it has now decoupled drivers from its command line installation. It also introduced a way to override, alter, extend, and add new functionality to Appium by creating Plugins. It also encourages using the W3C protocol for automation compared to earlier Mobile JSON wire protocol.&lt;/p&gt;

&lt;p&gt;If you’re new to Appium, this tutorial can provide an easy-to-follow guide on performing &lt;a href="https://www.lambdatest.com/mobile-app-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;mobile app testing.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Through this &lt;a href="https://www.lambdatest.com/learning-hub/usability-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;usability testing&lt;/a&gt; tutorial, you will learn how usability testing is a great way to discover unexpected bugs, find what is unnecessary or unused before going any further, and have unbiased opinions from an outsider.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/pI5zrUhydyo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Android app automation
&lt;/h2&gt;

&lt;p&gt;For Appium to run successfully and automate Android apps on your machine, you must set up your machine correctly. Let’s see what setup is required to be done to automate Android apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Node JS
&lt;/h2&gt;

&lt;p&gt;You can install Node JS v16 LTS using Node Version Manager (NVM) by executing the following command on the terminal or command prompt on your machine.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command will download the installation script and run it on your machine to install NVM.&lt;/p&gt;

&lt;p&gt;Once NVM is installed successfully, you can install Node JS 16.x.x LTS using the following command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; nvm install lts/gallium
Downloading and installing node v16.19.0...
Downloading https://nodejs.org/dist/v16.19.0/node-v16.19.0-darwin-arm64.tar.xz...
######################################################################################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v16.19.0 (npm v8.19.3).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once this is installed, you can confirm the installed Node version by running the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; node -v
V16.19.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;p&gt;You must also download and install the following to compile and run your tests successfully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;JDK 11: You can download the installer from the link provided for your machine and install it, or you can also use Homebrew on your macOS machine to install the JDK using the following command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;brew tap homebrew/cask-versions&lt;br&gt;
brew install --cask temurin11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maven: You can download the distribution package from the provided link, unzip it in the location of your choice, and set the M2_HOME, or you can simply run brew install maven on your macOS machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Install Android Studio
&lt;/h2&gt;

&lt;p&gt;To install Android Studio, download the installer from the Android download page and run it. Once the installation is done, open SDK manager and install the following selected packages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run your &lt;a href="https://www.lambdatest.com/jest?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Jest testing&lt;/a&gt; automation in massive parallel across multiple browser and OS combinations with LambdaTest, Read more.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2188%2F0%2AN4584V9ACc_Snu63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2188%2F0%2AN4584V9ACc_Snu63.png" alt="image2" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the package highlighted in red. This package will only get visible when you uncheck Hide Obsolete Packages.&lt;/p&gt;

&lt;p&gt;All these packages are required to automate Android apps.&lt;/p&gt;

&lt;p&gt;The last step is setting up the ANDROID_HOME environment variable pointing to the SDK path. Also, we need to update the PATH variable with paths to emulator, tools, platform-tools, and cmdline-tools paths.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export ANDROID_HOME="/path/to/Android/sdk"


export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Install Appium Server CLI
&lt;/h2&gt;

&lt;p&gt;To run Appium to automate Android apps on your machine, you will need to install the Appium Command line tool to manage the server and drivers. To install the Appium CLI, run the following command on your terminal:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npm install -g appium@next


added 453 packages, and audited 454 packages in 30s


49 packages are looking for funding
 run `npm fund` for details


found 0 vulnerabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will only install the latest Appium v2.0 CLI on your machine. Run appium -v to confirm that v2.0.0 was installed successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Available Appium Drivers
&lt;/h2&gt;

&lt;p&gt;With Appium 2.0, they have decoupled the Appium Server and drivers. So when you installed Appium CLI, it did not install any drivers. To see all the supported drivers by Appium, run this command:&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium Driver
&lt;/h2&gt;

&lt;p&gt;Now, from the list of supported drivers, you can install any of the required drivers as per your requirement. To install a specific driver, in this case, the uiautomator2 driver for Android, run the following command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2APAjsyORitJJhRGi7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2APAjsyORitJJhRGi7.png" alt="image3" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check if the driver is installed, you can again run the command to list all the supported drivers, and it will show a tick (✔️) next to the installed driver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium Doctor
&lt;/h2&gt;

&lt;p&gt;To check whether your machine setup is done correctly now, you would need appium-doctor to help us check it. To install appium-doctor, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npm install -g @appium/doctor
npm WARN deprecated debug@4.1.1: Debug versions &amp;gt;=3.2.0 &amp;lt;3.2.7 || &amp;gt;=4 &amp;lt;4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)


changed 367 packages, and audited 368 packages in 43s


44 packages are looking for funding
 run `npm fund` for details


found 0 vulnerabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Check Machine Setup
&lt;/h2&gt;

&lt;p&gt;Once Appium doctor is installed, run the following command to check machine setup to automate Android apps:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AH1O5UO8sgG0Cpygj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AH1O5UO8sgG0Cpygj.png" alt="image4" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium &lt;/a&gt;mobile testing of native and web apps. Improve your app quality with instant access to real devices on LambdaTest. Register now for free.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Start Appium Server
&lt;/h2&gt;

&lt;p&gt;To start the Appium Server using Appium v2, run the following command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; appium server --address localhost --port 4723 --use-drivers uiautomator2 --base-path /wd/hub
[Appium] Welcome to Appium v2.0.0-beta.48 (REV 0ccd099bff8e384043883c4ae01b589794b13d72)
[Appium] Non-default server args:
[Appium] {
[Appium]   address: 'localhost',
[Appium]   basePath: '/wd/hub',
[Appium]   useDrivers: [
[Appium]     'uiautomator2'
[Appium]   ]
[Appium] }
[Appium] Attempting to load driver uiautomator2...
[debug] [Appium] Requiring driver at /Users/wasiqbhamla/.appium/node_modules/appium-uiautomator2-driver
[Appium] Appium REST http interface listener started on localhost:4723
[Appium] Available drivers:
[Appium]   - uiautomator2@2.12.1 (automationName 'UiAutomator2')
[Appium] No plugins have been installed. Use the "appium plugin" command to install the one(s) you want to use.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once the server starts, it’s ready to connect to this server instance, communicate with the device, and execute your test using this session.&lt;/p&gt;

&lt;p&gt;To stop the server, you must press Ctrl + C.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Android Device
&lt;/h2&gt;

&lt;p&gt;The last step of starting with Android automation using Appium is setting up the device to make it ready for Appium to connect with the device. The device can be a virtual Emulator or your real device. Let’s see how to set up both kinds of devices properly.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZbP-vUTosP4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Android Emulator
&lt;/h2&gt;

&lt;p&gt;Let’s create an &lt;a href="https://www.lambdatest.com/android-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Android Emulator&lt;/a&gt; using Android Studio. Firstly open Android Studio and click More Actions &amp;gt; Virtual Device Manager as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ATVxaDBhJ6I9tjBFh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ATVxaDBhJ6I9tjBFh.png" alt="image5" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open up Device manager, which will contain a list of any existing virtual devices and provide an option to create new ones. This is what the device manager screen looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AEThUGiWL39xM6jIQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AEThUGiWL39xM6jIQ.png" alt="image6" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start the Emulator
&lt;/h2&gt;

&lt;p&gt;To start the emulator, you can click on the (▶️) button in the device manager screen corresponding to the device you want to start. Once you start the emulator, it will take some time to load. Check out a sample emulator screen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AP66BIDJf7b2nueJG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AP66BIDJf7b2nueJG.png" alt="image7" width="449" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Cloud Platforms?
&lt;/h2&gt;

&lt;p&gt;If you don’t want to set up a local emulator and still wish to inspect elements for the Android application, you can use cloud-based devices. Before we move ahead, let’s first understand what cloud providers are. Cloud providers are test orchestration &amp;amp; execution platforms like LambdaTest, which provide an &lt;a href="https://www.lambdatest.com/online-device-farm?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;online device farm &lt;/a&gt;of 3000+ real devices and operating systems to perform &lt;a href="https://www.lambdatest.com/real-device-cloud?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;real device cloud&lt;/a&gt; testing at scale over an Appium grid. Using LambdaTest, you can perform app test automation on real Android and iOS devices.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Test your native, hybrid, and web apps across all legacy and latest mobile operating systems on the most powerful &lt;a href="https://www.lambdatest.com/intl/en-in/android-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Android emulator&lt;/a&gt; online.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vDHFbEjXxdc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can also subscribe to the &lt;a href="https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw?sub_confirmation=1?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=youtube" rel="noopener noreferrer"&gt;LambdaTest YouTube Channel&lt;/a&gt; and stay updated with the latest tutorials around &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Selenium testing&lt;/a&gt;, &lt;a href="https://www.lambdatest.com/cypress-e2e-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Cypress E2E testing&lt;/a&gt;, CI/CD, and more.&lt;/p&gt;

&lt;p&gt;Here are some of the features of LambdaTest &lt;a href="https://www.lambdatest.com/appium?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium automation&lt;/a&gt; platform &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Test native features of your mobile apps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lambdatest.com/automated-device-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Automated device testing&lt;/a&gt; on blazing fast test automation cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for all Languages &amp;amp; Frameworks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comprehensive test execution logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Geolocation testing of mobile apps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the Cloud Platform
&lt;/h2&gt;

&lt;p&gt;For this blog on how to automate Android apps, we use the LambdaTest cloud platform. On the &lt;a href="https://accounts.lambdatest.com/dashboard?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;LambdaTest Dashboard&lt;/a&gt;, navigate to Real Device &amp;gt; App Automation on the left-hand panel. Once on that page, click Upload App to upload the application. Check out the upload app page shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxu079i66t32ajan7gbd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxu079i66t32ajan7gbd.png" alt="image8" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you upload the application APK, LambdaTest will return you with a unique application URL in the format lt://, which you must copy and keep safe as it will be required later when you try to inspect element from the cloud or try running your Android test on the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying Locators
&lt;/h2&gt;

&lt;p&gt;The first step after you have done the setup on your machine is, identifying the element locators for the Application Under Test (AUT). Let’s look at how to inspect elements for Android applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium Server
&lt;/h2&gt;

&lt;p&gt;To inspect elements, it’s better to use the Appium Server desktop application, which will give us plenty of server options that we can set up as per our requirements. To install the Appium Server application, you can download it from their GitHub Release page. From that page, download the application which is compatible with your machine. Since I am using a MacBook, I downloaded the .dmg installer file from this release page.&lt;/p&gt;

&lt;p&gt;Once you have downloaded the installer compatible with your machine and installed the application, it will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AAWfZ4TU2OlcmFDVf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AAWfZ4TU2OlcmFDVf.png" alt="image9" width="762" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start the Appium Server with default settings, press the startServer button. You can also modify server settings from the Advanced tab. You can save the server settings you modified for later use by clicking the Save as Preset button under the Advanced tab. These saved presets will be available under the Presets tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium Inspector
&lt;/h2&gt;

&lt;p&gt;Next important tool is the &lt;a href="https://www.lambdatest.com/blog/appium-inspector-for-apps/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium Inspector&lt;/a&gt; application itself. This is also a desktop-based application that you can use to connect to a local Appium Server session; we started using the Appium Server application and the local device (whether Emulator or Real device) or even a cloud-based device where it will install the application under test on the device, launch it and will help you inspect the elements of the application.&lt;/p&gt;

&lt;p&gt;To download the Appium Inspector application, visit their GitHub Release page and download the application compatible with your machine’s operating system. Once the application is downloaded and installed, it will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AyJJV2hGZZxk43l_F.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AyJJV2hGZZxk43l_F.png" alt="image10" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On this screen, you can create desired capabilities for different devices and save them for later use.&lt;/p&gt;

&lt;p&gt;With these capabilities, you can select any capability you want to run and the server instance where you want to run this capability. It can be either a local Appium Server or any of the supported cloud platforms, which you can select from the Select Cloud Provider tab, which will list all the supported providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect the element on the device using the Inspector
&lt;/h2&gt;

&lt;p&gt;To inspect the element, you will select the capability from the Appium Inspector and update the server details to connect to and then click on the Start Session button. Let’s see how this screen looks before you start the session.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AZ4Y1TLjXq7aNjHKX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AZ4Y1TLjXq7aNjHKX.png" alt="image11" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here one thing to notice is the base path, which is provided as /wd/hub, and we don’t have to provide Remote Host and Remote Port as it defaults to the localhost and port is 4723 which is where you started the Appium Server using the server application.&lt;/p&gt;

&lt;p&gt;Once the session starts, the Android Emulator will start as mentioned in the capability avd where you must mention the Emulator name you created using Android Studio’s Virtual device manager. This is how the inspector screen looks when the session is started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ATFKLmDwfXCftVAO6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ATFKLmDwfXCftVAO6.png" alt="image12" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On this screen, you can click on the element on the application screen, mirrored on this inspector from the device. You will be able to see the properties of that element on the right-hand panel. You can see all the element hierarchies in the XML tree in the center panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect Element on Cloud Device
&lt;/h2&gt;

&lt;p&gt;To inspect an element on a cloud device, you must get your cloud credentials which you can get from the page when you visit Real Device &amp;gt; App Automation, which can be seen here below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AR5AgcbNX5SIvgd9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AR5AgcbNX5SIvgd9e.png" alt="image13" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can copy the user name and access key by clicking on the copy button next to them. Now open the inspector window, click Select Cloud Providers, and select LambdaTest from the list of providers. Check out the screen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ARR5RDVKbnohg-ehP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ARR5RDVKbnohg-ehP.png" alt="image14" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you select the desired cloud provider, you can see it in the main window tabs. Select that tab and add the desired capabilities for starting the session on LambdaTest. Let’s see the example in the next screenshot where I have selected LambdaTest and added all the desired capabilities along with additional LambdaTest-specific capabilities identified with the help of the &lt;a href="https://www.lambdatest.com/capabilities-generator/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;LambdaTest Capabilities Generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AAU0E9_2xZcc2dQ1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2AAU0E9_2xZcc2dQ1z.png" alt="image15" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once everything looks good, click Start Session. The Appium Inspector application will establish a connection on LambdaTest. Once the session is started, you will see the inspector screen as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7yrly9mf8wfv4vds0pc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7yrly9mf8wfv4vds0pc.png" alt="image16" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;Note: **One thing to note here is, while setting the app capability in the inspector, is that I am passing the App URL provided by LambdaTest when the application was first uploaded on their servers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can confirm that the inspector session has started on LambdaTest by navigating to the LambdaTest dashboard and clicking on Real Devices &amp;gt; App Automation. You will see that the build and session you provided in the capability in the inspector will be visible running on the dashboard. The same is shown in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ACdaFItlrrskWe2ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ACdaFItlrrskWe2ce.png" alt="image17" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get more details about the session when you click on the session name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2APO8hh02JN3xyhEHa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2APO8hh02JN3xyhEHa.png" alt="image18" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run your &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Selenium Automation&lt;/a&gt; Testing scripts on the LambdaTest cloud grid. Test on 3000+ desktop &amp;amp; mobile environments. Try it for free.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the Appium test for Android App
&lt;/h2&gt;

&lt;p&gt;Since you are now aware of how to inspect elements, the final step is to write an Appium test for an Android application on an Android device. In this blog on how to automate Android apps, &lt;a href="https://www.lambdatest.com/blog/setup-junit-environment/#intellij?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;IntelliJ IDEA Community Edition&lt;/a&gt; is used. You are also suggested to use IntelliJ, but it’s up to you which IDE is your preferred one.&lt;/p&gt;

&lt;p&gt;In this blog, the following test scenario will be covered, which will help you in getting a basic understanding of how to automate Android apps using Appium.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use the proverbial application provided by LambdaTest and test the Hybrid page, which contains WebView, where we will enter a URL, navigate to that web page, and validate if we are on that page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the test on a local emulator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the test on LambdaTest cloud real device.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a Maven Project
&lt;/h2&gt;

&lt;p&gt;To create our project, let’s open IntelliJ IDEA and create a new project using Java 11 JDK and Maven. Make sure you have mentioned “group id” and “artifact id” in the Advance Setting section as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AxXF7CCUIFEToKG-Z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AxXF7CCUIFEToKG-Z.png" alt="image19" width="800" height="721"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Dependencies
&lt;/h2&gt;

&lt;p&gt;Once the project is created, open the pom.xml file and add the following dependencies:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
&amp;lt;dependencies&amp;gt;
   &amp;lt;!-- https://mvnrepository.com/artifact/io.appium/java-client --&amp;gt;
   &amp;lt;dependency&amp;gt;
       &amp;lt;groupId&amp;gt;io.appium&amp;lt;/groupId&amp;gt;
       &amp;lt;artifactId&amp;gt;java-client&amp;lt;/artifactId&amp;gt;
       &amp;lt;version&amp;gt;8.3.0&amp;lt;/version&amp;gt;
   &amp;lt;/dependency&amp;gt;
   &amp;lt;!-- https://mvnrepository.com/artifact/org.testng/testng --&amp;gt;
   &amp;lt;dependency&amp;gt;
       &amp;lt;groupId&amp;gt;org.testng&amp;lt;/groupId&amp;gt;
       &amp;lt;artifactId&amp;gt;testng&amp;lt;/artifactId&amp;gt;
       &amp;lt;version&amp;gt;7.7.1&amp;lt;/version&amp;gt;
       &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
   &amp;lt;/dependency&amp;gt;
   &amp;lt;!-- https://mvnrepository.com/artifact/com.google.truth/truth --&amp;gt;
   &amp;lt;dependency&amp;gt;
       &amp;lt;groupId&amp;gt;com.google.truth&amp;lt;/groupId&amp;gt;
       &amp;lt;artifactId&amp;gt;truth&amp;lt;/artifactId&amp;gt;
       &amp;lt;version&amp;gt;1.1.3&amp;lt;/version&amp;gt;
       &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
   &amp;lt;/dependency&amp;gt;
   &amp;lt;!-- https://mvnrepository.com/artifact/com.google.guava/guava --&amp;gt;
   &amp;lt;dependency&amp;gt;
       &amp;lt;groupId&amp;gt;com.google.guava&amp;lt;/groupId&amp;gt;
       &amp;lt;artifactId&amp;gt;guava&amp;lt;/artifactId&amp;gt;
       &amp;lt;version&amp;gt;31.1-jre&amp;lt;/version&amp;gt;
   &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let’s understand why we have used these dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Appium Java client:&lt;/strong&gt; This dependency is required to automate Android apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TestNG:&lt;/strong&gt; This dependency executes our tests on a local emulator and the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Truth:&lt;/strong&gt; This dependency is used to assert our test to ensure validation of our test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Guava:&lt;/strong&gt; This is required for the Appium Java client to execute without any issues. Without this dependency, the Java client gives an Error while executing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Starting Appium Server programmatically
&lt;/h2&gt;

&lt;p&gt;When automating with Appium, it is essential to start the Appium Server from our test to control the &lt;a href="https://prod-mobile-artefacts.lambdatest.com/assets/docs/proverbial_android.apk?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;test execution&lt;/a&gt;. To start an Appium Server programmatically, you must build the Appium service. Let’s see how to build the service:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private AppiumDriverLocalService buildAppiumService () {
   final var appiumPath = Path.of (System.getenv ("HOME"),
           ".nvm/versions/node/v16.19.0/lib/node_modules/appium/build/lib/main.js")
       .toFile ();
   final var logFile = Path.of (System.getProperty ("user.dir"), "logs", "appium.log")
       .toFile ();


   final var builder = new AppiumServiceBuilder ();
   return builder.withIPAddress (System.getProperty ("host", "127.0.0.1"))
       .usingPort (Integer.parseInt (System.getProperty ("port", "4723")))
       .withLogFile (logFile)
       .withAppiumJS (appiumPath)
       .withArgument (GeneralServerFlag.BASEPATH, "/wd/hub")
       .withArgument (GeneralServerFlag.USE_DRIVERS, "uiautomator2")
       .withArgument (GeneralServerFlag.SESSION_OVERRIDE)
       .withArgument (GeneralServerFlag.ALLOW_INSECURE, "chromedriver_autodownload")
       .build ();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This method builds the AppiumServiceBuilder class instance with the required attributes per your machine. The attributes we set here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**host: **We get the hostname from the system property. If it is not set, we will use host 127.0.0.1 by default for localhost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;port:&lt;/strong&gt; We set the port number from the system property. If it is not set, we will use port 4723, the default on which the Appium Server will start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;log file:&lt;/strong&gt; We are setting the log file name where the Appium Server will save all the server logs in this file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Appium JS path:&lt;/strong&gt; We are setting the Appium main.js path from its installation folder. Normally when you install Node JS using NVM, then when you install Appium, its path is under the ‘.nvm’ directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Base path:&lt;/strong&gt; The base path for the server, which is normally /wd/hub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Drivers:&lt;/strong&gt; We set all the drivers we will use here. In this example, we will be using uiautomator2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allow insecure:&lt;/strong&gt; We will automate a WebView in a hybrid application in this example. So to automate the web view, we must set the insecure flag chromedriver_autodownload to allow the Appium Server to automatically download the Chrome driver compatible with your device’s web view.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now to start the Appium Server, you need to call the start method as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.service = buildAppiumService ();
this.service.start ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And to stop the Appium Server, you must call the stop method like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (this.service != null) {
   this.service.stop ();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Start the session on Local Emulator
&lt;/h2&gt;

&lt;p&gt;Now your Appium Server is ready to start and accept sessions and connect your tests with the running device. To start the session, you must first create a set of capabilities describing your test device and the application under test. Let’s see how to achieve this in the following code snippet:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static final String DEVICE_NAME_KEY = "deviceName";
private static final String DEVICE_VERSION_KEY = "deviceVersion";
. . .
private Capabilities buildCapabilities () {
   final var deviceName = System.getProperty (DEVICE_NAME_KEY, "Pixel_6_Pro");
   final var deviceVersion = System.getProperty (DEVICE_VERSION_KEY, "11");
   final var options = new UiAutomator2Options ();
   options.setPlatformName ("Android")
       .setPlatformVersion (deviceVersion)
       .setDeviceName (deviceName)
       .setAvd (deviceName)
       .setApp (Path.of (System.getProperty ("user.dir"), "src/test/resources/proverbial.apk")
           .toString ())
       .setAutoGrantPermissions (true)
       .setIsHeadless (Boolean.parseBoolean (System.getProperty ("headless", "false")));
   return options;
}
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In Appium Java client v8.x.x, you can now use the UiAutomator2Options class instance to build the capabilities. In this example, we are setting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Platform Name:&lt;/strong&gt; This is set as Android as we automate Android apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Platform Version: **This is to set the Android version passed from the system property or use 11 by default if the property is not set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Device Name:&lt;/strong&gt; To set the Android device name, which will be passed from the system property, or use Pixel_6_Pro by default. You must ensure that you pass the device name via system property as it may fail if not passed because you may not have the Emulator with the default name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avd Name:&lt;/strong&gt; This is the same as the device name. When this capability is set with the correct Emulator name, Appium will launch the Emulator if it is not started already.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**App Path: **This is set as the application APK file path from your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto Grant permission:&lt;/strong&gt; This is set to true by default, allowing all the permissions required by the application under test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Is Headless:&lt;/strong&gt; This is set as the boolean value passed using system property to determine whether to run on the Emulator in a headless mode. If set to true, the Emulator UI will not be visible, and the emulator will run in the background. However, if the Emulator is already running and visible, this flag value will not be considered.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start the session on the Appium Server, you must pass these capabilities to the AndroidDriver instance along with the server URL. Let’s see how to achieve this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final Capabilities capabilities = buildCapabilities ();
final URL serverUrl = this.service.getUrl ();


this.driver = new AndroidDriver (serverUrl, capabilities);
this.driver.setSetting (Setting.IGNORE_UNIMPORTANT_VIEWS, true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can get the server URL using the service instance we created earlier and pass the capabilities we built to the AndroidDriver instance a while ago. This will establish the connection between the Appium Server and the device. If not started already, it will launch the emulator and install and start the application under test on the device.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pro Tip: We are updating the driver settings to set IGNORE_UNIMPORTANT_VIEWS as true. What this will do is it will clean up the element hierarchy of the element displayed on the screen. You will only see those elements in the hierarchy which are visible. This will speed up the process of finding the elements later on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To disconnect the session with the Appium Server, you must call the quit method from the driver instance as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.driver.quit ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Start the session on the Cloud Device
&lt;/h2&gt;

&lt;p&gt;To connect our tests to run on LambdaTest cloud devices, you must first set a few environment variables on your machine which will be used in the test setup. Those environment variables can be set by adding the following lines in your .zshrc or .bash_profile file if you are on Mac, or an equivalent file on Linux or by manually adding to the Windows environment variable window:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export LT_USERNAME="your-user-name"
export LT_ACCESS_KEY="your-access-key"
export LT_APP_ANDROID="your-app-url"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once these is set, now let’s see how to set up the cloud capabilities below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static final String DEVICE_NAME_KEY = "deviceName";
private static final String DEVICE_VERSION_KEY = "deviceVersion";
. . .
private URL getCloudUrl () {
   final var cloudUrl = "@mobile-hub.lambdatest.com/wd/hub"&amp;gt;https://{0}:{1}@mobile-hub.lambdatest.com/wd/hub";
   final var userName = Objects.requireNonNull (System.getenv ("LT_USERNAME"), "Cloud user name is required");
   final var key = Objects.requireNonNull (System.getenv ("LT_ACCESS_KEY"), "Cloud access key is required");
   final var path = MessageFormat.format (cloudUrl, userName, key);
   try {
       return new URL (path);
   } catch (final MalformedURLException e) {
       throw new UnsupportedOperationException (format ("URL malformed: {0}", path));
   }
}
. . .
private Capabilities buildCloudCapabilities () {
   final var deviceName = System.getProperty (DEVICE_NAME_KEY, "Pixel_6_Pro");
   final var deviceVersion = System.getProperty (DEVICE_VERSION_KEY, "11");
   final var options = new UiAutomator2Options ();
   final var ltOptions = new HashMap&amp;lt;&amp;gt; ();
   ltOptions.put ("w3c", true);
   ltOptions.put ("platformName", "Android");
   ltOptions.put (DEVICE_NAME_KEY, deviceName);
   ltOptions.put ("platformVersion", deviceVersion);
   ltOptions.put ("app", Objects.requireNonNull (System.getenv ("LT_APP_ANDROID"), "Cloud App URL is required"));
   ltOptions.put ("devicelog", true);
   ltOptions.put ("visual", true);
   ltOptions.put ("network", true);
   ltOptions.put ("video", true);
   ltOptions.put ("build", "Appium sample Build");
   ltOptions.put ("name", "Android Sample");
   ltOptions.put ("project", "Appium Sample Project");
   ltOptions.put ("autoGrantPermissions", true);
   ltOptions.put ("isRealMobile", true);
   options.setCapability ("lt:options", ltOptions);
   return options;
}
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let’s break down this code snippet. First, we are building the cloud platform URL by concatenating our cloud user name and access key in the URL itself. Secondly, we have created the capabilities specific to the LambdaTest cloud and saved it as a Map, which is later passed on to the UiAutomator2Options instance class.&lt;/p&gt;

&lt;p&gt;To know what capabilities are supported by LambdaTest, refer to the LambdaTest Capabilities Generator and play around to see what capabilities you want. The best thing about this is that it also generates a Java code snippet which you can refer to when writing your tests.&lt;/p&gt;

&lt;p&gt;To connect your test to run on the cloud device, you need to pass the cloud URL and the capabilities we built in the previous step to the AndroidDriver instance as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`URL serverUrl = getCloudUrl ();
Capabilities capabilities = buildCloudCapabilities ();


this.driver = new AndroidDriver (serverUrl, capabilities);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To stop the cloud session, you must call the quit method as demonstrated before for running on a local emulator.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Automate &lt;a href="https://www.lambdatest.com/cypress-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Cypress cloud&lt;/a&gt; tests and perform browser automation testing with LambdaTest. Our cloud infrastructure has 3000+ desktop &amp;amp; mobile environments. Try for free.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Page Objects
&lt;/h2&gt;

&lt;p&gt;Next step is creating a page object. Since we are looking into a hybrid screen in the Proverbial application used in this blog on how to automate Android apps using Appium, we will have this minimal page object just to understand the basic interaction Appium allows us to do:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;


import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;


public class HybridPage {
   private final AndroidDriver driver;
   private final WebDriverWait wait;


   public HybridPage (final AndroidDriver driver, final WebDriverWait wait) {
       this.driver = driver;
       this.wait = wait;
   }


   public WebElement browserTab () {
       return this.wait.until (visibilityOfElementLocated (AppiumBy.accessibilityId ("Browser")));
   }


   public void navigateTo (final String url) {
       browserTab ().click ();
       url ().sendKeys (url);
       this.driver.hideKeyboard ();
       find ().click ();
   }


   public String webTitle () {
       return this.wait.until (visibilityOfElementLocated (By.tagName ("h1")))
           .getText ();
   }


   private WebElement find () {
       return this.wait.until (visibilityOfElementLocated (AppiumBy.id ("find")));
   }


   private WebElement url () {
       return this.wait.until (visibilityOfElementLocated (AppiumBy.id ("url")));
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, on the test screen, we click on the Browser tab to navigate to the hybrid screen of the application. It contains a text box where the user will enter the website address, which you want to navigate using the sendKeys method. Then click the Find button using the click method, which will load that website in the web view component below on that same screen.&lt;/p&gt;

&lt;p&gt;In this page object, we have a method for all the elements we will interact with in the complete flow of the tests, which we will cover in the next section. We also have the navigateTo method, which will be called from the test with the intended URL passed as the parameter.&lt;/p&gt;

&lt;p&gt;We also have a method called webTitle, which is nothing but the h1 tag of the website we will be visiting in our test, where we will assert the text of this title element by getting the text of the element using the getText method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Test Classes
&lt;/h2&gt;

&lt;p&gt;Let’s put everything together in our test class. Following is the test class content:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import static com.google.common.truth.Truth.assertThat;


import java.time.Duration;


import com.github.wasiqb.pages.HybridPage;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;


public class AndroidTest {
   private AndroidDriver driver;
   private DriverManager driverManager;


   @Parameters ("isCloud")
   @BeforeTest (alwaysRun = true)
   public void setupTest (final boolean isCloud) {
       this.driverManager = DriverManager.createDriver (isCloud);
       this.driver = this.driverManager.getDriver ();
   }


   @AfterTest (alwaysRun = true)
   public void teardownTest () {
       this.driverManager.close ();
   }


   @Test
   public void testHybridScreen () {
       final var wait = new WebDriverWait (this.driver, Duration.ofSeconds (5));


       final var hybridPage = new HybridPage (this.driver, wait);
       hybridPage.navigateTo ("https://www.lambdatest.com");


       wait.until (d -&amp;gt; this.driver.getContextHandles ()
           .size () &amp;gt; 1);


       this.driver.context ("WEBVIEW_com.lambdatest.proverbial");


       assertThat (hybridPage.webTitle ()).isEqualTo ("Cross Browser\nTesting Cloud");


       this.driver.context ("NATIVE_APP");


       assertThat (hybridPage.browserTab ()
           .isEnabled ()).isTrue ();
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;First, in this test class, we have a setup method, where we initialize the driverManager class and specify where we intend to run the test on. If we want to run on a local emulator, we pass false in the parameter of the createDriver method, and when we want to run on the cloud instance, we pass true.&lt;/p&gt;

&lt;p&gt;Next, we have a teardown method where we close the driver session, which internally quits the driver and closes the Appium Server on a local emulator.&lt;/p&gt;

&lt;p&gt;Next, in our test method, we initialize the HybridPage instance, where we navigate to the browser tab, enter the URL &lt;a href="https://www.lambdatest.com" rel="noopener noreferrer"&gt;https://www.lambdatest.com&lt;/a&gt; and click on the Find button. Later we verify the web page title to verify that the page is loaded correctly.&lt;/p&gt;

&lt;p&gt;One thing to note is the context method, which tells Appium to switch its context from the native to the web view so we can find the elements from the web page visible in the web view on that screen.&lt;/p&gt;

&lt;p&gt;You can get all the available contexts on the screen using the getContextHandles method, which will return the context names. This name you can use to switch the driver context according to your requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Appium tests to automate Android Apps
&lt;/h2&gt;

&lt;p&gt;Before you run the test, you must create the testng.xml file. In our case, we will create two files, one for local execution called testng-local.xml and another one called testng-cloud.xml for executing on the cloud platform.&lt;/p&gt;

&lt;p&gt;Let’s check out one of the testng.xml files to understand how to set up TestNG to run our test:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"&amp;gt;
&amp;lt;suite name="Appium Android Suite" verbose="2"&amp;gt;
   &amp;lt;test name="Appium Android Local Test"&amp;gt;
       &amp;lt;parameter name="isCloud" value="false" /&amp;gt;
       &amp;lt;classes&amp;gt;
           &amp;lt;class name="com.github.wasiqb.AndroidTest" /&amp;gt;
       &amp;lt;/classes&amp;gt;
   &amp;lt;/test&amp;gt;
&amp;lt;/suite&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This file is for running on a local emulator. In the other file, we will have the value of the isCloud parameter to true.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running tests on CLI using mvn
&lt;/h2&gt;

&lt;p&gt;To run our tests using the Maven command line, we must first tell Maven what TestNG file needs to be executed and all the required system properties. For this, you must update your pom.xml file with the following build block as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;properties&amp;gt;
   . . .
   &amp;lt;argLine&amp;gt;-Dfile.encoding=UTF-8 -Xdebug -Xnoagent&amp;lt;/argLine&amp;gt;
   &amp;lt;target&amp;gt;local&amp;lt;/target&amp;gt;
&amp;lt;/properties&amp;gt;
. . .
&amp;lt;build&amp;gt;
   &amp;lt;plugins&amp;gt;
       &amp;lt;plugin&amp;gt;
           &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
           &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
           &amp;lt;version&amp;gt;3.0.0-M5&amp;lt;/version&amp;gt;
           &amp;lt;executions&amp;gt;
               &amp;lt;execution&amp;gt;
                   &amp;lt;goals&amp;gt;
                       &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;
                   &amp;lt;/goals&amp;gt;
               &amp;lt;/execution&amp;gt;
           &amp;lt;/executions&amp;gt;
           &amp;lt;configuration&amp;gt;
               &amp;lt;useSystemClassLoader&amp;gt;false&amp;lt;/useSystemClassLoader&amp;gt;
               &amp;lt;properties&amp;gt;
                   &amp;lt;property&amp;gt;
                       &amp;lt;name&amp;gt;usedefaultlisteners&amp;lt;/name&amp;gt;
                       &amp;lt;value&amp;gt;false&amp;lt;/value&amp;gt;
                   &amp;lt;/property&amp;gt;
               &amp;lt;/properties&amp;gt;
               &amp;lt;suiteXmlFiles&amp;gt;
                   &amp;lt;suiteXmlFile&amp;gt;testng-${target}.xml&amp;lt;/suiteXmlFile&amp;gt;
               &amp;lt;/suiteXmlFiles&amp;gt;
               &amp;lt;argLine&amp;gt;${argLine}&amp;lt;/argLine&amp;gt;
           &amp;lt;/configuration&amp;gt;
       &amp;lt;/plugin&amp;gt;
   &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we are using the maven-surefire-plugin plugin, and we specify the testng.xml file using the suiteXmlFile property. We are using the target property to differentiate which TestNG file to run, and we have declared the target property in the properties block with the default value as local. This means that if you don’t pass the system property of target, the local target will be used by default, and the local test will be executed.&lt;/p&gt;

&lt;p&gt;Once this is setup, you can run the following command to run on the local emulator:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; mvn clean install -Dtarget=local -DdeviceName=&amp;lt;emulator_name&amp;gt;
-DdeviceVersion=&amp;lt;emulator_version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And run the following command to run on the cloud device:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; mvn clean install -Dtarget=cloud -DdeviceName=&amp;lt;emulator_name&amp;gt;
-DdeviceVersion=&amp;lt;emulator_version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Check out the execution of tests using the command mentioned above:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AMjUmWybq2HM1io4f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AMjUmWybq2HM1io4f.gif" alt="image21" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running tests on IDE
&lt;/h2&gt;

&lt;p&gt;Now to run our test on the IDE, you can simply right-click on the testng.xml file and click on the Run option as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AYumQtQl0iASm0uXK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AYumQtQl0iASm0uXK.png" alt="image22" width="632" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the test runs for the first time, it will fail because you have not yet set the system properties and specify the deviceName and deviceVersion. Let’s see how to update the system properties in the IDE.&lt;/p&gt;

&lt;p&gt;You can edit the run configuration created when you first ran the test by clicking the “Edit Configurations…” option as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ANOXZTVaDWNiL2ka2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ANOXZTVaDWNiL2ka2.png" alt="image23" width="397" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open the configuration window, where you can mention the system properties required by your test. You can specify the system properties in the field as shown in the below screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5hu6kw3gq3j98vc844f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5hu6kw3gq3j98vc844f.png" alt="image24" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once everything looks good, you can click on Apply and OK to save the configurations and then click on the (▶️) button next to the run configuration you saved, This will execute the tests in your IDE, and you will be able to see the run results in the corresponding panel in the IDE as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2304%2F0%2AJj4YYyM1UiG92d2V.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2304%2F0%2AJj4YYyM1UiG92d2V.png" alt="image25" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reporting of the test result on LambdaTest
&lt;/h2&gt;

&lt;p&gt;When your run is started on the cloud device, you will be able to see the real-time test execution video streaming and steps being executed on the device from your tests on the LambdaTest Dashboard. To navigate your test:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2212%2F0%2ASko-hNYcvyLlsGWG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2212%2F0%2ASko-hNYcvyLlsGWG.png" alt="image26" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Log in to the dashboard and click Real Devices &amp;gt; App Automation on the left-hand side navigation panel. You will see the below screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ASvLHE_1ocAJAHG5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ASvLHE_1ocAJAHG5m.png" alt="image27" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On this screen, you will see all the test executions you have ever run. To reduce the clutter, you can filter the records based on the “Project name” you mentioned in the cloud capabilities while executing the tests. Once the filter is applied, you will see only those tests which are a part of that project.&lt;/p&gt;

&lt;p&gt;When a test is running, you will see it running in the right section of this screen with the status &lt;strong&gt;RUNNING&lt;/strong&gt;. When you click it, you will be able to see all the real-time interactions of the test.&lt;/p&gt;

&lt;p&gt;Once the test execution is completed, you can see loads of details about the test when you click and open the test from the right section. This is what you will see first when you open the test session:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AXcGDNPucefjhWaP5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AXcGDNPucefjhWaP5.png" alt="image28" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On this screen, you will see the video of the tests, all the test steps that were executed, and the time it took to run that step, along with the screenshots at the time of executing that step.&lt;/p&gt;

&lt;p&gt;You can also see the device logs of the executed test when you click on the “Device Logs” tab as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ATr4I_krD_LuJ0oOB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2ATr4I_krD_LuJ0oOB.png" alt="image29" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, you can see the network logs of the tests by clicking on “Network Logs” as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AV5yLFksE1VfE2VAX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AV5yLFksE1VfE2VAX.png" alt="image30" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And similarly, you can see the Appium Server logs from the cloud server by clicking on “Appium Logs” tab as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AyxA9bGUfztJ6VpmW.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AyxA9bGUfztJ6VpmW.png" alt="image31" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To conclude and recap this &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=mar03_ap&amp;amp;utm_term=ap&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium tutorial&lt;/a&gt; on how to automate Android apps using Appium, we learned about running Appium tests on an Android device on your local machine as well as on the LambdaTest cloud platform. We also learned how to use the new Appium 2.0 for automation, setting up our machine, setting up the required drivers, automating a hybrid app, and interacting with different elements like a button, text field, and web view. This example is enough for you to get started with Android automation and automate any type of application you may work on in the future.&lt;/p&gt;

&lt;p&gt;Don’t forget to check out the GitHub repository used for this blog to automate Android apps.&lt;/p&gt;

&lt;p&gt;If you liked this blog on how to automate Android apps, don’t forget to share it with your network, who may also benefit from it and help them learn about Appium.&lt;/p&gt;

</description>
      <category>appium</category>
      <category>node</category>
      <category>selenium</category>
      <category>automationtesting</category>
    </item>
    <item>
      <title>How To Identify Locators In Appium [With Examples]</title>
      <dc:creator>WasiqBhamla</dc:creator>
      <pubDate>Fri, 16 Dec 2022 08:18:59 +0000</pubDate>
      <link>https://dev.to/testmuai/how-to-identify-locators-in-appium-with-examples-5cmg</link>
      <guid>https://dev.to/testmuai/how-to-identify-locators-in-appium-with-examples-5cmg</guid>
      <description>&lt;p&gt;Nowadays, automation is becoming integral to the overall quality of the products being developed. Especially for mobile applications, it’s even more important to implement automation robustly.&lt;/p&gt;

&lt;p&gt;As per Statista, the number of mobile users is likely to be 7.26 billion by 2022 and will increase up to 7.46 billion by 2025. This indicates how mobile applications will grow in the coming years, making &lt;a href="https://www.lambdatest.com/learning-hub/mobile-app-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile app testing&lt;/a&gt; extremely important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ee1oo86r73y4pvxzk72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ee1oo86r73y4pvxzk72.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many &lt;a href="https://www.lambdatest.com/blog/best-mobile-app-testing-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile testing frameworks&lt;/a&gt; available for performing &lt;a href="https://www.lambdatest.com/mobile-automation-test?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile automation tests&lt;/a&gt;, but in this &lt;a href="https://www.lambdatest.com/blog/appium-tutorial/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium testing tutorial&lt;/a&gt;, we will focus on the Appium automation tool to automate Android and iOS applications. To learn more about mobile automation, you can refer to my earlier blog on &lt;a href="https://www.lambdatest.com/blog/appium-with-testng-tutorial/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium with TestNG&lt;/a&gt; to perform &lt;a href="https://www.lambdatest.com/android-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Android automation testing&lt;/a&gt; and &lt;a href="https://www.lambdatest.com/ios-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;iOS automation testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my experience, I have seen many Test engineers, whether newbies or experienced, using XPaths blindly, which later resulted in flaky tests. Thus, to make automation robust, it’s important to understand which locator strategies are supported in Appium and what locator strategy is ideal for better automation performance.&lt;/p&gt;

&lt;p&gt;In case you are a beginner to Appium you can learn to perform mobile app testing easily through this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/pI5zrUhydyo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;By the end of this tutorial on using locators in &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium testing&lt;/a&gt;, you’ll learn about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Common locator strategies are provided by Appium.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Android-specific locator strategies when the Automation name is UIAutomator2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Android-specific locator strategies when the Automation name is Espresso.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;iOS-specific locator strategies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code snippets and examples used in this blog on locators in Appium are available on GitHub. You can clone the repository and follow along.&lt;/p&gt;

&lt;p&gt;We will be using the Proverbial app for Android and iOS for most of the locator strategies while we will use the API-demo Android app for the UIAutomator -&amp;gt; UiScrollable locator and Espresso-specific Data Matcher and View Matcher locator strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Try an online &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Selenium testing tool&lt;/a&gt; Grid to run your browser automation testing scripts. Our cloud infrastructure has 3000+ desktop &amp;amp; mobile environments. Try for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategies to use locators in Appium
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://www.lambdatest.com/appium?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium&lt;/a&gt;, there are some locator strategies that you can use for Android and iOS platforms. These strategies are very straightforward and almost identical to &lt;a href="https://www.lambdatest.com/learning-hub/selenium-locators?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Selenium locators&lt;/a&gt;, which we are already used to; thus, all these locators are very easy to use.&lt;/p&gt;

&lt;p&gt;Let’s look at all the common strategies to use locators in Appium:&lt;/p&gt;

&lt;h2&gt;
  
  
  ID locator in Appium
&lt;/h2&gt;

&lt;p&gt;The first common locator that Appium supports is ID. The ID is the resource-id defined in the Android app, while in iOS, it’s the name property for the element.&lt;/p&gt;

&lt;p&gt;While using Java, we can use this locator in Appium as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorById = MobileBy.id ("color");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.lambdatest.com/blog/appium-inspector-for-apps/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium Inspector&lt;/a&gt; also suggests using ID if it is declared for the element. The same is shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faftm9le51xuy9pl9kilw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faftm9le51xuy9pl9kilw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ID locator and Accessibility ID locator are very similar, making finding the element easy due to its uniqueness. If these IDs are set for the locator, then you should always prefer using this locator in Appium over other strategies to use locators in Appium. It is preferred to use an ID locator in Appium because it makes the element unique and results in finding the element much more quicker.&lt;/p&gt;

&lt;p&gt;Normally the format of the ID locator for the Android platform is &amp;lt; package-name &amp;gt;:id/&amp;lt; id-name &amp;gt;. So while finding the element, you can use the whole text or only the &amp;lt; id-name &amp;gt;. In the example screenshot, you can either use com.lambdatest.proverbial:id/geoLocation or simply geoLocation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Are you using Playwright for automation testing? Run your &lt;a href="https://www.lambdatest.com/playwright-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;playwright test&lt;/a&gt; scripts instantly on 50+ browser/OS combinations using the LambdaTest cloud. Sign up for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility ID locator in Appium
&lt;/h2&gt;

&lt;p&gt;This is also the most preferred strategy after the ID locator in Appium. Accessibility ID for Android is the content-desc property of the element, while in iOS, it’s the accessibility-id property. It is also one of the fastest performing locator strategies.&lt;/p&gt;

&lt;p&gt;While using Java, we can use this locator in Appium as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByAccessibilityId = MobileBy.AccessibilityId ("color");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Appium Inspector will suggest using Accessibility id if it is defined for the element. The same is shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AiRWQDkjl0iSD2JR4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AiRWQDkjl0iSD2JR4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find that in your application under test if there is any element that is not dynamic but still does not have the accessibility id set, nor does it have any ID set, then you should ask your development team to add those attributes. This will help you save so much time that you may have to build other locators in Appium like XPath, UISelector, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Class Name locator in Appium
&lt;/h2&gt;

&lt;p&gt;Class name is another common strategy to identify the element in the application. The class is the full name of the XCUI element for iOS, which starts with XCUIElementType, and for Android is the fully qualified name of the element, which normally starts with android.widget.* when you select UIAutomator2 as the Automation name in the capability.&lt;/p&gt;

&lt;p&gt;While using Java, you can use this locator in Appium as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByClassName = MobileBy.className ("android.widget.Button");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find exactly what class name there is for any element in Appium Inspector, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AhLAvUYZ0IOl7TXkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AhLAvUYZ0IOl7TXkm.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Normally, you won’t need the use of the class name unless the element is a dynamic one. There is only one element for that particular class name. Use cases would be many where you can use the class name locator, but it is highly suggested to use ID or accessibility id wherever possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This Playwright tutorial will guide you through the setup of the &lt;a href="https://www.lambdatest.com/blog/playwright-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;playwright browser testing&lt;/a&gt; framework, which will enable you to write end-to-end tests for your future projects.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  XPath locator in Appium
&lt;/h2&gt;

&lt;p&gt;XPath scans the whole XML source tree of the application screen. It is the only locator in Appium that is not recommended by the Appium team out of all the locator strategies that Appium supports. The reason is that it has performance issues and is also the slowest performing locator strategy. Normally this locator is still supported when in the rare scenario when all the other locator strategies do not work, we can use XPath to find the element.&lt;/p&gt;

&lt;p&gt;While using Java, you can use the XPath locator in Appium as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByXpath = MobileBy.xpath (".//android.widget.Button[@text='COLOR']");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Appium Inspector also helps you with pre-built XPath expressions, which you can use directly. The same is shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AIR1MJMyVKMGotWh_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AIR1MJMyVKMGotWh_.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is preferred not to use this locator strategy because even if there is no ID or accessibility id, you can still use other platform-specific locator strategies (which we will look at in some time) to find the element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategies to use Android-specific locators in Appium
&lt;/h2&gt;

&lt;p&gt;After commonly supported strategies to use locators in Appium, there are few platforms and automation type-specific locator strategies. Let’s look into the Android-specific locators in Appium in detail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Perform manual or automated cross browser &lt;a href="https://www.lambdatest.com/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;testing web&lt;/a&gt; on 3000+ browsers online. Deploy and scale faster with the most powerful cross browser testing tool online.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  UIAutomator2: UIAutomator Selector
&lt;/h2&gt;

&lt;p&gt;The UIAutomator selector locator in Appium is one of the unique locator strategies where you have to create a Java statement and pass it as the locator text to the method. In this statement, you need to use the UiSelector class to build the Java statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   new UiSelector().&amp;lt;method_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shown below is an example of using this locator in our Java tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByUiSelector = MobileBy.AndroidUIAutomator ("new UiSelector().text(\"COLOR\")");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are creating an instance for UiSelector and informing the server that we need to find an element that has the text COLOR.&lt;/p&gt;

&lt;p&gt;Some of the frequently used methods in the UiSelector class are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;checked:&lt;/strong&gt; This method takes the expected value for the element to find an element that is checked. Mostly it is used with a checkbox element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;className:&lt;/strong&gt; This method takes a class name string, which you can find from Appium Inspector.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;classNameMatches:&lt;/strong&gt; This method takes a regex expression to find an element based on its class name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;description:&lt;/strong&gt; This method takes in the content description attribute for the element, which can be found in Appium Inspector&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;descriptionContains:&lt;/strong&gt; This method takes in full or partial content description attributes for the element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;descriptionMatches:&lt;/strong&gt; This method uses a regex expression to find the element based on its content description.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;descriptionStartsWith:&lt;/strong&gt; This method takes a starting part or full content description to find the element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;enabled:&lt;/strong&gt; This method takes a boolean value to determine whether it’s enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;index:&lt;/strong&gt; This method takes the element’s index from the list of elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;resourceId:&lt;/strong&gt; This method takes in the resource id equivalent to the ID locator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;resourceIdMatches:&lt;/strong&gt; This method takes a regex expression for resource id to find the element based on its resource id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;selected:&lt;/strong&gt; This method takes a boolean value to find the selected or unselected element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;text:&lt;/strong&gt; This method takes in a text value to find an element by its text value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;textContains:&lt;/strong&gt; This method takes a partial text to find an element by its partial text value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;textMatches:&lt;/strong&gt; This method takes a regex value to find an element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;textStartsWith:&lt;/strong&gt; This method takes in a text value for an element to find it based on the text starting value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can verify if your selector is working or not by executing the locator expression in the Search for element window in the Appium Inspector.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2A2VY6e6uAXlaECQJl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2A2VY6e6uAXlaECQJl.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Appium Inspector, click on the magnifying glass icon and select locator strategy as UIAutomator Selector, create your selector, and click on the Search button. You will see the element once it’s found on the next screen, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ArsIUml_br6EmimPW.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ArsIUml_br6EmimPW.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use the UiScrollable class to make the element move into view along with the UiSelector class.&lt;/p&gt;

&lt;p&gt;Let’s check out the UiScrollable example where normal UiSelector cannot find the element not in the viewport, whereas UiScrollable was able to find the element and scroll it into view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByUiSelector = MobileBy.AndroidUIAutomator ("new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\"PathEffects\"))");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above snippet is added as an example here but the same is not there in our demo project.&lt;/p&gt;

&lt;p&gt;In Appium Inspector, we can validate that the UiSelector was not able to find the element as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A_wcggrtR6I8vl5qz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A_wcggrtR6I8vl5qz.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, with UiScrollable, it was able to find and scroll to the element without any problems, the same can be seen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A9yVFfxLWwbCbBNHd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A9yVFfxLWwbCbBNHd.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These locator strategies are more useful while finding dynamic elements, which normally is difficult to find using other commonly used locator strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Espresso: Data Matcher
&lt;/h2&gt;

&lt;p&gt;In Android, when you want to find any element, only the element visible in the viewport can be found. You cannot find an element at the bottom of the list with 100s of items unless you scroll through the list until you find that element or if you’re using UiScrollable with the UiSelector locator strategy. This is possible when you use &lt;a href="https://www.lambdatest.com/espresso?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Espresso&lt;/a&gt; as the Automation type in Appium.&lt;/p&gt;

&lt;p&gt;In Appium Espresso driver, there is a specific locator strategy that you can use to find the element anywhere in the list, and it does not matter how many items are in that list. That locator strategy is Data Matcher.&lt;/p&gt;

&lt;p&gt;Data matcher will only work on elements that are part of a view, a subtype of AdapterViews, for example, ScrollView, ListView, and GridView. If you were to use native Espresso directly to find that element, then you would write something like shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    onData (hasEntry ("title", "App")
     .inAdapterView (withId ("android:id/list"))
     .perform (click ());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Appium you can write the locator similar to this by using Hamcrest exposed methods and create JSON string and pass it to the Data matcher locator method. Let’s see how to do this in Java.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    import org.openqa.selenium.json.Json;
    . . .
    private final By appItemDataMatcher = MobileBy.androidDataMatcher (new Json ().toJson (ImmutableMap.of (
      "name", "hasEntry",
      "args", ImmutableList.of ("title", "App")
    )));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you compare this locator values with the native Espresso expression we used earlier, we are breaking the hasEntry call and creating the JSON string.&lt;/p&gt;

&lt;p&gt;Let’s see how you can find the element using the data matcher locator in Appium Inspector.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2Ayt_aw82FfDhnwCU1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2Ayt_aw82FfDhnwCU1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we want to find elements from the list, first, we will select the main listview and get the value from its adapters attribute, as shown in the screenshot above.&lt;/p&gt;

&lt;p&gt;Let’s see what value is there in the adapters attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    {
      contentDescription=Access'ibility, title=Access'ibility, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Accessibility, title=Accessibility, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Animation, title=Animation, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=App, title=App, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Content, title=Content, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Graphics, title=Graphics, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Media, title=Media, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=NFC, title=NFC, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=OS, title=OS, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Preference, title=Preference, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Text, title=Text, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    },
    {
      contentDescription=Views, title=Views, intent=Intent { cmp=io.appium.android.apis/.ApiDemos (has extras)
       }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the values we used in the Java example for the data matcher locator in Appium for the args field? As mentioned above, we have used the title property, which is part of the adapters attribute. You can use any combination of key/value pairs from these attributes, for example, contentDescription or intent apart from title.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus Tip:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Appium Inspector behaves weirdly when you try to find the element by clicking on it. Instead, you need to find the element from the XML tree. Also, Appium Inspector won’t help provide you with a pre-built locator as it does for other locators in Appium. To ascertain whether the data matcher locator you created works, you can check it by using the Search for element button in the inspector, as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ASKzo7U8dVZbVaXLx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2784%2F0%2ASKzo7U8dVZbVaXLx.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Need a great solution for &lt;a href="https://www.lambdatest.com/safari-browser-for-windows?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;safari browser for Windows&lt;/a&gt;? Forget about emulators or simulators — use real online browsers. Try LambdaTest for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Espresso: View Matcher
&lt;/h2&gt;

&lt;p&gt;View matcher locator strategy is very similar to the data matcher strategy, where we create a JSON string and pass it to the locator in Appium. The only difference is we use ViewMatchers class methods instead of Hamcrest class. Three fields are passed in the JSON string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;name:&lt;/strong&gt; This is the method’s name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;args:&lt;/strong&gt; This will have the parameter value for the method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;class:&lt;/strong&gt; This will have the class name which contains the method. Mostly, it will be androidx.test.espresso.matcher.ViewMatchers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While using Java, we can use the View Matcher locator in Appium, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import com.google.common.collect.ImmutableMap;
    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    import org.openqa.selenium.json.Json;
    . . .
    private final By animationItemViewMatcher = MobileBy.androidViewMatcher (new Json ().toJson (ImmutableMap.of (
      "name", "withText",
      "args", "Animation",
      "class", "androidx.test.espresso.matcher.ViewMatchers"
    )));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Strategies to use iOS-specific locators in Appium
&lt;/h2&gt;

&lt;p&gt;In iOS, there is only one Automation type, &lt;a href="https://www.lambdatest.com/xcuitest?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;XCUITest&lt;/a&gt;, which supports the following strategies to use locators in Appium.&lt;/p&gt;

&lt;h2&gt;
  
  
  XCUITest: Predicate String
&lt;/h2&gt;

&lt;p&gt;Predicate string locator strategy is similar to a SQL query where you query for a particular element using a combination of its attributes.&lt;/p&gt;

&lt;p&gt;While using Java, you can use the predicate string locator in Appium, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByPredicate = MobileBy.iOSNsPredicateString ("label == \"Colour\" AND name == \"color\"");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Appium Inspector also helps in providing a pre-built predicate string which you simply copy and use in your test. Below is the screenshot showing how Appium Inspector shows the pre-built locator in Appium.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AZKicq19OeRi-rtrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AZKicq19OeRi-rtrj.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While creating the predicate string, you can also use the following comparison expressions,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic comparisons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;=, ==: Left-hand expression is equal to right-hand expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;blockquote&gt;
&lt;p&gt;=, =&amp;gt;: Left-hand expression is greater than and equal to right-hand expression.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;=, =&amp;lt;: Left-hand expression is less than and equal to right-hand expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;blockquote&gt;
&lt;p&gt;: Left-hand expression is greater than right-hand expression.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;: Left-hand expression is less than right-hand expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;!=, &amp;lt;&amp;gt;: Left-hand expression is not equal to right-hand expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt; INPUT &amp;gt; BETWEEN { lower range, upper range }: Left-hand expression value lies between the range mentioned in the right-hand expression, with both the values inclusive.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Basic predicates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AND, &amp;amp;&amp;amp;: Logical and will check both the connected expressions to be true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OR, ||: Logical or will check if any of the connected expressions are true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NOT, !: Negating an expression will negate the outcome of the expression with which it is used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;String comparisons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;BEGINSWITH: Checks if the attribute starts with the provided string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CONTAINS: Checks if the attribute contains the provided string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ENDSWITH: Checks if the attribute ends with the provided string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LIKE: Checks if the attribute has the provided string containing wildcards like ? and *. Here, ? will try to match only one char, while * will try to match 0 or more chars from that position.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MATCHES: Checks if the attribute matches the regex string.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Test your native, hybrid, and web apps across all legacy and latest mobile operating systems on the most powerful &lt;a href="https://www.lambdatest.com/android-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;online Android emulator&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  XCUITest: Class chain
&lt;/h2&gt;

&lt;p&gt;Class chain locator in Appium is similar to XPath but more stable than XPath. With Class chains, you can combine predicate strings or directly reference child or descendent indexes to get a particular element.&lt;/p&gt;

&lt;p&gt;While using Java, you can use the iOS class chain locator in Appium, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;
    . . .
    private final By colorByClassChain = MobileBy.iOSClassChain ("**/XCUIElementTypeButton[`label == \"Colour\"`]");

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Appium Inspector also helps with providing pre-built iOS class chain locator in Appium as shown below,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AbbfZzDTiu-fKHJ8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AbbfZzDTiu-fKHJ8v.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips when creating a class chain expression:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can chain multiple classes in your expression, e.g.: **/&amp;lt; parent-class &amp;gt;/&amp;lt; target-class &amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can use indexes to get a specific element from the list of locators identified with the expression before the index, e.g.: &amp;lt; parent-class &amp;gt;[1]/&amp;lt; target-class &amp;gt;[2], where the parent class first instance will be used and then target class 2nd instance will be found with this expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Indexes here start from 1 instead of normally 0 index.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Indexes can also be negative. For example, -1 means the last element from the list of elements. Similarly, -2 means the second last item.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can also combine predicate string expression with class chains like we use indexes, e.g.: &amp;lt; target-class &amp;gt;[name CONTAINS[cd] "text"] means it will find the target element where its name contains a particular text irrespective of its casing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Predicate strings should always be enclosed in ticks, as shown in the example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can also combine index and predicate strings in the same expression at any level of the hierarchy, e.g.: **/&amp;lt; parent-class &amp;gt;[name BEGINSWITH "Some Text"][-1]/&amp;lt; target-class &amp;gt;[3] which will interpret as find the last parent out of the list of parents whose name starts with some text and find the third instance of target element from that parent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you like XPath more, this locator in Appium is the perfect replacement for XPath but is more stable and one of the best-performing locator strategies. Here also, it is suggested that if you can use ID or Accessibility ID or ask the development team to add these IDs to the element, you should use them instead of the Class chain locator in Appium.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo: Using Locators in Appium
&lt;/h2&gt;

&lt;p&gt;Until now, we have seen the code snippets. Now let us see the page object and the test we have in the demo project shared on &lt;a href="https://github.com/WasiqB/appium-locator-sample" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. You can download and clone the same and follow along.&lt;/p&gt;

&lt;h2&gt;
  
  
  DriverManager class
&lt;/h2&gt;

&lt;p&gt;This class is used to create driver sessions for different Automation types to demonstrate different locators in Appium specific for that particular Automation type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import static io.appium.java_client.remote.AndroidMobileCapabilityType.AVD;
    import static io.appium.java_client.remote.AutomationName.ANDROID_UIAUTOMATOR2;
    import static io.appium.java_client.remote.AutomationName.ESPRESSO;
    import static io.appium.java_client.remote.AutomationName.IOS_XCUI_TEST;
    import static io.appium.java_client.remote.MobileCapabilityType.APP;
    import static io.appium.java_client.remote.MobileCapabilityType.AUTOMATION_NAME;
    import static io.appium.java_client.remote.MobileCapabilityType.DEVICE_NAME;
    import static io.appium.java_client.remote.MobileCapabilityType.FULL_RESET;
    import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_VERSION;
    import static java.lang.System.getenv;
    import static java.text.MessageFormat.format;
    import static org.openqa.selenium.remote.CapabilityType.PLATFORM_NAME;

    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URL;

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.ios.IOSDriver;
    import io.appium.java_client.service.local.AppiumDriverLocalService;
    import io.appium.java_client.service.local.AppiumServiceBuilder;
    import io.appium.java_client.service.local.flags.GeneralServerFlag;
    import org.openqa.selenium.Capabilities;
    import org.openqa.selenium.remote.DesiredCapabilities;

    public class DriverManager {
       private static final String ANDROID = "Android";
       private static final String IOS = "iOS";

       public static DriverManager getInstance () {
           return new DriverManager ();
       }

       private AppiumDriverLocalService service;

       public AndroidDriver&amp;lt;MobileElement&amp;gt; getAndroidEspressoCloudDriver () throws MalformedURLException {
           return new AndroidDriver&amp;lt;&amp;gt; (getUrl (), getAndroidEspressoCloudOptions ());
       }

       public AndroidDriver&amp;lt;MobileElement&amp;gt; getAndroidEspressoDriver () {
           startServer ();
           return new AndroidDriver&amp;lt;&amp;gt; (this.service.getUrl (), getAndroidEspressoOptions ());
       }

       public AndroidDriver&amp;lt;MobileElement&amp;gt; getAndroidUiAutomatorDriver () throws MalformedURLException {
           return new AndroidDriver&amp;lt;&amp;gt; (getUrl (), getAndroidUiAutomatorOptions ());
       }

       public IOSDriver&amp;lt;MobileElement&amp;gt; getIosDriver () throws MalformedURLException {
           return new IOSDriver&amp;lt;&amp;gt; (getUrl (), getIosOptions ());
       }

       public void stopServer () {
           if (this.service != null &amp;amp;&amp;amp; this.service.isRunning ()) {
               this.service.stop ();
           }
       }

       private Capabilities getAndroidEspressoCloudOptions () {
           final var capabilities = new DesiredCapabilities ();
           capabilities.setCapability (PLATFORM_NAME, ANDROID);
           capabilities.setCapability (PLATFORM_VERSION, "11");
           capabilities.setCapability (DEVICE_NAME, "Pixel 5");
           capabilities.setCapability (AUTOMATION_NAME, ESPRESSO);
           capabilities.setCapability (APP, getenv ("LT_APP_ANDROID_2"));
           setCloudCapabilities (capabilities, ANDROID);
           return capabilities;
       }

       private Capabilities getAndroidEspressoOptions () {
           final var capabilities = new DesiredCapabilities ();
           capabilities.setCapability (PLATFORM_NAME, ANDROID);
           capabilities.setCapability (PLATFORM_VERSION, "10");
           capabilities.setCapability (DEVICE_NAME, "Pixel_5");
           capabilities.setCapability (AUTOMATION_NAME, ESPRESSO);
           capabilities.setCapability (APP, new File ("src/test/resources/apps/ApiDemos-debug.apk").getAbsolutePath ());
           capabilities.setCapability (AVD, "Pixel_5");
           capabilities.setCapability (FULL_RESET, true);
           return capabilities;
       }

       private Capabilities getAndroidUiAutomatorOptions () {
           final var capabilities = new DesiredCapabilities ();
           capabilities.setCapability (PLATFORM_NAME, ANDROID);
           capabilities.setCapability (PLATFORM_VERSION, "11");
           capabilities.setCapability (DEVICE_NAME, "Pixel 5");
           capabilities.setCapability (AUTOMATION_NAME, ANDROID_UIAUTOMATOR2);
           capabilities.setCapability (APP, getenv ("LT_APP_ANDROID"));
           setCloudCapabilities (capabilities, ANDROID);
           return capabilities;
       }

       private Capabilities getIosOptions () {
           final var capabilities = new DesiredCapabilities ();
           capabilities.setCapability (PLATFORM_NAME, IOS);
           capabilities.setCapability (PLATFORM_VERSION, "15");
           capabilities.setCapability (DEVICE_NAME, "iPhone 13 Pro");
           capabilities.setCapability (AUTOMATION_NAME, IOS_XCUI_TEST);
           capabilities.setCapability (APP, getenv ("LT_APP_IOS"));
           setCloudCapabilities (capabilities, IOS);
           return capabilities;
       }

       private URL getUrl () throws MalformedURLException {
           final var LT_KEY = System.getenv ("LT_ACCESS_KEY");
           final var LT_USER = System.getenv ("LT_USERNAME");
           return new URL (format ("@mobile-hub.lambdatest.com/wd/hub"&amp;gt;https://{0}:{1}@mobile-hub.lambdatest.com/wd/hub", LT_USER, LT_KEY));
       }

       private void setCloudCapabilities (final DesiredCapabilities capabilities, final String platform) {
           capabilities.setCapability ("project", "LambdaTest project");
           capabilities.setCapability ("build",
               format ("TestNG {0} Sample Build for {1}", platform, capabilities.getCapability (AUTOMATION_NAME)));
           capabilities.setCapability ("name", format ("{0} Test Case", platform));
           capabilities.setCapability ("visual", true);
           capabilities.setCapability ("network", true);
           capabilities.setCapability ("video", true);
           capabilities.setCapability ("autoGrantPermissions", true);
           capabilities.setCapability ("autoAcceptAlerts", true);
           capabilities.setCapability ("isRealMobile", true);
           capabilities.setCapability ("console", true);
       }

       private void startServer () {
           final AppiumServiceBuilder builder = new AppiumServiceBuilder ();
           builder.withIPAddress ("127.0.0.1")
               .usingPort (4723)
               .withAppiumJS (
                   new File ("/path/to/.nvm/versions/node/v16.16.0/lib/node_modules/appium/build/lib/main.js"))
               .withLogFile (new File (System.getProperty ("user.dir") + "/logs/appium.log"))
               .withArgument (GeneralServerFlag.LOG_LEVEL, "info")
               .withArgument (GeneralServerFlag.SESSION_OVERRIDE);
           this.service = AppiumDriverLocalService.buildService (builder);
           this.service.start ();
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have created a few different create-driver methods to create different driver instances for different automation types. Only for the Espresso driver, we have two methods, one for local execution and one for the cloud. This is because most cloud platform providers are not yet supporting the Espresso driver, due to which we will encounter errors like Data matcher locator strategy not implemented or View matcher locator strategy not implemented.&lt;/p&gt;

&lt;p&gt;For cloud &lt;a href="https://www.lambdatest.com/learning-hub/test-execution?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;test execution&lt;/a&gt;, we are using the LambdaTest cloud platform, while for local execution, we start and stop the Appium server from this class directly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.lambdatest.com/blog/cloud-testing-tutorial/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Cloud testing&lt;/a&gt; platforms like LambdaTest provide an &lt;a href="https://www.lambdatest.com/online-device-farm?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;online device farm&lt;/a&gt; of 3000+ real devices and operating systems to perform &lt;a href="https://www.lambdatest.com/app-test-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;app test automation&lt;/a&gt; at scale over a cloud Appium grid. You can perform &lt;a href="https://www.lambdatest.com/mobile-automation-test?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile automation testing&lt;/a&gt; on real Android and iOS devices.&lt;/p&gt;

&lt;p&gt;Here’s how you can use LambdaTest’s &lt;a href="https://www.lambdatest.com/blog/real-device-cloud/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;real device cloud&lt;/a&gt; to perform &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium mobile testing&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_gC5igQyJf8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can also subscribe to the &lt;a href="https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;LambdaTest YouTube Channel&lt;/a&gt; and stay updated with the latest tutorials around &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Selenium testing&lt;/a&gt;, &lt;a href="https://www.lambdatest.com/cypress-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Cypress testing&lt;/a&gt;, CI/CD, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Page object
&lt;/h2&gt;

&lt;p&gt;There is one page object for Android and one for iOS to demonstrate different locators in Appium. First, let’s see the AndroidLocators page object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    import io.appium.java_client.MobileBy;
    import lombok.Getter;
    import org.openqa.selenium.By;
    import org.openqa.selenium.json.Json;

    @Getter
    public class AndroidLocators {
       private final By animationItemViewMatcher = MobileBy.androidViewMatcher (new Json ().toJson (ImmutableMap.of ("name", "withText", "args", "Animation", "class", "androidx.test.espresso.matcher.ViewMatchers")));
       private final By appItemDataMatcher = MobileBy.androidDataMatcher (new Json ().toJson (ImmutableMap.of (
      "name", "hasEntry",
      "args", ImmutableList.of ("title", "App")
    )));
       private final By colorByClassName = MobileBy.className ("android.widget.Button");
       private final By colorById = MobileBy.id ("color");
       private final By colorByUiSelector = MobileBy.AndroidUIAutomator ("new UiSelector().text(\"COLOR\")");
       private final By colorByXpath = MobileBy.xpath (".//android.widget.Button[@text='COLOR']");
    }

The class seems very straightforward where we have declared all the Android-specific locators. Now let’s see the IOSLocator page object.

    import io.appium.java_client.MobileBy;
    import lombok.Getter;
    import org.openqa.selenium.By;

    @Getter
    public class IOSLocators {
       // Demoed with iOS.
       private final By colorByAccessibilityId = MobileBy.AccessibilityId ("color");
       private final By colorByClassChain = MobileBy.iOSClassChain ("**/XCUIElementTypeButton[`label == \"Colour\"`]");
       private final By colorByPredicate = MobileBy.iOSNsPredicateString ("label == \"Colour\" AND name == \"color\"");
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here also, we have declared all the iOS specific locators in Appium.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test classes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  BaseTest
&lt;/h3&gt;

&lt;p&gt;Before writing the tests, we have a common BaseTest class, which will be extended to all of our tests. Let’s see what we have in the Base test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   import static java.lang.System.currentTimeMillis;
    import static java.text.MessageFormat.format;

    import com.github.wasiqb.appium.core.DriverManager;
    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.MobileElement;
    import org.openqa.selenium.By;
    import org.testng.annotations.AfterClass;

    public class BaseTest {
       protected static final DriverManager               DRIVER_MANAGER = DriverManager.getInstance ();

       protected AppiumDriver&amp;lt;MobileElement&amp;gt; driver;

       @AfterClass (alwaysRun = true)
       public void tearDownClass () {
           this.driver.quit ();
           DRIVER_MANAGER.stopServer ();
       }

       protected MobileElement getElement (final By by, final String locatorType) {
           final long start = currentTimeMillis ();
           try {
               return this.driver.findElement (by);
           } finally {
               System.out.println (format ("Time taken by {0}: {1}ms", locatorType, currentTimeMillis () - start));
           }
       }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this class, we have only two methods, one where we quit the driver session and close the local Appium server if it’s running. At the same time, the other method is used to find the element using the locator strategy passed to this method and also prints the time it took to find the element so we can identify which locator strategy is the fastest and which one is the slowest.&lt;/p&gt;

&lt;h3&gt;
  
  
  LocatorsAndroidEspressoTest
&lt;/h3&gt;

&lt;p&gt;In this class, we will test the locators specific to the &lt;a href="https://www.lambdatest.com/espresso-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec16_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Espresso automation&lt;/a&gt; type. This test will execute on the local Appium server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import static org.testng.Assert.assertTrue;

    import com.github.wasiqb.appium.pages.AndroidLocators;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;

    public class LocatorsAndroidEspressoTest extends BaseTest {
       private AndroidLocators page;

       @BeforeClass (alwaysRun = true)
       public void setupClass () {
           this.driver = DRIVER_MANAGER.getAndroidEspressoDriver ();
           this.page = new AndroidLocators ();
       }

       @Test
       public void testByDataMatcher () {
           assertTrue (getElement (this.page.getAppItemDataMatcher (), "Data Matcher").isDisplayed ());
       }

       @Test
       public void testByViewMatcher () {
           assertTrue (getElement (this.page.getAnimationItemViewMatcher (), "View Matcher").isDisplayed ());
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have one more similar class which runs on LambdaTest cloud platform. But that class will fail, as mentioned earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  LocatorsAndroidUiAutomatorTest
&lt;/h3&gt;

&lt;p&gt;In this test, we will test all the locator strategies specific to the UiAutomator2 Automation type along with a few common locators in Appium.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   import static org.testng.Assert.assertTrue;

    import java.net.MalformedURLException;

    import com.github.wasiqb.appium.pages.AndroidLocators;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;

    public class LocatorsAndroidUiAutomatorTest extends BaseTest {
       private AndroidLocators page;

       @BeforeClass (alwaysRun = true)
       public void setupClass () throws MalformedURLException {
           this.driver = DRIVER_MANAGER.getAndroidUiAutomatorDriver ();
           this.page = new AndroidLocators ();
       }

       @Test
       public void testByClassName () {
           assertTrue (getElement (this.page.getColorByClassName (), "Class Name").isDisplayed ());
       }

       @Test
       public void testById () {
           assertTrue (getElement (this.page.getColorById (), "ID").isDisplayed ());
       }

       @Test
       public void testByUiSelector () {
           assertTrue (getElement (this.page.getColorByUiSelector (), "Ui Selector").isDisplayed ());
       }

       @Test
       public void testByXpath () {
           assertTrue (getElement (this.page.getColorByXpath (), "Xpath").isDisplayed ());
       }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LocatorsIOSTest
&lt;/h3&gt;

&lt;p&gt;In this class we will test all the iOS specific locator strategies for XCUITest automation name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   import static org.testng.Assert.assertTrue;

    import java.net.MalformedURLException;

    import com.github.wasiqb.appium.pages.IOSLocators;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;

    public class LocatorsIOSTest extends BaseTest {
       private IOSLocators page;

       @BeforeClass (alwaysRun = true)
       public void setupClass () throws MalformedURLException {
           this.driver = DRIVER_MANAGER.getIosDriver ();
           this.page = new IOSLocators ();
       }

       @Test
       public void testByAccessibilityId () {
           assertTrue (getElement (this.page.getColorByAccessibilityId (), "Accessibility Id").isDisplayed ());
       }

       @Test
       public void testByClassChain () {
           assertTrue (getElement (this.page.getColorByClassChain (), "Class Chain").isDisplayed ());
       }

       @Test
       public void testByPredicate () {
           assertTrue (getElement (this.page.getColorByPredicate (), "Predicate").isDisplayed ());
       }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test output
&lt;/h2&gt;

&lt;p&gt;When you execute all the tests which we saw until now, you’ll see an output something as the one shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Time taken by View Matcher: 36ms
    Time taken by Data Matcher: 209ms
    Time taken by Ui Selector: 230ms
    Time taken by ID: 251ms
    Time taken by Predicate: 266ms
    Time taken by Class Chain: 272ms
    Time taken by Class Name: 337ms
    Time taken by Accessibility Id: 376ms
    Time taken by Xpath: 517ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, all the locators are mentioned from fastest executing ones to the slowest one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now, you might have a fair idea of when to use which locator in Appium, depending on your needs. There are a few other locators in Appium, which were skipped from this blog on locators in Appium because it was either deprecated or an experimental feature by Appium. I hope you liked this blog and learned something new from it.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>testing</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Automated App Testing Using Appium With TestNG [Tutorial]</title>
      <dc:creator>WasiqBhamla</dc:creator>
      <pubDate>Thu, 15 Dec 2022 17:21:34 +0000</pubDate>
      <link>https://dev.to/testmuai/automated-app-testing-using-appium-with-testng-tutorial-3p7k</link>
      <guid>https://dev.to/testmuai/automated-app-testing-using-appium-with-testng-tutorial-3p7k</guid>
      <description>&lt;p&gt;In recent times, many web applications have been ported to mobile platforms, and mobile applications are also created to support businesses. However, Android and iOS are the major platforms because many people use smartphones compared to desktops for accessing web applications.&lt;/p&gt;

&lt;p&gt;As per Statcounter, Mobile is the clear leader with 61.16% market share while Desktop has 38.84% market share.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22bwawhkx51jsddha0zh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22bwawhkx51jsddha0zh.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence, the need to automate these platforms has also increased significantly. To automate testing on these platforms, we need &lt;a href="https://www.lambdatest.com/blog/best-mobile-app-testing-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile automation frameworks&lt;/a&gt; that we can use to automate the mobile flows. Appium is one such framework that extends the &lt;a href="https://www.lambdatest.com/blog/selenium-webdriver-tutorial-with-examples/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt; library further to enable automation of Android and iOS platform-related applications.&lt;/p&gt;

&lt;p&gt;Watch this video to learn about Appium, one of the most popular open-source test automation frameworks for mobile app testing.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Z_J8RmQf7Nw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;By the end of this &lt;a href="https://www.lambdatest.com/blog/appium-tutorial/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium Tutorial&lt;/a&gt; with TestNG, you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to set up Appium on a local machine?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to inspect elements using Appium Inspector with a local emulator?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to inspect elements using Appium Inspector on cloud instances?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How can we automate an application on Android and iOS platforms using Appium with TestNG?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to run tests on a local Android emulator?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to run tests on a cloud-based platform like LambdaTest?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code used in this Appium Java tutorial can be found on GitHub. You can clone the repository and follow along.&lt;/p&gt;

&lt;p&gt;In case you are a beginner to Appium you can learn to perform &lt;a href="https://www.lambdatest.com/mobile-testing-lab?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile app testing&lt;/a&gt; easily through this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/pI5zrUhydyo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Automate &lt;a href="https://www.lambdatest.com/cypress-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;cypress cloud&lt;/a&gt; tests and perform browser automation testing with LambdaTest. Our cloud infrastructure has 3000+ desktop &amp;amp; mobile environments. Try for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set up Appium on the local machine?
&lt;/h2&gt;

&lt;p&gt;Before automating app testing using Appium with TestNG, we must set up our environment first. Follow the steps I mentioned below:&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Node LTS
&lt;/h2&gt;

&lt;p&gt;On Windows, you can download the installer. On Mac, you could simply use Homebrew to install Node. Similarly, on Linux, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; sudo apt install nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Android Studio SDK
&lt;/h2&gt;

&lt;p&gt;Please follow the instructions below to install Android Studio SDK:&lt;/p&gt;

&lt;p&gt;1- Download the Android installer and install it on your machine.&lt;/p&gt;

&lt;p&gt;2- Once installed, open the Android Studio and install the following SDK platform packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd7u265azyyd714b1egi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd7u265azyyd714b1egi.png" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- Also, install the following SDK tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm5ihftr7ilj4ls46iue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm5ihftr7ilj4ls46iue.png" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4- Once these steps are done, you need to set environment variables on your machine. Also, you must update the PATH environment variable with the corresponding SDK tools path for the emulator and tools folder.&lt;/p&gt;

&lt;p&gt;5- Run the below commands on the terminal if you are using Linux or macOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    export ANDROID_HOME="/Users/youruser/Library/Android/sdk"
    export ANDROID_SDK_ROOT=$ANDROID_HOME
    export PATH="$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$PATH"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6- For Windows users, you can set environment variables by right-clicking on &lt;strong&gt;This PC -&amp;gt; Properties&lt;/strong&gt; and then clicking on &lt;strong&gt;Advanced System settings -&amp;gt; Environment variables&lt;/strong&gt; and adding the environment variable under the System variable section. Also, update the PATH system variable as demonstrated above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This Cypress automation testing tutorial will help you learn the benefits of &lt;a href="https://www.lambdatest.com/blog/cypress-test-automation-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;cypress test automation&lt;/a&gt;, and how to install Cypress and execute Cypress automation testing over scores of browsers and operating systems online.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Xcode
&lt;/h2&gt;

&lt;p&gt;If you want to run your automated test on a local &lt;a href="https://www.lambdatest.com/ios-simulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;iOS simulator&lt;/a&gt;, you will also be required to install Xcode. But this will only apply to Mac OS X users. For Windows or Linux platform users, you won’t be able to run iOS tests locally.&lt;/p&gt;

&lt;p&gt;For Mac OS users, you can install Xcode from the App Store by searching for Xcode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedfe8t93g03fumjm2es1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedfe8t93g03fumjm2es1.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium
&lt;/h2&gt;

&lt;p&gt;Please follow the instructions below to install Appium:&lt;/p&gt;

&lt;p&gt;1- From the command prompt or terminal, install Appium using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;gt; npm install -g appium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Once Appium is installed, you can confirm by checking the installed version by executing the following command, and you will see the version of Appium installed on your machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;gt; appium -v
    1.22.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Learn the advantages of Cypress automation, how to install Cypress, and how to carry out online &lt;a href="https://www.lambdatest.com/blog/cypress-test-automation-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;cypress automation&lt;/a&gt; testing across a wide range of browsers and operating systems with the aid of this lesson on Cypress automation testing.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Java
&lt;/h2&gt;

&lt;p&gt;Please follow the instructions below to install Java:&lt;/p&gt;

&lt;p&gt;1- Download and install Java OpenJDK 11 for your machine operating system. macOS users can also install it from Homebrew by executing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;gt; brew install openjedk@11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Once the installation is done, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; java -version
    openjdk version "18.0.1.1" 2022-04-22
    OpenJDK Runtime Environment Homebrew (build 18.0.1.1+0)
    OpenJDK 64-Bit Server VM Homebrew (build 18.0.1.1+0, mixed mode, sharing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- The reason we are using OpenJDK is that it is freely available. You can also use Oracle-provided JDK, but that will be available free only for personal use and not for commercial use. To avoid license violation issues, we considered using OpenJDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Maven
&lt;/h2&gt;

&lt;p&gt;Please follow the instructions below to install Maven:&lt;/p&gt;

&lt;p&gt;1- On Mac, you can install Maven via the Homebrew command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; brew install maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- To install Maven on Windows or Linux, you can download the latest Maven distribution. Once the zip file is downloaded, unzip it in the folder you want to install and set its path in the PATH environment variable, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;gt; export PATH=/path/to/apache-maven-3.8.6/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- Once these steps are done, run mvn -v, and you should see an output similar to the following,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; mvn -v
    Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
    Maven home: /usr/local/Cellar/maven/3.8.6/libexec
    Java version: 11.0.14, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-11.0.14.jdk/Contents/Home
    Default locale: en_IN, platform encoding: UTF-8
    OS name: "mac os x", version: "12.4", arch: "x86_64", family: "mac"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;This Playwright tutorial will guide you through the setup of the &lt;a href="https://www.lambdatest.com/blog/playwright-framework/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;playwright automated testing&lt;/a&gt; framework, which will enable you to write end-to-end tests for your future projects.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Appium Doctor
&lt;/h2&gt;

&lt;p&gt;Since we have already installed Appium on our machine, we must now validate if all the setup is done correctly to run our tests with Appium. To check this, there is another library called &lt;em&gt;appium-doctor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;1- To install this library, we must run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;gt; npm install -g appium-doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Once this command is executed successfully, run the following command to check the Android setup,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; appium-doctor --android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- And to check setup for iOS, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; appium-doctor --ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will check if the setup is done correctly or not. If there is some issue in the setup of mandatory components, it will try to fix it automatically. If it can’t fix on its own, it will mention steps to follow to fix the issues and complete the setup successfully.&lt;/p&gt;

&lt;p&gt;In the next section of this tutorial on Appium with TestNG, we will learn how to inspect app elements locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;It’s crucial to debug websites for Safari before pushing them live. In this article, we look at how to debug websites using &lt;a href="https://www.lambdatest.com/blog/debug-websites-using-safari-developer-tools/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;developer tools for safari&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to inspect the application’s elements locally?
&lt;/h2&gt;

&lt;p&gt;Once the machine is set up correctly, the next step would be inspecting the Application Under Test elements (AUT). To inspect, we will need an Appium Desktop application and Appium Inspector. You can download the build to your platform from their respective links and install the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appium Desktop
&lt;/h2&gt;

&lt;p&gt;Appium desktop application is a user interface tool to start Appium server sessions by configuring different server settings. This is how the Appium desktop application looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hekvfns8yexq13qzlh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hekvfns8yexq13qzlh9.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the settings as per your requirement and start the server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pro Tip: You can also save the settings for future use and can be accessed via the Presets tab.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once you start the Appium server, this is how it will look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ef8asfgzmma3992ay7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ef8asfgzmma3992ay7m.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Appium Inspector
&lt;/h2&gt;

&lt;p&gt;Once the server is up and running, we can connect &lt;a href="https://www.lambdatest.com/blog/appium-inspector-for-apps/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium Inspector&lt;/a&gt; to this running instance. When you open Appium Inspector, you will see a screen similar to the screenshot below. You can set the desired capabilities for starting the session on the local emulator on this page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cdnu8ojazp0jo1pz8gl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cdnu8ojazp0jo1pz8gl.png" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to note here is you need to set the remote path as /wb/hub for the latest Appium Inspector application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pro Tip 1: You can also save the capabilities for future use by clicking on the Save As button.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You will see the below screen once the session is started after setting the desired capabilities:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92p3w9q69l3g57vb3mrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92p3w9q69l3g57vb3mrs.png" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the AUT loads on Appium Inspector, you will see it on the left panel, where you can select any element, and the details of that element will get displayed on the right panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Before launching them, websites must be Safari-tested. This article discusses using the &lt;a href="https://www.lambdatest.com/blog/debug-websites-using-safari-developer-tools/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;dev tools for safari&lt;/a&gt; to debug webpages.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Suggested Locator strategy
&lt;/h2&gt;

&lt;p&gt;When inspecting the elements, you must know which locator you should use. Following are the &lt;a href="https://www.lambdatest.com/blog/locators-in-selenium-webdriver-with-examples/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;locator strategy&lt;/a&gt; I would suggest you try using first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accessibility ID:&lt;/strong&gt; Ideally, this locator strategy should be used because it is one of the fastest. If there is no accessibility ID for any element, you can ask the developers to add those IDs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ID:&lt;/strong&gt; In some applications, the developer sets accessibility ID; then, you can use the ID locator strategy in those cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Android-specific for UIAutomator2 automation type:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UiSelector:&lt;/strong&gt; This locator strategy involves building a locator using the UiSelector class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Android-specific for Espresso automation type:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data matcher: This locator strategy is useful when you want to access any element which is not yet visible on the viewport.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;iOS specific:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NSPredicate string:&lt;/strong&gt; This locator strategy involves writing simple query conditions based on different element attributes. This is the fastest working locator strategy for iOS, sometimes even faster than Accessibility ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;iOS Class chain:&lt;/strong&gt; This locator strategy is similar to XPath but is considered a combination of XPath and NSPredicate string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;XPath:&lt;/strong&gt; This locator strategy, in my opinion, is the last option when you cannot use any of the locators mentioned earlier. This is also the slowest working strategy out of all the available ones. Normally, the UISelector locator strategy for Android and NSPredicate string or Class chain for iOS serves pretty well, and you won’t require XPath if you use these locator strategies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to inspect the application’s elements on the cloud?
&lt;/h2&gt;

&lt;p&gt;Similar to inspecting elements with local &lt;a href="https://www.lambdatest.com/android-emulator-online?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Android emulators&lt;/a&gt;, we can also inspect elements on cloud-based test automation platforms like LambdaTest. The only difference here is you don’t need an Appium server running.&lt;/p&gt;

&lt;p&gt;Test orchestration &amp;amp; execution platforms like LambdaTest provide an &lt;a href="https://www.lambdatest.com/online-device-farm?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;online device farm&lt;/a&gt; of 3000+ real devices and operating systems to perform &lt;a href="https://www.lambdatest.com/mobile-automation-test?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;mobile automation testing&lt;/a&gt; at scale over a cloud Appium grid. Using LambdaTest, you can perform &lt;a href="https://www.lambdatest.com/app-test-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;app test automation&lt;/a&gt; on real Android and iOS devices.&lt;/p&gt;

&lt;p&gt;Here are some of the features of LambdaTest Appium Automation platform –&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Test native features of your mobile apps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lambdatest.com/automated-device-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Automated device testing&lt;/a&gt; on blazing fast test automation cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for all Languages &amp;amp; Frameworks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comprehensive test execution logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lambdatest.com/geolocation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Geolocation testing&lt;/a&gt; of mobile apps. Here’s how you can perform geolocation testing using TestNG.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5S8HwT56DYs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LambdaTest Tunnel for testing locally hosted applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the walkthrough of the &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Appium mobile testing&lt;/a&gt; on LambdaTest’s &lt;a href="https://www.lambdatest.com/blog/real-device-cloud/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;real device cloud&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_gC5igQyJf8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can also subscribe to the &lt;a href="https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;LambdaTest YouTube Channel&lt;/a&gt; and stay updated with the latest tutorials around &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Selenium testing&lt;/a&gt;, &lt;a href="https://www.lambdatest.com/cypress-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Cypress testing&lt;/a&gt;, CI/CD, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;A comprehensive UI testing tutorial that covers what &lt;a href="https://www.lambdatest.com/learning-hub/ui-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=learning_hub" rel="noopener noreferrer"&gt;UI testing&lt;/a&gt; is, its importance, benefits, and how to perform it with real-time examples.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1- When you open the Appium Inspector, click on &lt;strong&gt;Select cloud providers&lt;/strong&gt; and select LambdaTest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkvgkquib1yitkf4iurt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkvgkquib1yitkf4iurt.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- Once you select the preferred cloud-based &lt;a href="https://www.lambdatest.com/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;cross browser testing&lt;/a&gt; platform, select the newly added tab and provide cloud-specific details, like username and access key (of LambdaTest), as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feukz8o7qpf6pvm9fpxzy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feukz8o7qpf6pvm9fpxzy.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- Also, we need to specify the capabilities for our session, which we will start in Appium Inspector.&lt;/p&gt;

&lt;p&gt;Let’s see each capability we have used in this example in more detail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;deviceName:&lt;/strong&gt; Here, the device name should be the actual device name provided by LambdaTest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;platformVersion:&lt;/strong&gt; This will have the platform version for the device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;platformName:&lt;/strong&gt; This will be the platform’s name, like Android and iOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;app:&lt;/strong&gt; This will have the app URL that LambdaTest will give you after you upload your application to their server. We will see how to upload the application to their server in a later part of this blog.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;build:&lt;/strong&gt; This capability is specific to LambdaTest, which will describe the build name provided to the running session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;name:&lt;/strong&gt; This will specify the currently running test case name for the current build session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;console:&lt;/strong&gt; If this capability is true, then console logs will be logged to the session dashboard or skipped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;network:&lt;/strong&gt; If this capability is true, then network call logs will get logged to the session dashboard or skipped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;visual:&lt;/strong&gt; If this capability is true, then screenshots will be captured on each step, or no screenshot will be taken.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;video:&lt;/strong&gt; If this capability is true, then video recording will be captured for the complete test case, or no video recording will be done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;terminal:&lt;/strong&gt; If this capability is true, it will capture terminal logs; otherwise, it will not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;isRealMobile:&lt;/strong&gt; This capability will ensure that LambdaTest uses real devices if set to true else, it will run on simulators.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Pro Tip: All these capabilities were generated using the &lt;a href="https://www.lambdatest.com/capabilities-generator/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;LambdaTest Capability Generator&lt;/a&gt; tool provided by LambdaTest.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Following are other capabilities supported by LambdaTest,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;project:&lt;/strong&gt; This capability will specify the project’s name for the running session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;deviceOrientation:&lt;/strong&gt; This will specify the device orientation, whether it should be portrait or landscape.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;geoLocation:&lt;/strong&gt; This will specify the device’s geographic location.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;location:&lt;/strong&gt; This will specify the latitude and longitude of the device location.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;language:&lt;/strong&gt; This will specify the device language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;locale:&lt;/strong&gt; This will specify the device’s regional locale.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;autoAcceptAlerts:&lt;/strong&gt; This is iOS specific, which will mention whether to accept pop-up alerts or dismiss them automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;autoGrantPermissions:&lt;/strong&gt; This is Android specific, which will automatically mention whether to accept or dismiss pop-up alerts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;idleTimeout:&lt;/strong&gt; This will specify an idle timeout in milliseconds on how long a session can be alive if no action is happening in the tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;queueTimeout:&lt;/strong&gt; This will specify the queue timeout in milliseconds on how long a session can stay in the queue lane.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;otherApps:&lt;/strong&gt; This will specify an array of app URLs for other supporting apps which will also get installed on the device along with the actual application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;tunnel:&lt;/strong&gt; This will specify that you are under a VPN private network and that LambdaTest should connect via a tunnel connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;tunnelName:&lt;/strong&gt; This will specify the tunnel’s name to connect with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dedicatedProxy:&lt;/strong&gt; This will mention that there is a dedicated proxy for the tunnel if set to true.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4- Once satisfied with the capabilities you have set, click on the &lt;strong&gt;Start Session&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupn7chwhtgwkor8hyotg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupn7chwhtgwkor8hyotg.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how the inspector will be displayed once the session is successfully created with LambdaTest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run your &lt;a href="https://www.lambdatest.com/jest?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;jest testing&lt;/a&gt; automation tests in massive parallel across multiple browser and OS combinations with LambdaTest, Read more.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with app automation using Appium with TestNG
&lt;/h2&gt;

&lt;p&gt;In this blog section on Appium with TestNG, let’s understand how to inspect elements using Appium Inspector with a local emulator and with cloud platforms. Now we will see how we can automate with Java, Appium, and TestNG.&lt;/p&gt;

&lt;p&gt;We will be using TestNG for executing our tests. TestNG is a &lt;a href="https://www.lambdatest.com/blog/best-test-automation-frameworks-2021/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;popular testing framework&lt;/a&gt; similar to JUnit and has many features of annotating our tests; and has set up methods annotated with before and after hook &lt;a href="https://www.lambdatest.com/blog/complete-guide-on-testng-annotations-for-selenium-webdriver/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;TestNG annotations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;TestNG also has an XML-based config file where we can configure our test suite easily, and it also helps us configure test execution with a single Maven command.&lt;/p&gt;

&lt;p&gt;Since we will be performing &lt;a href="https://www.lambdatest.com/android-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Android automation testing&lt;/a&gt; and &lt;a href="https://www.lambdatest.com/ios-automation-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;iOS automation testing&lt;/a&gt;, we will be using a proverbial app for &lt;a href="https://www.lambdatest.com/blog/appium-with-testng-tutorial/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Android&lt;/a&gt; and iOS for demonstration in this Appium with TestNG blog. This app has some buttons to replicate some scenarios. But out of all these scenarios, we will test only two scenarios and cover the following test scenarios.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify the notification scenario&lt;/strong&gt; — When a user clicks on the Notification button, the user will receive a native notification pop-up in the notification pane. Next, we will open the notification pane and verify if we can see the test notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify the text button scenario&lt;/strong&gt; — when a user clicks on the Text button, the user will see the Proverbial text instead of the welcome message.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Run &lt;a href="https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Appium&lt;/a&gt; mobile testing of native and web apps. Improve your app quality with instant access to real devices on LambdaTest. Register now for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Suggested IDE
&lt;/h2&gt;

&lt;p&gt;To automate, you can use any of your favorite IDEs available, but for this blog on Appium with TestNG, we are using IntelliJ IDEA CE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;We will use the project hosted on my GitHub. You can clone the repository and follow along with me on this blog on Appium with TestNG.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jg6to222u6coks4ze4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jg6to222u6coks4ze4a.png" width="780" height="1356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see how the project is structured.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Our main project code will be in src/main/java.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our tests and page objects will be in src/test/java.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The application under test will be saved in src/test/resources/apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the TestNG XML file, which will have details about our tests will be in the root folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next section of this Appium with TestNG tutorial, we will do a walkthrough for our sample project to understand how we can automate the scenarios highlighted above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this XCUITest tutorial, learn about XCUITest framework and its benefits for mobile automation testing. Take a look at how &lt;a href="https://www.lambdatest.com/xcuitest?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;XCUITest&lt;/a&gt; works and see how to use it to test your mobile applications.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project pom.xml
&lt;/h2&gt;

&lt;p&gt;Following is the content of the pom.xml file for the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
    &amp;lt;project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://maven.apache.org/POM/4.0.0"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
       &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;

       &amp;lt;groupId&amp;gt;com.lambdatest.appium.sample&amp;lt;/groupId&amp;gt;
       &amp;lt;artifactId&amp;gt;appium-lambdatest-sample&amp;lt;/artifactId&amp;gt;
       &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;

       &amp;lt;properties&amp;gt;
           &amp;lt;maven.compiler.source&amp;gt;11&amp;lt;/maven.compiler.source&amp;gt;
           &amp;lt;maven.compiler.target&amp;gt;11&amp;lt;/maven.compiler.target&amp;gt;
           &amp;lt;argLine&amp;gt;-Dfile.encoding=UTF-8 -Xdebug -Xnoagent&amp;lt;/argLine&amp;gt;
       &amp;lt;/properties&amp;gt;

       &amp;lt;dependencies&amp;gt;
           &amp;lt;!-- https://mvnrepository.com/artifact/io.Appium/java-client --&amp;gt;
           &amp;lt;dependency&amp;gt;
               &amp;lt;groupId&amp;gt;io.appium&amp;lt;/groupId&amp;gt;
               &amp;lt;artifactId&amp;gt;java-client&amp;lt;/artifactId&amp;gt;
               &amp;lt;version&amp;gt;7.6.0&amp;lt;/version&amp;gt;
           &amp;lt;/dependency&amp;gt;
           &amp;lt;!-- https://mvnrepository.com/artifact/org.testng/testng --&amp;gt;
           &amp;lt;dependency&amp;gt;
               &amp;lt;groupId&amp;gt;org.testng&amp;lt;/groupId&amp;gt;
               &amp;lt;artifactId&amp;gt;testng&amp;lt;/artifactId&amp;gt;
               &amp;lt;version&amp;gt;7.6.0&amp;lt;/version&amp;gt;
               &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
           &amp;lt;/dependency&amp;gt;
       &amp;lt;/dependencies&amp;gt;
       &amp;lt;build&amp;gt;
           &amp;lt;plugins&amp;gt;
               &amp;lt;plugin&amp;gt;
                   &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                   &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
                   &amp;lt;version&amp;gt;3.0.0-M5&amp;lt;/version&amp;gt;
                   &amp;lt;executions&amp;gt;
                       &amp;lt;execution&amp;gt;
                           &amp;lt;goals&amp;gt;
                               &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;
                           &amp;lt;/goals&amp;gt;
                       &amp;lt;/execution&amp;gt;
                   &amp;lt;/executions&amp;gt;
                   &amp;lt;configuration&amp;gt;
                       &amp;lt;useSystemClassLoader&amp;gt;false&amp;lt;/useSystemClassLoader&amp;gt;
                       &amp;lt;properties&amp;gt;
                           &amp;lt;property&amp;gt;
                               &amp;lt;name&amp;gt;usedefaultlisteners&amp;lt;/name&amp;gt;
                               &amp;lt;value&amp;gt;false&amp;lt;/value&amp;gt;
                           &amp;lt;/property&amp;gt;
                       &amp;lt;/properties&amp;gt;
                       &amp;lt;suiteXmlFiles&amp;gt;
                           &amp;lt;suiteXmlFile&amp;gt;testng.xml&amp;lt;/suiteXmlFile&amp;gt;
                       &amp;lt;/suiteXmlFiles&amp;gt;
                       &amp;lt;argLine&amp;gt;${argLine}&amp;lt;/argLine&amp;gt;
                   &amp;lt;/configuration&amp;gt;
               &amp;lt;/plugin&amp;gt;
           &amp;lt;/plugins&amp;gt;
       &amp;lt;/build&amp;gt;
    &amp;lt;/project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our pom, we have added the following dependencies,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Appium Java client with version 7.6.0:&lt;/strong&gt; This library will be used to automate Android and iOS user flows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TestNG with version 7.6.0:&lt;/strong&gt; This library will be used to write and perform &lt;a href="https://www.lambdatest.com/blog/what-is-parallel-testing-and-why-to-adopt-it/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;parallel testing&lt;/a&gt;.&lt;br&gt;
We have also set Maven to use the Java version as 11.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have also configured the surefire Maven plugin to use our testng.xml file to run our tests using the Maven command.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Test your website or web app online for iOS browser compatibility. Perform seamless cross browser testing on the latest &lt;a href="https://www.lambdatest.com/test-on-iphone-simulator?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;iphone tester&lt;/a&gt;. Try for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Helper Classes
&lt;/h2&gt;

&lt;p&gt;To perform automation using Appium with TestNG, we will need some helper classes, which will help us in our automation. Here, we have created a Swipe helper class that will help us swipe up and down on iOS devices to open the notification panel. Let’s see how does this class look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    package com.lambdatest.appium.sample.utils;

    import static io.appium.java_client.touch.WaitOptions.waitOptions;
    import static io.appium.java_client.touch.offset.PointOption.point;
    import static java.time.Duration.ofMillis;

    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.offset.PointOption;
    import org.openqa.selenium.Dimension;

    // 1.
    @SuppressWarnings ("rawtypes")
    public class Swipe&amp;lt;D extends AppiumDriver&amp;lt;MobileElement&amp;gt;&amp;gt; {
       // 2.
       private final D driver;

       public Swipe (final D driver) {
           this.driver = driver;
       }

       // 3.
       public void down () {
           final Dimension screenDimension = this.driver.manage ()
               .window ()
               .getSize ();
           final PointOption startPoint = point (screenDimension.getWidth () / 2, 10);
           final PointOption endPoint = point (screenDimension.getWidth () / 2, screenDimension.getHeight () / 2);
           perform (startPoint, endPoint);
       }

       // 4.
       public void up () {
           final Dimension screenDimension = this.driver.manage ()
               .window ()
               .getSize ();
           final PointOption startPoint = point (screenDimension.getWidth () / 2, screenDimension.getHeight () - 10);
           final PointOption endPoint = point (screenDimension.getWidth () / 2, 10);
           perform (startPoint, endPoint);
       }

       // 5.
       private void perform (final PointOption startPoint, final PointOption endPoint) {
           final TouchAction action = new TouchAction (this.driver);
           action.press (startPoint)
               .waitAction (waitOptions (ofMillis (200)))
               .moveTo (endPoint)
               .release ()
               .perform ();
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s understand what this &lt;a href="https://www.lambdatest.com/blog/what-is-actions-class-in-selenium/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;Helper class&lt;/a&gt; does.&lt;/p&gt;

&lt;p&gt;1- We have created a generic Swipe class which declares a generic type D, which will extend AppiumDriver having a generic type of MobileElement.&lt;/p&gt;

&lt;p&gt;2- Type D is then declared for the driver instance field, which will hold driver instances like AndroidDriver in the case of Android devices and IOSDriver for iOS device automation. Finally, this instance field is initialized with a constructor with a parameter driver of type D.&lt;/p&gt;

&lt;p&gt;3- We have a down method to perform a down swipe on an iOS device to open the notification panel.&lt;/p&gt;

&lt;p&gt;4- We have an up method to perform an up swipe on an iOS device to close the notification panel.&lt;/p&gt;

&lt;p&gt;5- Lastly, we have a perform utility method, which will help us swipe up and down and is used in the respective gesture methods.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;**Note:&lt;/em&gt;* The TouchAction class is provided by Appium and helps us compose a sequence of actions and perform those gestures. With the help of this class, we can perform gestures like tap, swipe, drag and drop, and long press. In our example, we have looked into how we can swipe using this class.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Try an online Selenium Grid to run your browser &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=webpage" rel="noopener noreferrer"&gt;Selenium automation&lt;/a&gt; testing scripts. Our cloud infrastructure has 3000+ desktop &amp;amp; mobile environments. Try for free!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Page Object Model
&lt;/h2&gt;

&lt;p&gt;POM (Page Object Model) is a design pattern commonly used to perform &lt;a href="https://www.lambdatest.com/automated-ui-testing?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;automated UI testing&lt;/a&gt;. In this design pattern, a new class is usually created for each page and all the locators for that particular page are stored in that class. Also, any actions related to that screen are added to the same class.&lt;/p&gt;

&lt;p&gt;But in our sample project, we will not add screen-specific action to the page object, because we want our page object to be loosely coupled with the driver instance. Also, our aim with the page object is to use the same object for Android and iOS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File name: HomePage.java&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    package com.lambdatest.appium.sample.pages;

    import java.util.Map;

    import com.google.common.collect.ImmutableMap;
    import com.lambdatest.appium.sample.enums.Platform;
    import io.appium.java_client.MobileBy;
    import org.openqa.selenium.By;

    public class HomePage {
       // 1.
       public Map&amp;lt;Platform, By&amp;gt; message () {
           return ImmutableMap.of (Platform.IOS, MobileBy.AccessibilityId ("Textbox"), Platform.ANDROID,
               By.id ("Textbox"));
       }

       // 2.
       public Map&amp;lt;Platform, By&amp;gt; notificationButton () {
           return ImmutableMap.of (Platform.IOS, MobileBy.AccessibilityId ("notification"), Platform.ANDROID,
               By.id ("notification"));
       }

       // 3.
       public Map&amp;lt;Platform, By&amp;gt; proverbialNotification () {
           return ImmutableMap.of (Platform.IOS, MobileBy.iOSNsPredicateString ("label BEGINSWITH \"PROVERBIAL\""),
               Platform.ANDROID, By.id ("android:id/title"));
       }

       // 4.
       public Map&amp;lt;Platform, By&amp;gt; textButton () {
           return ImmutableMap.of (Platform.IOS,
               MobileBy.iOSNsPredicateString ("label == \"Text\" AND type == \"XCUIElementTypeButton\""), Platform.ANDROID,
               By.id ("Text"));
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this class, we:&lt;/p&gt;

&lt;p&gt;1- Created a message method representing the message element on the application home page, which will display text when the text button is pressed. This method will provide locators for both Android and iOS.&lt;/p&gt;

&lt;p&gt;2- Created a notificationButton method representing the notification button element on the application, which will send a native notification message on the notification panel. This method will provide locators for both Android and iOS.&lt;/p&gt;

&lt;p&gt;3- Created a proverbialNotification method representing the actual notification element, which is displayed on the notification panel after the user presses the notification button in the application. This method will provide locators for both Android and iOS.&lt;/p&gt;

&lt;p&gt;4- Created a textButton method representing the test button element on the application, which will show proverbial text on the message element. This method will provide locators for both Android and iOS.&lt;/p&gt;

&lt;p&gt;5- In the case of iOS, we composed the locator such that it will make sure we are interacting with the correct element. We combined attributes we found while inspecting the element on the inspector and created a predictable string query, where we will check for the label to be “Text” and the class type of the element to be a button.&lt;/p&gt;

&lt;h2&gt;
  
  
  Base test class
&lt;/h2&gt;

&lt;p&gt;Once we have the page object ready, the next step is writing the tests. Again, we will have two test classes, one for Android and one for iOS. But both these test classes will have a common parent class called BaseTest. Let’s see what this class looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    package com.lambdatest.appium.sample;

    import static java.text.MessageFormat.format;

    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URL;

    import com.lambdatest.appium.sample.enums.Environment;
    import com.lambdatest.appium.sample.utils.Swipe;
    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.remote.AndroidMobileCapabilityType;
    import io.appium.java_client.remote.AutomationName;
    import io.appium.java_client.remote.MobileCapabilityType;
    import io.appium.java_client.service.local.AppiumDriverLocalService;
    import io.appium.java_client.service.local.AppiumServiceBuilder;
    import io.appium.java_client.service.local.flags.GeneralServerFlag;
    import org.openqa.selenium.Capabilities;
    import org.openqa.selenium.remote.CapabilityType;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.testng.ITestContext;
    import org.testng.annotations.AfterTest;

    // 1.
    public class BaseTest&amp;lt;D extends AppiumDriver&amp;lt;MobileElement&amp;gt;&amp;gt; {
       // 2.
       protected static final String LT_KEY  = System.getenv ("LT_ACCESS_KEY");
       protected static final String LT_USER = System.getenv ("LT_USERNAME");

       // 3.
       protected D                        driver;
       protected AppiumDriverLocalService service;
       protected Swipe&amp;lt;D&amp;gt;                 swipe;
       protected WebDriverWait            wait;

       // 4.
       @AfterTest (alwaysRun = true)
       public void tearDown (final ITestContext context) {
           if (Environment.valueOf (context.getCurrentXmlTest ()
               .getParameter ("environment")) == Environment.CLOUD) {
               final var status = (context.getFailedTests ()
                   .size () &amp;gt; 0) ? "failed" : "passed";
               this.driver.executeScript (format ("lambda-status={0}", status));
           }
           this.driver.quit ();
           if (this.service != null &amp;amp;&amp;amp; this.service.isRunning ()) {
               this.service.stop ();
           }
       }

       // 5.
       protected Capabilities getOptions (final Environment environment, final String platform, final String deviceName,
           final String version, final String appKey) {
           final var app = environment == Environment.CLOUD
                           ? System.getenv (appKey)
                           : System.getProperty ("user.dir") + appKey;
           final DesiredCapabilities capabilities = new DesiredCapabilities ();
           capabilities.setCapability (CapabilityType.PLATFORM_NAME, platform);
           capabilities.setCapability (MobileCapabilityType.PLATFORM_VERSION, version);
           capabilities.setCapability (MobileCapabilityType.DEVICE_NAME, deviceName);
           capabilities.setCapability (MobileCapabilityType.APP, app);
           if (environment == Environment.CLOUD) {
               setCapabilitiesForCloud (capabilities, platform);
           } else {
               if (platform.equalsIgnoreCase ("Android")) {
                   setCapabilitiesForLocalAndroid (capabilities, deviceName);
               }
           }
           return capabilities;
       }

       // 6.
       protected URL getUrl (final Environment environment) throws MalformedURLException {
           if (environment == Environment.CLOUD) {
               return new URL (format ("@mobile-hub.lambdatest.com/wd/hub"&amp;gt;https://{0}:{1}@mobile-hub.lambdatest.com/wd/hub", LT_USER, LT_KEY));
           }
           if (this.service != null &amp;amp;&amp;amp; this.service.isRunning ()) {
               return this.service.getUrl ();
           }
           return new URL ("http://localhost:4723/wd/hub");
       }

       // 7.
       protected void startServer (final Environment environment, final boolean isAutomatic) {
           if (!isAutomatic || environment == Environment.CLOUD) {
               return;
           }
           final AppiumServiceBuilder builder = new AppiumServiceBuilder ();
           builder.withIPAddress ("127.0.0.1")
               .usingPort (4723)
               .withAppiumJS (
                   new File ("/path/to/.nvm/versions/node/v16.15.0/lib/node_modules/appium/build/lib/main.js"))
               .withLogFile (new File (System.getProperty ("user.dir") + "/logs/appium.log"))
               .withArgument (GeneralServerFlag.LOG_LEVEL, "info")
               .withArgument (GeneralServerFlag.SESSION_OVERRIDE);
           this.service = AppiumDriverLocalService.buildService (builder);
           this.service.start ();
       }

       private void setCapabilitiesForCloud (final DesiredCapabilities capabilities, final Object platform) {
        capabilities.setCapability ("project", "LambdaTest project");
           capabilities.setCapability ("build", format ("TestNG {0} Sample Build", platform));
           capabilities.setCapability ("name", format ("{0} Test Case", platform));
           capabilities.setCapability ("console", true);
           capabilities.setCapability ("network", true);
           capabilities.setCapability ("visual", true);
           capabilities.setCapability ("video", true);
           capabilities.setCapability ("terminal", true);
           capabilities.setCapability ("devicelog", true);
           capabilities.setCapability ("isRealMobile", true);
       }

       private void setCapabilitiesForLocalAndroid (final DesiredCapabilities capabilities, final String deviceName) {
           capabilities.setCapability (AndroidMobileCapabilityType.AVD, deviceName);
           capabilities.setCapability (MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s understand this class. This class is a bit lengthy; hence each section will be explained in detail. Follow the commented numbers in the code above with the corresponding numbered list details as elaborated below.&lt;/p&gt;

&lt;p&gt;1- We have a generic base test class with a generic type D, which extends AppiumDriver having a generic type of MobileElement. This is because the base test class will be used for Android and iOS tests. Hence the type D can be either AndroidDriver or IOSDriver&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8lyz4ie80xla17y3llr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8lyz4ie80xla17y3llr.png" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- Now we will get the credentials for LambdaTest, a cloud-based device lab provider. In case we want to run our tests on the cloud. We will look into how to run the test on the cloud with the help of LambdaTest later in this blog on Appium with TestNG.&lt;/p&gt;

&lt;p&gt;3- Next, we have instance fields that save different instances, which will help us in automation. Also, note that all these fields are marked protected, which makes all these fields accessible to both Android and iOS tests.&lt;/p&gt;

&lt;p&gt;4- Now, we have a teardown method that will help mark the test as pass or fail on LambdaTest if we run on the cloud. Later we will quit the driver instance. If we are running the test locally, we need to close the Appium service.&lt;/p&gt;

&lt;p&gt;5- Here, we will create and set the capabilities depending on where we want to run the tests, whether locally or on the cloud. Also, some capabilities are specific to local Android emulators, which we have handled.&lt;/p&gt;

&lt;p&gt;6- Get URL method will get the server URL on which our test will run based on the environment. For example, if we run on the cloud, we will get a cloud-specific URL. If we run on the server where our test starts, we will get that server URL. Otherwise, if we have a server already running on port 4723 or any other available port number, we will get that URL. This method will be used in the individual test class for both Android and iOS.&lt;/p&gt;

&lt;p&gt;7- The start server method will be used to start the Appium server programmatically by providing some server arguments, and this method will be called from our test. This method will not perform any action if we run on the cloud or have an Appium server already running externally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android test
&lt;/h2&gt;

&lt;p&gt;In this section of this tutorial on Appium with TestNG, we will create a new class for the Android test where we will write two test cases as described earlier. First, let’s see how this test looks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    package com.lambdatest.appium.sample.android;

    import static com.lambdatest.appium.sample.enums.Platform.ANDROID;
    import static org.testng.Assert.assertEquals;

    import java.net.MalformedURLException;

    import com.lambdatest.appium.sample.BaseTest;
    import com.lambdatest.appium.sample.enums.Environment;
    import com.lambdatest.appium.sample.enums.Platform;
    import com.lambdatest.appium.sample.pages.HomePage;
    import com.lambdatest.appium.sample.utils.Swipe;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.Setting;
    import io.appium.java_client.android.AndroidDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;

    // 1.
    public class AndroidTest extends BaseTest&amp;lt;AndroidDriver&amp;lt;MobileElement&amp;gt;&amp;gt; {
       private static final Platform PLATFORM = ANDROID;
       private              HomePage homePage;

       // 2.
       @Parameters ({ "environment", "deviceName", "version", "app", "isAutomatic" })
       @BeforeTest
       public void setupDriver (final Environment environment, final String deviceName, final String version,
           final String app, final boolean isAutomatic) throws MalformedURLException {
           this.homePage = new HomePage ();
           startServer (environment, isAutomatic);
           this.driver = new AndroidDriver&amp;lt;&amp;gt; (getUrl (environment),
               getOptions (environment, "Android", deviceName, version, app));
           this.driver.setSetting (Setting.IGNORE_UNIMPORTANT_VIEWS, true);
           this.wait = new WebDriverWait (this.driver, 10);
           this.swipe = new Swipe&amp;lt;&amp;gt; (this.driver);
       }

       // 3.
       @Test
       public void testNotifications () {
           this.wait.until (ExpectedConditions.elementToBeClickable (this.homePage.notificationButton ()
                   .get (PLATFORM)))
               .click ();
           this.driver.openNotifications ();
           assertEquals (this.wait.until (ExpectedConditions.visibilityOfElementLocated (
                   this.homePage.proverbialNotification ()
                       .get (PLATFORM)))
               .getText (), "Test Notification");
           this.driver.navigate ()
               .back ();
       }

       // 4.
       @Test
       public void testTextButton () {
           this.wait.until (ExpectedConditions.elementToBeClickable (this.homePage.textButton ()
                   .get (PLATFORM)))
               .click ();
           assertEquals (this.wait.until (ExpectedConditions.visibilityOfElementLocated (this.homePage.message ()
                   .get (PLATFORM)))
               .getText (), "Proverbial");
       }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this test, we are:&lt;/p&gt;

&lt;p&gt;1- Extending our BaseTest class and specifying the generic type of the class as AndroidDriver.&lt;/p&gt;

&lt;p&gt;2- Next, we have the setupDriver method, which takes parameters from testng.xml, which decides:&lt;/p&gt;

&lt;p&gt;a. In which environment will we be running our tests, on cloud or local.&lt;/p&gt;

&lt;p&gt;b. The name of the device.&lt;/p&gt;

&lt;p&gt;c. The version of the platform&lt;/p&gt;

&lt;p&gt;d. App path, local file path in the case of local execution, or app URL if running on the cloud.&lt;/p&gt;

&lt;p&gt;e. If we run locally, the isAutomatic parameter will tell if we want to start the server internally in our test or already have a server running on our external terminal.&lt;/p&gt;

&lt;p&gt;f. We are also updating the Appium setting to set IGNORE_UNIMPORTANT_VIEWS which will reduce unnecessary elements from the overall elements hierarchy tree.&lt;/p&gt;

&lt;p&gt;3- testNotifications test method will test our first test scenario where the user clicks on the notification button and sees a notification pop-up on the panel. We will also assert the notification text to ensure our test passes. Here we use the HomePage class to get the platform-specific locators.&lt;/p&gt;

&lt;p&gt;4- testTextButton test method will verify if the Proverbial text is displayed when the user clicks on the text button. We also use the HomePage class to get the platform-specific locators.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygi2wv4z41npte8acfzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygi2wv4z41npte8acfzw.png" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  iOS test
&lt;/h2&gt;

&lt;p&gt;Similar to the Android test, we have another class for the iOS test that also uses the same page object class used in the Android test. Let’s see what this class looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   package com.lambdatest.appium.sample.ios;

    import static com.lambdatest.appium.sample.enums.Platform.IOS;
    import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable;
    import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

    import java.net.MalformedURLException;

    import com.lambdatest.appium.sample.BaseTest;
    import com.lambdatest.appium.sample.enums.Environment;
    import com.lambdatest.appium.sample.enums.Platform;
    import com.lambdatest.appium.sample.pages.HomePage;
    import com.lambdatest.appium.sample.utils.Swipe;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.ios.IOSDriver;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.testng.Assert;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;

    // 1.
    public class IOSTest extends BaseTest&amp;lt;IOSDriver&amp;lt;MobileElement&amp;gt;&amp;gt; {
       private static final Platform PLATFORM = IOS;
       private              HomePage homePage;

       // 2.
       @Parameters ({ "environment", "deviceName", "version", "app" })
       @BeforeTest
       public void setupDriver (final Environment environment, final String deviceName, final String version,
           final String app) throws MalformedURLException {
           this.homePage = new HomePage ();
           this.driver = new IOSDriver&amp;lt;&amp;gt; (getUrl (environment), getOptions (environment, "iOS", deviceName, version, app));
           this.wait = new WebDriverWait (this.driver, 10);
           this.swipe = new Swipe&amp;lt;&amp;gt; (this.driver);
       }

       // 3.
       @Test
       public void testNotifications () {
           this.wait.until (elementToBeClickable (this.homePage.notificationButton ()
                   .get (PLATFORM)))
               .click ();
           this.swipe.down ();
           Assert.assertTrue (this.wait.until (visibilityOfElementLocated (this.homePage.proverbialNotification ()
                   .get (PLATFORM)))
               .getText ()
               .contains ("Test Notification, Please enjoy this notification"));
           this.swipe.up ();
       }

       // 4.
       @Test
       public void testTextButton () {
           this.wait.until (elementToBeClickable (this.homePage.textButton ()
                   .get (PLATFORM)))
               .click ();
           Assert.assertEquals (this.wait.until (visibilityOfElementLocated (this.homePage.message ()
                   .get (PLATFORM)))
               .getText (), "Proverbial");
       }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this test, we are,&lt;/p&gt;

&lt;p&gt;1- Extending our BaseTest class and specifying the generic type of the class as IOSDriver.&lt;/p&gt;

&lt;p&gt;2- Next, we have the setupDriver method, which takes parameters from testng.xml, which decides:&lt;/p&gt;

&lt;p&gt;a. In which environment will we be running our tests, on cloud or local.&lt;br&gt;
b. The name of the device.&lt;br&gt;
c. The version of the platform.&lt;br&gt;
d. App path, local file path in the case of local execution, or app URL if running on the cloud.&lt;/p&gt;

&lt;p&gt;3- testNotifications test method is almost identical, except that the openNotification method does not work here. Instead, we will use the Swipe util class to swipe down and open the notification panel. After verification, we will swipe up to close the notification panel.&lt;/p&gt;

&lt;p&gt;4- testTextButton test method is the same as the Android test.&lt;/p&gt;
&lt;h2&gt;
  
  
  TestNG XML file
&lt;/h2&gt;

&lt;p&gt;We now have all the test classes in place. Now it’s time to execute the tests for which we will create a testng.xml file in the project’s root folder. Let’s see how this file content will look.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
    &amp;lt;!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"&amp;gt;
    &amp;lt;!-- 1. --&amp;gt;
    &amp;lt;suite name="Mobile Suite" verbose="2"&amp;gt;
       &amp;lt;!-- 2. --&amp;gt;
       &amp;lt;test name="Test iOS App on LambdaTest"&amp;gt;
           &amp;lt;parameter name="environment" value="CLOUD"/&amp;gt;
           &amp;lt;parameter name="deviceName" value="iPhone 13 Pro"/&amp;gt;
           &amp;lt;parameter name="version" value="15"/&amp;gt;
           &amp;lt;parameter name="app" value="LT_APP_IOS"/&amp;gt;
           &amp;lt;parameter name="isAutomatic" value="false"/&amp;gt;
           &amp;lt;classes&amp;gt;
               &amp;lt;class name="com.lambdatest.appium.sample.ios.IOSTest"/&amp;gt;
           &amp;lt;/classes&amp;gt;
       &amp;lt;/test&amp;gt;
       &amp;lt;!-- 3. --&amp;gt;
       &amp;lt;test name="Test Android App on LambdaTest"&amp;gt;
           &amp;lt;parameter name="environment" value="CLOUD"/&amp;gt;
           &amp;lt;parameter name="deviceName" value="Galaxy S10"/&amp;gt;
           &amp;lt;parameter name="version" value="10"/&amp;gt;
           &amp;lt;parameter name="app" value="LT_APP_ANDROID"/&amp;gt;
           &amp;lt;parameter name="isAutomatic" value="false"/&amp;gt;
           &amp;lt;classes&amp;gt;
               &amp;lt;class name="com.lambdatest.appium.sample.android.AndroidTest"/&amp;gt;
           &amp;lt;/classes&amp;gt;
       &amp;lt;/test&amp;gt;
       &amp;lt;!-- 4. --&amp;gt;
       &amp;lt;test name="Test Android App on Local"&amp;gt;
           &amp;lt;parameter name="environment" value="LOCAL"/&amp;gt;
           &amp;lt;parameter name="deviceName" value="Pixel_5"/&amp;gt;
           &amp;lt;parameter name="version" value="10"/&amp;gt;
           &amp;lt;parameter name="app" value="/src/test/resources/apps/proverbial_android.apk"/&amp;gt;
           &amp;lt;parameter name="isAutomatic" value="true"/&amp;gt;
           &amp;lt;classes&amp;gt;
               &amp;lt;class name="com.lambdatest.appium.sample.android.AndroidTest"/&amp;gt;
           &amp;lt;/classes&amp;gt;
       &amp;lt;/test&amp;gt;
    &amp;lt;/suite&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1- We declared the test suite for our tests.&lt;/p&gt;

&lt;p&gt;2- The first test is for iOS running on the LambdaTest cloud server.&lt;/p&gt;

&lt;p&gt;3- The second test is for Android running on the LambdaTest cloud server.&lt;/p&gt;

&lt;p&gt;4- The last test is for Android running locally where the Appium server will be started from our tests automatically and later the same will be closed once the test run completes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking Execution reports
&lt;/h2&gt;

&lt;p&gt;To check the tests that were executed using Appium with TestNG on the LambdaTest cloud server:&lt;/p&gt;

&lt;p&gt;1- Navigate on their dashboard to &lt;strong&gt;Real Device -&amp;gt; App Automation&lt;/strong&gt; from the left navigation panel. You will see a screen similar to the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vx41xag3g40cmtbzid2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vx41xag3g40cmtbzid2.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- When you click on any test sessions, a screen similar to the following will be displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94j0tsnmzovn8vwb9vm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94j0tsnmzovn8vwb9vm1.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can see the recorded video, all the event logs, device logs, network logs, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the tests
&lt;/h2&gt;

&lt;p&gt;Since we have a couple of tests running on LambdaTest, we must first save our LambdaTest credentials in the environment variables LT_USERNAME having your username and LT_ACCESS_KEY having your access key.&lt;/p&gt;

&lt;p&gt;1- To run the tests, you can directly right-click in your IDE on the testng.xml file and click Run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugnjax8qf9ryqvpou8je.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugnjax8qf9ryqvpou8je.png" width="800" height="809"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- Another option is to run the test from your terminal by executing the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; mvn clean install 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will execute our testng.xml file because we have configured the Maven surefire plugin in our pom.xml earlier.&lt;/p&gt;

&lt;p&gt;This command will execute our testng.xml file because we have configured the Maven surefire plugin in our pom.xml earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to upload an app to the cloud?
&lt;/h2&gt;

&lt;p&gt;In this Appium with TestNG tutorial, we have already seen some tests run on the LambdaTest cloud server. But to run the test successfully, we must first upload our Android / iOS application on the LambdaTest cloud server. We must upload the .apk file for Android and the .ipa file for iOS. While uploading, you will require your user name and access key.&lt;/p&gt;

&lt;p&gt;Following are the ways of uploading the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upload using the cUrl command
&lt;/h2&gt;

&lt;p&gt;One way is to execute the following cURL command on your terminal window on Mac OS and Linux.&lt;/p&gt;

&lt;p&gt;For Android:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    curl -u "&amp;lt;your-user-name&amp;gt;:&amp;lt;your-access-key&amp;gt;" \
    --location --request POST 'https://manual-api.lambdatest.com/app/upload/realDevice' \
    --form 'name="Android_App"' \
    --form 'appFile=@"src/test/resources/apps/proverbial_android.apk"'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For iOS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   curl -u "&amp;lt;your-user-name&amp;gt;:&amp;lt;your-access-key&amp;gt;" -X POST "https://manual-api.lambdatest.com/app/upload/realDevice" -F "appFile=@"your/ios/app.ipa"" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In any of the above commands, you will get a JSON response where you can use app_url as your App capability. It will be in the format: lt://.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upload from the LambdaTest dashboard
&lt;/h2&gt;

&lt;p&gt;On the &lt;a href="https://accounts.lambdatest.com/login?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=dec15_pk&amp;amp;utm_term=pk&amp;amp;utm_content=blog" rel="noopener noreferrer"&gt;LambdaTest Dashboard&lt;/a&gt;, navigate to Real Device -&amp;gt; App Automation and click on the App Upload button towards the right of the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmegoizy7326tcvr1vrtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmegoizy7326tcvr1vrtq.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you have uploaded the file, you will get app_url on the screen as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgo02mfnewqorykfbmvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgo02mfnewqorykfbmvn.png" width="800" height="983"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this extensive blog on automated app testing using Appium with TestNG, we learned many things. We learned how to set up our machine to automate mobile applications for Android and iOS and inspect elements on a local emulator and cloud devices.&lt;/p&gt;

&lt;p&gt;We also learned about the different locator strategies, creating a single page object for Android and iOS, and leveraging Appium with TestNG to run our tests locally and on the cloud using test parameters. Finally, we configured the pom.xml file to run the tests using Maven commands.&lt;/p&gt;

&lt;p&gt;Don’t forget to share your feedback on this Appium with TestNG tutorial. Also, share it with your network if you like it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
