Skip to content

[BUG] Appium: tapOn ignores element-relative point when a selector is supplied #175

Description

@yesiamdaniel

Description

On Android with the Appium driver, tapOn accepts an element selector plus point: "90%,50%", but taps the selected element's center. In an alarm list, the selector matched a full-width row containing a switch on its right edge. The tap opened the row's edit screen instead of toggling the switch.

Observed with v1.1.27. The same implementation remains in main at 3c448e8c49c2bc38bea0784f6f4bbb66ce22308f (source inspection only; main was not device-tested).

Steps to Reproduce

  1. Open an Android screen where a selectable row contains a separately actionable control near its right edge. Match the outer row using its accessibility label.
  2. Run the flow below using the Appium driver and your usual app/device capabilities:
    maestro-runner --platform android --driver appium \
      --appium-url http://127.0.0.1:4723 --caps capabilities.json \
      test tap-offset.yaml
  3. Inspect the outgoing W3C pointer coordinates and the resulting screen.

The flow uses generalized app and label values; it requires an app screen with the described row/control layout.

Expected Behavior

The official Maestro tapOn documentation includes a "Tap a coordinate within an element" example. It defines point as:

A specific coordinate to tap on the screen or within a selected element.

Apply this documented element-relative behavior to the matched element's bounds. For the observed row bounds [0,639][1080,855], 90%,50% should produce (972,747), inside the switch bounds [912,716][1038,779]. The switch should turn off while the list remains open.

Actual Behavior

The outgoing action uses (540,747), exactly the outer row's center. tapOn reports success, the edit screen opens, and the subsequent off-state assertion times out. The trace contains one tap, so this was not a retry toggling the switch back on.

Environment

  • Host OS: Amazon Linux 2, AWS Device Farm
  • maestro-runner: v1.1.27, prebuilt binary; Go build version not captured
  • Driver: --driver appium
  • Appium: 2.11.5
  • Appium UiAutomator2 driver: 2.44.0
  • Device: physical Google Pixel 11, Android 17, 1080 x 2424
  • App UI: React Native

Flow File

appId: ${APP_ID}
---
- tapOn:
    text: "^Example alarm on$"
    checked: true
    point: "90%,50%"
    retryTapIfNoChange: true
- extendedWaitUntil:
    visible:
      text: "^Example alarm off$"
      checked: false
    timeout: 30000

Error Output

Relevant fields from the recorded Appium request:

{"duration":0,"origin":"viewport","type":"pointerMove","x":540,"y":747}

The pointer move is followed by pointerDown, a 50 ms pause, and pointerUp. The later assertion fails after 30 seconds because the app is on the edit screen.

Additional Context

In pkg/driver/appium/commands.go at v1.1.27, step.Point is handled only when step.Selector.IsEmpty(). After resolving a selector, the code unconditionally computes:

cx, cy := info.Bounds.Center()

Those center coordinates are sent to d.client.Tap(cx, cy). The same code is present in the inspected main revision.

Please apply the requested relative point within the resolved element bounds, retaining the current center behavior when no point is supplied. A regression check could resolve the bounds above and assert the injected coordinates are (972,747), rather than (540,747).

This report concerns Android/Appium. Other drivers and platforms were not tested but we could we please do a check there to ensure parity. Issue #6 concerns point-only absolute coordinates, which is a different path.

Activity

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions