Appium Mobile Testing
Mobile application testing skill using Appium for iOS and Android, covering device capabilities, selectors, gestures, and cross-platform testing strategies.
git clone --depth 1 https://github.com/PramodDutta/qaskills /tmp/appium-mobile-testing && cp -r /tmp/appium-mobile-testing/seed-skills/appium-mobile ~/.claude/skills/appium-mobile-testingSKILL.md
# Appium Mobile Testing Skill
You are an expert QA automation engineer specializing in mobile testing with Appium. When the user asks you to write, review, or debug Appium mobile tests, follow these detailed instructions.
## Core Principles
1. **Cross-platform design** -- Write tests that can run on both iOS and Android with minimal duplication.
2. **Accessibility-first selectors** -- Use accessibility IDs as the primary selector strategy.
3. **Explicit waits** -- Mobile apps have variable load times; always use explicit waits.
4. **Real device preference** -- Test on real devices when possible; emulators for development.
5. **App lifecycle management** -- Handle app install, launch, background, and foreground states.
## Project Structure (Java)
```
src/
main/java/com/example/
pages/
BasePage.java
LoginPage.java
HomePage.java
utils/
DriverFactory.java
GestureHelper.java
WaitHelper.java
CapabilityBuilder.java
config/
AppConfig.java
test/java/com/example/
tests/
BaseTest.java
LoginTest.java
HomeTest.java
data/
TestDataProvider.java
test/resources/
apps/
app-debug.apk
app-release.ipa
config/
android.properties
ios.properties
pom.xml
```
## Project Structure (TypeScript with WebdriverIO)
```
tests/
mobile/
specs/
login.spec.ts
home.spec.ts
pages/
base.page.ts
login.page.ts
home.page.ts
utils/
gestures.ts
helpers.ts
config/
wdio.android.conf.ts
wdio.ios.conf.ts
apps/
android/
app-debug.apk
ios/
app-release.ipa
package.json
```
## Desired Capabilities
### Android Capabilities
```java
UiAutomator2Options options = new UiAutomator2Options()
.setDeviceName("Pixel 6")
.setPlatformVersion("14")
.setApp(System.getProperty("user.dir") + "/apps/app-debug.apk")
.setAppPackage("com.example.myapp")
.setAppActivity("com.example.myapp.MainActivity")
.setAutomationName("UiAutomator2")
.setNoReset(false)
.setFullReset(false)
.setNewCommandTimeout(Duration.ofSeconds(300))
.setAutoGrantPermissions(true);
// For running on a real device
options.setUdid("emulator-5554");
// Performance options
options.setCapability("disableWindowAnimation", true);
options.setCapability("skipServerInstallation", false);
```
### iOS Capabilities
```java
XCUITestOptions options = new XCUITestOptions()
.setDeviceName("iPhone 15 Pro")
.setPlatformVersion("17.0")
.setApp(System.getProperty("user.dir") + "/apps/MyApp.ipa")
.setBundleId("com.example.myapp")
.setAutomationName("XCUITest")
.setNoReset(false)
.setAutoAcceptAlerts(true)
.setNewCommandTimeout(Duration.ofSeconds(300));
// For simulators
options.setCapability("useSimulator", true);
// For real devices
options.setUdid("device-udid-here");
options.setCapability("xcodeOrgId", "YOUR_TEAM_ID");
options.setCapability("xcodeSigningId", "iPhone Developer");
```
### WebdriverIO Configuration (TypeScript)
```typescript
// wdio.android.conf.ts
export const config: WebdriverIO.Config = {
runner: 'local',
port: 4723,
specs: ['./tests/mobile/specs/**/*.spec.ts'],
capabilities: [{
platformName: 'Android',
'appium:deviceName': 'Pixel 6',
'appium:platformVersion': '14',
'appium:app': './apps/android/app-debug.apk',
'appium:automationName': 'UiAutomator2',
'appium:noReset': false,
'appium:autoGrantPermissions': true,
}],
framework: 'mocha',
mochaOpts: {
timeout: 60000,
},
services: ['appium'],
};
```
## Page Object Model
### Base Page (Java)
```java
package com.example.pages;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public abstract class BasePage {
protected AppiumDriver driver;
protected WebDriverWait wait;
public BasePage(AppiumDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(15));
PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(10)), this);
}
protected WebElement waitForElement(String accessibilityId) {
return wait.until(ExpectedConditions.visibilityOfElementLocated(
AppiumBy.accessibilityId(accessibilityId)
));
}
protected void tap(String accessibilityId) {
waitForElement(accessibilityId).click();
}
protected void type(String accessibilityId, String text) {
WebElement element = waitForElement(accessibilityId);
element.clear();
element.sendKeys(text);
}
protected String getText(String accessibilityId) {
return waitForElement(accessibilityId).getText();
}
protected boolean isDisplayed(String accessibilityId) {
try {
return waitForElement(accessibilityId).isDisplayed();
} catch (Exception e) {
return false;
}
}
protected void hideKeyboard() {
try {
driver.hideKeyboard();
} catch (Exception ignored) {
// Keyboard not visible
}
}
}
```
### Login Page (Java)
```java
package com.example.pages;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.pagefactory.AndroidFindBy;
import io.appium.java_client.pagefactory.iOSXCUITFindBy;
import org.openqa.selenium.WebElement;
public class LoginPage extends BasePage {
@AndroidFindBy(accessibility = "email-input")
@iOSXCUITFindBy(accessibility = "email-input")
private WebElement emailInput;
@AndroidFindBy(accessibility = "password-input")
@iOSXCUITFindAutomated accessibility testing with axe-core integrated into CI pipelines, including custom rule configuration, issue prioritization, and remediation guidance.
Validating A/B test implementations including traffic splitting accuracy, statistical significance calculation, metric tracking, and experiment cleanup.
Comprehensive WCAG compliance and accessibility testing covering ARIA, keyboard navigation, screen readers, color contrast, and automated a11y validation.
Comprehensive WCAG 2.1 AA compliance testing combining automated axe-core scans with manual keyboard navigation, screen reader compatibility, and focus management verification
American Fuzzy Lop Plus Plus mutation-based fuzz testing for finding crashes, hangs, and security vulnerabilities in binary programs.
Fast Rust-based headless browser automation CLI with Node.js fallback for AI agents, featuring navigation, clicking, typing, snapshots, and structured commands optimized for agent workflows.
AI-first testing methodology where autonomous agents plan, generate, execute, and maintain test suites with minimal human intervention, covering agent orchestration, feedback loops, and intelligent test prioritization.
Comprehensive evaluation patterns for AI agents including multi-turn conversation testing, LLM-as-judge frameworks, benchmark suites, regression detection, and systematic eval pipelines for measuring agent quality and safety.