引导弹出窗口的 Selenium ElementNotVisibleException

Posted

技术标签:

【中文标题】引导弹出窗口的 Selenium ElementNotVisibleException【英文标题】:Selenium ElementNotVisibleException for Bootstrap Popover 【发布时间】:2013-12-22 20:53:03 【问题描述】:

我正在使用 Selenium 2.37.1 和 Chrome 驱动程序 2.7(在 Ubuntu 13.10 上使用 Chrome 31.0.1650.63)为我的基于 Java/Spring/Boostrap 的网站编写一些测试。

测试单击登录文本,然后尝试在单击提交按钮之前将提供的用户名和密码输入表单。我已经分解了元素的发现并调用了 sendKeys 来确定 Selenium 的后续位置(它在 username.sendKeys 上)

public void login(final String user) 
    webDriver.findElement(By.id("login")).click();
    final WebElement loginForm = webDriver.findElement(By.id("loginForm"));
    final WebElement username = loginForm.findElement(By.id("username"));
    username.sendKeys(user);
    final WebElement password = loginForm.findElement(By.id("password"));
    password.sendKeys(dslConstants.PASSWORD);
    loginForm.submit();

用户名找到成功,但是当我运行username.isDisplayed()的时候,它实际上是被显示出来的。

我假设这与 Selenium 无法正确处理 Bootstrap 弹出框有关,并且想知道是否有人对此有任何修复?

提前致谢。

编辑: loginForm.isDisplayed() 在调试时可见时也会返回 false。我也试过加一个等待条件,也没有解决问题。

final WebDriverWait wait = new WebDriverWait(webDriver, TIME_OUT_IN_SECONDS);
wait.until(ExpectedConditions.visibilityOf(webDriver.findElement(By.id("username"))));

编辑2: 这是页面的 html/JSTL 方面。

<div class="navbar">
        <ul class="nav navbar-nav">
            <li><a href="/">Home</a></li>
            <sec:authorize ifAnyGranted="ROLE_ANONYMOUS">
                <div class="hide" id="login-popover">
                    <form role="form" id="loginForm" method="post" action="j_spring_security_check">
                        <div class="control-group">
                            <label class="control-label" for="username">Username</label>
                            <div class="controls">
                                <input type="text" id="username" class="form-control" name="j_username" />
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="password">Password</label>
                            <div class="controls">
                                <input type="password" id="password" class="form-control" name="j_password" />
                            </div>
                        </div>
                        &nbsp;
                        <div class="control-group">
                            <div class="controls">
                                <button class="btn btn-primary" type="submit">Login</button>
                            </div>
                        </div>
                    </form>
                </div>
                <li><a href="#" id="login">Login</a></li>
                <li><a href="/accounts/register">Register</a></li>
            </sec:authorize>
        </ul>
    </div>

编辑 3: 使用 FireFox 25 时也会出现这种情况

【问题讨论】:

我有两个问题:您使用的是哪种浏览器?您是否尝试调试此代码? 我正在使用 Chrome 网络驱动程序,并且我已经调试了代码。我想附上的截图是在执行 username.sendKeys(user) 之前显示正在显示的登录表单 您使用的是哪个版本的 chrome? 你能附上html的部分吗?还需要 chromedriver 的版本。 版本 31.0.1650.63 我应该补充一点,我正在 Ubuntu 13.10 上通过 IntelliJ 12 运行网站和测试 【参考方案1】:

尝试移动到弹出框元素以使其在与它交互之前可见。类似:

    WebElement element = webDriver.findElement(By.id("login-popover"));
    Actions actions = new Actions(driver);
    actions.moveToElement(element).build().perform();

然后执行您的等待序列。如果您必须单击元素才能使其显示,那么您可以在 build() 之前进行。

【讨论】:

我在 webDriver.findElement(By.id("login")).click() 之前和之后添加了这个,但仍然找不到用户名。 请说明您必须手动执行哪些操作才能登录?当我认为这是一些悬停的登录弹出窗口时,我是对的吗? 当然。你去 localhost:8080,点击“登录”链接(这会弹出登录框),在各自的字段中输入用户名/密码,点击登录按钮。【参考方案2】:

我已经设法解决了这个问题。在调试和检查网页时(使用 Chrome),我注意到实际上有两个登录表单。

我可以通过在另一个文件中(或在单击登录链接时执行的 javascript 中)声明登录表单 html 来解决此问题。无论哪种方式,通过执行 webDriver.findElement(By.class("popover-content")) 然后在其中搜索表单可以解决我的问题。

public void login(final String user) 
    webDriver.findElement(By.id("login")).click();
    final WebElement loginForm = webDriver.findElement(By.class("popover-content)).findElement(By.id("loginForm"));
    loginForm.findElement(By.id("username")).sendKeys(user);
    loginForm.findElement(By.id("password"))password.sendKeys(dslConstants.PASSWORD);
    loginForm.submit();

我想从中吸取的教训是,我回顾了我在 Web 应用程序中使用的库的实际工作方式!

【讨论】:

以上是关于引导弹出窗口的 Selenium ElementNotVisibleException的主要内容,如果未能解决你的问题,请参考以下文章

引导弹出窗口,关闭按钮

在 jquery 中验证引导弹出窗口

在引导弹出窗口中包含表单?

来自 Laravel 循环的引导弹出窗口

引导弹出窗口中的 Django 登录表单

带有文本区域的引导弹出窗口:无法水平调整大小