In Appium, why does a window the app does not own break a run differently on Android and iOS?
answer
- the screen is a stack of windows
- Android omits, Apple misattributes
- which windows versus which application
- enableMultiWindows on the Android side
- respectSystemAlerts on the Apple side
basics
~20 sEach platform loses something different. On Android a foreign window such as the keyboard is absent from UiAutomator2's default tree, so the obstruction is invisible. On Apple platforms it shows, but can make the driver read the wrong app.
solid answer
~40 sA device screen is a stack of windows, and only some of them belong to the app under test. On Android, UiAutomator2's page source carries the active application's window by default, so an input-method window or a dialog from another package is simply not in the tree — the find succeeds against the app's own nodes and the tap lands on a keyboard nobody can see in the data. The `enableMultiWindows` setting is what brings the other windows in, and `enableTopmostWindowFromActivePackage` narrows the choice differently. On Apple platforms the XCUITest driver has the opposite problem: a system alert is a *different application*, so the driver has to decide whose tree to return, which is what `respectSystemAlerts`, `activeAppDetectionPoint` and `defaultActiveApplication` govern.
go deeper
Know that other windows can sit above the app under test, and that a control the tree shows as present can still be covered. Do not assume the tree describes every pixel on screen.
Explain the divergence: Android reports the active application's window by default and needs enableMultiWindows to show more, while XCUITest keeps the keyboard in the app's tree and instead has to decide which application is active.
Diagnose from a source captured at the moment of failure, tell an obstruction apart from a missing element on Android, and recognise a wrong-active-application signature on Apple platforms rather than blaming locators.
Own the position that a fix for this class has to be written twice, once per platform, and decide whether foreign-window handling belongs in shared harness code or in the cases that actually encounter it.
## A screen is a stack of windows, not one document A browser test works inside a single document that the browser owns. A mobile screen is composed by the window manager out of surfaces from several processes: the app under test, the input method, the status and navigation chrome, and whatever the OS decides to draw above them. Appium's job is to describe that composite through one element tree — and the two platforms make different compromises doing it. Those compromises are the source of a specific class of intermittent failure, because a foreign window appears on a schedule that has nothing to do with the test. In a greenhouse climate run the recurring cases are the soft keyboard covering the setpoint field after a tap opened it, and a system-owned prompt drawn over the dashboard on the first run after install. Handling either — hiding the keyboard, accepting the prompt — is a separate subject. What matters here is why the run misreads the screen while one is up, and why the misreading looks different per platform. ## Android: the tree shows one window unless you say otherwise UiAutomator2 builds the page source from the accessibility node tree, and by default it reports the active application's window. That default is a cost decision, and it has a consequence for triage: - The input method runs in **another process** and owns its own window, so its keys are not in the tree at all under the default. - Therefore a covered control still resolves. The find is answered from the app's window, the returned rectangle is real, and the interaction lands on whatever is actually drawn there — the keyboard. - The symptom is a test that types into nothing, taps a key instead of a button, or fails an assertion about a control that the tree insists is present. - `enableMultiWindows` is the setting that puts other windows into the source, which is how you *see* the obstruction while triaging. - `enableTopmostWindowFromActivePackage` scopes the choice differently again, so "which window am I looking at" is a configurable question on Android rather than a fixed one. ## Apple platforms: the tree is available, the question is whose XCUITest models the screen as applications. The keyboard is part of the app's own element tree, where the `visible` and `hittable` attributes describe occlusion honestly — an element can be present and visible and still not hittable. The harder case is a system-owned alert, because that is a **different application** in the foreground: - `respectSystemAlerts` governs whether a system alert is taken into account when the driver works out which application is active. - `activeAppDetectionPoint` sets the screen point sampled to make that determination. - `defaultActiveApplication` names which application to treat as active when the answer is ambiguous. Get that determination wrong and the driver returns a coherent, correct-looking tree — for the wrong application. Every locator then misses, and the failure reads like a broken selector rather than a foreign window. ## The divergence in one table | | Android, UiAutomator2 driver | Apple platforms, XCUITest driver | |---|---|---| | Where the keyboard lives | a separate window from another process | inside the app's own element tree | | Default tree contents | the active application's window | the active application, whichever that is judged to be | | Obstruction is visible? | no, unless `enableMultiWindows` is on | yes, via `visible` and `hittable` | | The configurable question | which windows are in the tree | which application counts as active | | Settings to know | `enableMultiWindows`, `enableTopmostWindowFromActivePackage` | `respectSystemAlerts`, `activeAppDetectionPoint`, `defaultActiveApplication` | ## How to work with it 1. **Capture the source at the moment of failure, not afterwards.** A foreign window is usually gone by the time anyone looks, and the tree captured later shows a screen that never failed. 2. **On Android, widen the window scope before concluding the element is missing.** With the default tree, "the control is there and the tap did nothing" is exactly what an obstruction looks like. 3. **On Apple platforms, check which application the tree came from.** A whole screen of failed locators is more often a wrong active application than a wrong locator. 4. **Expect the two platforms to fail differently for the same cause.** One suite, one root cause, two signatures — and a fix framed only in Android's vocabulary leaves the Apple side unaddressed. ## Why this is a mobile-only class Nothing in a browser run corresponds to it. The page cannot be overlapped by a window from another process that the automation tool then either omits or attributes to someone else. On a device that is the normal state of affairs, and the driver's answer to "what is on screen" is a considered choice with settings behind it — different settings on each platform, which is why this failure class has to be learned twice.
- On Android, why does a covered control still resolve from the page source?Because UiAutomator2 reports the active application's window by default, and the input method's window belongs to a different process. The app's node is genuinely in the tree and its bounds are genuine; the pixels at those bounds just belong to the keyboard now. Turning on `enableMultiWindows` is how you get the obstruction into the source and see it.
- What does an Apple-side failure look like when the driver picks the wrong active application?Every locator on the screen misses at once, and the page source looks internally consistent — because it is, for the wrong application. The tell is the breadth of the failure and the presence of a system-owned window at that moment; `respectSystemAlerts`, `activeAppDetectionPoint` and `defaultActiveApplication` are the settings that govern the determination.
saying these in an interview costs you the question
- Assumes the page source always contains every window on screen
- Says the soft keyboard is in the tree on both platforms
- Treats a screenful of failed locators as a selector problem
- Thinks a system alert belongs to the app under test
- Captures the page source after the failure and trusts it