skip to content

Environment Controls

Making the target's world misbehave on purpose - the link, the location, the language - through driver commands issued inside the session rather than a human toggling settings on the device.

on this pageshow

explore

questions

7

In Appium, when does an appium:language or appium:locale change take effect on Android and iOS?

level: middleimportance: must knowfreq 52%

answer

  1. capabilities are read once
  2. no in-session locale command on Android
  3. Apple simulators get an extra command
  4. configureLocalization is simulator-only

basics

~20 s

Both are session-start capabilities, so on Android and on Apple real devices a language or locale change needs a new session. Apple simulators are the exception: XCUITest's mobile: configureLocalization changes localization inside a live session.

solid answer

~40 s

`language` and `locale` are Appium base capabilities, still written with the `appium:` prefix because only the W3C standard names may go bare. Being capabilities, they are read while the session is being created, so on Android the value you pass is the value you get for the whole session; changing it means tearing the session down and starting another. The Android drivers add `appium:localeScript` for a writing system that a language-and-country pair cannot pin, and it is a session-start capability too. Apple is where this leaf diverges: the XCUITest driver ships `mobile: configureLocalization`, a **simulator-only** execute method that changes localization inside a running session. On an Apple real device there is no such command, so you are back to capabilities and a fresh session, exactly like Android.

code

java · 14 lines
java
import org.openqa.selenium.MutableCapabilities;

final class LocaleSession {

    static MutableCapabilities androidFrenchCanadian(String appPath) {
        MutableCapabilities caps = new MutableCapabilities();
        caps.setCapability("platformName", "Android");
        caps.setCapability("appium:automationName", "UiAutomator2");
        caps.setCapability("appium:app", appPath);
        caps.setCapability("appium:language", "fr");
        caps.setCapability("appium:locale", "CA");
        return caps;
    }
}

go deeper

for a junior

Be ready to say that appium:language and appium:locale are read when the session is created, so a different locale means a different session. Name the Apple simulator exception if you know it.

for a middle

Explain why a capability cannot change mid-session, and that XCUITest's mobile: configureLocalization is the one in-session lever and works only on simulators. Mention appium:localeScript as the Android-only third knob.

for a senior

Show that you would not build a locale switch into a page object at all, and be able to say exactly what a suite loses the day it moves from Apple simulators onto real hardware.

for a principal

Own where the locale knob lives in the framework's configuration — something a session is built from rather than a runtime step — and defend that even on a fleet where simulators would let you cheat.

