IOS click request is being sent but another element is being clicked

Hi all, I am facing a weird issue while testing on IOS.
Running IOS 15.2 on iPhone 13 simulator.
Appium version is: 1.22.2

The issue happened for about 3 times in the last 5 days so it will be hard for me to test it…

The issue is as so:
The issue happens each time on the same page with the same button! (any other time it works!)

I am locating an element using POM appium annotations (@iOSXCUITFindBy annotation).
Then, waiting for it to be clickable using WebDriverWait and ExpectedConditions class.
And then click it.

The problem is that in reality, another element is being clicked on the page and the test fails.
I will specify some code bellow but please note that it happens rarely (maybe some race condition…)
and when looking on appium logs and comparing it with a successful test, they are the same.
I can see that a ‘…/click’ request is being sent to appium with the correct element and appium does not even try to locate the wrong element(the one who is being clicked).

My code:
Locating the element:
@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSXCUITAutomation = ALL_POSSIBLE)
@iOSXCUITFindBy(id = “next”) @iOSXCUITFindBy(id = “Next”) @iOSXCUITFindBy(id = “done”)
private WebElement nextBtn;

Clicking it:
public void clickNext(){wait.until(elementToBeClickable(nextBtn)).click();}

Some of appium logs: (all logs are after the WebDriverWait instance checked they are displayed and enabled, for both it is ‘true’)

