как выбрать li из автозаполнения - PullRequest
1 голос
/ 03 марта 2011

В текстовом поле при вводе у нас есть автозаполнение, которое генерирует список, имеющий следующую структуру:

<div class="results">
  <ul>
    <li class="even">
    <li class="odd">
    <li class="even">
    etc...

Я пишу тесты с Cucumber (плюс Capybara и Webdriver), и мне нужно выбрать первый li.

page.execute_script не получает правильного jQuery, я думаю, потому что следующий фрагмент кода продолжает возвращать null.

page.execute_script %Q{ $('li').eq(1).trigger("mouseenter").click(); }

То есть я получаю эту ошибку:

TypeError: $("li") is null (Selenium::WebDriver::Error::UnexpectedJavascriptError)

Я только что подобрал jQuery, поэтому кто-нибудь скажет мне, что не так, почему это неправильно и, возможно, как это исправить?

Элемент li существует на странице, и я посмотрел на источник, чтобы убедиться, поэтому я действительно растерян, что он не может его найти.

Ответы [ 3 ]

5 голосов
/ 08 марта 2011

Я, вероятно, не стал бы пытаться щелкнуть элемент списка автозаполнения с помощью метода page.execute_script. В идеале When шаги огурца всегда должны имитировать то, на что способен пользователь. И я не ожидал бы, что они откроют консоль javascript и начнут вводить скрипты для выполнения, чтобы выбрать элементы списка;)

Очевидно, я знаю, что это не то, что вы собираетесь, но это то, что вы тестируете своим методом.

Лучшим методом было бы что-то вроде следующего в одном из ваших определений шагов огурца.

When /^I follow the autocomplete link containing "([^"]*)"$/ do |link_text|
  page.find(:css, ".results ul li", :text => link_text).click
end

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

Обратите внимание, что метод page.find возвращает Capybara :: Node :: Element (я полагаю). Опция: text hash указывает capybara найти только элемент, который содержит указанный текст. Если элемент не найден, капибара вызовет исключение.

Если по какой-либо причине у вашего li на самом деле нет кликабельного текста, вы можете изменить селектор на ".results ul li:first", но в идеале вы можете использовать это определение не только для выбора первого элемента.

Существует ошибка, с которой вы можете столкнуться (что-то о методе 'node' не найдено или о некоторых shinanigans). Если вы получаете странную ошибку, которую не можете объяснить при этом, и не сразу понятно, что это такое, то вам может понадобиться закомментировать следующую строку в env.rb каталога поддержки вашего огурца:

require 'cucumber/rails/capybara_javascript_emulation'

Огурец обезьяны, поставленный там, сломался, когда капибара была обновлена, а последний проверенный мной еще не был развернут как стабильный выпуск.

Надеюсь, это решит вашу проблему:)

ИЗМЕНИТЬ В ДОБАВИТЬ:

Я просто снова посмотрел на ваш вопрос и подумал, что хочу сообщить вам, почему $ ("li") будет возвращать ноль. Когда вы добавили шаг «И я должен увидеть…» перед выполнением этого скрипта, капибара имеет встроенные тайм-ауты ожидания появления элемента по умолчанию, которые она использует при поиске элемента на странице, которая не ' пока нет. Если он не появится в указанное время (я думаю, 5 секунд по умолчанию?) , тогда capybara даст вам неудачный тест.

Однако, когда вы запускаете вызов execute_script, вы обходите все потрясающие фреймворки Capybara и пытаетесь взаимодействовать с DOM напрямую, используя jquery - за исключением того, что Capybara еще не «дождался» появления объекта, так что ваш JavaScript, вероятно, не найдет его.

Я считаю, что решение, которое я разместил с помощью page.find, будет работать для вас, потому что этот метод ожидает появления элемента на странице, прежде чем выдавать ошибку. Искатели более подробно описаны здесь: https://github.com/jnicklas/capybara в подзаголовке «Поиск», где отображается файл readme.

0 голосов
/ 03 марта 2011

Следующий код работает для меня.Я вычеркнул весь лишний код.Ключевой момент, который следует помнить, заключается в том, что элемент списка существует при вызове функции (т.е. я обращаюсь к нему, когда страница «готова»)

В вашем случае вы должны выполнять только $ ('li')как только автоматическое предложение будет заполнено, иначе оно будет нулевым.Также обратите внимание, что eq () основана на нуле, поэтому первым элементом является eq (0), а не eq (1).

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script>
        $(document).ready(function() {
            console.log($('li').eq(0)); // outputs the first list element Item 1
        });
    </script>
</head>
<body>

    <div class="results">
        <ul>
            <li class="even">Item 1</li>
            <li class="odd">Item 2</li>
            <li class="even">Item 3</li>
            <li class="odd">Item 4</li>
        </ul>
    </div>

</body>
0 голосов
/ 03 марта 2011

Возможно, потому что автозаполнение генерируется (после), когда страница отображается, и, таким образом, сценарий выполнения, возможно, не подхватит ее.

попробуйте с помощью команды jQuery live присоединить триггеры к элементам, отображаемым послеdocument.ready.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...