2

I am currently working on a selenium test to test some pagination buttons

These buttons are outside the viewport of the screen...

In firefox I can execute this code just fine (obviously with driver = webdriver.Firefox)

from selenium.webdriver.common.action_chains import ActionChains
import selenium.common.exceptions
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
url = 'https://stackoverflow.com'

driver.get(url)
driver.maximize_window()

footer_link = driver.find_element_by_css_selector("#footer > div > nav > div:nth-child(1) > h5 > a")
action = ActionChains(driver)
action.move_to_element(footer_link).click().perform()
driver.quit()

(btw this is a minimal production of my error)

Again, the code works just fine in firefox

However in Chrome (version 89), the code fails with this error

selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: move target out of bounds

I have tried a couple things to make it work, and I have been able to make it work by scrolling to the element with execute_script() but I need to use a sleep(), implicit wait, or explicit wait.

I would like to use the established way to scroll to the element without using sleep, aka using the ActionChains object

From the little bit of digging on the internet, I would assume this code to work, but I keep getting the same error...

Any help would be greatly appreciated!

  • From the error, you can see the height is 8545 `Element is not clickable at point (137, 8545)` that is why you can't scroll to it... try [this method](https://stackoverflow.com/a/27760083/6845383) – Moshe Slavin Mar 24 '21 at 23:43

1 Answers1

1

https://github.com/SeleniumHQ/selenium/issues/7315

you have to scroll it into view first ,

also isvisible doesn't check if element is in view port, so its not possible to use wait for visibility

https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/8054

so use :

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import selenium.common.exceptions
from selenium import webdriver
import time

from selenium.webdriver.support.wait import WebDriverWait

options = webdriver.ChromeOptions()

driver = webdriver.Chrome()
url = 'https://stackoverflow.com'

driver.get(url)
driver.maximize_window()

 
footer_link=WebDriverWait(driver, 10).until(EC.presence_of_element_located(
   (By.CSS_SELECTOR, "#footer > div > nav > div:nth-child(1) > h5 > a")))

driver.execute_script("arguments[0].scrollIntoView()", footer_link)

time.sleep(3)


footer_link.click()

driver.quit()

you can use custom waits also:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import selenium.common.exceptions
from selenium import webdriver
import time

from selenium.webdriver.support.wait import WebDriverWait

options = webdriver.ChromeOptions()

driver = webdriver.Chrome()
url = 'https://stackoverflow.com'

driver.get(url)
driver.maximize_window()

 
footer_link=WebDriverWait(driver, 10).until(EC.presence_of_element_located(
   (By.CSS_SELECTOR, "#footer > div > nav > div:nth-child(1) > h5 > a")))

driver.execute_script("$('footer').scrollIntoView(true)", footer_link)

WebDriverWait(driver, 100).until(lambda a: driver.execute_script(
    "return parseInt($('html').scrollTop())>6500"))


footer_link.click()

driver.quit()

here i am using jquery.scrollTop() to get current scroll position.

PDHide
  • 18,113
  • 2
  • 31
  • 46
  • 1
    Thanks, this answer makes sense, and is the approach I will definitely use, I just wish that the ActionChains method move_to_element would work as expected.... Thanks for the answer!! – Nate Simonsen Mar 25 '21 at 16:11