Appium

Q: How Appium works?

Ans:

Appium is an ‘HTTP Server’ written using a Node.js platform and drives iOS and an Android session using Webdriver JSON wire protocol.

Hence, before initializing the Appium Server, Node.js must be pre-installed on the system.

When Appium is downloaded and installed, then a server is set up on our machine that exposes a REST API.

It receives connection and command request from the client and executes that command on mobile devices (Android / iOS).

It responds back with HTTP responses. Again, to execute this request, it uses the mobile test automation frameworks to drive the user interface of the apps



Q: What are main locator used in Appium?

Ans:

  1. Xpath
  2. ID
  3. accessibilityID
  4. className
  5. androidUIAutomator

Q: Automation for test case in Android vs IOS app

Ans:
import io.appium.java_client.MobileElement;
import io.appium.java_client.ios.IOSDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
import org.junit.Assert;

public class RatingTest {
    public static void main(String[] args) throws Exception {
        // DesiredCapabilities for iOS App
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("platformName", "iOS");
        capabilities.setCapability("platformVersion", "14.4");
        capabilities.setCapability("deviceName", "iPhone 12");
        capabilities.setCapability("app", "/path/to/your/app.app");
        capabilities.setCapability("automationName", "XCUITest");
        
        // Initialize the AppiumDriver
        WebDriver driver = new IOSDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
        
        // Locate the 4th star and click on it to rate
        MobileElement star4 = (MobileElement) driver.findElement(By.id("star4"));
        star4.click();  // Rating 4 stars
        
        // Locate and click on the Submit button
        MobileElement submitButton = (MobileElement) driver.findElement(By.id("submitButton"));
        submitButton.click();
        
        // Verify if rating was successfully submitted
        MobileElement confirmationMessage = (MobileElement) driver.findElement(By.id("confirmationMessage"));
        String message = confirmationMessage.getText();
        Assert.assertEquals("Thank you for your rating!", message);
        
        // Quit the driver session
        driver.quit();
    }
}
======================================

import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.junit.Assert;

import java.net.URL;

public class RatingTest {
    public static void main(String[] args) throws Exception {
        // DesiredCapabilities for Android App
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("platformName", "Android");            // Set the platform to Android
        capabilities.setCapability("platformVersion", "10.0");            // Android version
        capabilities.setCapability("deviceName", "Android Emulator");     // Device or emulator name
        capabilities.setCapability("app", "/path/to/your/app.apk");       // Path to the APK file
        capabilities.setCapability("automationName", "UiAutomator2");     // Use UiAutomator2 for Android automation

        // Initialize the AndroidDriver
        WebDriver driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

        // Locate the 4th star (for a 4-star rating) and click it
        MobileElement star4 = (MobileElement) driver.findElement(By.id("com.example:id/star4"));
        star4.click();  // Rate 4 stars

        // Locate and click the Submit button
        MobileElement submitButton = (MobileElement) driver.findElement(By.id("com.example:id/submitButton"));
        submitButton.click();

        // Verify if rating was successfully submitted
        MobileElement confirmationMessage = (MobileElement) driver.findElement(By.id("com.example:id/confirmationMessage"));
        String message = confirmationMessage.getText();
        Assert.assertEquals("Thank you for your rating!", message);

        // End the session
        driver.quit();
    }
}

Q: How to install any application on Emulator?

Ans:
First move to platform-tool folder and then open cmd
Secondly run below command
adb install <path of apk file>
Ex:
C:\Users\dheer\AppData\Local\Android\Sdk\platform-tools>adb install <C:\Users\dheer\Desktop\Appium\Appium_New\google-chrome-111.apk>

