问题
I am learning how to automate tests with Selenium WebDriver, however I got stuck and cannot make dropdown menu to work in Firefox. The same code runs perfectly fine in Chrome.
The site I am practicing on is: http://www.executeautomation.com/demosite/index.html and I want to click the following item from menu: Automation Tools > Selenium > Selenium WebDriver.
The error message suggest that the web element may not be loaded on the screen yet, so I have implemented some method to wait with every execution until the element shows up:
public static void ImplicitWait(WebDriver driver){
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
but it did not helped.
Then I read that it is better to "pipe" those moveToElement() methods instead of performing them one by one. So I changed this:
action.moveToElement(menu).perform();
action.moveToElement(selenium).perform();
action.moveToElement(seleniumWebDriver).click().build().perform();
to one line. At this point it started to work on Chrome, but I am still struggling to make it work on Firefox.
The current code looks like this:
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver-v0.24.0-win64\\geckodriver.exe");
System.setProperty("webdriver.firefox.bin", "C:\\Program Files\\Mozilla Firefox\\firefox.exe");
WebDriver driver = new FirefoxDriver();
ImplicitWait(driver);
driver.navigate().to("http://executeautomation.com/demosite/index.html");
WebElement menu = driver.findElement(By.id("Automation Tools"));
WebElement selenium = driver.findElement(By.id("Selenium"));
WebElement seleniumWebDriver = driver.findElement(By.id("Selenium WebDriver"));
Actions action = new Actions(driver);
action.moveToElement(menu).moveToElement(selenium).moveToElement(seleniumWebDriver).click().build().perform();
As I mentioned above the same works fine when I switch to Chrome, but with Firefox I get the error message:
Exception in thread "main" org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: (-9862, 206) is out of bounds of viewport width (1283) and height (699)
I am using: * Firefox v66.0.2 * Java v1.8.0_201 * Selenium Java v3.141.59 * GeckoDriver v0.24.0
Please help.
回答1:
The main issue with the Web Application is that the HTML DOM attains document.readyState
equals to complete
even before the sub-menu element with text as Selenium WebDriver gets rendered. Hence you see the error as:
Exception in thread "main" org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: (-4899, 91) is out of bounds of viewport width (1366) and height (664)
Solution
So an ideal solution would be:
- Induce WebDriverwait for the
titleIs()
Execute Automation
- Induce WebDriverwait for the menu element with text as Automation Tools
- Induce WebDriverwait for the sub-menu element with text as Selenium
- Induce WebDriverwait for the sub-menu
elementToBeClickable
with text as Selenium - You can use the following solution:
Code Block:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class MouseHoverFirefox { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe"); WebDriver driver=new FirefoxDriver(); driver.get("http://www.executeautomation.com/demosite/index.html"); new WebDriverWait(driver, 20).until(ExpectedConditions.titleIs("Execute Automation")); new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[@id='Automation Tools']")))).build().perform(); new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@class='active has-sub']/a/span//following::ul[1]/li[@class='has-sub']/a/span[@id='Selenium']")))).build().perform(); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@class='active has-sub']/a/span//following::ul[1]/li/a/span[@id='Selenium']//following::ul[1]/li/a/span[text()='Selenium WebDriver']"))).click(); } }
Browser Snapshot:
回答2:
Use WebDriverWait
and try the following code.
driver.get("http://executeautomation.com/demosite/index.html");
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement menu= wait.until(ExpectedConditions.elementToBeClickable(By.id("Automation Tools")));
Actions action = new Actions(driver);
action.moveToElement(menu).build().perform();
WebElement selenium =wait.until(ExpectedConditions.elementToBeClickable(By.id("Selenium")));
action.moveToElement(selenium).build().perform();
WebElement seleniumWebDriver =wait.until(ExpectedConditions.elementToBeClickable(By.id("Selenium WebDriver")));
action.moveToElement(seleniumWebDriver).click().build().perform();
回答3:
Try using it -
action.moveToElement(menu).build().perform();
Thread.sleep(500);
moveToElement(selenium).build().perform();
Thread.sleep(500);
moveToElement(seleniumWebDriver).click().build().perform();
回答4:
I've observed the same issue with geckodriver
and Actions
class. Although you can go with following code
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver-v0.24.0-win64\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("http://executeautomation.com/demosite/index.html");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
WebElement mainmenu = driver.findElement(By.xpath("//li[@class='active has-sub']"));
WebElement submenu = driver.findElement(By.xpath("//li[@class='has-sub'] [contains(.,'Selenium')]"));
WebElement intendedLink = driver.findElement(By.xpath("//li[@class='has-sub'] [contains(.,'Selenium')]//li[contains(.,'Selenium WebDriver')]"));
Actions action =new Actions(driver);
action.moveToElement(mainmenu).clickAndHold().build().perform();
Thread.sleep(1000);
action.moveToElement(submenu).clickAndHold().build().perform();
Thread.sleep(1000);
intendedLink.click();
Code is working fine at my end. let me know if any issue.
Note: Keep the mouse pointer out of web page screen else it override the current focus.
来源:https://stackoverflow.com/questions/55413422/org-openqa-selenium-interactions-movetargetoutofboundsexception-x-y-is-out-o