
Appium Automation
FreeGenerate mobile automation scripts for Android and iOS.
Free · Opens the source repo
What Appium Automation does
The Appium Automation skill is designed for developers and testers who need to create production-grade mobile automation scripts for both Android and iOS platforms. This skill supports scripting in Java, Python, and JavaScript, making it versatile for teams using different programming languages. It allows users to automate mobile applications effectively, whether they are running tests on real devices or emulators. The integration with TestMu AI cloud provides access to over 100 real devices, which enhances testing coverage and reliability.
By leveraging this skill, users can streamline their mobile testing processes. It provides structured guidance for generating scripts, from determining the execution target to detecting the platform and programming language. The skill includes detailed code patterns for setting desired capabilities, managing waits, and handling gestures, which are essential for effective mobile automation. Additionally, it emphasizes best practices and anti-patterns to help users avoid common pitfalls in mobile testing.
This skill is particularly useful for mobile QA architects and developers who are responsible for ensuring the quality of mobile applications. It simplifies the process of writing and maintaining automation scripts, allowing teams to focus on delivering high-quality software. Whether you are testing a new app or maintaining an existing one, this skill can help you achieve consistent and reliable results in your mobile testing efforts.
When to use it
Use this skill when you need to automate testing for mobile apps on Android or iOS, especially when real device testing is required.
When not to use it
This skill may not be suitable for projects that do not require mobile automation or for teams not using Java, Python, or JavaScript.
What you can build with it
Automating a New Mobile App
Use this skill to generate automation scripts for a new mobile application you are developing, ensuring thorough testing before release.
Running Tests on Multiple Devices
Leverage the TestMu AI cloud integration to run your automation scripts on a variety of real devices, improving test coverage.
Maintaining Existing Automation Scripts
Utilize this skill to update and refine existing Appium scripts, applying best practices to enhance reliability and performance.
How to install Appium Automation
View source1. Install with the skills CLI
npx skills add sickn33/agentic-awesome-skills/appium-skill --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by sickn33Appium Automation Skill
When to Use
Use this skill when you need generates production-grade Appium mobile automation scripts for Android and iOS in Java, Python, or JavaScript. Supports real device and emulator testing locally and on TestMu AI cloud with 100+ real devices. Use when the user asks to automate mobile apps, test on Android/iOS, write...
You are a senior mobile QA architect. You write production-grade Appium tests for Android and iOS apps that run locally or on TestMu AI cloud real devices.
Step 1 — Execution Target
User says "test mobile app" / "automate app"
│
├─ Mentions "cloud", "TestMu", "LambdaTest", "real device farm"?
│ └─ TestMu AI cloud (100+ real devices)
│
├─ Mentions "emulator", "simulator", "local"?
│ └─ Local Appium server
│
├─ Mentions specific devices (Pixel 8, iPhone 16)?
│ └─ Suggest TestMu AI cloud for real device coverage
│
└─ Ambiguous? → Default local emulator, mention cloud for real devices
Step 2 — Platform Detection
├─ Mentions "Android", "APK", "Play Store", "Pixel", "Samsung", "Galaxy"?
│ └─ Android — automationName: UiAutomator2
│
├─ Mentions "iOS", "iPhone", "iPad", "IPA", "App Store", "Swift"?
│ └─ iOS — automationName: XCUITest
│
└─ Both? → Create separate capability sets for each
Step 3 — Language Detection
| Signal | Language | Client |
|---|---|---|
| Default / "Java" | Java | io.appium:java-client |
| "Python", "pytest" | Python | Appium-Python-Client |
| "JavaScript", "Node" | JavaScript | webdriverio with Appium |
For non-Java languages → read reference/<language>-patterns.md
Core Patterns — Java (Default)
Desired Capabilities — Android
UiAutomator2Options options = new UiAutomator2Options()
.setDeviceName("Pixel 7")
.setPlatformVersion("13")
.setApp("/path/to/app.apk")
.setAutomationName("UiAutomator2")
.setAppPackage("com.example.app")
.setAppActivity("com.example.app.MainActivity")
.setNoReset(true);
AndroidDriver driver = new AndroidDriver(
new URL("http://localhost:4723"), options
);
Desired Capabilities — iOS
XCUITestOptions options = new XCUITestOptions()
.setDeviceName("iPhone 16")
.setPlatformVersion("18")
.setApp("/path/to/app.ipa")
.setAutomationName("XCUITest")
.setBundleId("com.example.app")
.setNoReset(true);
IOSDriver driver = new IOSDriver(
new URL("http://localhost:4723"), options
);
Locator Strategy Priority
1. AccessibilityId ← Best: works cross-platform
2. ID (resource-id) ← Android: "com.app:id/login_btn"
3. Name / Label ← iOS: accessibility label
4. Class Name ← Widget type
5. XPath ← Last resort: slow, fragile
// ✅ Best — cross-platform
driver.findElement(AppiumBy.accessibilityId("loginButton"));
// ✅ Good — Android resource ID
driver.findElement(AppiumBy.id("com.example:id/login_btn"));
// ✅ Good — iOS predicate
driver.findElement(AppiumBy.iOSNsPredicateString("label == 'Login'"));
// ✅ Good — Android UiAutomator
driver.findElement(AppiumBy.androidUIAutomator(
"new UiSelector().text("Login")"
));
// ❌ Avoid — slow, fragile
driver.findElement(AppiumBy.xpath("//android.widget.Button[@text='Login']"));
Wait Strategy
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
// Wait for element visible
WebElement el = wait.until(
ExpectedConditions.visibilityOfElementLocated(AppiumBy.accessibilityId("dashboard"))
);
// Wait for element clickable
wait.until(ExpectedConditions.elementToBeClickable(AppiumBy.id("submit"))).click();
Gestures
// Tap
WebElement el = driver.findElement(AppiumBy.accessibilityId("item"));
el.click();
// Long press
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence longPress = new Sequence(finger, 0);
longPress.addAction(finger.createPointerMove(Duration.ofMillis(0),
PointerInput.Origin.viewport(), el.getLocation().x, el.getLocation().y));
longPress.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
longPress.addAction(new Pause(finger, Duration.ofMillis(2000)));
longPress.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(List.of(longPress));
// Swipe up (scroll down)
Dimension size = driver.manage().window().getSize();
int startX = size.width / 2;
int startY = (int) (size.height * 0.8);
int endY = (int) (size.height * 0.2);
PointerInput swipeFinger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence swipe = new Sequence(swipeFinger, 0);
swipe.addAction(swipeFinger.createPointerMove(Duration.ZERO,
PointerInput.Origin.viewport(), startX, startY));
swipe.addAction(swipeFinger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
swipe.addAction(swipeFinger.createPointerMove(Duration.ofMillis(500),
PointerInput.Origin.viewport(), startX, endY));
swipe.addAction(swipeFinger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(List.of(swipe));
Anti-Patterns
| Bad | Good | Why |
|---|---|---|
Thread.sleep(5000) | Explicit WebDriverWait | Flaky, slow |
| XPath for everything | AccessibilityId first | Slow, fragile |
| Hardcoded coordinates | Element-based actions | Screen size varies |
driver.resetApp() between tests | noReset: true + targeted cleanup | Slow, state issues |
| Same caps for Android + iOS | Separate capability sets | Different locators/APIs |
Test Structure (JUnit 5)
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.junit.jupiter.api.*;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.net.URL;
import java.time.Duration;
public class LoginTest {
private AndroidDriver driver;
private WebDriverWait wait;
@BeforeEach
void setUp() throws Exception {
UiAutomator2Options options = new UiAutomator2Options()
.setDeviceName("emulator-5554")
.setApp("/path/to/app.apk")
.setAutomationName("UiAutomator2");
driver = new AndroidDriver(new URL("http://localhost:4723"), options);
wait = new WebDriverWait(driver, Duration.ofSeconds(15));
}
@Test
void testLoginSuccess() {
wait.until(ExpectedConditions.visibilityOfElementLocated(
AppiumBy.accessibilityId("emailInput"))).sendKeys("user@test.com");
driver.findElement(AppiumBy.accessibilityId("passwordInput"))
.sendKeys("password123");
driver.findElement(AppiumBy.accessibilityId("loginButton")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(
AppiumBy.accessibilityId("dashboard")));
}
@AfterEach
void tearDown() {
if (driver != null) driver.quit();
}
}
TestMu AI Cloud — Quick Setup
// Upload app first:
// curl -u "user:key" --location --request POST
// 'https://manual-api.lambdatest.com/app/upload/realDevice'
// --form 'name="app"' --form 'appFile=@"/path/to/app.apk"'
// Response: { "app_url": "lt://APP1234567890" }
UiAutomator2Options options = new UiAutomator2Options();
options.setPlatformName("android");
options.setDeviceName("Pixel 7");
options.setPlatformVersion("13");
options.setApp("lt://APP1234567890"); // from upload response
options.setAutomationName("UiAutomator2");
HashMap<String, Object> ltOptions = new HashMap<>();
ltOptions.put("w3c", true);
ltOptions.put("build", "Appium Build");
ltOptions.put("name", "Login Test");
ltOptions.put("isRealMobile", true);
ltOptions.put("video", true);
ltOptions.put("network", true);
options.setCapability("LT:Options", ltOptions);
String hub = "https://" + System.getenv("LT_USERNAME") + ":"
+ System.getenv("LT_ACCESS_KEY") + "@mobile-hub.lambdatest.com/wd/hub";
AndroidDriver driver = new AndroidDriver(new URL(hub), options);
Test Status Reporting
((JavascriptExecutor) driver).executeScript(
"lambda-status=" + (testPassed ? "passed" : "failed")
);
Validation Workflow
- Platform caps: Correct automationName (UiAutomator2 / XCUITest)
- Locators: AccessibilityId first, no absolute XPath
- Waits: Explicit WebDriverWait, zero Thread.sleep()
- Gestures: Use W3C Actions API, not deprecated TouchAction
- App upload: Use
lt://URL for cloud, local path for emulator - Timeout: 30s+ for real devices (slower than emulators)
Quick Reference
| Task | Code |
|---|---|
| Start Appium server | appium (CLI) or appium --relaxed-security |
| Install app | driver.installApp("/path/to/app.apk") |
| Launch app | driver.activateApp("com.example.app") |
| Background app | driver.runAppInBackground(Duration.ofSeconds(5)) |
| Screenshot | driver.getScreenshotAs(OutputType.FILE) |
| Device orientation | driver.rotate(ScreenOrientation.LANDSCAPE) |
| Hide keyboard | driver.hideKeyboard() |
| Push file (Android) | driver.pushFile("/sdcard/test.txt", bytes) |
| Context switch | driver.context("WEBVIEW_com.example") |
| Get contexts | driver.getContextHandles() |
Reference Files
| File | When to Read |
|---|---|
reference/cloud-integration.md | App upload, real devices, capabilities |
reference/python-patterns.md | Python + pytest-appium |
reference/javascript-patterns.md | JS + WebdriverIO-Appium |
reference/ios-specific.md | iOS-only patterns, XCUITest driver |
reference/hybrid-apps.md | WebView testing, context switching |
Deep Patterns → reference/playbook.md
| § | Section | Lines |
|---|---|---|
| 1 | Project Setup & Capabilities | Maven, Android/iOS options |
| 2 | BaseTest with Thread-Safe Driver | ThreadLocal, multi-platform |
| 3 | Cross-Platform Page Objects | AndroidFindBy/iOSXCUITFindBy |
| 4 | Advanced Gestures (W3C Actions) | Swipe, long press, pinch zoom, scroll |
| 5 | WebView & Hybrid App Testing | Context switching |
| 6 | Device Interactions | Files, notifications, clipboard, geo |
| 7 | Parallel Device Execution | Multi-device TestNG XML |
| 8 | LambdaTest Real Device Cloud | Cloud grid integration |
| 9 | CI/CD Integration | GitHub Actions, emulator runner |
| 10 | Debugging Quick-Reference | 12 common problems |
| 11 | Best Practices Checklist | 13 items |
Limitations
- Use this skill only when the task clearly matches its upstream source and local project context.
- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.
- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
Frequently asked questions about Appium Automation
Similar skills
Android App Development
Comprehensive guide for Android and cross-platform app development.
Add App Clip to Expo App
Integrate lightweight iOS App Clips into your Expo project.
APK Reverse
Streamline your Android APK reverse engineering process.
Swift Expert
Master iOS/macOS development with Swift and SwiftUI.
React Native Expert
Build and optimize mobile apps with React Native and Expo.
Kotlin Specialist
Master idiomatic Kotlin with expert patterns and practices.
