feat(android): expose system-bar membership on snapshot nodes

Merged
TH
3d ago
+438-20

Summary

Expose optional systemBar: "status" | "navigation" on Android snapshot nodes, including descendants whose ancestors were omitted. SystemUI bars and launcher navigation controls carry membership; shade headers, dialogs, popups, and taskbar apps remain distinct.

Example: { "label": "Back", "bundleId": "com.google.android.apps.nexuslauncher", "systemBar": "navigation" }.

Settle chrome is now an allowlist, including keyguard/shade status headers without public bar membership. Appium settle now applies package rules; package identity also enables IME collapse and replay foreign-overlay promotion. Attribute-less XML containers keep their existing behavior. The Android membership pass stays lazy.

18 files; includes unchanged-snapshot field declarations and snapshot/settle docs. Closes #3526.

Validation

Head 62714f5fffe6d63561ab50e0502ba6b59cc0001d: serialized pnpm check:affected --run and eager-closure/test-file-size CI gates passed; 76 focused tests passed. CI passed, including Coverage, Integration Tests, all smoke lanes and cubic review.

Appium interactor regression: replacing the membership call with parseWebDriverSourceFacts(source, 'android').nodes gives 1 failed / 28 passed (missing returned systemBar); restoring the lazy path gives 29 passed. Scroll-frame tests pass after removing the attribute-less-node branch.

Prior API 35 Pixel 7 emulator-5558 evidence at b31bb1714: ADB 27 status / 7 navigation, Appium 26 status / 7 navigation; shade/dialog controls have no membership. Commands and capture evidence.

That live evidence predates the lazy-path move and used a local Appium script; no daemon-route Appium live rerun in this round. Sessions/daemon closed and temporary AVD deleted. No unresolved review threads at publication.