[Bug]: Click Failure When Interacting with Multiple Elements Have the Same Locator
Describe the bug
If two elements with the same locator and clicks are performed on them in series, sometimes the execution fails because it canβt find the second element, but it has already been clicked on.
Link to SHAFT_Engine Console logs
https://gist.github.com/SEREPie/89517c6dace5b8a81d74e375006fff7c
Link to SHAFT_Engine Extent Report HTML
https://gist.github.com/SEREPie/28ad9065bb9e9b1675e3b7bc874cd394
Environment
- SHAFT_Engine version that exhibits the issue (Note: We support only the latest release): 9.2.20250409
- Last SHAFT_Engine version that did not exhibit the issue (if applicable): None
- Desktop OS: Windows 11
- Desktop Browser (if applicable): None
- Desktop Browser Version (if applicable): None
- Mobile Device Name (if applicable): Samsung Galaxy A33
- Mobile Device OS (if applicable): Android 14
- Mobile Device Browser or Native App: Native App
- Mobile Device Browser (if applicable): [e.g. chrome, safari]
- Mobile Device Browser Version (if applicable): [e.g. 22]
To Reproduce
Steps to reproduce the behavior:
- Tap on "Login as a guest" button.
- Tap on "Login as a guest" button in the modal.
- See error.
Expected behavior
After clicking on the "Login as a guest" button in the modal, the execution should continue executing.
Actual behavior
After clicking on the "Login as a guest" button in the modal, the execution fails because it can't find the "Login as a guest" button, however It already clicked on it.
I don't understand the issue dear. From the screenshots it seems to me that when you click that element the first time, it is no longer present. So it makes sense "to me since I don't really understand the business on your side" that the action should fail. From the screenshot it seems that you're trying to click an element which truly doesn't exist.
Can you explain more?
@SEREPie your response is highly appreciated.
Also, please note that enabling screenshots "Always" is highly unrecommended due to the aggressive performance impact. And that setting the application name and activity name variables are also not recommended since they're not CI/CD compliant. It'd be better if you take screenshots only with assertion points, and if you pass the relative apk path and allow appium to install it for you.
A final observation is related to starting/ending your appium server from within the tests. this is not standard CI/CD compliant practice. Ideally in a CI/CD pipeline you won't need to manage the appium server like that... so tc of that for future reference.
@MohabMohie After tapping on the "Login as a guest" button for the first time, a modal will be displayed that has another "Login as a guest" button in it. so after tapping on the "Login as a guest" button in the modal and moving to the next step, it fails because it says that it can't find the "Login as a guest" button, however it already clicked on it but it takes a screenshot after tapping on it and moved to the next screen. so it likely tapped twice as expected but it didn't memorize the second click.
The issue seems to be a timing problem, possibly with SHAFT's logging system. Here's what actually happens:
- SHAFT clicks "Login as a guest" β modal opens
- SHAFT clicks "Login as a guest" in the modal β navigation succeeds and moves to next screen
- But SHAFT's logging seems to be delayed, so the second click isn't recorded immediately (though I'm not 100% sure it's specifically the logging causing this)
- SHAFT tries to verify the second click happened, but by then we're already on the next screen where that button doesn't exist
- Test fails saying "button not found" even though the clicks worked and we successfully logged in
So the functionality works fine - we do get logged in - but the test fails because SHAFT is checking for the button on the wrong screen due to some timing issue between the action and verification.
i uploaded a video explaining the steps that should be made.
https://github.com/user-attachments/assets/eeba472b-f385-4f6e-9b9d-793d4f31a9b9
And thank you so much for your advices. i made the screenshots "Always" because i wanted to make sure of something in the steps but of course i will change it back to only with assertion.
And for the apk, i had to make it with app activity and app package because the app is installed through firebase so i don't have an apk. but i will ask the devs to make an apk so appium can install it for me. is that what you meant?
@MohabMohie By the way this is the same issue I mentioned on Slack earlier. You had asked me to report it on GitHub but I got caught up with other tasks and when I resumed working on the script and encountered the issue again, I was reminded to finally report it. The Slack thread: https://shaft-engine.slack.com/archives/CTWG4AA0P/p1744816095250259?thread_ts=1742847935.934799&cid=CTWG4AA0P
@SEREPie that's an excellent analysis, however the current core logic of shaft doesn't take a screenshot after clicking the element, and it doesn't assert in any way that the click was successful.
as you can see from the below code block, SHAFT will take the screenshot first, and then click the element.
this block (along with others) exist within a fluent wait block. so, if shaft fails to take the screenshot, it will retry until it's able to take it, and then click the element. nothing calls webdriver after clicking the element. shaft will use the screenshot it had already taken for logging animated gifs (which was broken in the release you're using)
case CLICK -> {
try {
screenshot.set(0, takeActionScreenshot(foundElements.get().getFirst()));
foundElements.get().getFirst().click();
} catch (InvalidElementStateException exception) {
if (SHAFT.Properties.flags.clickUsingJavascriptWhenWebDriverClickFails()) {
((JavascriptExecutor) driver).executeScript("arguments[0].click();", foundElements.get().getFirst());
ReportManager.logDiscrete("Performed Click using JavaScript; If the report is showing that the click passed but you observe that no action was taken, we recommend trying a different element locator.");
} else {
throw exception;
}
}
}
Since some fixes were made to the animated gif and the screenshot upon failure, I suggest upgrading to the release that'll come out in a few hours and trying again.
If the same issue persists, kindly provide a fresh stacktrace. I will debug it and identify the line of code that's causing the issue and will push a new release ASAP.
@MohabMohie It is fixed! π
I've tested on multiple test cases where this bug was occurring, and it's working perfectly now. Also, screenshots are being taken correctly.
Great work and thanks for the response π