How to connect IOS Device in Appium

  

To connect an iOS device with Appium for mobile automation testing, you need to set up your environment properly. Here's a step-by-step explanation:


System Requirements

RequirementDetails
OSmacOS (Appium for iOS requires Xcode)
iOS DeviceReal device with Developer Mode enabled
XcodeInstalled from Mac App Store
AppiumInstall via NPM or App
Node.jsRequired for Appium
CarthageRequired for WebDriverAgent
USB CableTo connect your iOS device
Apple Developer IDFor signing WebDriverAgent




Step-by-Step Setup

1. Install Prerequisites

Open Terminal and install the following:

brew install carthage
npm install -g appium
npm install -g ios-deploy



2. Enable Developer Mode on iPhone

  • Plug in the iPhone.

  • On the phone, tap Trust this computer.

  • Open Xcode > Devices and Simulators and ensure your device appears.



3. Create and Build WebDriverAgent

WebDriverAgent (WDA) is used by Appium to interact with iOS.

  • Clone WebDriverAgent or use Appium’s default one located at:

/usr/local/lib/node_modules/appium/node_modules/appium-webdriveragent
     
  • Open WebDriverAgent.xcodeproj in Xcode.
  • Set Development Team under Signing & Capabilities for both:

    • WebDriverAgentLib

    • WebDriverAgentRunner

  • Select your device as the build target.

  • Build the project using Xcode (⌘ + B).




4. Start Appium Server

Use terminal or Appium Desktop to start the server:

appium

You can also start it with custom settings:


appium --port 4723





5. Desired Capabilities (Sample)


{
  "platformName": "iOS",
  "platformVersion": "16.0",
  "deviceName": "iPhone 13",
  "udid": "<your_device_udid>",
  "automationName": "XCUITest",
  "bundleId": "com.apple.Preferences",  // or your app's bundle id
  "xcodeOrgId": "<your_team_id>",
  "xcodeSigningId": "iPhone Developer",
  "updatedWDABundleId": "com.yourcompany.WebDriverAgentRunner"
}




To get UDID, use:

idevice_id -l





Step 6: Java Code to Connect iOS Device in Appium


import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.IOSMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.URL;

public class IOSAppiumTest {
    public static void main(String[] args) {
        try {
            DesiredCapabilities caps = new DesiredCapabilities();

            caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
            caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "16.0"); // your iOS version
            caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 13"); // or "iPhone"
            caps.setCapability(MobileCapabilityType.UDID, "your_device_udid_here");
            caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");
            caps.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.apple.Preferences"); // Open Settings app
            caps.setCapability("xcodeOrgId", "YOUR_TEAM_ID_HERE"); // from Apple Developer account
            caps.setCapability("xcodeSigningId", "iPhone Developer");
            caps.setCapability("updatedWDABundleId", "com.yourcompany.WebDriverAgentRunner");

            // Start Appium session
            IOSDriver driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps);

            // Example: Interact with the Settings app
            System.out.println("App launched on iOS device successfully!");

            // Always quit the driver after test
            driver.quit();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}






Maven Depenencies:


<dependencies>
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>8.5.1</version>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.12.0</version>
    </dependency>
</dependencies>

How to connect Android Device in Appium

 

To connect an Android device in Appium, follow these steps. This setup will allow Appium to communicate with the device for automated testing.


Prerequisites

  • Install Java JDK
  • Install Android Studio or SDK Tools
  • Install Node.js
  • Install Appium Server
  • Install Appium Inspector (optional for inspecting elements)
  • Enable Developer Options and USB Debugging on your Android device
  • USB Cable or Wi-Fi ADB connection



Step-by-Step: Connect Android Device to Appium


Step 1: Enable Developer Mode on Android

  • Go to Settings > About Phone
  • Tap Build Number 7 times to enable Developer Options
  • Go to Settings > Developer Options
  • Enable USB Debugging


Step 2: Connect Device via USB

  • Use a USB cable to connect your phone to your PC.

  • Allow the USB debugging prompt on your device.



