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!
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.