Hi yes @Suraj786.
The Problem:
Clicking on web element but nothing happens because the click happens at the wrong location. I tested my click method on an Android device with touch pointer location ON and the co-ordinates were all wrong.
The Cause:
My app is designed in such a way that it stretches the content to fit the screen with the content. Selenium/Appium expects the content to be placed in the un-stretched location and therefore performs click at the wrong location.
The Solution:
The solution is VERY simple. Many people have tried to explain it but have failed to present it in a good way. I hope my explanation makes sense to you and to anyone who reads it in the future. Here it is -
Due to the stretching of content, there is a difference between the device pixels and the css pixels. Device pixels are native screen pixels which are different from css pixels on web. We can get the css pixels from element.getLocation(). All we need to do is multiply it with the right ratio and voila, we get the correct location.
Let us say that the location that we get when we use element.getLocation() be (x1, y1).
Switch to web context (can be any webview just switch to it).
Get the element location (x1, y1)
Get the element size
Get the window size via driver.manage().window().getSize();
Run 2 javascript queries to get screen.availHeight and screen.availWidth
Switch to native context
Your ratio for correct x-coordinate will be availWidth/windowWidth
Your ratio for correct y-coordinate will be availHeight/windowHeight
Find the center of the element you want to tap on using it's location and dimensions.
Now multiply this central point with the ratio you just calculated.
Sorted.
My code in Java looks as follows:
switchContext(true);
Point elementLocation = element.getLocation();
Dimension elementSize = element.getSize();
Dimension windowSize = driver.manage().window().getSize();
JavscriptExecutor js = (JavascriptExecutor) driver;
long webRootWidth = js.executeScript("return screen.availWidth");
long webRootHeight = js.executeScript("return screen.availHeight");
switchContext(false);
double xRatio = (double) (webRootWidth * 1.0 / windowSize.getWidth());
double yRatio = (double) (webRootHeight * 1.0 / windowSize.getHeight());
int pointX += (int) ((elementLocation.getX() + elementSize.getWidth() / 2.0));
int pointY += (int) ((elementLocation.getY() + elementSize.getHeight() / 2.0));
return new Point((int) (pointX * xRatio), (int) (pointY * yRatio));
Let me know if you still cannot find any solution. If this doesn't help you, let me know, I had a lot of problem with finding the right algorithm and making it my own and I would be happy to help everyone else as well.
Also, I've made a framework of my own using Appium and Selenium to run generic test scripts across all Android, iOS and Web platforms for certain apps. So I've had my fair share of problems with Appium. But in the end it all works out.
Going to start a blog soon as well. Again, hope I helped someone. Over and out.