Selenium ElementNotVisibleException для всплывающего окна Bootstrap

Я пишу несколько тестов для своего веб-сайта на основе Java/Spring/Boostrap, используя Selenium 2.37.1 и Chrome Driver 2.7 (с Chrome 31.0.1650.63 в Ubuntu 13.10).

Тест щелкает текст входа, а затем пытается ввести предоставленное имя пользователя и пароль в форму, прежде чем нажать кнопку отправки. Я разбил поиск элементов и вызов 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"))));

Edit2: Вот аспекты 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.


person Tom    schedule 22.12.2013    source источник
comment
У меня два вопроса: Какой браузер вы используете? Вы пытались отлаживать этот код?   -  person Ievgen    schedule 23.12.2013
comment
Я использую веб-драйвер Chrome и отлаживаю код. Скриншоты, которые я хотел прикрепить, должны были отображать форму входа в систему, отображаемую перед выполнением username.sendKeys(user)   -  person Tom    schedule 23.12.2013
comment
Какую версию хрома вы используете?   -  person Ievgen    schedule 23.12.2013
comment
А не могли бы вы прикрепить часть html? Также нужна версия chromedriver.   -  person Ievgen    schedule 23.12.2013
comment
Версия 31.0.1650.63 Я должен добавить, что я запускаю веб-сайт и тесты через IntelliJ 12 на Ubuntu 13.10.   -  person Tom    schedule 23.12.2013
comment
Может быть, это что-то с chromedriver. А как насчет FireFox 24?   -  person Ievgen    schedule 23.12.2013
comment
Версия драйвера Chrome добавлена ​​вместе с html. проверю файрфоксом   -  person Tom    schedule 23.12.2013
comment
У меня работает FireFox 25, и возникает проблема.   -  person Tom    schedule 23.12.2013
comment
Собственные события FireFox 25 поддерживаются только начиная с selenium 2.38. Поэтому вам нужно понизить версию Firefox или обновить Selenium.   -  person Ievgen    schedule 23.12.2013
comment
Я обновился до селена 2.39 для использования с FireFox 25, и эта проблема все еще возникает.   -  person Tom    schedule 23.12.2013


Ответы (2)


Попробуйте перейти к элементу всплывающего окна, чтобы сделать его видимым, прежде чем взаимодействовать с ним. что-то типа:

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

а затем выполните последовательность ожидания. Если вам нужно щелкнуть элемент, чтобы он появился, вы можете сделать это до build().

person Erki M.    schedule 23.12.2013
comment
Я добавил это до и после webDriver.findElement(By.id(login)).click(), но имя пользователя все еще не может быть найдено. - person Tom; 23.12.2013
comment
пожалуйста, укажите действия, которые вы должны были бы выполнить вручную, чтобы войти в систему? Был ли я прав, когда предположил, что это какое-то всплывающее окно входа в систему? - person Erki M.; 23.12.2013
comment
Конечно. Вы переходите на localhost:8080, нажимаете ссылку «Войти» (это вызывает всплывающее окно входа), вы вводите имя пользователя/пароль в соответствующие поля, нажимаете кнопку «Войти». - person Tom; 24.12.2013

Мне удалось решить эту проблему. Во время отладки и проверки веб-страницы (используя Chrome) я заметил, что на самом деле есть две формы входа.

введите здесь описание изображения

Я мог бы обойти это, объявив форму входа в систему html в другом файле (или в Javascript, который выполняется при нажатии на ссылку входа). В любом случае, выполнение 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();
}

Я полагаю, что урок из этого заключается в том, что я просматриваю, как на самом деле работают библиотеки, которые я использую в своем веб-приложении!

person Tom    schedule 24.12.2013