Swipe is not working in ios devices - appium

I have a app that want to allow contacts from a device event. I used
(autoAlertAccept,true) but that won't work for me. I am using appium 1.5.2 and
even I want to swipe that particular contact to chat or call with
that particular contact. When I used a:
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
driver.findElement(By.className("android.widget.ImageButton")).click();
size1 = driver.manage().window().getSize();
System.out.println(size1); int x1 = (int) (size1.width * 0.70);
int x2 = (int) (size1.width * 0.30);
int starty =size1.height / 2;
System.out.println(x1 + x2 + starty);
driver.findElement(By.name("Demo Usr"));
driver.swipe(x1,starty,x2,starty,3000);
I found some exception

ur provided code will swipe the screen from left to right. But to move an element from one position to another, use the below code:
WebElement elem = driver.findElement(By.xpath("ur xpath"));//get element locator as ur wish by accesibility id or xpath.
int startX = elem.getLocation().getX();
int startY = elem.getLocation().getY();
//this will swipe from right to left horizontally
driver.swipe(startX,startY,startX-90,startY,2000);
// use 90 or more according to ur screen position
//this will swipe from left to right horizontally
driver.swipe(startX,startY,startX+90,startY,2000);
//u must have to be sure that this location is within the screen, otherwise u will get an error
If there is any issue let me know.

Related

Appium - Horizontal Scroll view

I am using an android app that has horizontal scroll view, how to traverse through each of these items inside the horizontal scroll view using appium . The items change dynamically, so using textview won't work. Is there any method to get the length of the horizontal scroll view and traverse using loop?
Here is how i deal with a similar situation:
assuming you want to scroll down to a specific textView element.
while(!driver.findElement(By.id("textViewId").isdisplayed){
scrollDownManually();
}
public void scrollDownManually() {
Dimension size = Android.driver.manage().window().getSize();
int starty = (int) (size.height * 0.80);
int endy = (int) (size.height * 0.20);
int startx = size.width / 2;
Android.driver.swipe(startx, starty, startx, endy, 1000);
}
You can always perform swipe actions
TouchAction t=new TouchAction(driver);
//long press, for atleast 1 sec first and move the object
WebElement First=driver.findElementByXPath("//*[**First Element**]");
WebElement second=driver.findElementByXPath("//*[**Second Element**]");
t.longPress(longPressOptions().withElement(element(First)).withDuration(ofSeconds(3))).moveTo(element(second)).release().perform();

Appium 6.1.0 TouchActions vs TouchAction

I was searching for the "right", or the "latest" way to create Tap/Swipe/Drag etc. events using the latest (at this point) Appium Java-client 6.1.0.
I saw different documentations in the Appium site (Tap using TouchActions, Touch using TouchAction), and there is no reference as which should i use (and which is going to be deprecated?).
new TouchAction(driver)
.tap(tapOptions()
.withElement(element(myElement)))
.perform();
new TouchActions(driver)
.singleTap(myElement)
.perform();
It seems that TouchActions is a part of the Selenium project and TouchAction is a part of the Appium, but it does not mean that the Appium is the correct way.
p.s I am using at the moment Chrome/Safari browsers for Android/iOS the testing, but that does not mean that i don't need native apps support for the code.
Thank you for your time
The latest approach to using TouchAction class is to use AndroidTouchAction class instead of TouchAction class as the same is now made generic. That's why you see #SuppressWarnings("rawtypes") being used in the last answer.
This is how you will tap on an element in 6.1.0
For Android:
AndroidTouchAction touch = new AndroidTouchAction (driver);
touch.tap (TapOptions.tapOptions ()
.withElement (ElementOption.element (e)))
.perform ();
For iOS:
IOSTouchAction touch = new IOSTouchAction (driver);
touch.tap (TapOptions.tapOptions ()
.withElement (ElementOption.element (e)))
.perform ();
You want to use TouchAction (Appium).
Below is a section of my code. The first is the general scroll function which takes coordinates as parameters. You generally would not call that function directly, it was meant to be called by other functions, like the scrollDown function I've included below it, that calculates the coordinates and calls the general scroll function.
Hope this helps.
/**
* This method scrolls based upon the passed parameters
* #author Bill Hileman
* #param int startx - the starting x position
* #param int starty - the starting y position
* #param int endx - the ending x position
* #param int endy - the ending y position
*/
#SuppressWarnings("rawtypes")
public void scroll(int startx, int starty, int endx, int endy) {
TouchAction touchAction = new TouchAction(driver);
touchAction.longPress(PointOption.point(startx, starty))
.moveTo(PointOption.point(endx, endy))
.release()
.perform();
}
/**
* This method does a swipe upwards
* #author Bill Hileman
*/
public void scrollDown() {
//The viewing size of the device
Dimension size = driver.manage().window().getSize();
//Starting y location set to 80% of the height (near bottom)
int starty = (int) (size.height * 0.80);
//Ending y location set to 20% of the height (near top)
int endy = (int) (size.height * 0.20);
//x position set to mid-screen horizontally
int startx = (int) size.width / 2;
scroll(startx, starty, startx, endy);
}

How to check if element is visible in viewport?

If I am at the bottom of the page how can I check if some element is visible if that element is for example at the top of the page.
I need to write a test where I scroll down to the bottom of the page and when I click on div it moves me back to the top of the page. Next step is to check if I am at that position.
My idea was that I just need to check if that element is visible but it turns out that it is not that easy to do. Any suggestions?
.isDisplayed() and .isFocused() is not what I need.
Edit:
I had an idea and I need two methods for it.
First one is to get y coordinate of the element (we need only y), but the problem is that getY() returns number relative to your current position, so I need something that will move me to that element and then get y coordinate. So my method looked something like this:
int getYCoordinat() {
// first move to the element
interact {
moveToElement(element)
}
// get y coord
return element.getY()
}
second method looked something like this:
boolean isScrolledToElement(int yCoordinateOfElement) {
int y = element.getY()
return y == yCoordinateOfElement
}
}
So first I would call getYCoordinat(), store integer into yCoordinateOfElement.
Then I would click on div that moves me to the element and call isScrolledToElement(yCoordinateOfElement).
But it doesnt work because moveToElement moves you to that element only if the element is not visible. So if we stay where we are because moveToElement() didn't move us, because element is already visible, we get the wrong Y coordinate that won't be same as the one which we get when we click on div that moves us to the element.
Here is the only solution I could find. Basically you need to see if the pixel coordinate of the bottom-right corner of your element is within the window.
Taken from the link:
private boolean isWebElementVisible(WebElement w) {
Dimension weD = w.getSize();
Point weP = w.getLocation();
Dimension d = driver.manage().window().getSize();
int x = d.getWidth();
int y = d.getHeight();
int x2 = weD.getWidth() + weP.getX();
int y2 = weD.getHeight() + weP.getY();
return x2 <= x && y2 <= y;
}

