In Appium, which execute method starts a screen recording on Android, and which on iOS?
answer
- the still is shared, the video is not
- Android needs a helper app
- Apple has two recorders, not one
- the stop call returns the payload
- startMediaProjectionRecording versus startXCTestScreenRecording
basics
~10 sAndroid sessions call mobile: startMediaProjectionRecording, declared by the Android drivers and captured by the io.appium.settings helper app. Apple sessions call XCUITest's mobile: startXCTestScreenRecording. The names, the mechanisms and the outputs are all platform-specific.
solid answer
~40 sOn Android the pair is `mobile: startMediaProjectionRecording` and `mobile: stopMediaProjectionRecording`, declared in `appium-android-driver` — the base that both the UiAutomator2 driver and the Espresso driver extend — and the frames are actually captured by the `io.appium.settings` helper application on the device. On Apple platforms the XCUITest driver declares `mobile: startXCTestScreenRecording` and `mobile: stopXCTestScreenRecording`, backed by XCTest inside WebDriverAgent, plus `mobile: getXCTestScreenRecordingInfo` to ask whether one is running. XCUITest also ships a *second*, different recorder: `mobile: startScreenRecording` / `mobile: stopScreenRecording`, an ffmpeg capture taken over the MJPEG stream. The stop call is what hands back the payload, so it must run while the session is alive.
code
python · 10 linesdef start_recording(driver):
if driver.capabilities["platformName"].lower() == "android":
driver.execute_script("mobile: startMediaProjectionRecording", {})
return "mobile: stopMediaProjectionRecording"
driver.execute_script("mobile: startXCTestScreenRecording", {})
return "mobile: stopXCTestScreenRecording"
def stop_recording(driver, stop_method):
return driver.execute_script(stop_method, {})go deeper
Be ready to name both pairs from memory: startMediaProjectionRecording and its stop twin on Android, startXCTestScreenRecording and its stop twin on Apple platforms, and know the stop call is what returns the file.
Explain why the two cannot share a command: Android capture is privileged and runs through the io.appium.settings helper, while Apple capture is XCTest's own facility inside WebDriverAgent.
Show how you isolate the branch in one helper, stop the recorder before the session is deleted, and avoid mixing the legacy route with the execute methods in the same start/stop pair.
Own the artefact budget across a fleet: video is orders of magnitude larger than a still, the mechanisms differ per platform, and a policy that records everything everywhere buys less than it costs.
## Two platforms, two recorders A still screenshot in Appium is one W3C command that both drivers answer. A **screen recording is not**. Each driver ships its own recorder, built on the facility its platform actually provides, and the command names do not rhyme. On **Android**, the command is `mobile: startMediaProjectionRecording`, with `mobile: stopMediaProjectionRecording` as its twin. It is declared in `appium-android-driver`, the base driver that both the UiAutomator2 driver and the Espresso driver extend, so it is not "a UiAutomator2 command" — it belongs to the Android drivers generally. The capture itself is performed by the **`io.appium.settings` helper application** on the device. Android's screen capture is a privileged operation; a plain automation server cannot simply grab frames, and the helper is the component that holds that capability. That is the single most important structural fact about Android recording: there is a second process involved, and it can be missing, stale, or unable to project. On **Apple platforms**, the XCUITest driver declares `mobile: startXCTestScreenRecording` and `mobile: stopXCTestScreenRecording`, backed by XCTest's own recording facility inside WebDriverAgent, plus `mobile: getXCTestScreenRecordingInfo` so a session can ask whether a recording is currently active. ## The second Apple recorder, which is a different thing XCUITest ships **two** recording facilities, and confusing them is a common error: - `mobile: startXCTestScreenRecording` / `mobile: stopXCTestScreenRecording` — XCTest's native recorder inside WebDriverAgent. - `mobile: startScreenRecording` / `mobile: stopScreenRecording` — an ffmpeg capture taken over the driver's MJPEG stream. They are different mechanisms with different outputs, so "we record on iOS" is an ambiguous statement until you say which pair you called. XCUITest also declares `mobile: startAudioRecording`, which is a separate capture again and not part of either video path. ## The legacy route that did not actually go away Appium 3 removed a large block of the old `/appium/...` endpoint surface in favour of per-driver `mobile:` execute methods, and the screen-recording route is often listed among the casualties. It is not one. Both `appium-xcuitest-driver`'s and `appium-android-driver`'s `method-map.ts` **re-add** the `start_recording_screen` route through `newMethodMap`, un-deprecated, so it is still live on those drivers. The execute methods are the richer replacement, not the only way in. The practical reading: 1. Prefer the `mobile:` execute methods — they are per-driver, documented per driver, and carry the arguments that matter. 2. Do not tell a reader the legacy route "was removed"; it moved into the drivers and both re-declare it. 3. Do not mix the two surfaces: start through one and stop through the other and the pairing does not hold. ## The two mechanisms side by side | Concern | Android (the Android drivers) | Apple (XCUITest) | |---|---|---| | Start | `mobile: startMediaProjectionRecording` | `mobile: startXCTestScreenRecording` | | Stop, returns payload | `mobile: stopMediaProjectionRecording` | `mobile: stopXCTestScreenRecording` | | Ask if one is running | not declared here — track it in the harness | `mobile: getXCTestScreenRecordingInfo` | | Other capture surface | `mobile: startScreenStreaming` (live stream) | `mobile: startScreenRecording` (ffmpeg over MJPEG) | | Who captures the frames | the `io.appium.settings` helper application | XCTest inside WebDriverAgent | | Declared in | `appium-android-driver`, inherited by UiAutomator2 and Espresso | `appium-xcuitest-driver` | ## Writing one helper over two mechanisms Because the names diverge, a cross-platform suite for a cattle-auction bidding app cannot call one method and be done. It branches, and the branch is worth isolating: - Read `platformName` from the session's capabilities and pick the start/stop pair for that platform. - Wrap start and stop in the same try/finally so a failed bid-submission step still stops the recorder. - Call stop **before** the session is deleted. The video payload comes back from the stop call, and `DELETE /session/:sessionId` leaves nothing to ask. - Keep the platform difference in exactly one place, so a test body never names a driver-specific method directly. - Log which recorder was used. On Apple platforms, "we recorded" is ambiguous between two facilities, and a triage engineer looking at an unexpected file format needs to know which one produced it. What to record, and on which runs to keep it, is deliberately outside this layer: Appium's job here is to expose the mechanism each platform provides, and each platform provides a different one.
- Which of the two Apple recorders would you reach for first, and why?`mobile: startXCTestScreenRecording` is the XCTest-native path and the usual default, since it records through WebDriverAgent rather than through a second capture pipeline. `mobile: startScreenRecording` is an ffmpeg capture over the MJPEG stream, so it inherits that stream's framerate and scaling settings and needs the stream configured. Pick it when you already run the stream.
- Is the Android recording command a UiAutomator2 command?No, and the distinction matters. It is declared in `appium-android-driver`, the shared base that UiAutomator2 and Espresso both extend, so both inherit it. UiAutomator2's own execute-method map covers gestures, window commands and its extra screenshot commands. Saying "UiAutomator2's mobile: startMediaProjectionRecording" verifies token by token and is still the wrong attribution.
saying these in an interview costs you the question
- Claims one recording command works on both Android and iOS
- Says the legacy start_recording_screen route was removed in Appium 3
- Thinks the start call returns the video file
- Attributes mobile: startMediaProjectionRecording to the UiAutomator2 repo
- Assumes Apple has exactly one screen-recording facility
- Forgets that Android capture runs through the io.appium.settings helper app