Step 3: Verify Device Connection with ADB

Open Command Prompt (Windows) or Terminal (Mac/Linux) and run:

adb devices



You should see your device listed:

List of devices attached
emulator-5554   device

If unauthorized, replug the device and allow debugging access.



Step 4: Start Appium Server

You can use either of the two:

  • Appium Desktop App → Click Start Server

  • Command Line:

appium


Ensure it’s running on:

http://127.0.0.1:4723/



Step 5: Desired Capabilities to Connect Device

Below is a sample configuration for your test script or Appium Inspector:

{
  "platformName": "Android",
  "deviceName": "Android Device",
  "automationName": "UiAutomator2",
  "udid": "your_device_udid",
  "appPackage": "com.example.app",
  "appActivity": "com.example.app.MainActivity"
}



Use adb devices to get udid
Use adb shell pm list packages to find appPackage
Use adb shell dumpsys window windows | grep -E 'mCurrentFocus' for appActivity




Step 6: Run Your Test

You can now run your Appium test using Java, Python, or any supported language binding. For example, in Java:



DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("deviceName", "Android Device");
caps.setCapability("automationName", "UiAutomator2");
caps.setCapability("appPackage", "com.example.app");
caps.setCapability("appActivity", "com.example.app.MainActivity");

AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps);





Check if something is not working:

Always check if your device is listed with adb devices
Ensure the Appium version supports your Android version
Restart adb server using:

adb kill-server
adb start-server


How to Install Appium

 

To install and set up Appium in Eclipse, follow these steps carefully. This includes setting up all dependencies like Java, Android SDK, Appium server, Node.js, and Eclipse with Maven or TestNG support.



Step-by-Step Guide to Set Up Appium in Eclipse

1. Install Java (JDK)




JAVA_HOME = C:\Program Files\Java\jdk-<version>
Path => Add: %JAVA_HOME%\bin




2. Install Node.js

Appium is built on Node.js.
After installation, verify:


node -v
npm -v



3. Install Appium Server

  • Open Command Prompt and run:

npm install -g appium



Verify:

appium -v


Or, install Appium Desktop GUI version:




4. Install Eclipse IDE


5. Create a Maven Project in Eclipse

  • File > New > Project > Maven Project

  • Use archetype: maven-archetype-quickstart





Add Appium & Selenium Dependencies


<dependencies>
    <!-- Selenium -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.20.0</version>
    </dependency>

    <!-- Appium Java Client -->
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>9.0.0</version>
    </dependency>

    <!-- TestNG (Optional) -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.9.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>




6. Start Appium Server

  • Option 1: Use Appium Desktop GUI > Start Server

  • Option 2: Use CLI:


appium






Sample Appium Test in Eclipse

Sample Code to Launch Calculator in Android Emulator:



import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.URL;

public class AppiumTest {
    public static void main(String[] args) throws Exception {
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.0");  // your emulator/device version
        caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
        caps.setCapability("appPackage", "com.android.calculator2");
        caps.setCapability("appActivity", "com.android.calculator2.Calculator");

        AndroidDriver driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), caps);
        Thread.sleep(5000);
        driver.quit();
    }
}





Things to remember:
  • Emulator is running OR real device is connected with USB debugging ON

  • Appium server is running

  • Environment variables are correctly set

Locators in Appium

 


In Appium, we can use several locators to identify mobile elements in Android or iOS apps. These locators are similar to those in Selenium but are designed for mobile-specific contexts.



Common Appium Locators:

  • By.id – Resource-id of the element
  • By.className – UI class of the element
  • By.name (deprecated in latest versions) – Content-desc (for accessibility)
  • By.xpath – XPath expression
  • By.accessibilityId – Accessibility ID (Content-desc in Android)
  • By.androidUIAutomator – For Android-specific UI selectors
  • By.iOSNsPredicateString – For iOS-specific predicates
  • By.iOSClassChain – For iOS class chains



Calculator App Example (Android) in Java

Below is a sample Appium test script in Java using Eclipse IDE to automate basic addition (example: 2 + 3 = 5) in the Android calculator app.



