[Repost]Selenium ElementNotVisibleException: Cannot click on element

时间:2022-12-14 20:33:52

Problem Statement


I am using the Selenium WebDriver to clickon a menu item which is not visible until you hover over a toplevel menu, and when I invoke the Click method on the IWebElement,an ElementNotVisibleException is thrown with the message of Cannotclick on element.

The problem is that I have made the IWebElement visible by hoveringover the top level menu.  It is, in fact,absolutely visible, thus this exception should not bethrown.  The Click method works just fine on otherelements which are not hidden until the user hovers over themenu.

As an aside, here is the code I used to hover over the topmenu:

 1: var womensShoesMenu = this.webDriver.FindElement(By.CssSelector("a.topNavLink[href='/Womens-Shoe-Store']"));
 2: var builder = new Actions(this.webDriver);
 3: builder.MoveToElement(womensShoesMenu).Build().Perform();
 4: 

This is the code I used to invoke the Click method:
 1: var wait = new WebDriverWait(this.webDriver, TimeSpan.FromSeconds(5));
 2: var womensBoots = wait.Until((p) => this.webDriver.FindElement(By.CssSelector("#topNavigation ul div.menuItem a[href='/Womens-Boots']")));
 3: womensBoots.Click();
 4: 
 
I figured using the Wait code would fix the problem with the linknot being visible, assuming the code is simply executing tooquickly or something.  The debugger shows that theweb element is definitely visible, so, what isgoing?  I can definitively say that it beats thehell out of me; for now, I’m chalking this up to a bug withSelenium WebDriver.  Fortunately, however, I founda solution to the problem.

Solution

Instead of calling the Click method on the Selenium IWebElementobject, I used JavaScript instead.  This workslike a champ, and so far, appears to be reliable.

 1: var womensBoots = this.webDriver.FindElement(By.CssSelector("#topNavigation ul div.menuItem a[href='/Womens-Boots']"));
 2: ((IJavaScriptExecutor)this.webDriver).ExecuteScript("arguments[0].click();", womensBoots);
 3: 

 

Updated Solution

I’m adding a second solution after posting thisarticle.  It turns out that the Click method ofIWebElement works just fine in my scenario above; I simply wasn’tusing the WebDriverWait class correctly.  I reallyjust needed to have the browser wait for 1 second after performingthe hover on the top menu, and then all of the drivers I wastesting (Firefox, Internet Explorer, and Chrome) workedgreat.  Here is the updated code:

private static void DoWait(int milliseconds)
{
    var wait = new WebDriverWait(webDriver, TimeSpan.FromMilliseconds(milliseconds));
    var waitComplete = wait.Until<<span style="color: rgb(0, 0, 255);">bool>(
        arg =>
            {
                System.Threading.Thread.Sleep(milliseconds);
                return true;
            });
}
var womensBoots = webDriver.FindElement(By.CssSelector("#topNavigation ul div.menuItem a[href='/Womens-Boots']"));
DoWait(1000);
womensBoots.Click();
////((IJavaScriptExecutor)webDriver).ExecuteScript("arguments[0].click();", womensBoots);

 

Discussion

I’m new to Selenium, only having started using it as a developer afew days ago, so it is very likely I’m simply doing this wrong andI honestly have no idea of the problem I’m encountering is a bug ornot.  I’ve read similar posts about this, so itseems to be a bug, but as I dig deeper into the system I’ll learnmore.  Since Selenium is open source, if I get thetime, perhaps I’ll even go spelunking into the code to find out andmaybe even attempt to fix it!