Selenium – MoveTargetOutOfBoundsException with Firefox
Question:
I’v got problem with function move_to_element on Firefox Webdriver (Chrome, IE works well)
driver = webdriver.Firefox()
driver.get("https://stackoverflow.com")
time.sleep(5)
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
ActionChains(driver).move_to_element(source_element).perform()
I am working with these versions: geckodriver – 0.17.0 // Firefox – 54.0 // selenium – 3.4.3
After running this script, on output shows:
selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: (134.96666717529297, 8682.183013916016) is out of bounds of viewport width (1268) and height (854)
Answers:
This error…
selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: (134.96666717529297, 8682.183013916016) is out of bounds of Viewport width (1268) and height (854)
…implies that the element you are looking for is not within the Viewport. We need to scroll down to bring the element within the Viewport. Here is the working code:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains
binary = FirefoxBinary('C:\Program Files\Mozilla Firefox\firefox.exe')
caps = DesiredCapabilities().FIREFOX
caps["marionette"] = True
driver = webdriver.Firefox(capabilities=caps, firefox_binary=binary, executable_path="C:\Utility\BrowserDrivers\geckodriver.exe")
driver.get("https://stackoverflow.com")
last_height = driver.execute_script("return document.body.scrollHeight")
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
ActionChains(driver).move_to_element(source_element).perform()
Let me know if this Answers your Question.
I think the correct answer here got lucky that the element they were looking for happened to be at the bottom of the page and didn’t really explain why this occurs in Firefox commonly.
Browsers other than Firefox treat Webdrivers move_to_element
action as scroll to part of page with element then hover over it. Firefox seems to have taken a hardline stance that move_to_element is just hover and are waiting for a scroll action to fix this.
For now you have to workaround this bug using javascript as mentioned in previous answer, but I suggest using something like this instead of arbitrarily (well I guess the example was a footer) scrolling to bottom of page and hoping object is still in view.
def scroll_shim(passed_in_driver, object):
x = object.location['x']
y = object.location['y']
scroll_by_coord = 'window.scrollTo(%s,%s);' % (
x,
y
)
scroll_nav_out_of_way = 'window.scrollBy(0, -120);'
passed_in_driver.execute_script(scroll_by_coord)
passed_in_driver.execute_script(scroll_nav_out_of_way)
Then later
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
if 'firefox' in driver.capabilities['browserName']:
scroll_shim(driver, source_element)
# scroll_shim is just scrolling it into view, you still need to hover over it to click using an action chain.
actions = ActionChains(driver)
actions.move_to_element(source_element)
actions.click()
actions.perform()
You can try below while automating the script in Firefox when it usually throws MoveTargetOutOfBoundsException error:
One can transform/Zoom-in or out by
driver.execute_script("document.body.style.transform='scale(0.9)';")
Sometimes if you are running automation script in Jenkins(CI tools), you might also face the issue from above transform code where content of browser is scaled out not the actual browser, in those condition you can try out to resize the browser window:
driver.set_window_size(x, y)
or
driver.set_window_size(2000, 694)
I was searching for the solution for last 2 hours and nothing was working. Then I just gave a sleep time time.sleep(5)
after the window opened on which action is to be performed and it started working.
time.sleep() command can be used sometimes when an elements is taking time to switch.Scrolling always doesn’t help you.
This is not a generic solution, but might help ring a bell.
Thanks to the inputs in this thread, I could resolve the issue by tweaking the target page.
The exception, in my case, occurred :
- while checking for existence of an element that happened to be at the top of the page,
- while the page, when rendered on the browser, was getting auto-scrolled to the bottom due to "autofocus" that was set on a button element at the bottom of the page.
Because the test script was against my own development, I had the flexibility to review the need for the "autofocus" and avoid the auto-scroll to the bottom of the page when the page got rendered.
Alternatively, checking for existence of a different element, that gets rendered within the viewport, if feasible, could also resolve the issue.
I am using this to avoid getting MoveTargetOutOfBoundsException
with running Firefox. (in C#):
public void ScrollToElement(IWebElement elementLocator)
{
try
{
action.MoveToElement(elementLocator).Perform();
}
catch(MoveTargetOutOfBoundsException e)
{
Console.WriteLine(e);
js.ExecuteScript("arguments[0].scrollIntoView(true);", elementLocator);
}
}
In Python it would probably be like this:
def scroll_to_element(driver, element_locator):
actions = ActionChains(driver)
try:
actions.move_to_element(element_locator).perform()
except MoveTargetOutOfBoundsException as e:
print(e)
driver.execute_script("arguments[0].scrollIntoView(true);", element_locator)
You can also use the code below. I used it, the program works fine
lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
match=False
while(match==False):
lastCount = lenOfPage
time.sleep(3)
lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
if lastCount == lenOfPage:
match=True
time.sleep(5)
Then later
actions = ActionChains(driver)
actions.move_to_element(source_element)
actions.click()
actions.perform()
Besides you can add your code:
from selenium.common.exceptions import StaleElementReferenceException, MoveTargetOutOfBoundsException
and use try except
script.
For example:
try:
'Main Code'
except (StaleElementReferenceException, MoveTargetOutOfBoundsException):
pass
Note that if you’re encountering this problem while using move_to_element to trigger an event like a mouseover or mouseenter, you can skip using move_to_element entirely.
You can instead use execute_script to call the event directly:
driver = webdriver.Firefox()
driver.get("https://stackoverflow.com")
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
driver.execute_script("arguments[0].dispatchEvent(new Event('mouseover'));", source_element)
It works by using javascript to dispatch the event, and it will work even if the element isn’t in the viewport.
See also the dispatchEvent docs for more detail.
I’v got problem with function move_to_element on Firefox Webdriver (Chrome, IE works well)
driver = webdriver.Firefox()
driver.get("https://stackoverflow.com")
time.sleep(5)
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
ActionChains(driver).move_to_element(source_element).perform()
I am working with these versions: geckodriver – 0.17.0 // Firefox – 54.0 // selenium – 3.4.3
After running this script, on output shows:
selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: (134.96666717529297, 8682.183013916016) is out of bounds of viewport width (1268) and height (854)
This error…
selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: (134.96666717529297, 8682.183013916016) is out of bounds of Viewport width (1268) and height (854)
…implies that the element you are looking for is not within the Viewport. We need to scroll down to bring the element within the Viewport. Here is the working code:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains
binary = FirefoxBinary('C:\Program Files\Mozilla Firefox\firefox.exe')
caps = DesiredCapabilities().FIREFOX
caps["marionette"] = True
driver = webdriver.Firefox(capabilities=caps, firefox_binary=binary, executable_path="C:\Utility\BrowserDrivers\geckodriver.exe")
driver.get("https://stackoverflow.com")
last_height = driver.execute_script("return document.body.scrollHeight")
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
ActionChains(driver).move_to_element(source_element).perform()
Let me know if this Answers your Question.
I think the correct answer here got lucky that the element they were looking for happened to be at the bottom of the page and didn’t really explain why this occurs in Firefox commonly.
Browsers other than Firefox treat Webdrivers move_to_element
action as scroll to part of page with element then hover over it. Firefox seems to have taken a hardline stance that move_to_element is just hover and are waiting for a scroll action to fix this.
For now you have to workaround this bug using javascript as mentioned in previous answer, but I suggest using something like this instead of arbitrarily (well I guess the example was a footer) scrolling to bottom of page and hoping object is still in view.
def scroll_shim(passed_in_driver, object):
x = object.location['x']
y = object.location['y']
scroll_by_coord = 'window.scrollTo(%s,%s);' % (
x,
y
)
scroll_nav_out_of_way = 'window.scrollBy(0, -120);'
passed_in_driver.execute_script(scroll_by_coord)
passed_in_driver.execute_script(scroll_nav_out_of_way)
Then later
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
if 'firefox' in driver.capabilities['browserName']:
scroll_shim(driver, source_element)
# scroll_shim is just scrolling it into view, you still need to hover over it to click using an action chain.
actions = ActionChains(driver)
actions.move_to_element(source_element)
actions.click()
actions.perform()
You can try below while automating the script in Firefox when it usually throws MoveTargetOutOfBoundsException error:
One can transform/Zoom-in or out by
driver.execute_script("document.body.style.transform='scale(0.9)';")
Sometimes if you are running automation script in Jenkins(CI tools), you might also face the issue from above transform code where content of browser is scaled out not the actual browser, in those condition you can try out to resize the browser window:
driver.set_window_size(x, y)
or
driver.set_window_size(2000, 694)
I was searching for the solution for last 2 hours and nothing was working. Then I just gave a sleep time time.sleep(5)
after the window opened on which action is to be performed and it started working.
time.sleep() command can be used sometimes when an elements is taking time to switch.Scrolling always doesn’t help you.
This is not a generic solution, but might help ring a bell.
Thanks to the inputs in this thread, I could resolve the issue by tweaking the target page.
The exception, in my case, occurred :
- while checking for existence of an element that happened to be at the top of the page,
- while the page, when rendered on the browser, was getting auto-scrolled to the bottom due to "autofocus" that was set on a button element at the bottom of the page.
Because the test script was against my own development, I had the flexibility to review the need for the "autofocus" and avoid the auto-scroll to the bottom of the page when the page got rendered.
Alternatively, checking for existence of a different element, that gets rendered within the viewport, if feasible, could also resolve the issue.
I am using this to avoid getting MoveTargetOutOfBoundsException
with running Firefox. (in C#):
public void ScrollToElement(IWebElement elementLocator)
{
try
{
action.MoveToElement(elementLocator).Perform();
}
catch(MoveTargetOutOfBoundsException e)
{
Console.WriteLine(e);
js.ExecuteScript("arguments[0].scrollIntoView(true);", elementLocator);
}
}
In Python it would probably be like this:
def scroll_to_element(driver, element_locator):
actions = ActionChains(driver)
try:
actions.move_to_element(element_locator).perform()
except MoveTargetOutOfBoundsException as e:
print(e)
driver.execute_script("arguments[0].scrollIntoView(true);", element_locator)
You can also use the code below. I used it, the program works fine
lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
match=False
while(match==False):
lastCount = lenOfPage
time.sleep(3)
lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
if lastCount == lenOfPage:
match=True
time.sleep(5)
Then later
actions = ActionChains(driver)
actions.move_to_element(source_element)
actions.click()
actions.perform()
Besides you can add your code:
from selenium.common.exceptions import StaleElementReferenceException, MoveTargetOutOfBoundsException
and use try except
script.
For example:
try:
'Main Code'
except (StaleElementReferenceException, MoveTargetOutOfBoundsException):
pass
Note that if you’re encountering this problem while using move_to_element to trigger an event like a mouseover or mouseenter, you can skip using move_to_element entirely.
You can instead use execute_script to call the event directly:
driver = webdriver.Firefox()
driver.get("https://stackoverflow.com")
source_element = driver.find_element_by_xpath('//*[@id="footer"]/div/ul/li[1]/a')
driver.execute_script("arguments[0].dispatchEvent(new Event('mouseover'));", source_element)
It works by using javascript to dispatch the event, and it will work even if the element isn’t in the viewport.
See also the dispatchEvent docs for more detail.