Pre-requisites:

  • Appium server is running

  • Android Emulator/Device is connected

  • Appium Java Client added to the project (pom.xml if using Maven or .jar added manually)





Java Code (in Eclipse)


import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.concurrent.TimeUnit;

public class CalculatorTest {
    public static void main(String[] args) throws MalformedURLException {
        DesiredCapabilities caps = new DesiredCapabilities();
        
        // Device details
        caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11"); // change as per your device
        caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
        
        // App details (default Android calculator)
        caps.setCapability("appPackage", "com.android.calculator2");
        caps.setCapability("appActivity", "com.android.calculator2.Calculator");

        // No reset
        caps.setCapability("noReset", true);
        
        // Initialize driver
        AndroidDriver<MobileElement> driver = new AndroidDriver<>(
            new URL("http://127.0.0.1:4723/wd/hub"), caps);

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        // Locating buttons by ID
        driver.findElementById("com.android.calculator2:id/digit_2").click();
        driver.findElementByAccessibilityId("plus").click(); // or driver.findElementById("com.android.calculator2:id/op_add")
        driver.findElementById("com.android.calculator2:id/digit_3").click();
        driver.findElementById("com.android.calculator2:id/eq").click();

        // Get result
        MobileElement result = driver.findElementById("com.android.calculator2:id/result");
        System.out.println("Result of 2 + 3 = " + result.getText());

        driver.quit();
    }
}



Maven Dependency:


<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>8.5.1</version> <!-- use latest -->
</dependency>

Appium Architecture

 

The diagram you provided illustrates the Appium Architecture, which is based on a client-server model. Let's break it down step by step:









Appium Architecture


Components of the Appium Architecture:


1. Webdriver Script (Client)

  • This is your test script, written in any supported programming language (like Java, Python, JavaScript, etc.).

  • It sends commands to the Appium Server using the WebDriver protocol (also called JSON Wire Protocol or W3C WebDriver).


2. Appium Server

  • It acts as a HTTP server written in Node.js.

  • Receives the commands from the test script (client).

  • Parses these commands and sends them to the respective native automation frameworks (like UIAutomator2, XCUITest, etc.).

  • Acts as a bridge between the client (script) and the mobile device.



3. Mobile Device

  • The actual Android or iOS device where the app is installed and tested.

  • Executes the commands sent via the native automation framework.


Communication Flow:

  1. Test Script to Appium Server

    • The WebDriver test script sends requests (example: click, tap, send keys) to the Appium Server using WebDriver Wire Protocol over HTTP.



  • Appium Server to Mobile Device
    • Appium translates these commands into actions using the Native Automation Framework:

      • For Android: UIAutomator2 or Espresso

      • For iOS: XCUITest

    • The framework interacts directly with the app installed on the mobile device.



  • Execution Results Back
    • The response from the mobile device (e.g., element clicked, text entered) goes back through the same path in reverse:

      • Native framework → Appium Server → WebDriver Script



At a Glance:



ComponentRole
Webdriver ScriptSends test commands using WebDriver protocol
Appium ServerActs as a middleware to translate commands to native automation code
Mobile DeviceExecutes the commands and returns results


Appium Overview

  

What is Appium?

Appium is an open-source automation testing framework used for testing mobile applications. It allows QA engineers and developers to automate tests for:

  • Native apps (built using iOS, Android SDKs),

  • Hybrid apps (web + native),

  • Mobile web apps (accessed via mobile browsers like Chrome, Safari).

Appium supports AndroidiOS, and Windows platforms and works across real devicesemulators, and simulators.


Key Features of Appium:


FeatureDescription
Cross-platformWrite once, test on Android & iOS both using the same test script.
Language-agnosticSupports multiple languages like Java, Python, JavaScript, Ruby, C#, etc.
No app modification requiredTests apps without modifying or recompiling the source code.
Uses WebDriver protocolFollows the W3C WebDriver protocol (same as Selenium).
Supports parallel executionCan run tests simultaneously on multiple devices.
Integrates with CI/CD toolsWorks with Jenkins, GitLab CI, Bamboo, etc.


