Skip to content
Advertisement

Selenium – Wait for the ScrollIntoView to finish

I need to scroll to an element and take a screenshot of the page but the driver takes the screenshot before the page is completely scrolled to the element. I’ve used a time sleep in this way

driver.execute_script("""arguments[0].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });""", element)
time.sleep(1)
scr = driver.get_screenshot_as_png()

but I really don’t want to use sleeps since they are not test-oriented. I’ve tried to wait for the element to be visible but it didn’t work too. Another attempt was to move to the element with ActionChains but it doesn’t show the entire element moving on it. Is there a way to wait for the scroll to finish? Besides this specific case of the screenshot, it would be useful knowing a way to wait for the scroll to finish.

Advertisement

Answer

I found a solution using Javascript waiting until the element is fully visible:

def wait_until_specific_condition(func, timeout=30):
  
    endtime = time.time() + timeout
    while True:
       if time.time() > endtime:
            raise TimeoutException("The condition is not satisfied")
       result = func()
       if result is True:
            return result

So with this function I wait until a specific condition is satisfied; in my case the condition is the entire visibility of the element obtained using Javascript in this way:

driver.execute_script("arguments[0].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });",
                          element)
is_visible_script = """function isScrolledIntoView(el) {
                                    var rect = el.getBoundingClientRect();
                                    var elemTop = rect.top;
                                    var elemBottom = rect.bottom;
                                
                                    // Only completely visible elements return true:
                                    var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
                                    // Partially visible elements return true:
                                    //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
                                    return isVisible;
                                }
                           return isScrolledIntoView(arguments[0]);"""
wait_until_specific_condition(lambda: driver.execute_script(is_visible_script, element))
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement