Scroll/Swipe to specific Element Help for an IOS App

Hi there !!

I’m kind a new to appium and during my test automation I observed there are no “scrollTo” and “scrollToExact” functionalities in latest appium version. Is this correct ? If so, kindly let me know how can I perform scrollToSpecificElement using appium for IOS App.

Additionally,

I tried the following piece of code which does the “SWIPE.UP” in the “TableView” of the App :

HashMap scrollMap = getScrollStartAndEndElements(driver); // This function gets the start and end coordinates calculated from dimensions of the window and relevant element dimensions

Map Contains : {{start,start_coordinates},{end,end_coordinates}}

for(int i=0;i< driver.findElementsByXPath("//XCUIElementTypeTable//XCUIElementTypeCell").size();i++)
{
driver.swipe(0, ((Integer) scrollMap.get(“start”)), 0, (Integer) scrollMap.get(“end”), 2000);
}

But how can I exactly scrollToSpecificElement using above code or any alternative way. Any help would be greatly appreciated.

@Karthik_Sriharsha
when you list not LONG (cause it can take long time to fail if element not exists) you can user something like:

public boolean tapItemByDescription(String text) {
        System.out.println("   tapItemByDescription(): " + text);

        // scroll to item
        JavascriptExecutor js = (JavascriptExecutor) driver;
        HashMap scrollObject = new HashMap<>();
        scrollObject.put("predicateString", "value == '" + text + "'");
        js.executeScript("mobile: scroll", scrollObject);

        // tap item
        WebElement el = ((IOSDriver) driver).findElementByIosNsPredicate("value = '" + text + "'");
        return tapElement((MobileElement) el);
    } 

other approach swipe manually and check that element on screen (assumption in this function that element is located BUT it is below screen. when you build list dynamically you should slightly update):

public boolean tapItemByDescription(String text) {
        System.out.println("   tapItemByDescription(): " + text);

        int y;
        MobileElement el = (MobileElement) ((IOSDriver) driver).findElementByIosNsPredicate("value = '" + text + "'");
        if (el != null) {
            try {
                y = el.getCenter().getY();
                System.out.println("   el y = " + y);
                while (y <= 0) {
                    swipeToDirection_iOS(mainContainer.get(0), "u", 120);
                    y = el.getCenter().getY();
                }
                try{Thread.sleep(300);}catch (Exception e){}
                if (tapElement(el)) {
                    return true;
                } else { //not scrolled enough yet
                    System.out.println("    tapItemByDescription: cellContainer not visible do scroll up again");
                    swipeToDirection_iOS(mainContainer.get(0), "u", 120);
                    try{Thread.sleep(300);}catch (Exception e){}
                    return tapElement(el);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

Hi Aleksei,

Can you kindly explain the “swipeToDirection_iOS(mainContainer.get(0), “u”, 120)” function ???

it is just mine custom function that actually does:

public void swipeToDirection_iOS(MobileElement elemContainer, String dir, Integer byNumberOfPixels, Integer startPointShift, Integer durationLength) {
        int duration = 1000; // = 1sec
        if (durationLength!=null)
            duration = durationLength;
        //get location and size
        point = elemContainer.getLocation();
        size = elemContainer.getSize();
        int x_start, y_start, x_end, y_end, screenWidth, screenHeight;
....
if (dir.equals("l")) {
...
            ((IOSDriver) driver).swipe(x_start, y_start, x_end, y_start, duration);
}

Hi again !!

Sorry got :confused: with the “container” word in your function. Thanks again for the prompt reply.

One qq, I see that swipe is also deprecated in the latest version (though we can use it currently). There is alternative to swipe ???

@Karthik_Sriharsha alternative code from appium (use it :- ):

    /**
     * This method is deprecated. It is going to be removed
     */
    @Override public void swipe(int startx, int starty, int endx, int endy, int duration) {
        int xOffset = endx - startx;
        int yOffset = endy - starty;
        new TouchAction(this).press(startx, starty).waitAction(duration).moveTo(xOffset, yOffset).release().perform();
    }

// or

    public boolean swipeToDirection_iOS_XCTest(MobileElement el, String direction) {
        try {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            HashMap<String, String> swipeObject = new HashMap<String, String>();
            if (direction.equals("d")) {
                swipeObject.put("direction", "down");
            } else if (direction.equals("u")) {
                swipeObject.put("direction", "up");
            } else if (direction.equals("l")) {
                swipeObject.put("direction", "left");
            } else if (direction.equals("r")) {
                swipeObject.put("direction", "right");
            }
            swipeObject.put("element", el.getId());
            js.executeScript("mobile:swipe", swipeObject);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

Hi,
I have used the above code to swipe in iOS but it not working for me… Same code is working in android though.
There is no error message displaying but there is no swipe happening on the phone… Please help me the solution.

Check that element you swipe is correct.