Как сделать капибара проверки видимости после какого-нибудь JS работать?
после загрузки страницы у меня есть код, который работает и скрывает и показывает различные элементы на основе данных, возвращенных xhr.
мой интеграционный тест выглядит примерно так:
it "should not show the blah" do
page.find('#blah').visible?.should be_true
end
когда я вручную перехожу на страницу в контексте этого теста, #blah is не видно, как я ожидал. Я подозреваю, что Capybara смотрит на начальное состояние страницы (невидимое в этом случае), оценивая состояние DOM и проваливая тест до запуска JS.
Да, я поставил :js => true на содержащем описании блока:)
любые идеи были бы очень признательны! Я надеюсь, что мне не придется намеренно откладывать здесь, это кажется странным и замедлит все.
8 ответов:
думаю, что
findоператор здесь имеет неявное ожидание, поэтому Capybara будет ждать, пока элемент не появится на странице, но не будет ждать, пока он станет видимым.здесь вы хотите, чтобы капибара ждала появления видимого элемента, который должен быть достижим путем указания :
expect(page).to have_selector('#blah', visible: true)Я не пробовал, но
ignore_hidden_elementsопция конфигурации может быть полезна и здесь, Если вы хотитеfindвсегда ждать видимый элемент.
Это еще один способ сделать это, что отлично работает для меня:
find(:css, "#some_element").should be_visibleособенно для более сложных находок, таких как
find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visibleчто бы утверждать, что элемент был скрыт.
Если вы хотите проверить, что элемент находится на странице, но не виден,
visible: falseне будет работать, как вы могли бы ожидать. Это меня немного озадачило.вот как это сделать:
# assert element is present, regardless of visibility page.should have_css('#some_element', :visible => false) # assert visible element is not present page.should have_no_css('#some_element', :visible => true)
использование:
Ruby: ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux] Rails: 3.2.9 Capybara: 2.0.3у меня есть приложение Rails, в котором есть ссылка, которая при нажатии должна отправить запрос AJAX post и вернуть ответ JS.
код ссылки:
link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)ответ JS (.js.haml file) должен переключать следующий скрытый div на странице, на которой существует ссылка:
#notification_status(style='display:none')js.содержимое файла haml:
:plain var notificationStatusContainer = $('#notification_status'); notificationStatusContainer.val("#{@notification_status_msg}"); notificationStatusContainer.show();я тестировал свой сценарий отправки уведомления и отображение уведомление о состоянии сообщения пользователю с помощью Cucumber (огурец-рельсы камень со встроенным Поддержка капибары)
я пытался проверить, что элемент, имеющий ID: notification_status было видно на успешный ответ в моем определении шага.Для этого я попробовал следующие утверждения:
page.find('#notification_status').should be_visible page.should have_selector('#notification_status', visible: true) page.should have_css('#notification_status', visible: true) page.find('#notification_status', visible: true) page.find(:css, 'div#notification_status', visible: true)ни один из вышеперечисленных не работал на меня и не подвел мой шаг.Из перечисленных выше 5 фрагментов последние 4 не с ошибка:
'expected to find css "#notification_status" but there were no matches. Also found "", which matched the selector but not all filters. (Capybara::ExpectationNotMet)'что было странно, потому что следующее заявление шло правильно:
page.has_selector?('#notification_status')и на самом деле я проверил источник страницы с помощью
print page.html, который показал
<div style='' id='notification_status'></div>чего и следовало ожидать.
наконец-то я нашел эту ссылку капибары утверждают атрибуты элемента который показал, как проверить атрибут элемента в сыром виде.
также я нашел в Капибара документация для видимых? способ (http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element#visible%3F-instance_method) следующая информация:
Not all drivers support CSS, so the result may be inaccurate.таким образом, я пришел к выводу, что при проверке видимости элемента не полагаетесь на результаты капибары видимой? метод при использовании селектора CSS и используя решение, предложенное в ссылке капибары утверждают атрибуты элемента
I придумал следующее:
module CustomMatchers def should_be_visible(css_selector) find(css_selector)['style'].should_not include('display:none', 'display: none') end end World(CustomMatchers)использование:
should_be_visible('#notification_status')
что видимое означает не очевидно
сбой может произойти из-за непонимания того, что считается видимым или нет, поскольку это неочевидно, не переносится драйвером и недокументировано. Некоторые тесты:
HTML:
<div id="visible-empty" ></div> <div id="visible-empty-background" style="width:10px; height:10px; background:black;"></div> <div id="visible-empty-background-same" style="width:10px; height:10px; background:white;"></div> <div id="visible-visibility-hidden" style="visibility:hidden;" >a</div> <div id="visible-display-none" style="display:none;" >a</div>единственное, что тест стойки считает невидимым, это inline
display: none(не внутренний CSS, так как он не делает селекторы):!all('#visible-empty', visible: true).empty? or raise !all('#visible-empty-background', visible: true).empty? or raise !all('#visible-empty-background-same', visible: true).empty? or raise !all('#visible-visibiility-hidden', visible: true).empty? or raise all('#visible-display-none', visible: true).empty? or raiseполтергейст имеет подобное поведение, но он может иметь дело с внутренние CSS и Js
style.displayманипуляции:Capybara.current_driver = :poltergeist !all('#visible-empty', visible: true).empty? or raise !all('#visible-empty-background', visible: true).empty? or raise !all('#visible-empty-background-same', visible: true).empty? or raise !all('#visible-visibiility-hidden', visible: true).empty? or raise all('#visible-display-none', visible: true).empty? or raiseселен ведет себя совершенно иначе: если считает пустой элемент невидимым и
visibility-hiddenа такжеdisplay: none:Capybara.current_driver = :selenium all('#visible-empty', visible: true).empty? or raise !all('#visible-empty-background', visible: true).empty? or raise !all('#visible-empty-background-same', visible: true).empty? or raise all('#visible-visibiility-hidden', visible: true).empty? or raise all('#visible-display-none', visible: true).empty? or raiseДругой распространенный улов является значением по умолчанию
visible:
- это было
false(видит и видимые и невидимые элементы),- в настоящее время
true- управляет
Capybara.ignore_hidden_elementsвыбор.полный запускаемый тест на моем GitHub.
вы можете посмотреть на этот пост, который дает пример метода для ожидания, пока все запросы ajax не будут завершены:
def wait_for_ajax(timeout = Capybara.default_wait_time) page.wait_until(timeout) do page.evaluate_script 'jQuery.active == 0' end end
принятый ответ немного устарел, так как "должен" является устаревшим синтаксисом. В эти дни вам было бы лучше делать что-то вроде
expect(page).not_to have_css('#blah', visible: :hidden)
другие ответы здесь-лучший способ "дождаться" элемента. Однако я обнаружил, что это не работает для сайта, над которым я работаю. В основном элемент, который нужно было щелкнуть, был виден до того, как функция за ним была полностью загружена. Это в доли секунды, но я обнаружил, что мой тест работает так быстро, что он нажал кнопку, и ничего не произошло. Мне удалось обойти это, выполнив это логическое выражение make-shift:
if page.has_selector?('<css-that-appears-after-click>') puts ('<Some-message-you-want-printed-in-the-output>') else find('<css-for-the-button-to-click-again>', :match == :first).trigger('click') endв основном он использует капибара по умолчанию время ожидания, чтобы искать что-то, что должно появиться, если его там нет, он повторит ваш щелчок.
еще раз скажу, что
should have_selectorметод должен быть первым, но если он просто не будет работать, попробуйте это
Comments