skip to content

Hierarchy Snapshots

Every tree walk, every XPath and every page-source dump comes off one bounded snapshot, so whatever that snapshot leaves out is simply not addressable by any strategy at all.

on this pageshow

explore

questions

4

Which Appium settings bound the page-source snapshot on Android, and which do so on iOS?

level: middleimportance: must knowfreq 46%

answer

  1. one shared name, two vocabularies
  2. depth on both, breadth on one
  3. visibility filters differ per platform
  4. settings apply to the next snapshot
  5. two famous knobs were removed

basics

~10 s

Both drivers honour snapshotMaxDepth. Android's UiAutomator2 adds allowInvisibleElements, ignoreUnimportantViews and enableMultiWindows; Apple's XCUITest adds snapshotMaxChildren, useJSONSource, includeHittableInPageSource and pageSourceExcludedAttributes. Same job, almost entirely different names.

solid answer

~30 s

`snapshotMaxDepth` is the one name both drivers share, and it caps how deep the tree is walked on each. Everything else diverges. On Android, UiAutomator2 exposes `allowInvisibleElements` for nodes the platform reports as not visible, `ignoreUnimportantViews` for nodes accessibility marks unimportant, `enableMultiWindows` and `enableTopmostWindowFromActivePackage` for window scope, and `includeExtrasInPageSource` and `includeA11yActionsInPageSource` for extra per-node data. On Apple platforms, XCUITest exposes `snapshotMaxChildren` for breadth, `defaultActiveApplication` and `activeAppDetectionPoint` for which app is snapshotted, and `includeHittableInPageSource`, `includeNativeAccessibilityElementInPageSource`, `includeMinMaxValueInPageSource`, `pageSourceExcludedAttributes` and `useJSONSource` for the serialisation itself. Set them as `appium:settings[...]` capabilities at session start, or change them mid-session, and re-dump afterwards.

code

json · 12 lines
json
{
  "capabilities": {
    "alwaysMatch": {
      "platformName": "Android",
      "appium:automationName": "UiAutomator2",
      "appium:settings[snapshotMaxDepth]": 70,
      "appium:settings[allowInvisibleElements]": true,
      "appium:settings[enableMultiWindows]": true
    },
    "firstMatch": [{}]
  }
}

go deeper

for a junior

Be ready to name snapshotMaxDepth as the bound both drivers share, and to say that the other snapshot settings have different names on Android and on Apple platforms.

for a middle

Be ready to list the per-platform vocabulary and explain what each bound removes from the tree, including that only the Apple side caps breadth with snapshotMaxChildren.

for a senior

Be ready to justify a specific setting change on a real suite: the narrowest widening that makes the node appear, why it is scoped rather than global, and how it is recorded per platform.

for a principal

Be ready to own the policy: whether snapshot settings are suite-wide defaults or per-case overrides, and how you keep a locator's dependence on a non-default setting visible to everyone maintaining it.

