"Element is not currently visible and so may not be interacted with" but another is?

ton.yeung picture ton.yeung · Jul 11, 2013 · Viewed 28.6k times · Source

I've created another question which I think is the cause for this error: Why does the Selenium Firefox Driver consider my modal not displayed when the parent has overflow:hidden?

Selenium version 2.33.0
Firefox driver

The code that causes the error:

        System.Threading.Thread.Sleep(5000);
        var dimentions = driver.Manage().Window.Size;
        var field = driver.FindElement(By.Id("addEmployees-password")); //displayed is true
        field.Click(); //works fine
        var element = driver.FindElement(By.Id(buttonName)); //displayed is false
        element.Click(); //errors out

The button that its trying to click:

<div id="addEmployees" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="addEmployeesLabel" aria-hidden="true">

    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
        <h3>Add Employee</h3>
    </div>

    <div class="modal-body">
        <p class="alert alert-info">
            <input name="addEmployees-username" id="addEmployees-username" />
            <input name="addEmployees-password" id="addEmployees-password" type="password" />
            <input name="addEmployees-employee" id="addEmployees-employee" />
        </p>
    </div>

    <div class="modal-footer">
        <button name="addEmployees-add" id="addEmployees-add" type="button" class="btn" data-ng-click="submit()">Add</button>
    </div>

</div>
  • If I change the call to FindElements then I get ONE element, so there isn't anything else on the page.
  • If I FindElement on a field that occurs right before the button, say addEmployees-employee, then addEmployees-employee is displayed
  • In the browser itself, it shows up fine, all i need to do is actually click the button and the desired behavior executes, but the webdriver refuses to consider the element displayed

How is it that one field can be considered displayed and the other is not?

enter image description here

The modal with the add button in the bottom right, all the other elements are displayed = true

The window size is 1200x645 per driver.Manage().Window.Size;
The element location is: 800x355y per driver.FindElement(By.Id(buttonName)).Location
The element dimentions are: 51x30 per driver.FindElement(By.Id(buttonName)).Size
The password element location is: 552x233y per driver.FindElement(By.Id("addEmployees-password")).Size

Answer

Jim Holmes picture Jim Holmes · Jul 16, 2013

Brian's response was right: use an explicit wait versus Thread.Sleep(). Sleep() is generally brittle, you're losing five seconds needlessly, and moreover it's just a really rotten practice for automated testing. (It took me a long, LONG time to learn that, so you're not alone there.)

Avoid implicit waits. They generally work for new items being added to the DOM, not for transitions for things like a modal to become active.

Explicit waits have a great set of ExpectedConditions (detailed in the Javadox) which can get you past these problems. Use the ExpectedCondition which matches the state you need for your next action.

Also, see Ian Rose's great blogpost on the topic, too.