Access iOS Control Center using appium

I am trying to open the Control Center using appium and the following code:
int halfWidth = driver.manage().window().getSize().width / 2;
int screenHeight = driver.manage().window().getSize().height;
driver.swipe(halfWidth, screenHeight-5, halfWidth, screenHeight-300, 500); // driver is instance of IOSDriver
Instead of opening control centre the app simply draws on the screen upwards from the bottom (using coordinates input). Anyone know how to open Control Center using appium and swipe (or any other way)?
Thanks, Charlie
We can do this. I tried in Appium 1.4.13 and I am able to change settings.
I used below code to change the settings in my iPadAir2.
int height = driver.findElementByClassName("UIAWindow").getSize().getHeight();
int width = driver.findElementByClassName("UIAWindow").getSize().getWidth();
driver.swipe(width-100, height, width-100, height-200, 500);
driver.findElementByAccessibilityId("Wi-Fi").click();
Appium 1.6.5, You can use swipe method, bellow my Python code:
window_size = self.driver.get_window_size() # this returns dictionary
el = self.driver.find_element(*self.configuration.CommonScreen.WEB_VIEW)
action = TouchAction(self.driver)
start_x = window_size["width"] * 0.5
start_y = window_size["height"]
end_x = window_size["width"] * 0.5
end_y = window_size["height"] * 0.5
action.press(el, start_x, start_y).wait(100).move_to(el, end_x, end_y).release().perform()
I am able to toggle the Wifi OFF or turn Airplane mode ON using Appium 1.6.4-beta for iOS
Swipe up from the bottom of the screen
Click continue link
Click the Wifi or Airplane button
Swipe down from middle of screen
But this doesn't appear to be doing anything in the simulator. I have to actually turn off my computers internet connection to disable the internet on the simulator.
#iOSFindBy(xpath = "//XCUIElementTypeSwitch[#name='Wi-Fi']")
private MobileElement WIFI_MODE_BUTTON;
public void disableWifi() {
openToolBarMenu();
//if wifi is on/true then turn it off
if (WIFI_MODE_BUTTON.getAttribute("value") == "true" ) {
Autoscope.tap(WIFI_MODE_BUTTON);
}
closeToolBarMenu();
}
#iOSFindBy(xpath = "//XCUIElementTypeButton[#name='Continue']")
private MobileElement CONTINUE_BUTTON; //continue button on control center
public void openToolBarMenu() {
Autoscope.scrollFromBottomOfScreen();
if (Autoscope.isElementDisplayed(CONTINUE_BUTTON)) {
Autoscope.tap(CONTINUE_BUTTON);
}
}
static public void scrollFromBottomOfScreen() {
TouchAction touchAction = new TouchAction(autoscopeDriver);
int xStartPoint = Math.round(pixelWidth() / 2);
int yStartPoint = pixelHeight();
int yEndPoint = 0 - yStartPoint;
touchAction.press(xStartPoint, yStartPoint).moveTo(0, yEndPoint).release().perform();
}
This code will help in bringing up the Control center, while you are in your app, you can perform all the operations which are available in the Control Center
new TouchAction(DriverConfig.getInstance().getDriver()).press(point(250, 735)).waitAction(waitOptions(Duration.ofSeconds(3))).moveTo(point(250, -460)).release()
.perform();
C#: iOS 13.x
//Opening control center
var size = Driver.Manage().Window.Size;
var height = size.Height;
var width = size.Width;
var touchAction = new TouchAction(Driver);
touchAction.Press(width - 100, height).Wait(1000).MoveTo(width - 100, height - 200).Release().Perform();
//Clicking the WiFi button
Driver.FindElementByAccessibilityId("wifi-button").Click();
//Checking if WiFi enabled or not
var myElement = Driver.FindElementByAccessibilityId("wifi-button");
var result = myElement.GetAttribute("label");
if(!result.Contains("Wi-Fi, Not Connected") && !result.Equals("Wi-Fi"))
{
// WiFi connected
}
else
{
// WiFi Not connected
}
The idea is to simulate the swipe action you use to open Control Center on the corresponding iOS device. My device is iPhone 11 so it is swipe from the top right(to the right of the notch) down. My code is to swipe from position(x,y) (80% width, 0) to (80% width, 50% height)
Dimension size = getScreenSize();
int x = (size.getWidth() / 5) * 4;
int startY = 0;
int endY = size.getHeight() / 2;
new TouchAction(driver).press(PointOption.point(x, startY))
.waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)))
.moveTo(PointOption.point(x, endY))
.release().perform();
Ok so after a fair amount of investigation it seems to me that this is not possible. If you really need this functionality then I think a tool like eggplant might be appropriate.