Q: How to set chromedriver path in Appium?

  • UiAutomator2Options is a class that helps configure desired capabilities for running Appium tests on Android devices using the UiAutomator2 automation engine.
  • It simplifies the process of setting Android-specific configurations (e.g., app path, device name, platform version, etc.).
  • By using this class, you can customize the Appium test environment for Android, enabling better cross-platform testing with Appium for both iOS and Android.
  • ============================================================
    UiAutomator2Options options = new UiAutomator2Options();
    options.setDeviceName("DheerajEmulater"); //emulator
    options.setChromedriverExecutable("C:\\Users\\dheer\\Desktop\\Appium\\Appium_New\\chromedriver\\chromedriver_83.exe");

    =============================================================
    import io.appium.java_client.android.options.UiAutomator2Options;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import io.appium.java_client.android.AndroidDriver;
    import java.net.URL;

    public class AppiumTest {

        public static void main(String[] args) throws Exception {
            // Create an instance of UiAutomator2Options
            UiAutomator2Options options = new UiAutomator2Options();

            // Set the desired capabilities for the Android test
            options.setCapability("platformName", "Android");  // The platform for the device
            options.setCapability("deviceName", "Android Emulator");  // Device name
            options.setCapability("platformVersion", "11.0");  // Android version
            options.setCapability("app", "/path/to/your/android/app.apk");  // Path to your APK
            options.setCapability("automationName", "UiAutomator2");  // Automation engine
            options.setCapability("noReset", true);  // Whether to reset app state before testing

            // Initialize the driver with the UiAutomator2Options
            AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), options);

            // Run the test or automation steps here
            System.out.println("App launched on Android device with UiAutomator2!");

            // Quit the driver after the test
            driver.quit();
        }
    }


    Q: Write a test case that can be run on Android as well as on IOS Application.

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.ios.IOSDriver;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.testng.annotations.BeforeMethod;
    import org.testng.annotations.Test;
    import org.testng.annotations.Parameters;

    import java.net.URL;

    public class CrossPlatformDropdownTest {

        private WebDriver driver;

        @BeforeMethod
        @Parameters({"platform"})
        public void setUp(String platform) throws Exception {
            DesiredCapabilities capabilities = new DesiredCapabilities();

            // Set the capabilities for Android or iOS dynamically
            if (platform.equalsIgnoreCase("Android")) {
                // Android-specific capabilities
                capabilities.setCapability("platformName", "Android");
                capabilities.setCapability("deviceName", "Android Emulator");
                capabilities.setCapability("app", "/path/to/android/app.apk"); // Path to your Android app
                capabilities.setCapability("automationName", "UiAutomator2");
                capabilities.setCapability("platformVersion", "11.0");  // Android version

                driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
                System.out.println("Android test setup complete");

            } else if (platform.equalsIgnoreCase("iOS")) {
                // iOS-specific capabilities
                capabilities.setCapability("platformName", "iOS");
                capabilities.setCapability("deviceName", "iPhone 12");
                capabilities.setCapability("app", "/path/to/ios/app.app"); // Path to your iOS app
                capabilities.setCapability("automationName", "XCUITest");
                capabilities.setCapability("platformVersion", "14.4");  // iOS version

                driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
                System.out.println("iOS test setup complete");
            } else {
                System.out.println("Unsupported platform: " + platform);
            }
        }

        @Test
        public void testDropdownSelection() {
            if (driver != null) {
                System.out.println("Running test on " + driver.getCapabilities().getCapability("platformName"));

                // Cross-platform logic for interacting with dropdown
                if (driver instanceof AndroidDriver) {
                    // Android-specific: Interact with a dropdown (Spinner or similar)
                    // Assume the dropdown has an ID of "dropdown"
                    MobileElement dropdown = (MobileElement) driver.findElement(By.id("com.example.android:id/dropdown"));
                    dropdown.click(); // Click to open the dropdown

                    // Select an option from the dropdown (example by text)
                    MobileElement option = (MobileElement) driver.findElement(By.xpath("//android.widget.TextView[@text='Option 2']"));
                    option.click(); // Select Option 2
                    System.out.println("Option selected on Android: Option 2");

                } else if (driver instanceof IOSDriver) {
                    // iOS-specific: Interact with a picker view (UIPickerView)
                    // Assume the UIPickerView is being used for the dropdown
                    MobileElement dropdown = (MobileElement) driver.findElement(By.xpath("//XCUIElementTypePicker"));
                    dropdown.click(); // Click to activate the picker

                    // Select the desired option from the picker (example: "Option 2")
                    MobileElement option = (MobileElement) driver.findElement(By.xpath("//XCUIElementTypePickerWheel[@value='Option 1']"));
                    option.sendKeys("Option 2"); // Change the picker value to "Option 2"
                    System.out.println("Option selected on iOS: Option 2");
                }
            }
        }

        @AfterMethod
        public void tearDown() {
            if (driver != null) {
                driver.quit();  // Quit the driver after the test
                System.out.println("Test completed, driver closed.");
            }
        }
    }

    ===============================================
    <?xml version="1.0" encoding="UTF-8"?>
    <suite name="Cross-Platform Test Suite" parallel="tests" thread-count="2">
        <!-- Android Test -->
        <test name="Android Test">
            <parameter name="platform" value="Android"/>
            <classes>
                <class name="CrossPlatformDropdownTest"/>
            </classes>
        </test>

        <!-- iOS Test -->
        <test name="iOS Test">
            <parameter name="platform" value="iOS"/>
            <classes>
                <class name="CrossPlatformDropdownTest"/>
            </classes>
        </test>
    </suite>

    Q: What is use of UiAutomator2Options in Appium 8 ?

    Ans:
    // From Appium Java Client version 8.0.0 Beta
                            UiAutomator2Options options = new UiAutomator2Options();
    options.setDeviceName("DheerajEmulater"); //emulator
    options.setChromedriverExecutable("C:\\Users\\dheer\\Desktop\\Appium\\Appium_New\\chromedriver\\chromedriver_83.exe");
    options.setApp("C:\\Users\\dheer\\Desktop\\Appium\\Appium_New\\src\\test\\java\\resources\\General-Store.apk");
    //options.setApp("C:\\Users\\dheer\\Desktop\\Appium\\Appium_New\\google-chrome-111.apk");
    driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

    // Older approach: Java Client version 7.X.X
                            DesiredCapabilities capabilities = new DesiredCapabilities();
                            capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
                            capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 700000);

    Q: List out the limitations of using Appium?

    Ans:
    • Appium does not support testing of Android Version lower than 4.2
    • Limited support for hybrid app testing. E.g., not possible to test the switching action of application from the web app to native and vice-versa
    • No support to run Appium Inspector on Microsoft Windows

    Q: Explain how to find DOM element or xPath in a mobile application?

    Ans:
    To find the DOM element use “UIAutomateviewer” to find DOM element for Android application.

    Q: What language does Appium support?

    Ans:
    Appium support any language that support HTTP request like Java, JavaScript with Node.js, Python, Ruby, PHP, Perl, etc.

    Q: Explain the pros and cons of Appium?

    Pros:
    • For programmer irrespective of the platform, he is automating ( Android or iOS) all the complexities will remain under single Appium server
    • It opens the door to cross-platform mobile testing which means the same test would work on multiple platforms
    • Appium does not require extra components in your App to make it automation friendly
    • It can automate Hybrid, Web and Native mobile applications

    Cons:
    • Running scripts on multiple iOS simulators at the same time is possible with Appium
    • It uses UIAutomator for Android Automation which supports only Android SDK platform, API 16 or higher and to support the older API’s they have used another open source library called Selendroid

    Q: Explain what is APPIUM INSPECTOR?

    Ans:
    Similar to Selenium IDE record and Playback tool, Appium has an “Inspector” to record and playback. It records and plays native application behavior by inspecting DOM and generates the test scripts in any desired language. However, Appium Inspector does not support Windows and use UIAutomator viewer in its option.

    Q: Mention what are the basic requirement for writing Appium tests?

    Ans:
    For writing Appium tests you require,

    • Driver Client: Appium drives mobile applications as though it were a user. Using a client library you write your Appium tests which wrap your test steps and sends to the Appium server over HTTP.
    • Appium Session: You have to first initialize a session, as such Appium test takes place in the session. Once the Automation is done for one session, it can be ended and wait for another session
    • Desired Capabilities: To initialize an Appium session you need to define certain parameters known as “desired capabilities” like PlatformName, PlatformVersion, Device Name and so on. It specifies the kind of automation one requires from the Appium server.
    • Driver Commands: You can write your test steps using a large and expressive vocabulary of commands.

    Q: Mention what are the possible errors one might encounter using Appium?

    Ans:
    The possible errors one might face in Appium includes:

    • Error 1: The following desired capabilities are needed but not provided: Device Name, platformName
    • Error 2: Could not find adb. Please set the ANDROID_HOME environment variable with the Android SDK root directory path
    • Error 3: openqa.selenium.SessionNotCreatedException: A new session could not be created
    • Error 4: How to find DOM element or XPath in a mobile application?
    • SessionNotFoundException: On disconnection of Appium connection or Session not established, display this exception
    • ElementNotFoundException: When Appium does not find the element it is looking for, this exception is displayed
    • WebDriverException: When Driver does not exist, this exception is displayed
    • NoSuchContextException: is thrown when the context target that is to be switched to does not exist.

    Q: What are native Apps/Mobile Web Apps/hybrid apps ?

    Ans: 
    • Those Apps are written by using Android SDKs and IOS are known as Native Apps.
    •  There are mobile web pages that are those web apps that are accessed with mobile. browsers. In the case of the IOS platform, Appium supports Safari and for the Android platform, Chrome or any other built-in browser is used.
    •  Hybrid app are a mix of native and web applications, like native applications are available on the mobile app stores, and have features similar to native applications, like web applications rely on web browsers to be rendered. Online eCommerce sites and Netflix are some of the best examples of hybrid applications.

    Q: How can you inspect elements that are present in the Native Android App?

    Ans: 

    1 .With the help of the UI Automator tool that is present in Android SDK, you will be able to access those object locators that are part of the Android Native app.

    Steps to use UIAutomator Viewer:

    1. Launch UIAutomator Viewer: You can find it in the tools/bin directory of your Android SDK installation. Run uiautomatorviewer from the command line or through Android Studio.
    2. Capture a Screenshot: Click the "Device Screenshot" button in the UIAutomator Viewer to capture the current screen of your connected Android device.
    3. Inspect Elements: After capturing, you can inspect elements on the screenshot. UIAutomator Viewer will display information about the selected UI element, including its resource ID, class, and text.

    2 . Appium Inspector is a feature of Appium that lets you inspect and interact with the elements of your mobile app.

    • Steps to use Appium Inspector:
      1. Start Appium Server: Launch the Appium server on your machine.
      2. Open Appium Inspector: In Appium Desktop, click the "Start Inspector Session" button.
      3. Configure Desired Capabilities: Set up the desired capabilities for your test, such as platformName, deviceName, appPackage, and appActivity.
      4. Start the Session: Click "Start Session" to open the app on the device or emulator.
      5. Inspect Elements: Use the Inspector's UI to interact with and inspect the elements of the app. You can view element properties and hierarchies.

    Q: Mention the method with which you can scroll down in App?

    Ans: With the help of the scrollTo () method, you will be able to scroll down in App. Also, such a method will help you to automatically scroll until the specific text is not match.

    For Android

    TouchAction action = new TouchAction(driver);

    action.press(PointOption.point(500, 1000))

          .waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)))

          .moveTo(PointOption.point(500, 500))

          .release()

          .perform();


    For iOS

    In iOS, scrolling is often performed using the scroll method from the MobileElement class, or by executing mobile-specific commands like mobile:scroll.


    public class ScrollDownExample {

        public static void main(String[] args) {

            DesiredCapabilities capabilities = new DesiredCapabilities();

            capabilities.setCapability("platformName", "iOS");

            capabilities.setCapability("deviceName", "MyDevice");

            capabilities.setCapability("app", "/path/to/your/app.app");

            IOSDriver<MobileElement> driver = new IOSDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities);

            // Scroll down to find a specific element

            driver.executeScript("mobile: scroll", ImmutableMap.of("direction", "down"));

            // Perform operations on the element if needed

            MobileElement element = driver.findElementByAccessibilityId("elementId");

            element.click(); // Example action

            driver.quit();

        }

    }

    Explanation

    Android:

    findElementByAndroidUIAutomator allows you to use UIAutomator for scrolling actions.

    new UiScrollable(new UiSelector().scrollable(true)).scrollForward() scrolls down in a scrollable view.

    iOS:

    executeScript("mobile: scroll", ImmutableMap.of("direction", "down")) scrolls the screen in the specified direction.

    Q: Is it possible to start an Appium server programmatically?

    Ans: 

    It is possible to start an appium server programmatically. Generally, the commands that are being entered to the command prompt are written in note pad and it is saved with .bat extension and you can click the bat file. 

    public class AppiumServerManager {

        public static void main(String[] args) {

            // Create and configure the Appium service

            AppiumDriverLocalService appiumService = AppiumDriverLocalService.buildService(

                new AppiumServiceBuilder()

                    .usingAnyFreePort() // Automatically select a free port

                    .withArgument(ServerFlag.LOG_LEVEL, "info") // Set the log level to info

                    .withStartUpTimeInSeconds(60) // Adjust startup time if needed

            );

            // Start the Appium server

            appiumService.start();

            System.out.println("Appium server started at: " + appiumService.getUrl());

            // Add your test automation code here

            // Stop the Appium server

            appiumService.stop();

            System.out.println("Appium server stopped.");

        }

    }

    Q: How to handle hybrid Apps?

    Ans:

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.android.AndroidElement;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.remote.DesiredCapabilities;

    import java.net.URL;
    import java.util.Set;

    public class HybridAppTest {
        public static void main(String[] args) throws Exception {
            // Setup the desired capabilities
            DesiredCapabilities capabilities = new DesiredCapabilities();
            capabilities.setCapability("platformName", "Android");  // or "iOS"
            capabilities.setCapability("deviceName", "emulator-5554"); // Adjust for your device/emulator
            capabilities.setCapability("app", "path/to/your/hybrid/app.apk");  // Path to your APK

            // Create an AndroidDriver instance (use IOSDriver for iOS)
            AndroidDriver<MobileElement> driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

            // Wait for the app to load
            Thread.sleep(5000);

            // Get all available contexts (native and webview)
            Set<String> contextHandles = driver.getContextHandles();
            System.out.println("Available contexts: " + contextHandles);

            // Switch to WebView context (assuming WebView context is available)
            for (String context : contextHandles) {
                if (context.contains("WEBVIEW")) {
                    driver.context(context);  // Switch to WebView context
                    System.out.println("Switched to WebView context: " + context);
                    break;
                }
            }

            // Interact with web elements (inside WebView)
            WebElement webElement = driver.findElement(By.id("elementId"));  // Replace with actual web element ID
            webElement.click();  // Perform actions in WebView

            // Switch back to the native context
            driver.context("NATIVE_APP");  // Switch back to native context

            // Interact with native elements
            MobileElement nativeElement = driver.findElement(By.id("nativeElementId"));  // Replace with actual native element ID
            nativeElement.click();  // Perform actions on native elements

            // Close the driver session
            driver.quit();
        }
    }


    Q: How can you inspect elements on the IOS apps?

    Ans: 

    With the help of using an Appium inspector that is a GUI-based tool, you can identify elements on IOS apps. These GUI-based tools are quite similar to that of selenium IDE.

    Q: How is it possible to identify Mobile browser objects?

    Ans: 

    you can make use of User-Agent in order to identify objects in the Mobile browser. It is done by using the user agent and then changing the browser as the mobile proxy and thus gets an object.

    Q: Write the command that will allow you to identify objects uniquely when there are multiple objects within the same class name using Appium?

    Ans: 

    With the help of the command driver. find element (By.className) it is possible to identify the elements uniquely. 

    Q: Give the difference between emulator and simulator?

    Ans: 

    The simulator is used for calling IOS virtual devices that will launch from Xcode in MAC. The emulator is used for calling Android virtual devices.

    Q: What is Appium’s most considerable limitation?

    Ans: 

    Hand down my chin starting to think and mumbling. If I had to provide one single thing you should be aware of about Appium before starting using it, it would surely be multiple session handling. Since Appium is a server, it serves HTTP requests; you might have two different computers running a test each against the same Appium server:

    what happens? As for now, Appium does not support this scenario and the second test will be aborted. This is a considerable limitation because no queuing system comes with Appium. If you need to support multiple sessions, you will need to implement this feature by yourself.

    Q: What data exchange is?

    Ans: 

    When we say “data exchange” I am not referring to scenarios like getting or setting the value of a textbox. I am also not referring to getting or setting the value of an element’s attribute. All these things are easy to achieve in Appium as Selenium provides commands just for those. 

    By “data exchange” I mean exchanging information hosted by complex objects stored in different parts of your review-based app like the window object.

    Consider when you dispatch and capture events, your app can possibly do many things and the ways data flows can be handled are many. Some objects might also have a state and the state machine behind some scenarios in your app can be large and articulated. For all these reasons you might experience problems when testing.

    Q:List difference between Selenium WebDriver and Appium WebDriver

    Ans: Selenium and Appium both use

    *JSON wire protocol

    *Methods like

    sendKeys(),

    findByClassName(),

    findByElementId(),

    findByXPath()

    There is a difference between Selenium WebDriver and Appium WebDriver as below.

    • Selenium WebDriver Supports mobile web applications using browsers like Firefox, Chrome, Opera, Safari and Appium WebDriver Supports native mobile application installed on iOS and Android devices
    • Selenium WebDriver has become standard for automation testing of browser-based web applications while RemoteWebDriver class is inherited by Appium WebDriver class. This class with help of Appium server provides additional functions useful in context of mobile test automation.

    Q: Describe ways to debug Appium tests?

    Ans: Following are some ways we can do:
    1. Any error that occurred during mobile tests can be traced from the logs generated at the Appium server.
    2. Test scripts created can be debugged with the help of the programming language used in writing these tests.

    Q: How can we retrieve the test status of Appium test execution?

    Ans:
    There are various ways to display the test status:
    1. Integrating TestNG with Appium
    2. ExtentReports that give test status reports in the dashboard
    3. REST API of BrowserStack App Automate for .apk (Android app) or .ipa (iOS app).
    4. Built-in reporting tools like Maven and Allure


    Q: Difficult Scenarios to automate in Appium

    Ans
    1. Device Fragmentation:
    Mobile automation often involves testing on a variety of devices with different screen sizes, OS versions, and hardware specifications.

    Challenge: Ensuring that tests run consistently across a wide variety of devices can be difficult due to differences in the user interface, performance, and device-specific behaviors.
    Solution: Use cloud-based device farms (e.g., Sauce Labs, BrowserStack) or create device farms within your own infrastructure to ensure cross-device compatibility.

    2. Handling Dynamic Elements:
    Mobile apps frequently have dynamic elements that can change IDs, positions, or visibility based on different conditions (e.g., network, user interaction, time-based behavior).

    Challenge: Dealing with elements that change dynamically or are not visible on the screen (e.g., loading indicators or popups).
    Solution: Use Explicit Waits and WebDriverWait to wait for elements to be available before interacting. For dynamic elements, use strategies like XPath with contains or dynamic CSS Selectors.

    WebDriverWait wait = new WebDriverWait(driver, 10);
    MobileElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("dynamic_element_id")));

    3. Synchronization Issues:
    Mobile apps often have delayed or asynchronous loading of elements (e.g., data from an API or animations), leading to issues with synchronization between the test and the app behavior.

    Challenge: The app may take time to load elements or complete animations, which can lead to stale element exceptions or element not found issues.
    Solution: Implement Explicit Waits (as shown above) and avoid using Thread.sleep(), which can cause tests to be slow and brittle.

    4. Appium Server Issues:
    Appium relies on the Appium server to communicate with the mobile devices. Sometimes, the Appium server may fail to start, or the connection between the Appium server and the mobile device may be unstable.

    Challenge: Appium server crashing or disconnecting from the mobile device, resulting in test failures.
    Solution: Monitor the Appium server logs for errors, ensure the correct version of Appium is installed, and check that the correct dependencies are set. Also, check that the devices are properly connected, and network/firewall settings are configured correctly.

    5. Platform-Specific Challenges (iOS vs. Android):
    There are often differences in how mobile applications behave on iOS and Android platforms, which can lead to challenges in test automation.

    Challenge: Features or behaviors may differ between iOS and Android. For instance, gesture recognition and touch events are implemented differently on each platform.
    Android: UI Automator and other device-specific features.
    iOS: XCUITest and iOS-specific gestures, such as swiping or pull-to-refresh.
    Solution: Use platform-specific capabilities and logic to differentiate between Android and iOS during test execution, for example:

    if (driver instanceof IOSDriver) {
        // iOS-specific actions
    } else if (driver instanceof AndroidDriver) {
        // Android-specific actions
    }

    6. Managing Multiple Appium Sessions:
    Running multiple Appium sessions in parallel can be difficult, especially if you need to run tests on multiple devices or emulators simultaneously.

    Challenge: Setting up and managing multiple Appium sessions at once for parallel test execution can lead to resource management issues (e.g., managing multiple devices or simulators/emulators).
    Solution: Use a Grid (e.g., Appium Grid) or third-party tools like Sauce Labs or BrowserStack to manage and scale parallel testing.

    7. Handling Device-Specific Capabilities:
    Mobile devices require specific configurations (e.g., device name, platform version, app package name) to interact with Appium correctly.

    Challenge: Ensuring that the correct capabilities are set for each test device and that configurations are updated when there is a change in devices, OS versions, or the app itself.
    Solution: Automate the process of setting device capabilities or use configuration management tools to handle different environments.

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("deviceName", "Android Emulator");
    capabilities.setCapability("app", "path/to/app.apk");
    capabilities.setCapability("appPackage", "com.example.banking");
    capabilities.setCapability("appActivity", "com.example.banking.MainActivity");

    8. Handling App State (Background, Foreground):
    Mobile apps can run in the background or be interrupted (e.g., by a phone call), which can cause tests to fail.

    Challenge: Managing the app's state (background/foreground) during a test to ensure consistency.
    Solution: Use Appium’s built-in functions to handle app state transitions like sending the app to the background and bringing it back to the foreground.

    driver.runAppInBackground(Duration.ofSeconds(5)); // Send app to background for 5 seconds

    9. Handling App Permissions:
    Both iOS and Android apps may require permissions (e.g., camera, location, contacts) that need to be handled for automation to proceed smoothly.

    Challenge: Automating scenarios where the app requests permissions (e.g., asking for camera access, location, etc.), which can block the test execution.
    Solution: Use capabilities to handle permissions in advance or manage permissions through OS settings during tests.

    capabilities.setCapability("autoGrantPermissions", true);  // Automatically grant app permissions on Android

    10. Handling Push Notifications:
    Testing push notifications in mobile apps can be tricky as the push notification may interfere with test execution or appear during important interactions.

    Challenge: Receiving and validating push notifications during the test execution can be difficult because the notification could be sent at unexpected times.
    Solution: Use Appium's push notification capabilities to simulate and validate notifications, or configure your app to mock notifications for testing purposes.

    11. Gesture Handling:
    Appium allows simulating gestures like swipe, pinch, zoom, and tap, but they can behave differently on different devices or OS versions.

    Challenge: Some gestures may not work consistently across all devices, especially with different screen sizes or OS versions.
    Solution: Test gestures on multiple devices, and consider using Appium’s TouchAction API or MultiTouchAction for advanced gestures.

    12. Test Flakiness:
    Mobile automation tests can be flaky due to the variability of network conditions, device performance, and other external factors (e.g., battery level, device overheating).

    Challenge: Mobile tests can often fail intermittently due to external conditions or device state.
    Solution: Increase the stability of tests by using explicit waits, optimizing the Appium server configuration, and ensuring tests are not dependent on unstable conditions like network speed.

    13. Handling Real Devices vs. Emulators/Simulators:
    Real devices have different performance characteristics compared to emulators or simulators. Testing on real devices can expose hardware-specific issues that are not present on virtual devices.

    Challenge: Tests may pass on emulators but fail on real devices due to factors such as hardware configurations, OS variations, or network connectivity.
    Solution: Always test on real devices for critical use cases and use emulators for initial testing or faster execution.

    Q: What are the operation that TouchAction can perform?

    Ans:

    1. Mobile-Specific Actions:
    These functions are specific to mobile app testing and allow interactions with mobile devices in ways that Selenium doesn't provide (since Selenium only works with web browsers).

    a. tap():
    This function simulates a tap on the screen at a specific x and y coordinate. It's used to simulate user taps, which is essential for interacting with mobile UI elements.

    TouchAction action = new TouchAction(driver);
    action.tap(PointOption.point(100, 200)).perform();  // Tapping at specific coordinates

    b. swipe():
    Swipe actions are commonly used to simulate gestures like scrolling, dragging, or navigating through mobile UI.

    TouchAction action = new TouchAction(driver);
    action.press(PointOption.point(500, 1000))
           .waitAction(WaitOptions.waitOptions(Duration.ofMillis(1000)))
           .moveTo(PointOption.point(500, 500))
           .release()
           .perform();
       
    c. pinch() and zoom():
    These functions allow simulating pinch-to-zoom and zoom-in gestures on mobile devices, which is especially useful for apps that involve image galleries or maps.

    MultiTouchAction multiTouch = new MultiTouchAction(driver);

    TouchAction action1 = new TouchAction(driver).press(PointOption.point(100, 100)).moveTo(PointOption.point(200, 200)).release();
    TouchAction action2 = new TouchAction(driver).press(PointOption.point(300, 300)).moveTo(PointOption.point(400, 400)).release();

    multiTouch.add(action1).add(action2).perform();  // Zoom gesture

    d. longPress():
    Simulates a long press on a mobile element, useful for interacting with elements that require a long press gesture (e.g., context menus or drag-and-drop operations).

    TouchAction action = new TouchAction(driver);
    action.longPress(PointOption.point(200, 200)).release().perform();  // Long press at specific coordinates

    e. shake() (Appium-specific for mobile devices):
    Appium has a built-in capability to simulate shaking the mobile device, which can trigger certain app behaviors (like resetting the app or triggering a specific feature).

    driver.shake();  // Shake the device (only for mobile apps)

    2. Mobile-Specific Element Locators:
    Appium provides additional locator strategies designed to work with mobile elements, such as accessibility IDs, class names, and mobile-specific attributes.

    a. findElementByAccessibilityId():
    The accessibilityId is a mobile-specific locator used to find elements by their accessibility label. It's commonly used in both Android and iOS for identifying elements in a more user-friendly way.

    MobileElement element = driver.findElementByAccessibilityId("loginButton");

    b. findElementByClassName():
    In mobile apps, elements can be identified by their class name (which represents the class of the element in the app). This is more mobile-specific and might differ from the standard Selenium findElementByClassName().

    MobileElement element = driver.findElementByClassName("android.widget.Button");

    c. findElementById() for mobile:
    In Appium, findElementById() is similar to Selenium’s WebDriver, but it targets mobile-specific attributes or elements, such as buttons, text fields, etc., within native apps.

    MobileElement element = driver.findElementById("com.example.banking:id/transfer_button");

    3. Context Switching:
    Appium allows context switching between native and webview contexts, especially useful for hybrid apps. Selenium does not support this directly as it is focused on web apps.

    a. Switching Between Native and WebView Contexts:
    Appium provides a method to switch between native and webview contexts in hybrid apps, allowing you to interact with both native UI elements and web elements within the same app.

    // Get all context handles (native and webview)
    Set<String> contextHandles = driver.getContextHandles();

    // Switch to WebView context (usually represented as WEBVIEW_1, WEBVIEW_2, etc.)
    for (String context : contextHandles) {
        if (context.contains("WEBVIEW")) {
            driver.context(context);  // Switch to webview context
            break;
        }
    }

    // Switch back to Native context
    driver.context("NATIVE_APP");

    4. Device and App-Specific Capabilities:
    Appium allows you to define device-specific capabilities for Android and iOS, which are essential for mobile testing but are not part of Selenium since Selenium works with web browsers.

    a. Setting Device Capabilities for Appium:
    You can define specific capabilities like platform version, device name, app package, and more, which are required for mobile app automation but not for web automation in Selenium.

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("deviceName", "Android Emulator");
    capabilities.setCapability("app", "path/to/app.apk");
    capabilities.setCapability("appPackage", "com.example.banking");
    capabilities.setCapability("appActivity", "com.example.banking.MainActivity");

    b. Managing Device Interaction (e.g., Shake, Lock/Unlock, Set GeoLocation):
    Appium provides several mobile-specific methods for interacting with the device directly, such as shaking the device, setting geo-location, or locking/unlocking the device.

    driver.shake();  // Shake the device
    driver.lockDevice();  // Lock the device
    driver.unlockDevice();  // Unlock the device
    driver.setLocation(37.7749, -122.4194);  // Set GeoLocation (latitude, longitude)

    5. Appium-Specific API for Mobile Features:
    Appium exposes APIs that help with handling various mobile-specific features, including app state management, notifications, and touch gestures.

    a. Managing App State:
    You can launch, close, and reset the app programmatically using Appium-specific methods.

    driver.launchApp();  // Launch the app
    driver.closeApp();  // Close the app
    driver.resetApp();  // Reset the app to its initial state

    b. Handling Push Notifications:
    Appium also supports the ability to trigger and test push notifications on both Android and iOS devices, which is not a feature supported by Selenium.

    // Using Appium to test push notifications (requires setup)

    6. Handling Mobile-Specific Gestures:
    Appium provides more advanced gesture handling, such as swipe, pinch, zoom, and drag-and-drop, which are essential for mobile testing.

    a. dragAndDrop():
    You can use drag-and-drop functionality to interact with elements, similar to web tests in Selenium, but more specifically tailored for mobile use cases.

    MobileElement source = driver.findElement(By.id("source_id"));
    MobileElement target = driver.findElement(By.id("target_id"));

    TouchAction touchAction = new TouchAction(driver);
    touchAction.longPress(ElementOption.element(source))
               .moveTo(ElementOption.element(target))
               .release()
               .perform();  // Perform drag-and-drop on mobile

    Q: Real time scenarios which can be automated in Appium

    Below are example Appium automation scripts written in Java for each of the specified real-time scenarios using the TouchAction and MultiTouchAction classes.

    1. Swipe to Refresh

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.offset.PointOption;
    import io.appium.java_client.touch.WaitOptions;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.support.ui.WebDriverWait;

    import java.time.Duration;

    public class SwipeToRefresh {
        public static void swipeToRefresh(AndroidDriver<MobileElement> driver) {
            int startX = 500;
            int startY = 1000;
            int endY = 300;

            new TouchAction<>(driver)
                    .press(PointOption.point(startX, startY))
                    .waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)))
                    .moveTo(PointOption.point(startX, endY))
                    .release()
                    .perform();
        }
    }

    2. Drag and Drop

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.offset.ElementOption;
    import org.openqa.selenium.WebDriver;

    public class DragAndDrop {
        public static void dragAndDrop(AndroidDriver<MobileElement> driver, MobileElement sourceElement, MobileElement targetElement) {
            new TouchAction<>(driver)
                    .press(ElementOption.element(sourceElement))
                    .waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)))
                    .moveTo(ElementOption.element(targetElement))
                    .release()
                    .perform();
        }
    }

    3. Zoom In/Out (Pinch to Zoom)

    import io.appium.java_client.MultiTouchAction;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.offset.PointOption;
    import org.openqa.selenium.WebDriver;

    public class ZoomInOut {
        public static void pinchToZoom(AndroidDriver<MobileElement> driver
            int centerY = 1000;
            int offsetX = 200;
            int offsetY = 200;

            TouchAction<?> finger1 = new TouchAction<>(driver)
                    .press(PointOption.point(centerX - offsetX, centerY - offsetY))
                    .moveTo(PointOption.point(centerX, centerY))
                    .release();

            TouchAction<?> finger2 = new TouchAction<>(driver)
                    .press(PointOption.point(centerX + offsetX, centerY + offsetY))
                    .moveTo(PointOption.point(centerX, centerY))
                    .release();

            new MultiTouchAction(driver)
                    .add(finger1)
                    .add(finger2)
                    .perform();
        }
    }

    4. Tap and Hold

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.LongPressOptions;
    import org.openqa.selenium.WebDriver;

    import java.time.Duration;

    public class TapAndHold {
        public static void tapAndHold(AndroidDriver<MobileElement> driver, MobileElement element) {
            new TouchAction<>(driver)
                    .longPress(LongPressOptions.longPressOptions()
                            .withElement(ElementOption.element(element))
                            .withDuration(Duration.ofSeconds(3)))
                    .release()
                    .perform();
        }
    }

    5. Double Tap

    import io.appium.java_client.MobileElement;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.touch.TapOptions;
    import org.openqa.selenium.WebDriver;

    public class DoubleTap {
        public static void doubleTap(AndroidDriver<MobileElement> driver, MobileElement element) {
            new TouchAction<>(driver)
                    .tap(TapOptions.tapOptions().withElement(ElementOption.element(element)))
                    .perform()
                    .tap(TapOptions.tapOptions().withElement(ElementOption.element(element)))
                    .perform();
        }
    }

    Comments