Skip to content

Controls under an app-drawn footer are not marked covered #4347

Open

Description

@TanmayOG

A text field under a sticky footer that the keyboard raised gets no interactionBlocked: 'covered', so a tap on the field lands on the footer button. The review on e2e-inc/e2e#1644 asked e2e to use agent-device's covered mark instead of its own detector, so this case needs to be flagged here.

Repro: https://github.com/TanmayOG/e2e-covered-input-repro

On an iOS 27.2 simulator with main (093341a), Brand (TextField, 17,745 368x46) has its centre at (201, 768), inside Next (Button, 201,728 201x112), which is listed after it. Brand comes back hittable: true with no interactionBlocked. press @e14 reports Tapped @e14 (201, 768), but the app's footer tap count goes from 0 to 1 and no field gets focus. The repro shows the same on a real Android 16 phone.

The scan only counts known overlay kinds as covers, since list order isn't draw order. What I'd like to check with you before building:

  • Android: the helper already reads drawing-order. A touch node could be marked covered when its centre is inside a clickable node from a sibling branch that draws later at their lowest common ancestor, published with coveredBy. That needs each node's ancestor path of sibling orders and the helper's clickable in the occlusion evidence. It would live in its own capture-kit module next to the replacement-surface rule.
  • iOS: snapshots have no z-order, and fix(ios): separate snapshot actionability from occlusion #1933 removed the runner's hit test on purpose, with a guard against element.isHittable in snapshot acquisition. Simulators also read through the host AX bridge by default. Is there a way you'd accept to learn what's on top, or should iOS stay as it is for now?
  • Screen scroll: a direction-only scroll starts in the middle of the band above the keyboard, so a raised footer takes the drag and the scroll fails with scroll_no_progress. readScrollTargetContainer could trim the container where a hittable node outside it overlaps, which Android's existing clamp then respects. iOS doesn't send containerRect to the runner today.

Happy to send the Android part first if this direction works for you.

Activity

  1. vzkn commented on Nov 13, 2026

    @vzkn
    Contributor

    We hit the same gap from another direction, with no keyboard and no custom footer, so I am adding it here instead of opening a duplicate.

    Case. A plain Activity with the platform action bar, built for target SDK 35, on Android 15 (API 35 emulator, 1080x2400). Edge-to-edge lays the content out from y=0, under the action bar. adb shell uiautomator dump:

    android:id/content                [0,0][1080,2400]
      EditText …:id/task_title        [48,96][1032,214]    clickable
      Button   …:id/save_task         [48,214][1032,340]   clickable
    android:id/action_bar_container   [0,0][1080,283]      clickable=false, listed after content
      android:id/action_bar           [0,136][1080,283]
        TextView "Bench Tasks"
    

    On 0.21.38-nightly.20261113.167 (android-helper backend):

    • snapshot --json: Save has hittable: true, no interactionBlocked, rect 48,214 984x126.
    • press 'id="dev.retest.bench.tasks:id/save_task"' answers Tapped … (540, 277) with success. The bar ends at y=283 and the button's click listener never runs.
    • press 540 311, a point in the visible part of the button, runs the listener.

    Two facts that may matter for the Android rule proposed above:

    1. The cover is not clickable. action_bar_container reports clickable=false and still takes the touch. A rule that counts only clickable later-drawn nodes would not mark this case.
    2. The cover is not in the regular tree. snapshot --raw has android:id/action_bar_container with the frame above. The regular snapshot drops it and android:id/action_bar, and keeps only the title text. The check has to read the tree before that filter.

    The button is also only partly covered: 57 of its 126 px are visible and a press there works. A covered mark would make the failure honest; a press point inside the uncovered part would make the press work.

    The app is one Activity of about 40 lines with no dependencies. I can push it to a public repository if that helps.

    Environment: Android 15 emulator (API 35, arm64), build-tools 35.0.0, macOS, Node 24.12.0.

  2. thymikee commented on Nov 14, 2026

    @thymikee
    Member

    Triage: needs a design decision. Thanks, the non-clickable cover and raw-tree comparison change the constraints: a clickable-only rule would miss this case, and the regular projected tree has already lost the covering frame. The Android occlusion contract still needs maintainer agreement before implementation. Please share the minimal Activity so the eventual rule can be checked against the same surface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions