Your Appium swimming-lesson booking suite leaves a simulated location on shared devices — how do you clear it per platform?
answer
- device state, not app state
- fullReset does not cover it
- two reset commands, one per platform
- restore the Android GPS toggle too
basics
~10 sClear it from teardown with the platform's own command: mobile: resetGeolocation on Android, mobile: resetSimulatedLocation on Apple platforms. On Android also restore the GPS provider with mobile: toggleGps if a case switched it off.
solid answer
~40 sA simulated position is device state, not app state, so nothing in the app-reset capabilities touches it — `appium:noReset` and `appium:fullReset` govern the application under test. Clear it explicitly with the platform's own command: `mobile: resetGeolocation` on Android, `mobile: resetSimulatedLocation` on Apple platforms. Put the call in teardown rather than at the end of the case body, so a case that fails mid-flight still leaves the device clean. On Android there is a second piece of state to restore: if a case called `mobile: toggleGps`, read `mobile: isGpsEnabled` and toggle back only if the state is wrong. And verify rather than assume — `mobile: getGeolocation` and `mobile: getSimulatedLocation` read the position back, and on shared hardware that read-back deserves an assertion of its own.
code
java · 17 linesimport io.appium.java_client.AppiumDriver;
import java.util.Map;
final class LocationTeardown {
static void restoreDevice(AppiumDriver driver, boolean isAndroid, boolean gpsWasEnabled) {
if (!isAndroid) {
driver.executeScript("mobile: resetSimulatedLocation", Map.of());
return;
}
driver.executeScript("mobile: resetGeolocation", Map.of());
Object enabled = driver.executeScript("mobile: isGpsEnabled", Map.of());
if (!Boolean.valueOf(gpsWasEnabled).equals(enabled)) {
driver.executeScript("mobile: toggleGps", Map.of());
}
}
}go deeper
Be ready to name the two clear commands and say which platform each belongs to: mobile: resetGeolocation on Android and mobile: resetSimulatedLocation on Apple platforms.
Explain why a simulated position survives the app-reset capabilities: it is device state the driver applied on top, so only the matching reset execute method removes it.
Show the teardown that runs on failure, the read-back assertion, and the Android provider restore — and describe the cross-run flake this prevents on shared hardware.
Own the rule that anything a run changes on a shared target belongs to the framework's lifecycle, and defend asserting a clean starting state over trusting every other suite to clean up after itself.
## Why this is a real failure mode A simulated position is **device** state. The driver applies it to the target, and it does not belong to the application under test, so nothing in Appium's app-reset story clears it: `appium:noReset` and `appium:fullReset` decide what happens to the app's installation and its data, not to the device's idea of where it is. Ending the session is not something to rely on either — treat the override as something you set and therefore something you must clear, exactly like a file you pushed to the device. On a shared emulator, simulator or physical handset the consequence is a cross-run bug that looks like flake. The swimming-lesson booking app's pool finder passes on the run that pinned the device to the city centre, and then the next suite on the same target opens the finder and gets a city-centre ordering it never asked for. Nothing in that second run's logs explains it. ## The clear commands, per platform There is no shared name here either: - **Android drivers** — `mobile: resetGeolocation` drops the mock position and hands control back to the device. - **Apple XCUITest driver** — `mobile: resetSimulatedLocation` clears the simulated position. - **Read-back on Android** — `mobile: getGeolocation` returns the position the device currently reports. - **Read-back on Apple** — `mobile: getSimulatedLocation` returns the simulated position. The read-back commands matter more than they look. On shared hardware, *assert* that the clear worked rather than trusting the call: a reset that throws inside a finally block is easy to swallow by accident, and the symptom appears in somebody else's suite. ## Android has a second piece of state Android separates the provider from the position, so a case that called `mobile: toggleGps` changed something `mobile: resetGeolocation` does not restore. And `toggleGps` is a toggle rather than a setter: calling it once more in teardown is only correct if you know the current state. The safe sequence is: 1. Read `mobile: isGpsEnabled`. 2. If it does not match the state the session started in, call `mobile: toggleGps` exactly once. 3. Read `mobile: isGpsEnabled` again and assert on the result. The XCUITest driver has nothing equivalent to restore, because it models no provider to switch — which makes Apple teardown the simple half and Android teardown the half worth getting right. ## Locale is a different problem The locale side of this subject has no reset command at all. `appium:language`, `appium:locale` and the Android drivers' `appium:localeScript` are session-start capabilities, and XCUITest's `mobile: configureLocalization` — the one in-session lever — is simulator-only. So instead of clearing locale in teardown: - state the locale explicitly in every session's capabilities rather than inheriting whatever the previous run left behind; - treat a run that called `mobile: configureLocalization` on a simulator as having changed the target, and be explicit that the next session is what restores order; - do not go looking for a reset twin of that command — there is none to call. | State the run changed | How to clear it | Where | |---|---|---| | Mock position, Android | `mobile: resetGeolocation` | teardown | | Simulated position, Apple | `mobile: resetSimulatedLocation` | teardown | | GPS provider, Android | `mobile: toggleGps`, guarded by `mobile: isGpsEnabled` | teardown | | Language and locale | explicit capabilities on the next session | session creation | ## Getting the teardown right The implementation details that decide whether any of this actually works: - put the clear where screenshot capture already lives, so it runs on failure as well as on success; - make it platform-aware through the one adapter that already knows the set commands, not through a second copy of that branch; - do not let a failing clear mask a failing test — log it loudly, but let the original failure stay the reported one; - when the fleet is shared with runs you do not own, assert the position at session start too, so an inherited override fails fast and visibly instead of quietly rewriting an expectation. ## Mistakes worth naming The common one is believing `appium:fullReset` covers it. It does not and never did: it is about the app, and a simulated position is about the device. The second is calling `mobile: resetGeolocation` on an Apple session, which throws, because that command belongs to the Android drivers and the XCUITest driver answers `mobile: resetSimulatedLocation`. The third is toggling GPS back blindly, which produces a device that is wrong half the time and right half the time — the signature of a flaky suite. And the fourth is the quiet one: clearing the position in the case body, on the line that never runs on exactly the failures that most need it.
- Why doesn't appium:fullReset clear a simulated location?Because it is scoped to the application under test — it governs installation and app data, not device-level state the driver applied on top. A mocked position is set by an execute method against the device, so only the matching execute method removes it: `mobile: resetGeolocation` on Android, `mobile: resetSimulatedLocation` on Apple platforms.
- What would you assert at session start on a shared device fleet?Read the position back with `mobile: getGeolocation` or `mobile: getSimulatedLocation` and fail fast if an override is already in place. That turns another run's leaked state into an obvious, immediate failure instead of a silent change of expectation halfway through the swimming-lesson booking app's pool-finder assertions.
saying these in an interview costs you the question
- Assuming appium:fullReset clears a simulated location
- Calling mobile: resetGeolocation on an Apple session
- Clearing the position in the case body, not in teardown
- Toggling GPS back without reading isGpsEnabled first
- Expecting a reset command for language or locale