position view relative to tab indicator

I've been given a UI that uses a UITabBarController, and in one of the tabbed ViewControllers, a View (an arrow as a UIImageView) needs to be positioned relative to the tab indicator (the arrow needs to point down at the indicator, centered along the x-axis). I used basic math to emulate the position based on known variables, and it works properly for iPhone/Pod in both landscape and portrait orientations, but fails on iPad (it's a little too far right in both orientations - seems worse in landscape but that might just be my perception).
Here's what I used:
int visibleWidth = self.view.frame.size.width;
int tabBarSize = self.tabBarController.tabBar.frame.size.width;
int tabSize = tabBarSize / [self.tabBarController.viewControllers count];
int tabPosition = 2; // hint should point at the 3rd tab
int arrowIconWidth = hintIcon.image.size.width;
int arrowIconHeight = hintIcon.image.size.height;
int tabEmulationPosition = visibleWidth / 2 - tabBarSize / 2;
int tabOffsetPosition = tabEmulationPosition + ( tabSize * tabPosition );
int iconPosition = tabOffsetPosition + ( tabSize / 2 - arrowIconWidth / 2 );
Is there a better way than trying to "fake" the math (maybe a getBoundingClientRect type method?) Or is the math approach the best bet, assuming there's a correct-able flaw in what I've got?
TYIA
Your math seems alright except one caveat: the Core Graphics distances are all of type CGFloat not int. Remember that integer division works differently in C than what you might expect:
int x = 5 / 2; // x == 2
Thus, replace your ints with CGFloats and divide by 2.0 rather than 2.
Also, in the iPad the tab button are not necessarily spaced evenly across the whole bar but have a certain padding to the left and right. You would have to fiddle for finding a suitable constant, or experimentally find a reliable way to calculate it based on the number of view controllers.
Assuming a fixed tab bar button width, you could calculate an offset to add to the x of your image:
CGFloat tabSize =
FIXED_TAB_BUTTON_WIDTH * self.tabBarController.viewControllers.count;
CGFloat offset = (tabBarSize - tabSize) / 2.0;

Resources