После загрузки страницы у меня есть код, который запускается, скрывает и показывает различные элементы на основе данных, возвращаемых xhr.
Мой интеграционный тест выглядит примерно так:
it "should not show the blah" do
page.find('#blah').visible?.should be_true
end
Когда я вручную перехожу на страницу в контексте этого теста, #blah не отображается, как я ожидал. Я подозреваю, что Capybara смотрит на начальное состояние страницы (в данном случае невидимо), оценивает состояние DOM и не проходит тест до запуска JS.
Да, я установил :js => true
на содержащий блок описания :)
Благодарим за любую идею! Я надеюсь, что мне не придется делать здесь преднамеренную задержку, это кажется ненадежным и замедлит процесс.
ruby
rspec
capybara
integration-testing
Кевин Дэвис
источник
источник
Ответы:
Я думаю, что
find
утверждение с неявным ожиданием, поэтому Capybara будет ждать, пока элемент не появится на странице, но не будет ждать, пока он станет видимым.Здесь вы хотите, чтобы Capybara ожидала появления видимого элемента, что должно быть достижимо, указав
visible
параметр:expect(page).to have_selector('#blah', visible: true)
Я не пробовал, но
ignore_hidden_elements
опция конфигурации может быть полезна и здесь, если вы хотитеfind
всегда ждать появления видимых элементов.источник
js:true
в содержащем блоке, чтобы это сработало.expect(page).to have_selector('#flash-message', visible: false, text: "Signed in Successfully")
- Спасибо за публикацию этого ответаЭто еще один способ, который мне подходит:
find(:css, "#some_element").should be_visible
Особенно для более сложных находок, таких как
find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visible
который утверждал бы, что элемент был скрыт.
источник
should_not be_visible
Не выглядит хорошо для меня , как Capybara перспектива ,wait_until { base.visible? }
когда элемент # видимые? вызывается..should_not be_visible
обложки сdisplay: none
помощью jQuery? Похоже, у меня это не работает.Если вы хотите проверить, что элемент находится на странице, но не отображается,
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)
источник
should_not
с капибарой из-за аяксаhave_css
будет ждать весь ваш тайм-аут, прежде чем сдаться, потому что он ожидает найти элемент. Например, вы должны использоватьshould have_no_content
вместоshould_not have_content
.expect(page).not_to have_selector("#some_element", visible: true)
отлично работал у меня, используяjavascript_driver
, не дожидаясь всего таймаута.should_not
сейчас, извините!С помощью:
Ruby: ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux] Rails: 3.2.9 Capybara: 2.0.3
У меня есть приложение Rails, в котором есть ссылка, которая при нажатии должна отправить запрос на отправку AJAX и вернуть ответ JS.
Код ссылки:
link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)
Ответ JS (файл .js.haml) должен переключить следующий скрытый div на странице, на которую существует ссылка:
#notification_status(style='display:none')
js.haml содержимое файла:
:plain var notificationStatusContainer = $('#notification_status'); notificationStatusContainer.val("#{@notification_status_msg}"); notificationStatusContainer.show();
Я тестировал свой сценарий отправки уведомления и отображения сообщения о состоянии уведомления пользователю, используя Cucumber ( драгоценный камень огурцов-рельсов со встроенной поддержкой Capybara. )
Я пытался проверить, что элемент с идентификатором: 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')
И на самом деле я проверил источник страницы, используя
который появился
<div style='' id='notification_status'></div>
чего и ожидалось.
Наконец я нашел эту ссылку capybara assert attributes элемента, которая показала, как проверять атрибут элемента в необработанном виде.
Также я нашел в документации Capybara для видимых? метод ( http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element#visible%3F-instance_method ) следующую информацию:
Таким образом, я пришел к выводу, что при тестировании видимости элемента не полагаться на результаты Capybara's visible? при использовании селектора CSS и использовании решения, предложенного в ссылке capybara assert атрибутов элемента
Я придумал следующее:
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>
Единственное, что Rack test считает невидимым, - это встроенный
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
Полтергейст имеет аналогичное поведение, но он может иметь дело с внутренними
style.display
манипуляциями CSS и Js :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
источник
wait_until
было удалено из Capybara 2 .Timeout.timeout
Selenium::WebDriver::Wait
Принятый ответ теперь немного устарел, поскольку синтаксис «следует» устарел. В наши дни вам лучше сделать что-нибудь вроде
expect(page).not_to have_css('#blah', visible: :hidden)
источник
Другие ответы здесь - лучший способ «дождаться» элемента. Однако я обнаружил, что это не работает для сайта, над которым я работаю. В основном элемент, на который нужно было щелкнуть, был виден до полной загрузки функции, стоящей за ним. Это доли секунды, но я обнаружил, что мой тест иногда запускался так быстро, что нажимал кнопку, и ничего не происходило. Мне удалось обойти это, выполнив это импровизированное логическое выражение:
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
сначала следует попробовать этот метод, но если он просто не работает, попробуйте этоисточник