Architecture of Appium:

  • Appium Client: Test code written in your preferred language using Appium libraries.
  • Appium Server: Node.js-based server that receives client requests, processes them, and interacts with the mobile device.
  • Automation Engine:
    • For Android: Uses UIAutomator2Espresso, or Selendroid.

    • For iOS: Uses XCUITest.


Workflow:

  • Test script sends commands to Appium server.
  • Server translates them into platform-specific actions.
  • The automation engine interacts with the app under test via the mobile OS.
  • Responses are sent back to the client.

Types of Apps Supported:


App TypeExamples
NativeBuilt with Android (Java/Kotlin), iOS (Swift/Obj-C) SDKs
HybridBuilt using frameworks like Ionic, React Native
Mobile WebAccessed via mobile browsers (e.g., Chrome, Safari)


Why Use Appium?

  • Free and open-source.

  • Doesn’t require access to app source code.

  • Works on Windows, macOS, Linux.

  • Actively maintained and widely supported.

How to Share data between Steps in Cucumber using Scenario Context

  

In CucumberScenario Context is a way to share data between step definitions during the execution of a single scenario. Since each scenario is stateless and Cucumber creates a new instance of step definition classes for each scenario, sharing data between steps requires an intermediate storage — Scenario Context.


Why use Scenario Context?

  • To avoid using static variables (which breaks parallel execution).

  • To maintain clean separation of concerns in step definitions.

  • To store and retrieve test data like user credentials, page titles, order IDs, etc.


Implementation Steps

We will:

  • Create an enum for keys (Context).
  • Create a ScenarioContext class to hold data.
  • Inject and use ScenarioContext in step definition classes.



1. Context.java — Enum for keys

package utils;

public enum Context {
    USER_NAME,
    PRODUCT_NAME,
    ORDER_ID
}




2. ScenarioContext.java — Storage class

package utils;

import java.util.HashMap;
import java.util.Map;

public class ScenarioContext {

    private final Map<String, Object> dataMap = new HashMap<>();

    public void setContext(Context key, Object value) {
        dataMap.put(key.toString(), value);
    }

    public Object getContext(Context key) {
        return dataMap.get(key.toString());
    }

    public Boolean contains(Context key) {
        return dataMap.containsKey(key.toString());
    }
}




3. TestContext.java — Shared container (optional but recommended for larger projects)

package utils;

public class TestContext {

    private final ScenarioContext scenarioContext;

    public TestContext() {
        scenarioContext = new ScenarioContext();
    }

    public ScenarioContext getScenarioContext() {
        return scenarioContext;
    }
}




4. Step Definition Example — Using Scenario Context

package stepDefinitions;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import utils.Context;
import utils.TestContext;

public class UserSteps {

    TestContext testContext;

    public UserSteps(TestContext context) {
        this.testContext = context;
    }

    @Given("User logs in with username {string}")
    public void user_logs_in_with_username(String username) {
        System.out.println("User logged in: " + username);
        testContext.getScenarioContext().setContext(Context.USER_NAME, username);
    }

    @Then("User name should be displayed on dashboard")
    public void user_name_should_be_displayed_on_dashboard() {
        String actualUsername = (String) testContext.getScenarioContext().getContext(Context.USER_NAME);
        System.out.println("Username on dashboard: " + actualUsername);
        // Add assertions here
    }
}




5. Cucumber Runner Setup

Ensure you pass the same TestContext object to all step definition classes.

If you are using Dependency Injection (like PicoContainer or Spring), Cucumber will manage the object sharing automatically.

package stepDefinitions;

import utils.TestContext;

public class Hooks {

    public Hooks(TestContext testContext) {
        // You can use this to perform Before/After actions using shared context
    }
}




Sample Feature File

Feature: Scenario Context Demo

  Scenario: Store and use data between steps
    Given User logs in with username "Himanshu"
    Then User name should be displayed on dashboard



Output

User logged in: Himanshu
Username on dashboard: Himanshu