7

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.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Michal Jeruzal
  • 89
  • 1
  • 1
  • 6
  • First thing to check is the zoom level of your browser, it can throw off hovering functions. It should always be 100%. If your zoom level is fine you may be suffering from this: https://github.com/mozilla/geckodriver/issues/1507 – Ardesco Mar 29 '19 at 10:15
  • @Ardesco the zoom level is fine. Also, I do not think I am affected by the linked issue. Some of the suggested answers works, but only partially. I am still looking for the perfect solution. – Michal Jeruzal Mar 29 '19 at 15:46

5 Answers5

6

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:

selenium_WebDriver

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Same situation as with @kajal-kundu 's code. It works with Firefox given the mouse pointer is out of the web browser, but it does not work in Chrome anymore. It opens menu "Automations Tools", but goes to submenu "BDD" instead. – Michal Jeruzal Mar 29 '19 at 15:41
  • What do you mean by _@kajal-kundu 's code_ ? What exacatly do you mean by _mouse pointer is out of the web browser_ ?? You specifically mentioned **same works fine when I switch to Chrome, but with Firefox I get the error**. This answer is specifically for _Firefox_ . Can you just _copy-paste_ the code and execute and update me the status please ??? – undetected Selenium Mar 29 '19 at 15:46
  • Kajal Kundu is the person that also answered to my question. If mouse cursor is over the web browser window the provided solution will not work. I have executed your code, it works in Firefox (given the cursor is not over web browser), but it does not work with Chrome anymore, hence I cannot accept the answer. I don't want to create multiple identical methods but for different web browsers if it is not necessary. – Michal Jeruzal Mar 29 '19 at 15:56
  • I don't think Kajal Kundu is associated with this answer anyway. I have no idea what exactly you mean by _mouse cursor is over the web browser window_ as most of we developers will trigger the execution from an IDE e.g. Eclipse. To reiterate, you specifically mentioned **same works fine when I switch to Chrome, but with Firefox I get the error**. Though this answer is generic but works perfecto specifically with Firefox. Am I missing something? – undetected Selenium Mar 29 '19 at 16:02
  • 1
    Strange thing, it started to work properly with your code on both web browsers after the reboot. Thank you :) – Michal Jeruzal Apr 03 '19 at 12:01
1

Please try the below code(if you are inside frame , you need to come out and use below code):

WebDriver driver=new ChromeDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(0,400)");
0

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();

enter image description here

KunduK
  • 32,888
  • 5
  • 17
  • 41
  • 1
    It works with Firefox given the mouse pointer is out of the web browser, but it does not work in Chrome anymore. It opens menu "Automations Tools" and goes to submenu "BDD" instead. I have tried to search for elements using By.xpath as well but with no luck. – Michal Jeruzal Mar 29 '19 at 15:29
  • My output comes from Chrome only and you are saying it is not working with Chrome.Sorry I can’t help you. – KunduK Mar 29 '19 at 17:52
0

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.

NarendraR
  • 7,577
  • 10
  • 44
  • 82
  • It works with Firefox given the mouse pointer is out of the web browser but it does not work in Chrome anymore. It opens menu and submenu but do not click the "Selenium WebDriver" web element. Also, I do not understand why you used clickAndHold() method instead of click(). What is the difference? I imagine that it will "press and hold" the LMB, move the coursor and release LMB. If I try to do that manually in the browser the dropdown menu would not appear, hence I am confused. – Michal Jeruzal Mar 29 '19 at 15:01
0

Try using it -

action.moveToElement(menu).build().perform();
Thread.sleep(500);
moveToElement(selenium).build().perform();
Thread.sleep(500);
moveToElement(seleniumWebDriver).click().build().perform();