## A capability is read once, at session creation Appium's `language` and `locale` are base capabilities — they sit in the core's constraint list alongside `platformName`, `app`, `newCommandTimeout` and `udid`. Like every non-standard name they are sent with the `appium:` prefix. What matters here is not the spelling but the lifecycle: a capability is part of the `POST /session` body, so the driver reads it exactly once, while it is building the session. Nothing in the WebDriver protocol lets a test edit a capability afterwards. That single fact answers most of this question — for anything driven purely by `appium:language` and `appium:locale`, the setting takes effect when the session starts and never again. ## The Android answer On Android the language and locale knobs are capabilities and only capabilities. The Android drivers expose a very large execute-method surface — app lifecycle, connectivity, geolocation, permissions, clipboard, shell and much more — but no in-session locale twin. So an Android run gets the locale it was born with: - pass `appium:language` and `appium:locale` in the session's capabilities; - add `appium:localeScript` when a language and country pair is not enough to pin the writing system; - to exercise a second locale, end the session and start another with different values; - expect the change to be device-level rather than app-level, so it is not what `appium:noReset` or `appium:fullReset` govern. ## The Apple answer, and why this leaf exists The XCUITest driver accepts the same session-start capabilities, and on a real device that is all you get. On a **simulator** it also ships `mobile: configureLocalization`, an execute method that applies a localization configuration to the running target. That command is simulator-only: it leans on facilities the driver has against a simulator and not against physical hardware, so pointing it at a real device fails rather than quietly doing nothing. The consequence is a three-way split that is easy to state and easy to get wrong: 1. **Android, any target** — capability only, effective at session start. 2. **Apple real device** — capability only, effective at session start. 3. **Apple simulator** — capability at session start, plus `mobile: configureLocalization` inside the session. ## Compared with location, the shape is inverted It is worth holding this next to the other half of the same subject, because the two behave in opposite ways. Position is an in-session command on both platforms — `mobile: setGeolocation` on Android, `mobile: setSimulatedLocation` on Apple platforms — and no capability sets it. Locale is the mirror image: a capability everywhere, with one simulator-only command as the single exception. | Knob | Android | Apple simulator | Apple real device | |---|---|---|---| | Language and locale | `appium:language`, `appium:locale`, `appium:localeScript` at session start | those capabilities, plus `mobile: configureLocalization` in session | those capabilities only | | Position | `mobile: setGeolocation` in session | `mobile: setSimulatedLocation` in session | `mobile: setSimulatedLocation` in session | ## What it means in practice For the swimming-lesson booking app, imagine the timetable screen renders lesson times and prices from the device locale. Reaching a second locale is not a step you bolt onto an existing case on Android — it is a different session. The practical consequences: - the locale is a property of the session, so it belongs in the capability builder, not in a page object; - a helper that tries to switch locale mid-case works on an Apple simulator and throws on everything else, which is the worst failure mode there is because it passes on the developer's machine; - if a suite leans on `mobile: configureLocalization`, say so in the run's requirements: that suite cannot move to real Apple hardware unchanged; - reading a locale back is not symmetrical with reading a location back — there is no locale twin of `mobile: getGeolocation`, so assert through the app's own rendered text. ## Mistakes worth naming The first is assuming `appium:locale` alone pins a writing system; `appium:localeScript` exists on the Android side precisely because it does not. The second is sending `language` and `locale` bare because they are core capabilities — being a core capability is not the same as being one of the W3C standard names, and only those may go unprefixed. The third is generalising the simulator-only command into a cross-platform feature: `mobile: configureLocalization` belongs to the XCUITest driver, it is simulator-only, and it has no Android counterpart at all. The honest one-line summary is that Appium treats language and locale as something a session is *born with*, and gives exactly one target — the Apple simulator — the ability to change its mind afterwards.

  • Why can't you change appium:locale in the middle of a running Appium session on Android?
    Capabilities are part of the `POST /session` body and the driver reads them once, while building the session; WebDriver has no command that edits a capability afterwards. The Android drivers also ship no in-session locale execute method, so the only lever left is a new session created with different `appium:language` and `appium:locale` values.
  • What breaks if a suite leans on mobile: configureLocalization and then moves to Apple real devices?
    The command is simulator-only, so every case that switches locale mid-session starts failing on hardware. The fix is to promote the locale to a session-start capability — `appium:language` and `appium:locale` — and create a separate session per locale, which is the shape Android already forces on you.
  • When does appium:localeScript earn its place on an Android session?
    When a language and country pair does not pin the writing system the app should render — the same language can be written in more than one script, and `appium:locale` has no room for that distinction. It is an Android-drivers capability read at session start, and the XCUITest driver has no counterpart to it.

saying these in an interview costs you the question

  • Thinking appium:locale can be changed mid-session on Android
  • Calling mobile: configureLocalization against an Apple real device
  • Assuming appium:localeScript exists on the XCUITest driver
  • Believing appium:fullReset resets the device language
  • Sending language and locale without the appium: prefix
open as a page

In Appium, which command sets the device location on Android, and which one on iOS?

level: juniorimportance: should knowfreq 60%

basics

~10 s

Appium has no single location command. The Android drivers answer mobile: setGeolocation, while the Apple XCUITest driver answers mobile: setSimulatedLocation. Both are execute methods carrying latitude and longitude, posted to the session's execute/sync endpoint.

open as a page

In Appium, which command switches Wi-Fi off on Android, and what does iOS offer instead?

level: juniorimportance: should knowfreq 52%

basics

~20 s

On Android, the execute method mobile: setConnectivity toggles wifi, mobile data and airplane mode. iOS has no equivalent radio switch: the XCUITest driver enables one of Apple's network condition profiles instead, and only on a real device.

open as a page

In Appium on Android, what does mobile: toggleGps control that no iOS command does?

level: middleimportance: should knowfreq 40%

basics

~20 s

It flips the Android device's GPS location provider on or off, which is state separate from the coordinates mobile: setGeolocation installs. The Apple XCUITest driver ships no provider toggle at all; it only simulates a position.

open as a page

In Appium, why does mobile: networkSpeed need an Android emulator while iOS condition inducers need a real device?

level: middleimportance: should knowfreq 44%

basics

~20 s

Each command drives a facility only one kind of target has: mobile: networkSpeed configures the Android emulator's simulated modem, which a real handset lacks, while Apple's condition inducers ship on real devices and not on a Simulator.

open as a page

Your Appium swimming-lesson booking suite leaves a simulated location on shared devices — how do you clear it per platform?

level: seniorimportance: should knowfreq 36%

basics

~10 s

Clear 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.

open as a page