0

I have this function who scroll an element into view and then click on it:

    private void iClickOnElement(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.elementToBeClickable(element));

        String scrollElementIntoMiddle = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);"
                + "var elementTop = arguments[0].getBoundingClientRect().top;"
                + "window.scrollBy(0, elementTop-(viewPortHeight/2));";

        ((JavascriptExecutor) driver).executeScript(scrollElementIntoMiddle, element);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        element.click();
    }

Since the scroll is "smooth", I added a "sleep()" to make sure the element is actually scrolled into view before I click on it.

However, using the sleep is ugly and I would like to just be able to wait for the scroll to be over before I click on anything. How can I do that?

I'm aware of this question but I'm not good enough with javascript interacting with selenium to make use of it.

7
  • Seems to me you have it backwards. You're waiting until the element is clickable first, then scrolling. Are you doing this (scroll) because it is not clickable unless it's also visible on-screen? I would do the scroll, then wait until displayed or clickable (no sleep statement). Jul 1, 2019 at 18:11
  • @BillHileman I'm using Firefox, so Firefox might say "this is clickable" and then complain that it's not because something obscure it. So I first ask "is this clickable", then scroll into view, then click. This used to work fine, but now the scrolling is "smooth" and not instantly like it used to be, so the scrolling might not be over when I click. Jul 1, 2019 at 18:15
  • Do you mean that it clicks before the element is visible or the element is visible, but the screen is still scrolling? If the former, you might want to consider just adding another wait (instead of sleep) with the condition visible (not clickable) Jul 1, 2019 at 18:18
  • Since you're already using javascript, you could also query the document readystate for "complete" Jul 1, 2019 at 18:21
  • @BillHileman According to Firefox, my element is visible even when it's not yet scrolled into view. Also, the document is already reading when the scrolling starts, so querying the document ready state wouldn't help. Jul 1, 2019 at 18:26

1 Answer 1

1

Below are my methods to scroll into view:

/**
 * Wait until JQuery is inactive
 * @author M1033792 - Bill Hileman
 */
public void waitForJQueryToBeInactive() {

    Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
            .executeScript("return (typeof(jQuery) != 'undefined')");

    if (isJqueryUsed) {
        while (true) {
            // JavaScript test to verify jQuery is active or not
            Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
                    .executeScript("return jQuery.active == 0"));
            if (ajaxIsComplete)
                break;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
    }

}

/** 
 * Scroll a web element into view
 * @author M1033792 - Bill Hileman
 * @param ele - WebElement
 */
public void scrollIntoView(WebElement ele) {

    ((JavascriptExecutor)driver).executeScript("window.scrollTo(" + ele.getLocation().x + 
                                                                "," + ele.getLocation().y + ")");
    waitForJQueryToBeInactive();

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.