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.
.app, .apk, or .ipa) or bundled dev server (React Native)uiautomator2 for Android, xcuitest for iOS) if using Appiumxcodebuild, ./gradlew assembleDebug, or npx react-native build).@ios, @android).npx detox test --configuration ios.sim.debug.tests/mobile/ or e2e/
| 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 |
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"