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

偶尔善良 提交于 2019-11-29 02:10:43

Selenium WebDriver does not just check for opacity != 0, visibility = true, height > 0 and display != none on the current element in question, but it also searches up the DOM's ancestor chain to ensure that there are no parent elements that also match these checkers. (UPDATE After looking at the JSON wire code that all the bindings refer back to, SWD also requires overflow != hidden, as well as a few other cases.)

I would do two things before restructuring the code as @Brian suggests.

  1. Ensure that the "div.modal_footer" element does not have any reason for SWD to consider it to not be visible.

  2. Inject some Javascript to highlight the element in question in your browser so you know absolutely you have selected the right element. You can use this gist as a starting point. If the button is highlighted in a yellow border, then you know you have the right element selected. If not, it means that the element selected is located elsewhere in the DOM. If this is the case, you probably don't have unique IDs as you would expect, which makes manipulation of the DOM very confusing.

If I had to guess, I would say that number two is what you are running into. This has happened to me as well, where a Dev reused an element ID, causing contention in which element you're supposed to find.

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.

After discussing this with you in chat, I think the best solution (for now, at least) is to move the button out of the footer for your modal and into the body of it.

This is what you want (for now):

<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" />
      <button name="addEmployees-add" id="addEmployees-add" type="button" class="btn" data-ng-click="submit()">Add</button>
   </p>
</div>

And not this:

<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>

I had the same issue of element not visible so cannot be interacted with. it just got solved. i updated my selenium stand alone server. previous version was 2.33.0 and now it is 2.35.0

In my case the element was already present in the page but it was disabled, so this didn't work (python):

wait.until(lambda driver: driver.find_element_by_id("myBtn"))
driver.find_element_by_id("myBtn").click()

it failed with error:

“Element is not currently visible and so may not be interacted with"

To solve my problem, I had to wait a couple of seconds ( time.sleep(5) ) until the element became visible.

You can also enable the element using JavaScript, a python example:

driver.execute_script("document.getElementById('myBtn').disabled='' ")
driver.execute_script("document.getElementById('myBtn').click() ")
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!