mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
b8ac75893a
* fix: make settle tail list real actionable targets Post-merge benchmark of #1167 (React Navigation prevent-remove flow, iOS sim, claude-haiku/sonnet) found the unchanged-interactive tail regressing to chrome-only noise in exactly the cases it was built for: - buildSettleTailEntries required `hittable === true`, stricter than what `snapshot -i` itself shows for the same interactive-only capture. Right after a dismiss animation, real buttons commonly report `hittable: false`/undefined while application/window containers pass, so the tail surfaced two useless chrome lines and dropped the actionable button. Fixed by dropping the hittable requirement and excluding structural application/window roles instead. - withoutKeyboardKeys only stripped `Key` nodes; real keyboard chrome (shift/Emoji/return/Dictate/Next keyboard) are XCUIElementTypeButton nodes and leaked through as fresh added-line refs, which suppressed the tail trigger for exactly the post-fill case it exists for. Fixed by detecting the whole keyboard subtree structurally (via parentIndex, not a locale-fragile label list): descendants collapse out of the diff, and the keyboard container's own ref no longer counts as a "meaningful" added ref for the trigger decision. Nobody presses shift via settle diff refs, so collapsing keyboard chrome does not block a user from explicitly targeting the keyboard itself. * fix: classify the whole iOS keyboard window as settle chrome Live-device review of the first Bug B fix found "Next keyboard" and "Dictate" still leaking into the settled diff as added refs: on a real iPhone 17 Pro simulator they live in a SIBLING subtree of the [Keyboard] container (the candidate bar), not under it, so the container-descendant walk missed them. A raw hierarchy capture shows the software keyboard in its own dedicated window hosting both the container and the candidate bar, so the structural rule is now: every node inside a window that has a [Keyboard] descendant is keyboard chrome. Conservative guard: a window also hosting an editable text node outside the container (iOS puts inputAccessoryView composers in the keyboard window) is never window-classified — those fall back to the container-descendant walk. The live run also showed the filled field re-labeling itself with its new value (ancestor wrappers inherit it), which produced added refs that suppressed the tail even with chrome fixed. The trigger now also ignores self-echo refs — added lines whose settled node rect contains the action point — since they re-describe the acted-on element, not a new target. The fill-keyboard provider fixture is now a trimmed REAL capture from the benchmark flow (sibling candidate bar, main app window absent from the interactive settled capture, self-echo relabels) instead of a hand-built tree that hid the sibling-branch shape.