【问题标题】:"Element is not currently visible and so may not be interacted with" but another is?“元素当前不可见,因此可能无法与之交互”,但另一个是?
【发布时间】:2013-07-11 19:58:42
【问题描述】:

我创建了另一个问题,我认为这是导致此错误的原因:Why does the Selenium Firefox Driver consider my modal not displayed when the parent has overflow:hidden?

Selenium 版本 2.33.0
火狐驱动

导致错误的代码:

        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

它试图点击的按钮:

<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>
  • 如果我将调用更改为 FindElements,那么我会得到一个元素,因此页面上没有其他任何内容。
  • 如果我FindElement 出现在按钮之前的字段上,比如addEmployees-employee,那么addEmployees-employee 就是displayed
  • 在浏览器本身中,它显示得很好,我需要做的就是实际单击按钮并执行所需的行为,但是 webdriver 拒绝考虑显示的元素

如何认为一个字段显示而另一个字段不显示?

右下角有添加按钮的modal,其他元素全部显示=true

每个driver.Manage().Window.Size;的窗口大小为1200x645
元素位置是:800x355y 每 driver.FindElement(By.Id(buttonName)).Location
元素尺寸为:51x30 每 driver.FindElement(By.Id(buttonName)).Size
密码元素位置为:552x233y per driver.FindElement(By.Id("addEmployees-password")).Size

【问题讨论】:

  • 我们使用类似的东西:waitUntil(Waits.elementDisplayed(web element goes here)); here at work。您的自动化框架中有类似的机制吗?
  • @Brian c#驱动程序有隐式等待,我已经配置了10秒,问题是,在它之前出现的元素被标记为显示,但按钮不是,踢球者是另一个相同但编辑而不是添加的模态可以正常工作!
  • 当您查看 DOM 时,这两个元素是否始终可见?
  • 嗯.. 我不确定你的意思是什么,但它们在浏览器视口上是可见的,如果我进入 firebug,它不会被标记为隐藏。这能回答你的问题吗?
  • @ton.yeung:你能调试一下位置和大小吗?也许还有浏览器视口大小。是不是靠近窗户的边缘?

标签: c# angularjs selenium-webdriver angular-strap


【解决方案1】:

Brian 的回答是正确的:使用显式等待而不是 Thread.Sleep()。 Sleep() 通常很脆弱,你会不必要地失去五秒钟,而且它只是自动化测试的一种非常糟糕的做法。 (我花了很长时间才知道这一点,所以你并不孤单。)

避免隐式等待。它们通常适用于添加到 DOM 的新项目,而不适用于使模态变为活动状态的过渡。

显式等待有一组很好的 ExpectedConditions (detailed in the Javadox) 可以帮助您解决这些问题。使用与您下一个操作所需的状态相匹配的 ExpectedCondition。

另外,请参阅Ian Rose's great blogpost on the topic

【讨论】:

【解决方案2】:

Selenium WebDriver 不仅检查当前元素的 opacity != 0、visibility = true、height > 0 和 display != none,它还向上搜​​索 DOM 的祖先链以确保没有父元素也匹配这些检查器的元素。 (更新在查看了所有绑定引用的 JSON 线路代码后,SWD 还需要overflow != hiddenaswell asa fewothercases。)

在按照@Brian 的建议重构代码之前,我会做两件事。

  1. 确保“div.modal_footer”元素没有任何理由让 SWD 认为它不可见。

  2. 注入一些 Javascript 以在浏览器中突出显示有问题的元素,这样您就绝对知道您选择了正确的元素。您可以使用this gist 作为起点。如果按钮以黄色边框突出显示,那么您知道您选择了正确的元素。如果不是,则表示所选元素位于 DOM 中的其他位置。如果是这种情况,您可能没有预期的唯一 ID,这使得 DOM 的操作非常混乱。

如果我不得不猜测,我会说第二个就是你遇到的问题。这也发生在我身上,开发人员重用了元素 ID,导致争用您应该在哪个元素中找到。

【讨论】:

  • 我认为它是第一名。我在 OP 中添加了另一个问题来说明原因。
  • 啊!我懂了。好吧,看了你的另一篇帖子后,我在SWD代码中发现了Overflow: hidden items也被认为不显示github.com/SeleniumHQ/selenium/blob/…
  • 它必须是特定于 firefox 的,因为 chrome 驱动程序没有这个问题。
  • 想回答我的其他问题吗? stackoverflow.com/questions/17624312/…
【解决方案3】:

在聊天中与您讨论后,我认为最好的解决方案(至少目前)是将按钮从您的模态页脚移到它的正文中。

这就是你想要的(目前):

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

不是这个:

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

【讨论】:

    【解决方案4】:

    我遇到了相同的元素不可见问题,因此无法与之交互。它刚刚得到解决。我更新了我的 selenium 独立服务器。以前的版本是2.33.0,现在是2.35.0

    【讨论】:

    • 对不起,我想知道如何解决这个问题。我使用最新的量角器,chromedriver 2.32,硒版本是 3.5.3。当我想测试模态页脚中的按钮时,它仍然是“元素不可见”。当我将按钮从页脚移动到模态体时,一切正常。
    • 你能检查一下这是否适用于任何浏览器吗?你能检查元素是否被正确识别吗?
    • 我找到了!原因很有趣,因为量角器启动浏览器只有正常宽度的一半,所以它当然是不可见的!我添加“ browser.driver.manage().window().maximize();”在测试开始,于是protractor启动全屏模式浏览器进行测试,解决!
    • 太棒了。我以为你已经以全屏模式启动了它。这是一个 preReq :)。我的建议:在您实例化浏览器的方法中,按照相同的顺序执行以下步骤:。 1) if else 以浏览器选择为条件并基于该浏览器实例化。 2) 最大化浏览器 3) 导航到 url 4) 返回驱动程序实例。这个方法的返回类型是 webDriver
    【解决方案5】:

    在我的情况下,该元素已经存在于页面中,但它被禁用了, 所以这不起作用(python):

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

    失败并出现错误:

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

    为了解决我的问题,我不得不等待几秒钟(time.sleep(5))直到元素变得可见。

    您还可以使用 JavaScript 启用该元素,python 示例:

    driver.execute_script("document.getElementById('myBtn').disabled='' ")
    driver.execute_script("document.getElementById('myBtn').click() ")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-13
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      相关资源
      最近更新 更多