Mobile App Tester
Overview
Execute automated mobile application testing on iOS simulators and Android emulators covering UI interactions, navigation flows, gesture handling, and platform-specific behaviors. Supports Appium, Detox (React Native), XCUITest (iOS native), Espresso (Android native), and Maestro for cross-platform mobile testing.
Prerequisites
- Mobile testing framework installed (Appium, Detox, Maestro, or native XCUITest/Espresso)
- iOS Simulator via Xcode (macOS only) or Android Emulator via Android SDK
- Application build artifact (
.app, .apk, or .ipa) or bundled dev server (React Native)
- Appium drivers installed (
uiautomator2 for Android, xcuitest for iOS) if using Appium
- Node.js for JavaScript-based test runners
Instructions
- Configure the test environment:
- List target devices/simulators: specify OS versions, screen sizes, and orientations.
- Build the application for testing (
xcodebuild, ./gradlew assembleDebug, or npx react-native build).
- Start the emulator/simulator or connect physical devices.
- Install the app on the target device.
- Create test cases for core mobile interactions:
- Tap and navigation: Tap buttons, navigate between screens, verify back navigation.
- Text input: Fill forms, verify keyboard behavior, test autocomplete and paste.
- Scrolling: Scroll lists, verify lazy loading, test pull-to-refresh.
- Gestures: Swipe (carousel), pinch-to-zoom, long press, drag-and-drop.
- System interactions: Handle permission dialogs, push notifications, deep links.
- Test platform-specific behaviors:
- iOS: Safe area insets, notch handling, Dynamic Type, VoiceOver accessibility.
- Android: Back button behavior, multi-window, different navigation patterns, TalkBack.
- Both: Screen rotation (portrait/landscape), dark mode, low battery mode.
- Implement device-specific test configurations:
- Define capability sets for each device/OS combination.
- Use test tagging to run subsets on specific platforms (
@ios, @android).
- Configure screenshot capture on failure for visual debugging.
- Handle asynchronous mobile behaviors:
- Wait for animations to complete before assertions.
- Handle network loading spinners with explicit waits.
- Account for system dialogs (permissions, updates) that interrupt test flow.
- Run the test suite and capture results:
- Execute tests per platform:
npx detox test --configuration ios.sim.debug.
- Collect device logs, screenshots, and crash reports.
- Generate JUnit XML or Allure reports for CI integration.
- Set up CI pipeline for mobile testing (GitHub Actions macOS runners for iOS, Linux for Android).
Output
- Mobile test files organized by feature/flow in
tests/mobile/ or e2e/
- Device configuration profiles for each target device/OS combination
- Screenshot captures for visual validation and failure debugging
- Test results in JUnit XML format with device-specific metadata
- CI pipeline configuration for automated mobile test execution
Error Handling
| Error |
Cause |
Solution |
| Simulator/emulator fails to boot |
Insufficient disk space or corrupted simulator image |
Delete derived data and reset simulator; increase disk allocation; recreate the emulator AVD |
| App crashes on launch during test |
Missing permissions or incompatible OS version |
Check minimum deployment target; grant required permissions in test setup; verify app signing |
| Element not found |
Element ID changed or screen did not finish loading |
Use accessibility IDs instead of XPath; add explicit waits; verify element visibility before interaction |
| Test flaky on CI but passes locally |
CI runner has slower CPU/GPU affecting animations and timing |
Increase wait timeouts for CI; disable animations in developer settings; use dedicated CI hardware |
| Permission dialog blocks test |
System alert appeared over the app UI |
Auto-dismiss alerts in test setup; pre-grant permissions via xcrun simctl or ADB commands |
Examples
Detox test for React Native login flow:
describe('Login Flow', () => {
beforeAll(async () => { await device.launchApp(); });
beforeEach(async () => { await device.reloadReactNative(); });
it('logs in with valid credentials', async () => {
await element(by.id('email-input')).typeText('user@test.com');
await element(by.id('password-input')).typeText('password123');
await element(by.id('login-button')).tap();
await expect(element(by.id('home-screen'))).toBeVisible();
});
});
Maestro flow file:
appId: com.example.myapp
---
- launchApp
- tapOn: "Sign In"
- inputText:
id: "email-input"
text: "user@test.com"
- inputText:
id: "password-input"
text: "password123"
- tapOn: "Submit"
- assertVisible: "Welcome"
Resources
Source: jeremylongshore/claude-code-plugins-plus-skills → skills/.curated/testing-mobile-apps/SKILL.md
Also appears in: jeremylongshore/claude-code-plugins-plus-skills/plugins/testing/mobile-app-tester/skills/testing-mobile-apps/SKILL.md
1---2name: testing-mobile-apps3description: "'Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like \"test mobile app\", \"run iOS tests\", or \"validate Android functionality\". '"4allowed-tools: "Read, Write, Edit, Grep, Glob, Bash(test:mobile-*)"5category: testing-and-qa6source_repo: jeremylongshore/claude-code-plugins-plus-skills7source_path: "skills/.curated/testing-mobile-apps/SKILL.md"8source_url: https://github.com/jeremylongshore/claude-code-plugins-plus-skills/blob/HEAD/skills/.curated/testing-mobile-apps/SKILL.md9---1011# Mobile App Tester1213## Overview1415Execute automated mobile application testing on iOS simulators and Android emulators covering UI interactions, navigation flows, gesture handling, and platform-specific behaviors. Supports Appium, Detox (React Native), XCUITest (iOS native), Espresso (Android native), and Maestro for cross-platform mobile testing.1617## Prerequisites1819- Mobile testing framework installed (Appium, Detox, Maestro, or native XCUITest/Espresso)20- iOS Simulator via Xcode (macOS only) or Android Emulator via Android SDK21- Application build artifact (`.app`, `.apk`, or `.ipa`) or bundled dev server (React Native)22- Appium drivers installed (`uiautomator2` for Android, `xcuitest` for iOS) if using Appium23- Node.js for JavaScript-based test runners2425## Instructions26271. Configure the test environment:28 - List target devices/simulators: specify OS versions, screen sizes, and orientations.29 - Build the application for testing (`xcodebuild`, `./gradlew assembleDebug`, or `npx react-native build`).30 - Start the emulator/simulator or connect physical devices.31 - Install the app on the target device.322. Create test cases for core mobile interactions:33 - **Tap and navigation**: Tap buttons, navigate between screens, verify back navigation.34 - **Text input**: Fill forms, verify keyboard behavior, test autocomplete and paste.35 - **Scrolling**: Scroll lists, verify lazy loading, test pull-to-refresh.36 - **Gestures**: Swipe (carousel), pinch-to-zoom, long press, drag-and-drop.37 - **System interactions**: Handle permission dialogs, push notifications, deep links.383. Test platform-specific behaviors:39 - iOS: Safe area insets, notch handling, Dynamic Type, VoiceOver accessibility.40 - Android: Back button behavior, multi-window, different navigation patterns, TalkBack.41 - Both: Screen rotation (portrait/landscape), dark mode, low battery mode.424. Implement device-specific test configurations:43 - Define capability sets for each device/OS combination.44 - Use test tagging to run subsets on specific platforms (`@ios`, `@android`).45 - Configure screenshot capture on failure for visual debugging.465. Handle asynchronous mobile behaviors:47 - Wait for animations to complete before assertions.48 - Handle network loading spinners with explicit waits.49 - Account for system dialogs (permissions, updates) that interrupt test flow.506. Run the test suite and capture results:51 - Execute tests per platform: `npx detox test --configuration ios.sim.debug`.52 - Collect device logs, screenshots, and crash reports.53 - Generate JUnit XML or Allure reports for CI integration.547. Set up CI pipeline for mobile testing (GitHub Actions macOS runners for iOS, Linux for Android).5556## Output5758- Mobile test files organized by feature/flow in `tests/mobile/` or `e2e/`59- Device configuration profiles for each target device/OS combination60- Screenshot captures for visual validation and failure debugging61- Test results in JUnit XML format with device-specific metadata62- CI pipeline configuration for automated mobile test execution6364## Error Handling6566| Error | Cause | Solution |67|-------|-------|---------|68| Simulator/emulator fails to boot | Insufficient disk space or corrupted simulator image | Delete derived data and reset simulator; increase disk allocation; recreate the emulator AVD |69| App crashes on launch during test | Missing permissions or incompatible OS version | Check minimum deployment target; grant required permissions in test setup; verify app signing |70| Element not found | Element ID changed or screen did not finish loading | Use accessibility IDs instead of XPath; add explicit waits; verify element visibility before interaction |71| Test flaky on CI but passes locally | CI runner has slower CPU/GPU affecting animations and timing | Increase wait timeouts for CI; disable animations in developer settings; use dedicated CI hardware |72| Permission dialog blocks test | System alert appeared over the app UI | Auto-dismiss alerts in test setup; pre-grant permissions via `xcrun simctl` or ADB commands |7374## Examples7576**Detox test for React Native login flow:**7778```javascript79describe('Login Flow', () => {80 beforeAll(async () => { await device.launchApp(); });81 beforeEach(async () => { await device.reloadReactNative(); });8283 it('logs in with valid credentials', async () => {84 await element(by.id('email-input')).typeText('user@test.com');85 await element(by.id('password-input')).typeText('password123');86 await element(by.id('login-button')).tap();87 await expect(element(by.id('home-screen'))).toBeVisible();88 });89});90```9192**Maestro flow file:**9394```yaml95appId: com.example.myapp96---97- launchApp98- tapOn: "Sign In"99- inputText:100 id: "email-input"101 text: "user@test.com"102- inputText:103 id: "password-input"104 text: "password123"105- tapOn: "Submit"106- assertVisible: "Welcome"107```108109## Resources110111- Appium documentation: https://appium.io/docs/en/latest/112- Detox (React Native): https://wix.github.io/Detox/113- Maestro mobile testing: https://maestro.mobile.dev/114- XCUITest:115- Espresso (Android): https://developer.android.com/training/testing/espresso116117---118119**Source:** [`jeremylongshore/claude-code-plugins-plus-skills`](https://github.com/jeremylongshore/claude-code-plugins-plus-skills) → `skills/.curated/testing-mobile-apps/SKILL.md`120121**Also appears in:** `jeremylongshore/claude-code-plugins-plus-skills/plugins/testing/mobile-app-tester/skills/testing-mobile-apps/SKILL.md`