Skip to main content

Mobile Testing

Ellithium provides robust support for mobile testing on Android and iOS platforms through its Appium integration.

Shared Interaction Classes

Ellithium provides a unified interaction API that works for both web and mobile testing. Most interaction classes are accessed through the DriverActions class:

For a complete overview of all interactions, see the Interactions Overview page.

These classes can be accessed through the DriverActions class:

// Initialize DriverActions with mobile driver
DriverActions actions = new DriverActions(driver);

// Use the same element interaction API for mobile
actions.elements().clickOnElement(By.id("login_button"));
actions.elements().sendData(By.id("username_field"), "testuser");
actions.elements().waitForElementToBeVisible(By.id("progress_indicator"));

// Mobile-specific key operations
actions.keyPress().pressKey(new KeyEvent(AndroidKey.BACK));

Additionally, Ellithium provides:

// Screen Recorder needs to be instantiated directly
ScreenRecorderActions screenRecorderActions = new ScreenRecorderActions<>(driver);

Setting Up Mobile Testing

Prerequisites

  • Appium Server (2.0 or higher)
  • Android SDK for Android testing
  • Xcode for iOS testing
  • Real devices or emulators/simulators

Android Testing

Creating Android Driver

// Basic Android driver setup
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Pixel 6");
capabilities.setCapability(MobileCapabilityType.APP, "/path/to/app.apk");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");

AndroidDriver driver = DriverFactory.getNewMobileDriver(
MobileDriverType.Android,
new URL("http://localhost:4723"),
capabilities
);

Advanced Android Configuration

// Extended capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "12");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Pixel 6");
capabilities.setCapability(MobileCapabilityType.APP, "/path/to/app.apk");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60);
capabilities.setCapability("appPackage", "com.example.app");
capabilities.setCapability("appActivity", "com.example.app.MainActivity");
capabilities.setCapability("noReset", false);
capabilities.setCapability("fullReset", true);

AndroidDriver driver = DriverFactory.getNewMobileDriver(
MobileDriverType.Android,
new URL("http://localhost:4723"),
capabilities
);

iOS Testing

Creating iOS Driver

// Basic iOS driver setup
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 13");
capabilities.setCapability(MobileCapabilityType.APP, "/path/to/app.ipa");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");

IOSDriver driver = DriverFactory.getNewMobileDriver(
MobileDriverType.IOS,
new URL("http://localhost:4723"),
capabilities
);

Advanced iOS Configuration

// Extended capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "15.0");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 13");
capabilities.setCapability(MobileCapabilityType.UDID, "auto");
capabilities.setCapability(MobileCapabilityType.APP, "/path/to/app.ipa");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");
capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60);
capabilities.setCapability("bundleId", "com.example.app");
capabilities.setCapability("noReset", false);
capabilities.setCapability("fullReset", true);
capabilities.setCapability("wdaLocalPort", 8100);

IOSDriver driver = DriverFactory.getNewMobileDriver(
MobileDriverType.IOS,
new URL("http://localhost:4723"),
capabilities
);

Mobile Element Interactions

Ellithium's DriverActions provides a unified API for mobile element interactions, making it easy to work with both Android and iOS:

// Initialize DriverActions with mobile driver
DriverActions actions = new DriverActions(driver);

// Basic interactions (work for both Android and iOS)
actions.elements().clickOnElement(By.id("login_button"));
actions.elements().sendData(By.id("username_field"), "testuser");
actions.elements().waitForElementToBeVisible(By.id("progress_indicator"));

// Mobile-specific key press operations for Android
actions.keyPress().pressKey(new KeyEvent(AndroidKey.BACK));
actions.keyPress().longPressKey(new KeyEvent(AndroidKey.HOME), 1000);
actions.keyPress().longPressAndroidKey(AndroidKey.VOLUME_UP, 500);

Mobile-Specific Locator Strategies

// Android locators
By androidElement = By.xpath("//android.widget.Button[@text='Login']");
By androidResourceId = By.id("com.example.app:id/login_button");
By androidContentDesc = By.AndroidUIAutomator("new UiSelector().description(\"Login\")");

// iOS locators
By iosElement = By.xpath("//XCUIElementTypeButton[@name='Login']");
By iosAccessibilityId = By.AccessibilityId("login_button");
By iosPredicate = By.iOSNsPredicateString("name == 'Login'");
By iosClassChain = By.iOSClassChain("**/XCUIElementTypeButton[`name == 'Login'`]");

Context Switching (Native/Web/Hybrid)

// Get available contexts
Set<String> contexts = driver.getContextHandles();

// Switch to WEBVIEW context
driver.context("WEBVIEW_com.example.app");

// Perform web operations
actions.elements().clickOnElement(By.cssSelector("button.login"));

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

Mobile Device Commands

// App management
driver.terminateApp("com.example.app");
driver.activateApp("com.example.app");
driver.removeApp("com.example.app");
driver.isAppInstalled("com.example.app");

// Device operations
driver.rotate(ScreenOrientation.LANDSCAPE);
driver.lockDevice(Duration.ofSeconds(5));
driver.unlockDevice();
driver.hideKeyboard();

// Android-specific
((AndroidDriver) driver).pressKey(new KeyEvent(AndroidKey.BACK));
((AndroidDriver) driver).openNotifications();

// iOS-specific
((IOSDriver) driver).shake();

Page Object Pattern for Mobile

public class LoginPage {
private final DriverActions actions;

// Locators
private final By usernameField = By.id("username_field");
private final By passwordField = By.id("password_field");
private final By loginButton = By.id("login_button");
private final By errorMessage = By.id("error_message");

public LoginPage(AppiumDriver driver) {
this.actions = new DriverActions(driver);
}

public void enterUsername(String username) {
actions.elements().sendData(usernameField, username);
}

public void enterPassword(String password) {
actions.elements().sendData(passwordField, password);
}

public void clickLogin() {
actions.elements().clickOnElement(loginButton);
}

public void login(String username, String password) {
enterUsername(username);
enterPassword(password);
clickLogin();
}

public boolean isErrorDisplayed() {
return actions.elements().isElementDisplayed(errorMessage);
}
}

Screen Recording

Ellithium's Screen Recorder Actions are particularly useful for mobile testing to document test failures. Unlike other interaction classes, ScreenRecorderActions needs to be instantiated directly:

// Create a screen recorder instance
ScreenRecorderActions screenRecorderActions = new ScreenRecorderActions<>(driver);

// Start recording before a complex operation
screenRecorderActions.startRecording("CheckoutProcess");

// Perform test steps
// ...

// Stop recording
screenRecorderActions.stopRecording();