How to scroll down is IOS using appium 2.0 in java?

Hi all,

This is the code to scroll vertically in ios device. But this code is not working.
Please tell me where is the error in my code?

public static void scrollToElementIOS(String xpathExpression) {
        IOSDriver driver = (IOSDriver) GlobalVariables.getDriver();
        boolean isElementFound = false;
        int startX = driver.manage().window().getSize().getWidth() / 2;
        int height = driver.manage().window().getSize().getHeight();
        int startY = (int) (height * 0.7); // Adjusted to be within screen bounds
        int endY = (int) (height * 0.3); // Adjusted to be within screen bounds
    
        while (!isElementFound) {
            System.out.println("Scrolling...");
            try {
                Thread.sleep(2000); // Slower scroll with longer wait time
                WebElement element = driver.findElement(AppiumBy.xpath(xpathExpression));
                if (element.isDisplayed()) {
                    isElementFound = true;
                }
            } catch (Exception e) {
                // iOS specific scroll using mobile:scroll
                HashMap<String, Object> scrollObject = new HashMap<>();
                scrollObject.put("direction", "down");
                scrollObject.put("startX", startX);
                scrollObject.put("startY", startY);
                scrollObject.put("endX", startX);
                scrollObject.put("endY", endY);
                driver.executeScript("mobile:scroll", scrollObject);
            }
        }
    }

I tried using TouchActions but they are deprecated in appium 2.0.
Please help!!!

Check appium-xcuitest-driver/docs/guides/gestures.md at master · appium/appium-xcuitest-driver · GitHub

1 Like

@virattomer You can try this code. this will work in android and iOS both.

public void scrollToFindElement(AppiumDriver driver, WebElement sourceElement, String direction) {
        Dimension dimension = driver.manage().window().getSize();
        int height = dimension.getHeight();
        int targetY;
        int sourceX = dimension.getWidth() / 2;
        int sourceY;
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
        Actions actions = new Actions(driver);

        for (int i = 0; i < 5; i++) {
            if (!isElementPresent(sourceElement, 0)) {
                switch (direction.toLowerCase()) {
                    case "down":
                        if (getDevice("platformName").equalsIgnoreCase("ios")) {
                            targetY = height / 4;
                        } else
                            targetY = height / 6;
                        sourceY = (int) (height / 1.15);
                        // Perform swipe action using W3C Actions
                        actions.tick(finger.createPointerMove(Duration.ofMillis(0),
                                        PointerInput.Origin.viewport(), sourceX, sourceY))
                                .tick(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()))
                                .tick(finger.createPointerMove(Duration.ofMillis(1700),
                                        PointerInput.Origin.viewport(), sourceX, targetY))
                                .tick(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()))
                                .perform();
                        break;
                    case "up":
                        if (getDevice("platformName").equalsIgnoreCase("ios")) {
                            sourceY = height / 4;
                        } else
                            sourceY = height / 6;
                        targetY = (int) (height / 1.15);
                        actions.tick(finger.createPointerMove(Duration.ofMillis(0),
                                        PointerInput.Origin.viewport(), sourceX, sourceY))
                                .tick(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()))
                                .tick(finger.createPointerMove(Duration.ofMillis(1700),
                                        PointerInput.Origin.viewport(), sourceX, targetY))
                                .tick(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()))
                                .perform();
                        break;
                    default:
                        throw new IllegalArgumentException("Direction not valid, valid positions - [Down, Up]");
                }
            } else {
                break;
            }
        }
    }
2 Likes

Thanks for the code @zaidakhter0080 . My code also worked. It was locating the element that was not displayed on the screen but was present. So I had to throw a manual exception if isDisplayed() returns false.