Root cause corrected (see evidence comment): the node is NOT missing — it is present in the raw uiautomator dump 100% of the time. The false "not found" comes from an unconditional dumpsys activity top scroll-hint call (deriveScrollableContentHintsIfNeeded, snapshot.ts:600) whose latency intermittently spikes to ~5s and is charged against the same wait/get timeout. The original "capture completeness / viewport-edge" framing below is superseded.
Summary
During the wave-3 E1 experiment (see #1269), a second, distinct failure surfaced on Android: an
element positioned at the bottom of the viewport intermittently falls outside the captured
accessibility tree, so a wait/read targeting it fails with action-failure even though the element is
on screen and the app is unchanged.
Filing separately from #1269 because it's a different subsystem — this is capture completeness, not
identity selection.
Observation
- Android Settings → Battery screen. The "Battery" row on the Settings root sits at ~y=2864 on a 2992px
screen (right at the viewport bottom).
- Across 20 unchanged-app replays, ~8 diverged at a
wait "label=\"Battery\"" step with
action-failure (COMMAND_FAILED) — the element was not present in the captured tree on those runs,
while present on others. Non-deterministic, position-correlated (bottom-of-viewport).
Why it matters
A recorded flow that reads/acts on a near-edge element becomes flaky on replay through no fault of the
app — a false divergence distinct from the android:id/title identity class in #1269. It also shapes
fixture design (avoid edge elements) and could mask real regressions.
Questions for the capture layer
- Is there an off-by-one / rounding at the viewport boundary in the Android hierarchy walk (helper or
UiAutomation), or a scroll/settle race where the bottom row isn't yet laid into the captured frame?
- Should near-edge elements be scrolled-into-safe-view before capture, or the capture viewport be
slightly over-scanned?
Repro
Record an Android flow that waits on a bottom-of-list row, replay ~20× unchanged; observe intermittent
action-failure on that step correlated with the element's y being near the screen bottom. Evidence
artifacts from the E1 run available (per-run divergence JSONs).
Summary
During the wave-3 E1 experiment (see #1269), a second, distinct failure surfaced on Android: an
element positioned at the bottom of the viewport intermittently falls outside the captured
accessibility tree, so a
wait/read targeting it fails withaction-failureeven though the element ison screen and the app is unchanged.
Filing separately from #1269 because it's a different subsystem — this is capture completeness, not
identity selection.
Observation
screen (right at the viewport bottom).
wait "label=\"Battery\""step withaction-failure(COMMAND_FAILED) — the element was not present in the captured tree on those runs,while present on others. Non-deterministic, position-correlated (bottom-of-viewport).
Why it matters
A recorded flow that reads/acts on a near-edge element becomes flaky on replay through no fault of the
app — a false divergence distinct from the
android:id/titleidentity class in #1269. It also shapesfixture design (avoid edge elements) and could mask real regressions.
Questions for the capture layer
UiAutomation), or a scroll/settle race where the bottom row isn't yet laid into the captured frame?
slightly over-scanned?
Repro
Record an Android flow that
waits on a bottom-of-list row, replay ~20× unchanged; observe intermittentaction-failureon that step correlated with the element's y being near the screen bottom. Evidenceartifacts from the E1 run available (per-run divergence JSONs).