C# “元素当前不可见,因此可能无法与之交互”但另一个是?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17602334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Element is not currently visible and so may not be interacted with" but another is?
提问by ton.yeung
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 Firefox 驱动程序认为我的模式未显示:隐藏?
Selenium version 2.33.0
Firefox driver
Selenium 版本 2.33.0
Firefox 驱动程序
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
FindElementsthen I get ONE element, so there isn't anything else on the page. - If I
FindElementon a field that occurs right before the button, sayaddEmployees-employee, thenaddEmployees-employeeisdisplayed - 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
- 如果我将调用更改为 ,
FindElements那么我会得到一个元素,因此页面上没有其他任何内容。 - 如果我
FindElement在按钮之前出现的字段上,比如说addEmployees-employee,那么addEmployees-employee是displayed - 在浏览器本身中,它显示得很好,我需要做的就是实际单击按钮并执行所需的行为,但 webdriver 拒绝考虑显示的元素
How is it that one field can be considered displayed and the other is not?
为什么一个字段可以被视为显示而另一个则不是?


The modal with the add button in the bottom right, all the other elements are displayed = true
带有右下角添加按钮的模态,所有其他元素都显示 = 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
窗口大小为 1200x645 perdriver.Manage().Window.Size;
元素位置为:800x355y perdriver.FindElement(By.Id(buttonName)).Location
元素尺寸为:51x30 perdriver.FindElement(By.Id(buttonName)).Size
密码元素位置为:552x233y perdriver.FindElement(By.Id("addEmployees-password")).Size
采纳答案by bbbco
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. (UPDATEAfter looking at the JSON wire code that all the bindings refer back to, SWD also requires overflow != hidden, aswell asa fewothercases.)
Selenium WebDriver 不仅检查不透明度 != 0、可见性 = true、高度 > 0 和显示 != none 在当前有问题的元素上,而且它还搜索 DOM 的祖先链以确保没有父元素也匹配这些跳棋。(UPDATE看JSON线代码,所有绑定重提后,社署也需要溢出!=隐藏,因为还有一些其他的情况。)
I would do two things before restructuring the code as @Brian suggests.
在像@Brian 建议的那样重构代码之前,我会做两件事。
Ensure that the "div.modal_footer" element does not have any reason for SWD to consider it to not be visible.
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 gistas 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.
确保“div.modal_footer”元素没有任何理由让 SWD 认为它不可见。
注入一些 Javascript 以突出显示浏览器中的相关元素,以便您绝对知道您选择了正确的元素。您可以使用此要点作为起点。如果按钮以黄色边框突出显示,那么您就知道您选择了正确的元素。如果不是,则表示所选元素位于 DOM 中的其他位置。如果是这种情况,您可能没有预期的唯一 ID,这使得对 DOM 的操作非常混乱。
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.
如果我不得不猜测,我会说第二个就是你遇到的问题。这也发生在我身上,开发人员重用了一个元素 ID,导致了你应该在哪个元素中找到的争用。
回答by Brian
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>
回答by Jim Holmes
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.)
Brian 的回答是正确的:使用显式等待而不是 Thread.Sleep()。Sleep() 通常很脆弱,你会无谓地损失五秒钟,而且这对于自动化测试来说只是一种非常糟糕的做法。(我花了很长时间才学会这一点,所以你并不孤单。)
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.
避免隐式等待。它们通常适用于添加到 DOM 的新项目,而不适用于诸如模态之类的东西变为活动状态的转换。
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.
显式等待有一组很好的 ExpectedConditions(在 Javadox 中有详细说明),可以让您解决这些问题。使用与您下一步操作所需的状态相匹配的 ExpectedCondition。
Also, see Ian Rose's great blogpost on the topic, too.
另外,请参阅Ian Rose 关于该主题的精彩博文。
回答by Arpan Buch
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.0and now it is 2.35.0
我有同样的元素不可见问题,因此无法与之交互。它刚刚得到解决。我更新了我的 selenium 独立服务器。以前的版本是2.33.0,现在是2.35.0
回答by CONvid19
In my case the element was already present in the page but it was disabled, so this didn't work (python):
在我的情况下,该元素已存在于页面中,但已被禁用,因此这不起作用(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.
为了解决我的问题,我不得不等待几秒钟 ( time.sleep(5)) 直到元素变得可见。
You can also enable the element using JavaScript, a python example:
您还可以使用 JavaScript(一个 Python 示例)启用该元素:
driver.execute_script("document.getElementById('myBtn').disabled='' ")
driver.execute_script("document.getElementById('myBtn').click() ")

