In Appium, why does Android's mobile: pressKey take a number where iOS pressButton takes a name?
answer
- open numbered space versus short named list
- modifiers only make sense on one side
- long press is its own Android event
- chassis buttons have no keycode
basics
~20 sAndroid exposes the platform's whole KeyEvent space, so UiAutomator2's mobile: pressKey identifies a key by its integer constant. XCUITest's mobile: pressButton drives a short, fixed set of physical device buttons, which a name identifies exactly.
solid answer
~50 sThe two parameters describe two different populations. Android's key events are a large, open, numbered vocabulary — the platform's `KeyEvent` constants — and UiAutomator2's `mobile: pressKey` takes one of those integers, so anything the system can deliver as a key is reachable: `4` for back, `24` for volume up, `66` for enter. It also carries `metastate`, the modifier bitmask meaning the key was pressed with shift or control held, and `isLongPress`, because Android models a long press as its own kind of event rather than as a duration the caller times. XCUITest's `mobile: pressButton` addresses something much smaller: the buttons on the device chassis, such as `home`, `volumeup` and `volumedown`. There is no integer space to index into and no modifier bitmask, because a chassis button has no modifiers. For keyboard keys on an Apple platform you reach for `mobile: keys` instead.
go deeper
Recall the shape of each parameter: a number on Android, a button name on Apple platforms. Do not try to hand one form to the other driver.
Explain why the shapes differ — an open integer vocabulary covering every key the system can report, against a short list naming the buttons on the device case.
Show judgment about which keycodes a suite hard-codes and how the numbers stay readable, because a bare integer in a step tells the next maintainer nothing.
Decide whether the suite carries its own named constants over the Android integers at all, and who owns that list when a new key is needed.
## Two parameters, two different populations The shape of an API parameter usually tells you what it is addressing. Android's `mobile: pressKey` takes a **number** and Apple's `mobile: pressButton` takes a **name**, and that is not a stylistic difference between two teams — it is the two platforms describing two different things. When the kayak-rental app is on screen and a tester presses a key, Android has to answer the question *which of every key this device could possibly report?* Apple's chassis-button method has to answer a much narrower one: *which of the few buttons on the outside of this device?* An integer suits the first question and a name suits the second. ## The Android side is an open numbered space The UiAutomator2 driver's `mobile: pressKey` identifies a key by an integer drawn from the platform's `KeyEvent` constants. That single channel carries keys from many sources — the buttons on the case, an attached hardware keyboard, an input method, a game controller — and each key has a number. The parameter map is therefore: - `keycode` — the integer. `4` back, `24` volume up, `25` volume down, `61` tab, `66` enter. - `metastate` — an optional bitmask of modifiers held at the moment of the press. It is a property **of this press**, not a device mode you switch on beforehand. - `isLongPress` — an optional boolean. Android distinguishes a long key press from a short one at the event level, so you set a flag rather than timing two calls. The practical consequence of an open numeric space is reach: a key nobody anticipated is still addressable, provided the caller knows its number. The practical cost is readability — `driver.executeScript("mobile: pressKey", Map.of("keycode", 66))` says nothing to the next reader of the kayak-rental suite unless the number is behind a named constant. ## The Apple side is a short closed list XCUITest's `mobile: pressButton` takes a `name`, and the accepted names describe the physical buttons of the hardware: `home`, `volumeup`, `volumedown`, and the remote-control buttons when the target is tvOS. There is no numeric space behind it and nothing to index into. There is also: - **No modifier parameter.** A volume button cannot be pressed *with shift held*, so there is nothing for a `metastate` equivalent to express. - **No long-press flag.** The method exposes a press of a chassis button, not an event whose duration is part of its identity. - **A separate method for keyboard keys.** `mobile: keys` sends a sequence of keys to whatever the application currently has focused; Enter and Tab live there, not in the button vocabulary. ## Side by side | | Android, UiAutomator2 | Apple platforms, XCUITest | |---|---|---| | Method | `mobile: pressKey` | `mobile: pressButton` | | Key argument | integer `KeyEvent` keycode | name string such as `volumeup` | | Size of vocabulary | open — every key the system reports | closed — the buttons on the case | | Modifiers | `metastate` bitmask | not expressible on this method | | Long press | `isLongPress` flag | not expressible on this method | | Keyboard keys | another keycode on the same method | `mobile: keys`, a different method | ## Why the mismatch matters in practice The two parameter maps are not two spellings of one idea, and three things follow for a kayak-rental suite that runs on both: 1. **You cannot write a converter.** Only a handful of intents — volume up, volume down, home — exist on both sides at all, so a keycode-to-name table would be three rows long and would imply a generality that is not there. 2. **Two Android parameters have no Apple counterpart.** Anything a test expresses through `metastate` or `isLongPress` is Android-only content, and a shared helper that accepts those arguments is lying about the other platform. 3. **The Apple split is by target, not by key.** Choosing between `mobile: pressButton` and `mobile: keys` is a question about *what you are pressing* — the case, or the keyboard — and getting it wrong produces a call that succeeds quietly. ## Keeping the Android numbers honest A bare integer in a test step is the readability tax of the open vocabulary, and it is worth paying deliberately: - Give the numbers names in one place, so a step reads as volume up rather than as `24`. - Keep the modifier in the same call as the key it modifies; a separate press of a modifier key does not leave the device in a held state that the next call inherits. - Set `isLongPress` rather than issuing a press and waiting, because the flag is what makes the platform emit a long-press event at all. The summary an interviewer is listening for: the number is an address into everything Android can report as a key, the name is a label on one of a handful of physical buttons, and no amount of wrapper code makes them the same alphabet.
- What does metastate carry, and why does the Apple button method have no equivalent?`metastate` is an Android modifier bitmask saying the key was pressed while shift, control or a similar modifier was held, and it travels on the same `mobile: pressKey` call as the key itself. XCUITest's `mobile: pressButton` presses a button on the device case, and a chassis button has no modifier state to express.
- Why can the Android method reach far more keys than the Apple button method can?Because the Android parameter is an integer drawn from the platform's `KeyEvent` constants, so any key the system can report is addressable once you know its number. `mobile: pressButton` takes a name from a short, closed list describing the physical buttons on the device case, and there is no numeric space behind it.
Android's keycode is like an extension number: any handset in the building is reachable if you know the digits. Apple's button name is one of the few labelled buttons beside the front door — a short list, and the label is the whole address.
saying these in an interview costs you the question
- Believing metastate is a duration rather than a modifier bitmask
- Timing a long press by hand instead of setting isLongPress
- Expecting the Apple button method to accept an arbitrary keycode
- Assuming the two parameter maps are interchangeable across drivers
- Treating volume buttons as keyboard keys on Apple platforms