In an Appium translation-glossary suite, an iOS locator finds nothing though the term is on screen — how do you triage?
answer
- dump first, edit the locator second
- absent from the tree, unmatchable
- depth, then breadth, then which app
- the two dumps are different models
- record the setting the fix depends on
basics
~20 sCapture 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.
solid answer
~40 sSplit the question in two before touching the selector. Dump `GET /session/:sessionId/source` at the exact moment the find fails — `appium:printPageSourceOnFindFailure` will do it for you — and search the XML for the glossary term. **If the node is not there**, the locator is irrelevant: nothing resolved against that tree can match it, and the candidates are XCUITest's bounds (`snapshotMaxDepth`, `snapshotMaxChildren`), which application the snapshot was taken of (`defaultActiveApplication`, `activeAppDetectionPoint`), what the serialisation includes (`includeHittableInPageSource`, `pageSourceExcludedAttributes`), or an app-side element that publishes nothing usable. **If the node is there**, compare its attributes with what the locator asserts, remembering iOS names differ from Android's. Change one thing, re-dump, and record whichever setting the fix depended on.
go deeper
Be ready to say that the first move is to capture the page source and look for the element in it, rather than rewriting the locator and re-running.
Be ready to name the Apple-side bounds you would check in order — snapshotMaxDepth, then snapshotMaxChildren, then which application was snapshotted — and to explain what each removes from the tree.
Be ready to walk the whole triage under pressure: one dump, one branch decision, one change at a time, and a judgement about whether the real defect is in the app's accessibility rather than in the suite.
Be ready to make it systemic: failure artefacts that always carry the dump, snapshot settings recorded as suite configuration, and an app-side identifier policy so addressability stops being negotiated per screen.
## The decision the dump makes for you A find that returns nothing has exactly two shapes, and they need opposite repairs. Either the node reached the tree and your locator described it wrongly, or the node never reached the tree at all. Guessing between them is how afternoons disappear into selector rewrites that could never have worked. The page source settles it in one call: capture `GET /session/:sessionId/source` at the moment of failure and search the XML for the glossary term you expected. Appium will capture it for you if you set `appium:printPageSourceOnFindFailure`, a core capability that makes the server emit the source when a find fails — worth having on in a suite whose failures you triage after the fact rather than live. ## Branch one — the node is absent from the dump This is the branch this leaf exists for. On Apple platforms the tree is an `XCUIElement` snapshot WebDriverAgent takes through XCTest, and it is bounded while it is built. Work the candidates in order of cheapness: - **Depth.** `snapshotMaxDepth` caps how far down the walk goes. A glossary row nested inside a section, a card and a stack of sense entries can sit below the cap. Raise it a step and re-dump. - **Breadth.** `snapshotMaxChildren` caps how many siblings are taken at a level, which is the bound that bites on a long term list. This one has no Android equivalent, so an engineer who only ever debugged Android will not think of it. - **Which application was snapshotted.** `defaultActiveApplication` and `activeAppDetectionPoint` steer which app XCUITest treats as active. If the term is rendered by a share sheet or another process, the snapshot may simply be of something else. - **What the serialisation carries.** `pageSourceExcludedAttributes` can strip attributes you were matching on, and `includeHittableInPageSource` and `includeNativeAccessibilityElementInPageSource` change what each node reports. - **The application itself.** A custom-drawn glossary cell that publishes no identifier and no label to the accessibility layer is not addressable by any strategy. That is an app defect with a real user consequence, not a test problem, and the fix is to give it an identifier. Only after one of those changes should you re-dump. Change one thing at a time; a widened snapshot plus a rewritten locator that suddenly passes tells you nothing about which one mattered. ## Branch two — the node is in the dump Now the locator is genuinely wrong, and the dump is the specification. Read the node's attributes as the XML actually spells them and compare them with what the locator asserts. The two platforms publish different attribute names, so a locator ported across from the Android suite can be internally reasonable and still describe nothing that exists in an Apple dump. Rewrite the locator against the dump you are holding, not against memory of the other platform's tree. ## The trap that produces the most wasted time The seductive failure mode is to assume symmetry. The Android run passes, the term is clearly on screen on the iPhone, so the iOS locator "must be nearly right". It need not be right at all: the two dumps are different models produced by different components with different bounds and different vocabularies. Treat the platforms as two independent addressability problems that happen to share a test intent. ## Things not to reach for 1. **`customSnapshotTimeout`** — removed when WebDriverAgent's custom snapshotting logic was removed. Older write-ups still recommend it; setting it changes nothing. 2. **`simpleIsVisibleCheck`** — also removed, and frequently misremembered as an Android setting, which it never was. 3. **Blind retries.** Re-running a find that was resolved against a tree the node was never in produces the same nothing, more slowly. 4. **Maximal settings as a default.** Turning every bound up suite-wide makes every snapshot heavier for every test to rescue one screen. ## Closing the loop When the fix lands, leave evidence behind: - Record which setting the locator now depends on, per platform, next to the suite's other configuration. An undeclared dependency on a non-default bound is a future mystery. - Attach the failing dump to the failure artefacts if your pipeline keeps them, so the next occurrence is triaged in minutes rather than reproduced by hand. - If the repair was an app-side identifier, say so in the ticket in accessibility terms as well as test terms — the same missing label affects assistive technology users, which is usually the stronger argument for getting it merged. - If you widened a bound, note why the narrower value was insufficient, so a later reader does not "tidy" it back. The senior signal in this question is not knowing a setting name. It is refusing to touch the locator until the dump has told you which of the two problems you actually have, and then making the smallest change that restores addressability on the platform that failed.
- The term is in the iOS dump but the find still fails. What have you learned?That the snapshot is not the problem, so stop touching its settings. The node reached the tree, which means the locator describes something the tree does not contain — usually because attribute names were carried over from the Android suite. Rewrite it against the attributes the dump actually spells, then re-run.
- Why is turning every XCUITest snapshot bound up as a suite-wide default a poor fix?Because every test then pays for a larger tree on every snapshot, to rescue one screen. Prefer the narrowest widening that restores addressability, scoped to the run or case that needs it, and record it so the dependency is visible. If the node is missing because the app publishes nothing usable, no bound will help anyway.
saying these in an interview costs you the question
- Rewriting the locator before looking at the dump
- Assuming a working Android locator is nearly right for iOS
- Suggesting customSnapshotTimeout, which was removed
- Retrying the find and hoping the node appears
- Turning every snapshot bound up across the whole suite
- Never recording which setting the fix depended on