DeviceFarm
Glossary
Operations

RPA

Also called: robotic process automation, mobile automation

RPA (robotic process automation) is software that performs interface actions the way a person would — tapping, typing, scrolling and waiting — rather than calling an API. On mobile it drives real apps through their real screens, which is the only option when no public API exposes the actions you need.

Where an API exists, use it: it is faster, more reliable, and does not break when a layout changes. RPA is what you reach for when there is no API, or when the API deliberately excludes the actions you need — posting, following, messaging, browsing a feed. Most consumer mobile apps fall into that category, which is why automation on phones is overwhelmingly interface-driven and why it inherits every fragility of a user interface.

How an action reaches the screen

Every step is two problems: find the thing, then touch it. Finding it is done against the view hierarchy or against pixels, and the choice determines how the script fails.

  • Resource ID — the most stable selector when it exists, but React Native, Flutter and Jetpack Compose surfaces frequently expose no usable IDs at all.
  • Content description — the accessibility label. Stable in well-built apps, missing or localised in others, so a script written against an English build breaks on a device set to Portuguese.
  • XPath over the hierarchy — works everywhere and breaks on any structural change, including the ones an A/B test rolls out to half of your fleet and not the other half.
  • Absolute coordinates — fastest and least portable. A layout tuned for 1080x2340 misses on a device with a different density or a taller aspect ratio.
  • Image or OCR matching — survives hierarchy changes, costs a screenshot and a match per step, and fails on dark mode, on a different font scale, or when the element is mid-animation.

Where the input comes from

The event itself arrives by one of three paths, and they are not equivalent from inside the app. Synthetic events via ADB input are simplest but coarse: an injected MotionEvent carries no meaningful pressure or contact size, reports an unknown tool type rather than a finger, and input swipe interpolates a perfectly straight line at constant velocity with no fling and no settle. An accessibility service produces gestures that look closer to real touch, at the cost of being enumerable — an app can list the enabled accessibility services on the device. Instrumentation frameworks such as UiAutomator sit in between, and are what Appium drives underneath.

Timing that survives inspection

The gap between an automated trace and a human one is almost entirely temporal, and the ranges are not secret:

  • Tap dwell — a real finger is down for roughly 50 to 150 ms. A default injected tap is a fixed value, identical every time.
  • Reaction to a new screen — a person takes 300 to 1200 ms to react to content that just rendered. A script frequently acts within 20 ms of the element appearing, which is faster than the screen refreshed.
  • Typing — 120 to 400 ms per character, with variance, pauses at word boundaries and occasional backspaces. input text delivers a whole string instantly, like a paste.
  • Scrolling — a real scroll is a curve with acceleration, a fling, and inertial settle. A scripted swipe is a segment.
  • Idle — humans stop. A session with no gaps longer than the scripted delay has no idle behaviour in it at all.

What separates workable RPA from brittle RPA

  • Variable timing — fixed delays produce identical traces across every device running the same script, which is the clearest signal a fleet can emit and costs nothing to detect.
  • State handling — a script that assumes the happy path breaks on the first unexpected dialog: a permission prompt, a rate-limit screen, an update nag, a feed that loaded slowly.
  • Explicit waits over sleeps — wait for a condition (an element present, the focused activity changed) rather than for a duration. Fixed sleeps are both slower on average and more fragile on a slow network.
  • Per-device variation — the same routine should not execute identically on two hundred phones at once, and the fleet should not start its day at the same second.
  • Idempotency — a retried step must not double-post. Every action needs a check for whether it already happened before it is repeated.
  • Failure visibility — knowing which device stopped, at which step, with a screenshot, before the whole fleet drifts silently for six hours.

Inspecting it yourself

Three commands cover most of the debugging. adb shell uiautomator dump writes the current hierarchy to /sdcard/window_dump.xml — pull it and you have every resource ID, content description and bounding box on screen, which is how you find a selector that will not move. adb shell dumpsys window | grep mCurrentFocus tells you which activity is actually in front, so a script can assert its position instead of guessing. And adb shell getevent -lt on the touch input device prints raw events with timestamps: run it while tapping the screen yourself, then again while the script runs, and the difference in ABS_MT_PRESSURE, contact size and inter-event timing is visible in the output without any interpretation.

Of everything above, the timing point is the one that decides whether automation is worth running at all. Perfectly regular intervals are the single clearest pattern a fleet emits, they are trivial to detect server-side, and no amount of work on device identity or proxies compensates for them.

Related terms