How to force Selenium WebDriver to click on element which is not currently visible?

Solution 1:

Selenium determines an element is visible or not by the following criteria (use a DOM inspector to determine what css applies to your element, make sure you look at computed style):

  • visibility != hidden
  • display != none (is also checked against every parent element)
  • opacity != 0 (this is not checked for clicking an element)
  • height and width are both > 0
  • for an input, the attribute type != hidden

Your element is matching one of those criteria. If you do not have the ability to change the styling of the element, here is how you can forcefully do it with javascript (going to assume WebDriver since you said Selenium2 API):

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

But that won't fire a javascript event, if you depend on the change event for that input you'll have to fire it too (many ways to do that, easiest to use whatever javascript library is loaded on that page).

The source for the visibility check -

https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577

The WebDriver spec that defines this -

https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#widl-WebElement-isDisplayed-boolean

Solution 2:

Sometimes this means there are multiple elements on a page that have the same property you're trying to search by and you're "talking to the wrong one".

If your element can't be uniquely identified by :id or :name (or :class), it could be tricky.

Sometimes searching for the element by the :xpath will help and in some cases even that is not practical.

In those cases, you may have to get all the elements that match your criteria and reference the right one by the index. It's dirty, but it works.

I'm using Selenium / Watir from Ruby on Rails app, so in my case the example would be:

browser = Watir::Browser.new(:firefox, :profile => "default")       
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click

Hope this helps.

Solution 3:

I had a similar issue, but it was related to the element not being visible in the viewport. I took a screenshot and realized the browser window was too narrow and the element couldn't be seen. I did one of these and it worked:

driver.maximize_window()

See: WebDriver.maximize_window()

Solution 4:

Or you may use Selenium Action Class to simulate user interaction -- For example

    WebDriver = new FirefoxDriver();

    WebElement menu = driver.findElement(By.xpath("")); // the triger event element

    Actions build = new Actions(driver); // heare you state ActionBuider
    build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
    WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
    m2m.click();

Solution 5:

There is also another case when visible element will be recognized as not visible:

  • When the Element is CSS transformed
  • When Parent Element of the Element is CSS transformed

In order to check if element you wan't to interact with is CSS transformed, on CHROME do this:

  1. open inspector
  2. Find interesting element (or more likely its parent element, supposedly div element)
  3. Select 'Computed' tab
  4. if there is a parameter: webkit-transform: matrix( ... ) it means that the element is CSS transformed, and may not be recognized by selenium 2 as a visible element