For my Native Android App , I have been trying for the past 2 weeks to get appium to scroll down on my native app. I have tried driver.scrollTo("Accounts");
Then I got this error
[org.openqa.selenium.WebDriverException: CATCH_ALL: io.selendroid.server.common.exceptions.SelendroidException: method (by) not found: -android uiautomator
and many other examples that I have found. Nothing seems to work . This is the latest example that I have tried .
Using appium 1.5.2 and appium java client version: ‘3.3.0'. When I try to run the following code.
TouchAction tAction=new TouchAction(driver);
int startx = driver.findElement(By.id("line_chart_line_chart")).getLocation().getX();
int starty = driver.findElement(By.id("line_chart_line_chart")).getLocation().getY();
int endx = driver.findElement(By.id("actionBarLogo")).getLocation().getX();
int endy = driver.findElement(By.id("actionBarLogo")).getLocation().getY();
System.out.println(startx + " ::::::: " + starty + " ::::::: " + endx + " ::::::: " + endy);
// This is what the console printed out startX=560 ::::::: starty=1420 ::::::: endx=560 ::::::: endy=240
//First tap on the screen and swipe up using moveTo function
tAction.press(startx,starty).moveTo(endx,endy).release().perform();
Then I get this error message
org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Could not proxy. Proxy
error: Could not proxy command to remote server. Original error: 404 - undefined (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 27 milliseconds
I am at a loss on what to do. In order to click on an element it has to be visible on the screen . In order for this element to appear on the screen I need to scroll down to it.
Is there something that I am doing wrong??? I just can't seem to figure it out.
You used Selendroid mode, which does not support UiAutomator By method.
You can change your appium running mode to UiAutomator by setting desired capability automationName to Appium
This function does the trick for me, put in "Accounts" for elementName when calling it in your case.
public static void scrollToElementAndroid(AndroidDriver driver, String elementName, boolean scrollDown) {
String listID = ((RemoteWebElement) driver.findElementByAndroidUIAutomator("new UiSelector().className(android.widget.ListView)")).getId();
String direction;
if (scrollDown) {
direction = "down";
} else {
direction = "up";
}
HashMap<String, String> scrollObject = new HashMap<String, String>();
scrollObject.put("direction", direction);
scrollObject.put("element", listID);
scrollObject.put("text", elementName);
driver.executeScript("mobile: scrollTo", scrollObject);
}
Use code like below:
Dimension size = driver.manage().window().getSize();
int x = size.width / 2;
int endy = (int) (size.height * 0.75);
int starty = (int) (size.height * 0.20);
driver.swipe(x, starty, x, endy, 1000);
Related
I am unable to scroll down in mobile page on an android device using appium. I have tried driver.scrollTo(element) , it is not scrolling down to the specified element.
I have tried using Actions class but I got an error as "Method has not been implemented yet"
I have tried another approach using Javascript but it didn't work either.
Someone give suggestion.
Here is the code:
public static void main(String[] args) throws IOException, InterruptedException {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(CapabilityType.BROWSER_NAME, "Android"); //Name of mobile web browser to automate. Should be an empty string if automating an app instead.
cap.setCapability(CapabilityType.VERSION, "6.0.1");
cap.setCapability(CapabilityType.PLATFORM, "Mac");
cap.setCapability("platformName", "android");
cap.setCapability("platformVersion", "6.0.1");
cap.setCapability("deviceName", "4d00a89e4b2631e9");
cap.setCapability("app", "/Users/ds_nivedha/Downloads/flipkart.apk");
cap.setCapability("appPackage", "com.usablenet.mobile.walgreen"); //Replace with your app's package
cap.setCapability("appActivity", "com.usablenet.mobile.walgreen.AppStart"); //Replace with app's Activity
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), cap);
driver.manage().timeouts().implicitlyWait(90, TimeUnit.SECONDS);
/* MobileElement skip= driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[2]/android.widget.Button[1]"));
skip.click(); */
MobileElement skiparrow=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[3]/android.widget.ImageButton[1]"));
skiparrow.click();
MobileElement skiparrowRefill=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[2]/android.widget.ImageButton[1]"));
skiparrowRefill.click();
MobileElement skiparrowPaperless=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[2]/android.widget.ImageButton[1]"));
skiparrowPaperless.click();
MobileElement done=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.Button[1]"));
done.click();
MobileElement shopProducts=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]/android.widget.TextView[2]"));
shopProducts.click();
MobileElement personalCare=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.ScrollView[1]/android.widget.LinearLayout[1]/android.widget.GridView[1]/android.widget.TextView[2]"));
personalCare.click();
MobileElement hairCare=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.ListView[1]/android.widget.TextView[3]"));
hairCare.click();
MobileElement stylingProduct=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.ListView[1]/android.widget.TextView[3]"));
stylingProduct.click();
MobileElement faroukAddToCart=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.webkit.WebView[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[3]/android.view.View[2]/android.view.View[1]/android.view.View[3]/android.view.View[1]/android.view.View[1]/android.view.View[4]/android.view.View[1]/android.view.View[1]/android.view.View[2]/android.widget.Button[1]"));
faroukAddToCart.click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//android.widget.Button[contains(#resource-id,'addToCart-cart-checkout')]")));
driver.findElement(By.xpath("//android.widget.Button[contains(#resource-id,'addToCart-cart-checkout')]")).click();
//driver.scrollTo("Proceed to checkout");
MobileElement proceedToCheckout=
driver.findElement(By.xpath("//android.widget.Button[contains(#resource-id,'proceedtocheckout')]"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", proceedToCheckout);
Thread.sleep(500);
/* Actions actions = new Actions(driver);
actions.moveToElement(proceedToCheckout);
actions.perform(); */
MobileElement checkout=
driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.webkit.WebView[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[2]/android.view.View[2]/android.view.View[5]/android.view.View[2]/android.view.View[5]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.widget.Button[1]"));
checkout.click();
Use swipe method
Keep start x and end x value constant and change start y and end y values to scroll up or down
The scrollTo() method is deprecated now, you can check on the official site over here
Instead if it you can use swipe method to swipe vertically on mobile device and to check if your expected text is visible or not, in not then you can make more swipes, of course you will be using loop for doing so.
To know more about Swipe refer here
For Swipe method refer below example
public void swipingVertical() throws InterruptedException {
//Get the size of screen.
size = driver.manage().window().getSize();
System.out.println(size);
//Find swipe start and end point from screen's with and height.
//Find starty point which is at bottom side of screen.
int starty = (int) (size.height * 0.80);
//Find endy point which is at top side of screen.
int endy = (int) (size.height * 0.20);
//Find horizontal point where you wants to swipe. It is in middle of screen width.
int startx = size.width / 2;
System.out.println("starty = " + starty + " ,endy = " + endy + " , startx = " + startx);
//Swipe from Bottom to Top.
driver.swipe(startx, starty, startx, endy, 3000);
Thread.sleep(2000);
//Swipe from Top to Bottom.
driver.swipe(startx, endy, startx, starty, 3000);
Thread.sleep(2000);
}
Let me know if you face any more hurdle in this.
I have java 1.4 application that is running on server.
I need to calculate the width of strings before I create pdf files that include them.
When running the app locally (on my pc) it is o.k. , but when I run it on a server I get an error :
Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY
variable.
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:77)
at java.lang.Class.forName1(Native Method)
at java.lang.Class.forName(Class.java:142)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:72)
at java.awt.Font.initializeFont(Font.java:285)
at java.awt.Font.<init>(Font.java:319)
the code that create the problem calculate the width of a string as follows :
protected static String mCutStr(String iText , int iWidthPt , int iEstimatedNumOfChars)
{
iWidthPt = iWidthPt-4; //remove padding
AffineTransform affinetransform = new AffineTransform();
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);
Font font = new Font("Times", Font.PLAIN, 9);
int textwidth = (int)(font.getStringBounds(iText, frc).getWidth());
// System.out.println("iText="+iText+"; textwidth = "+textwidth+" iWidthPt ="+iWidthPt);
if(textwidth <= iWidthPt)
return iText;
String vTestStr = iText.substring(0 , iEstimatedNumOfChars)+">>";
textwidth = (int)(font.getStringBounds(vTestStr, frc).getWidth());
while(textwidth < iWidthPt)
{
iEstimatedNumOfChars++;
vTestStr = iText.substring(0 , iEstimatedNumOfChars)+">>";
textwidth = (int)(font.getStringBounds(vTestStr, frc).getWidth());
// System.out.println("vTestStr="+vTestStr+" textwidth = "+textwidth);
}
vTestStr = iText.substring(0 , iEstimatedNumOfChars-1)+">>";
return vTestStr;
}
Is there an other way to calc this without using AWT?
(it must support minimum java 5)
You need to run your server in headless mode. Headless mode is useful when actual Window system like X server is not available and you need to perform some AWT related functions.
Java Documentation about Headless mode
If you are using web server like tomcat search how to execute that specific server in headless mode
OR
set system environment property java.awt.headless to true
I'm using Java to automate tests for mobile web on ios safari
Everything seems to be set up correctly but appium is crashing with the error:
uncaughtException: Cannot read property 'x' of undefined
the touch command comes through in the logs like so:
info: --> POST /wd/hub/session/1a925d31-d3cd-4231-9698-f7ff4db739fd/touch/perform {"actions":[{"action":"press","options":{"element":"5001"}},{"action":"wait","options":{"ms":1}},{"action":"release","options":{}}]}
info: [debug] Pushing command to appium work queue: "au.getElement('5001').rect()"
info: [debug] Sending command to instruments: au.getElement('5001').rect()
my code looks like this:
public void tap(MobileElement element) {
appiumDriver.context(getContext("NATIVE"));
element.tap(1,1);
appiumDriver.context(getContext("WEBVIEW"));
}
protected String getContext(String partial) {
String result = null;
Set<String> contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
if(contextName.contains(partial)){
result = contextName;
}
}
if (result == null){
throw new NoSuchContextException("Could not find requested context");
}
return result;
}
and I'm feeding it a mobileElement.
I can get the element location by treating it like a WebElement and doing getlocation() and then I can use a TouchAction, which works in terms of what appium is doing, but the location is super off so I'm trying to use the mobileElement tap() action here instead.
Does anyone know a workaround or see what I might be doing wrong? My site has a lot of elements that require a tap().
This also occurs when I define a WebElement, then move into Native context and use iosDriver.tap(1, webelement, 1); with the same crash on the appium side.
Try below:
AppiumDriver appiumDriver = new AppiumDriver();
String originalContext = appiumDriver.getContext();
Point coordinate = element.getLocation();
Dimension loc = element.getSize();
int centerX = loc.getWidth() / 2 + coordinate.getX();
int centerY = loc.getHeight() / 2 + coordinate.getY();
appiumDriver.context("NATIVE_APP");
appiumDriver.tap(1, centerX, centerY, 2);
appiumDriver.context(originalContext);
The Issues is that, in Native context Appium does not have any visibility to webelements on the webPage, You need to get the coordinated and then click using Tap method with coordinates
I need to transform coordinates using GeoTools. My code works fine in a Java project but when I put it in the Android I get the error at the mathTransform.transform(...) line: "The type java.awt.geom.Point2D$Double cannot be resolved. It is indirectly referenced from required .class files".
Here's my code:
CoordinateReferenceSystem sourceCrs = CRS.decode("EPSG:3765");
CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326");
boolean lenient = true;
double x, y;
MathTransform mathTransform = CRS.findMathTransform(sourceCrs, targetCrs, lenient);
parts = result.split(" ");
String coors = "";
for (int i = 0; i < parts.length; i += 2) {
x = Double.parseDouble(parts[i]);
y = Double.parseDouble(parts[i+1]);
DirectPosition2D srcDirectPosition2D = new DirectPosition2D(sourceCrs, x, y);
DirectPosition2D destDirectPosition2D = new DirectPosition2D();
mathTransform.transform(srcDirectPosition2D, destDirectPosition2D);
x = destDirectPosition2D.x;
y = destDirectPosition2D.y;
coors += x + " " + y + " ";
}
System.out.println(coors + ";");
Now I found this question which explains the reasons for it: Can't import Java awt in Eclipse, but what would be the solution?
what would be the solution?
You could not use this JAR, but instead find some other similar library that is ready for Android.
Or you could read up on prior attempts to get GeoTools working on Android.
Or you could contribute code changes back to the project that eliminate references to java.awt classes, replacing that code with algorithms implemented in the library itself.
Basically, Im just trying out a very simple collision test for another program Im working on, but it does seem to so simple (Or maybe Im just an idiot!) Anyway, here is the code:
public void run() {
while(true){
try {
if(rect.rect.intersects(rect1.rect)){
System.out.println("Test1");
if(rect1.x == ((rect.x + rect.width)-1)){
System.out.println("Test2");
rect1.x = rect.x + rect.width;
rect1.dx = 0;
}
}
rect.update();
rect1.update();
Thread.sleep(50);
The program does not get to test2!
Any help to solve this issue is greatly appreciated! Thanks in advance!
Paint component part:
public void paintComponent(Graphics g){
rect1.paint(g);
rect2.paint(g);
g.drawString(String.valueOf(rect1.x), 100, 100);
g.drawString(String.valueOf(rect2.x+rect2.width), 100, 150);
repaint();
}
Image:
Run the program in Eclipse (or your preferred IDE) and use its runtime debug facilities to set a breakpoint at the first if statement. Then step through and examine the values of the variables. Hopefully this will make clear why your code is failing to do what you expect.
How about constructing this method just for debugging convenience (unless you have a debugger):
public static printRectProperties(Rectangle rect, String rectangleName){
System.out.println(rectangleName + ": x = " + rect.x + ", y = "
+ rect.y + ", width = " rect.width + ", height = " + rect.height;
}
Then you can simply call this method to log statistics about the rectangles prior to the execution of the if statement:
if(rect.rect.intersects(rect1.rect)){
System.out.println("Test1");
printRectProperties(rect, "rect");
printRectProperties(rect1, "rect1");
if(rect1.x == ((rect.x + rect.width)-1)){
System.out.println("Test2");
That should make it easy to figure out why "Test2" is never printed.