## Why there are settings at all A snapshot has to stop somewhere. A deeply nested screen — a translation-glossary term list where each row wraps a headword, a part-of-speech tag, several senses and a set of usage notes — can produce a very deep and very wide tree, and both drivers apply bounds so that building it terminates in reasonable time. Those bounds are configurable, and because they are applied *while the tree is built*, they decide what exists to be addressed. That makes the settings vocabulary part of your locator strategy, not a performance footnote. ## The one shared name `snapshotMaxDepth` is declared by both the UiAutomator2 driver and the XCUITest driver, and it does the same conceptual job in both: cap how many levels down the walk goes. Do not read the shared name as a shared mechanism, though — on Android it bounds a walk over the accessibility node hierarchy, and on Apple platforms it bounds an `XCUIElement` snapshot taken through XCTest. Raise it and deeper nodes become addressable; leave it and a node below the cap is absent from the dump and from any find resolved against that tree. ## Android — the UiAutomator2 vocabulary - `snapshotMaxDepth` — how deep the walk goes. - `allowInvisibleElements` — whether nodes the platform reports as not visible are included at all. - `ignoreUnimportantViews` — whether nodes accessibility marks unimportant are skipped. - `enableMultiWindows` — whether the tree spans more than the single active window. - `enableTopmostWindowFromActivePackage` — which window is treated as topmost when scoping. - `currentDisplayId` — which display the tree is taken from. - `includeExtrasInPageSource` and `includeA11yActionsInPageSource` — extra per-node data in the serialisation. - `normalizeTagNames` and `alwaysTraversableViewClasses` — how node tags are written and which classes are always walked into. ## Apple platforms — the XCUITest vocabulary - `snapshotMaxDepth` — depth again, over a different model. - `snapshotMaxChildren` — breadth: how many siblings are taken at a level. Android has no twin for this. - `defaultActiveApplication` and `activeAppDetectionPoint` — which application the snapshot is taken of. - `includeHittableInPageSource`, `includeNativeAccessibilityElementInPageSource`, `includeMinMaxValueInPageSource`, `includeCustomActionsInPageSource` — which extra per-node facts are serialised. - `pageSourceExcludedAttributes` — attributes to leave out of the dump entirely. - `useJSONSource` — build the source from a JSON representation rather than the default path. ## Setting them, and what changes when you do Settings can travel as capabilities at session start, in the `appium:settings[<name>]` form, or be changed during a session. Two habits keep this from biting: 1. **Re-dump after every change.** The settings apply to the *next* snapshot; a dump you already captured is unaffected. 2. **Record per-platform values with the suite.** A locator that only works because `allowInvisibleElements` is on is a locator with an undeclared dependency, and the next engineer will not guess it. ## Widening is not free, and two famous knobs are gone Every bound you relax makes the tree bigger, and the tree is rebuilt each time it is needed, so the settings are a genuine trade between what is addressable and how heavy each snapshot is. Prefer the narrowest change that makes the node you need appear: raise `snapshotMaxDepth` by a step rather than to an extreme, and turn on `allowInvisibleElements` for the run that needs it rather than as a permanent default. Two settings that circulate in older advice are no longer there, and recommending them is a reliable interview tell: - `customSnapshotTimeout` was **removed** when WebDriverAgent's custom snapshotting logic was removed. It survives in stale documentation, not in the driver. - `simpleIsVisibleCheck` was an Apple-side visibility knob and it was **removed** as well. It is also frequently misfiled as an Android setting, which it never was. ## Putting it together | Concern | Android — UiAutomator2 | Apple — XCUITest | | --- | --- | --- | | Depth | `snapshotMaxDepth` | `snapshotMaxDepth` | | Breadth | no equivalent | `snapshotMaxChildren` | | Invisible nodes | `allowInvisibleElements` | `includeHittableInPageSource` and friends | | Scope | `enableMultiWindows`, `currentDisplayId` | `defaultActiveApplication`, `activeAppDetectionPoint` | | Serialisation detail | `includeExtrasInPageSource` | `pageSourceExcludedAttributes`, `useJSONSource` | Read that table the right way round: one row shares a name, one row exists on only one platform, and the rest are two different vocabularies for the same idea. A mid-level candidate is expected to know that the vocabularies are disjoint and to reach for the right one per platform rather than guessing a symmetric name that does not exist.

  • Which snapshot bound exists on Apple platforms but has no Android equivalent?
    `snapshotMaxChildren`. XCUITest bounds breadth as well as depth, capping how many siblings the snapshot takes at a level, which matters on a long glossary list where later rows can fall outside the tree. UiAutomator2 exposes `snapshotMaxDepth` for depth but no comparable breadth cap.
  • You raise snapshotMaxDepth and the element still is not in the dump. What next?
    Depth was not the bound that removed it. On Android check `allowInvisibleElements`, `ignoreUnimportantViews` and whether the node lives in another window, which needs `enableMultiWindows`. On Apple platforms check `snapshotMaxChildren` and whether the snapshot is being taken of the application you think, via `defaultActiveApplication`. Re-dump after each change.

saying these in an interview costs you the question

  • Recommending customSnapshotTimeout, which was removed
  • Filing simpleIsVisibleCheck as an Android setting
  • Assuming allowInvisibleElements exists on Apple platforms
  • Expecting snapshotMaxChildren to bound the Android tree
  • Raising every bound to its maximum as a default
open as a page

In Appium, what is the page-source tree actually built from on Android compared with iOS?

level: middleimportance: must knowfreq 58%

basics

~20 s

Android's UiAutomator2 driver serialises the accessibility node hierarchy the platform publishes. Apple's XCUITest driver serialises an XCUIElement snapshot WebDriverAgent takes through XCTest. Neither is the app's own view hierarchy, so whatever those layers withhold is unaddressable.

open as a page

In Appium, which request returns the current page source on Android, and what does iOS add?

level: juniorimportance: should knowfreq 64%

basics

~10 s

Both platforms answer the W3C endpoint GET /session/:sessionId/source, which returns the current screen as one XML tree. Apple's XCUITest driver additionally exposes a mobile: source execute method; the Android drivers ship no equivalent.

open as a page

In an Appium translation-glossary suite, an iOS locator finds nothing though the term is on screen — how do you triage?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Capture GET /session/:sessionId/source at the moment of failure and search it for the term. If the node is absent, no XCUITest locator can match it: widen snapshotMaxDepth or snapshotMaxChildren, or fix the app. If present, the locator is wrong.

open as a page