Successful:
08:33:57 [debug] [WD Proxy] Proxying [POST /element/0B000000-0000-0000-472E-000000000000/element] to [POST http://127.0.0.1:8100/session/81CC5F5B-09C7-4053-8B4F-93FDA43C0AB6/element/0B000000-0000-0000-472E-000000000000/element] with body: {“using”:“id”,“value”:“Next”}
08:33:57 [debug] [WD Proxy] Got response with status 200: {“value”:{“ELEMENT”:“DE070000-0000-0000-472E-000000000000”,“element-6066-11e4-a52e-4f735466cecf”:“DE070000-0000-0000-472E-000000000000”},“sessionId”:“81CC5F5B-09C7-4053-8B4F-93FDA43C0AB6”}
08:33:57 [debug] [W3C (8a24db39)] Responding to client with driver.findElementFromElement() result: {“element-6066-11e4-a52e-4f735466cecf”:“DE070000-0000-0000-472E-000000000000”,“ELEMENT”:“DE070000-0000-0000-472E-000000000000”}
08:33:57 [HTTP] <-- POST /wd/hub/session/8a24db39-e247-4433-92fc-e584c38bc871/element/0B000000-0000-0000-472E-000000000000/element 200 155 ms - 137
08:33:57 [HTTP]
08:33:57 [HTTP] --> POST /wd/hub/session/8a24db39-e247-4433-92fc-e584c38bc871/element/DE070000-0000-0000-472E-000000000000/click
08:33:57 [HTTP] {“id”:“DE070000-0000-0000-472E-000000000000”}
08:33:57 [W3C (8a24db39)] Driver proxy active, passing request on via HTTP proxy
08:33:57 [debug] [XCUITest] Executing command ‘proxyReqRes’
08:33:57 [debug] [WD Proxy] Matched ‘/wd/hub/session/8a24db39-e247-4433-92fc-e584c38bc871/element/DE070000-0000-0000-472E-000000000000/click’ to command name ‘click’
08:33:57 [debug] [WD Proxy] Proxying [POST /wd/hub/session/8a24db39-e247-4433-92fc-e584c38bc871/element/DE070000-0000-0000-472E-000000000000/click] to [POST http://127.0.0.1:8100/session/81CC5F5B-09C7-4053-8B4F-93FDA43C0AB6/element/DE070000-0000-0000-472E-000000000000/click] with body: {“id”:“DE070000-0000-0000-472E-000000000000”}
08:33:57 [debug] [WD Proxy] Got response with status 200: {“value”:null,“sessionId”:“81CC5F5B-09C7-4053-8B4F-93FDA43C0AB6”}
08:33:57 [WD Proxy] Replacing sessionId 81CC5F5B-09C7-4053-8B4F-93FDA43C0AB6 with 8a24db39-e247-4433-92fc-e584c38bc871
08:33:57 [HTTP] <-- POST /wd/hub/session/8a24db39-e247-4433-92fc-e584c38bc871/element/DE070000-0000-0000-472E-000000000000/click 200 227 ms - 65
08:33:57 [HTTP]

Unsuccessful:
06:34:00 [debug] [WD Proxy] Proxying [POST /element/0B000000-0000-0000-9E20-000000000000/element] to [POST http://127.0.0.1:8100/session/E7691ECA-7FBF-49C9-AFFC-6F479E3B04C7/element/0B000000-0000-0000-9E20-000000000000/element] with body: {“using”:“id”,“value”:“Next”}
06:34:00 [debug] [WD Proxy] Got response with status 200: {“value”:{“ELEMENT”:“DB070000-0000-0000-9E20-000000000000”,“element-6066-11e4-a52e-4f735466cecf”:“DB070000-0000-0000-9E20-000000000000”},“sessionId”:“E7691ECA-7FBF-49C9-AFFC-6F479E3B04C7”}
06:34:00 [debug] [W3C (636ac383)] Responding to client with driver.findElementFromElement() result: {“element-6066-11e4-a52e-4f735466cecf”:“DB070000-0000-0000-9E20-000000000000”,“ELEMENT”:“DB070000-0000-0000-9E20-000000000000”}
06:34:00 [HTTP] <-- POST /wd/hub/session/636ac383-7022-4e44-bb88-f41e0e7d47b5/element/0B000000-0000-0000-9E20-000000000000/element 200 155 ms - 137
06:34:00 [HTTP]
06:34:00 [HTTP] --> POST /wd/hub/session/636ac383-7022-4e44-bb88-f41e0e7d47b5/element/DB070000-0000-0000-9E20-000000000000/click
06:34:00 [HTTP] {“id”:“DB070000-0000-0000-9E20-000000000000”}
06:34:00 [W3C (636ac383)] Driver proxy active, passing request on via HTTP proxy
06:34:00 [debug] [XCUITest] Executing command ‘proxyReqRes’
06:34:00 [debug] [WD Proxy] Matched ‘/wd/hub/session/636ac383-7022-4e44-bb88-f41e0e7d47b5/element/DB070000-0000-0000-9E20-000000000000/click’ to command name ‘click’
06:34:00 [debug] [WD Proxy] Proxying [POST /wd/hub/session/636ac383-7022-4e44-bb88-f41e0e7d47b5/element/DB070000-0000-0000-9E20-000000000000/click] to [POST http://127.0.0.1:8100/session/E7691ECA-7FBF-49C9-AFFC-6F479E3B04C7/element/DB070000-0000-0000-9E20-000000000000/click] with body: {“id”:“DB070000-0000-0000-9E20-000000000000”}
06:34:00 [debug] [WD Proxy] Got response with status 200: {“value”:null,“sessionId”:“E7691ECA-7FBF-49C9-AFFC-6F479E3B04C7”}
06:34:00 [WD Proxy] Replacing sessionId E7691ECA-7FBF-49C9-AFFC-6F479E3B04C7 with 636ac383-7022-4e44-bb88-f41e0e7d47b5
06:34:00 [HTTP] <-- POST /wd/hub/session/636ac383-7022-4e44-bb88-f41e0e7d47b5/element/DB070000-0000-0000-9E20-000000000000/click 200 237 ms - 65
06:34:00 [HTTP]

Appium inspector photo:
in purple the element who is in fact being clicked - the back arrow button on the screen.
in red the element who is located and the ‘…/click’ request is being sent to appium with its elementId - the ‘Next’ button on the screen

Please let me know if you see something I do not or if you ever experienced a similar issue.
Thanks a lot!

  1. try with:
@iOSXCUITFindBy(iOSNsPredicate = "type == 'XCUIElementTypeButton' AND label == 'next' OR label == 'Next' OR label == 'done' AND visible == 1")
  1. add logic in test FIRST to check that we are on correct screen THEN do actions (tap, getText, setInput …)

Hi, I just saw your reply, thanks for the answer. I Changed it, I hope it will work. It is a really weird issue…
I check that I am testing the correct screen and the click action is the last action on this screen(clicking next button) after a couple of successful actions.
As well I changed to tap instead of click although it did not help much.

Try get x,y of element where tap happens. Check what is there and why it does tap into wrong place.

Hi @Aleksei; it wasn’t solved yet. I tried your predicate strategy lookup. I tried as well to change the ‘BoundElementByIndex’ setting before clicking the element like it was suggested to me elsewhere.
do you maybe know why it might happen? or an iOS specific capability that might help?
I am running appium 1.22.3
any idea will be appreciated.

Did you found where tap happens by coordinates and what element there?

yes. again, most of the time the element is correct but when it is wrong the coordinates are matching the wrong element.

Write a bit more about it.

  1. What element found instead?
  2. What flow in general? When you tap on element? 1-2 steps before.

Example:

  1. On x1 screen tap signIn button
  2. On x2 screen set user and pass and tap login button

With tap on login problem happens.

I have 2 elements - 1 is ‘back’ button (the arrow in the pic) and ‘next’ button (‘Next’ in the pic) - both are subelements of the toolbar element(the green one in the pic).
Basically, I login, do some testing and then starts a kind of “flow” test. I have multiple screens one after another that for all of them the toolbar element contains back and next buttons. on each screen I run some tests and the last action on each screen is clicking the ‘next’ button - I have 5 screens like that one after another. before starting each screen I am making sure that I am not on the previous screen(waiting for element to be stale) and I am on the new screen(checking that the screen’s title matches my expectations).

  • the problem is (each time on a different screen) when the test clicks the ‘next’ button, in reality, the ‘back’ button is getting clicked which breaks my test of course.

  • the ‘back’ button does not have any common attributes with the ‘next’ button and I already tried different strategies: class chain, predicate, xpath, id(name). all of the mentioned strategies did not help. I changed to ‘tap’ as I was suggested and it did not help but I observed that the coordinates are of the ‘back’ button instead of ‘next’. I tried to set to true the ‘BoundElementByIndex’ strategy before clicking the ‘next’ button and it did not help as well.

  • like I said, on each screen clicking ‘next’ is the last action so there is a space between the clicks on different screens.

since it happens arbitrarily and on different screens I would guess it has something to do with race conditions or that the iOS elements are returned each time on a different order…
but since this happens solely when I click ‘next’ button, I guess that I am not doing something correct as well.

in general with iOS we have access to all screens under visible (you visited before). that is why mess happens.

  1. i wrote a bit wrong locator missing (). try correct one:
@iOSXCUITFindBy(iOSNsPredicate = "type == 'XCUIElementTypeButton' AND (label == 'next' OR label == 'Next' OR label == 'done') AND visible == 1")
  1. try class chain like:
@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeNavigationBar[-1]/**/XCUIElementTypeButton[-1]")
// or
@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeNavigationBar[1]/**/XCUIElementTypeButton[-1]")
  1. if this button 100% has static position across all screens try find it coordinates and save. use them later. logic like: we have coordinates we use them, no = we finding element.

  2. disable animation on test phones. it helps while screen changing

first of all thanks a lot! I will try those solutions.
about the first one, I tried the following xpath:

@iOSXCUITFindBy(xpath = "//XCUIElementTypeButton[(@name=\"next\"or @name=\"Next\" or @name=\"done\") and @visible=\"true\"]")

let me know if it is considered the same so I’ll skip the first solution. I am asking this because it takes time to test if a change has succeed or not since it does not happen on every execution.

Never use xpath for ios it is tooooo slow.

yes I know, I just assumed that maybe with xpath appium relays less on WDA which maybe the cause of the elements confusion. but since I use iOS attributes (name, label) for sure it will.
It was just an assumption which is not correct.
but when I used xpath I used () like you suggested.
but is it compatible to your first solution? or you would recommend I will try it as well?

Also, sometimes I need to test the ‘next’ element (enable attribute) so I need it as an element and not just to save its coordinates.

@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeNavigationBar/**/XCUIElementTypeButton")
private List<WebElement> nextBtns;

Additionally, if I am using the above, do you maybe know if it is guaranteed that I’ll get the elements by theirs order?
I can run through them and look for the ‘next’ element(the order isn’t mandatory). although it might be time consuming… but there are not a lot of button subelements as well…

Try all approches… xcuitest framework is quite tricky.

1 Like