Как сделать капибара проверки видимости после какого-нибудь JS работать?



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



мой интеграционный тест выглядит примерно так:



it "should not show the blah" do
page.find('#blah').visible?.should be_true
end


когда я вручную перехожу на страницу в контексте этого теста, #blah is не видно, как я ожидал. Я подозреваю, что Capybara смотрит на начальное состояние страницы (невидимое в этом случае), оценивая состояние DOM и проваливая тест до запуска JS.



Да, я поставил :js => true на содержащем описании блока:)



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

717   8  

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

    Ничего не найдено.