Po załadowaniu strony mam kod, który działa, ukrywa i pokazuje różne elementy na podstawie danych zwróconych przez xhr.
Mój test integracji wygląda mniej więcej tak:
it "should not show the blah" do
page.find('#blah').visible?.should be_true
end
Kiedy ręcznie przechodzę do strony w kontekście tego testu, #blah nie jest widoczny zgodnie z oczekiwaniami. Podejrzewam, że Kapibara patrzy na początkowy stan strony (w tym przypadku niewidoczny), oceniając stan DOM i nie zdając testu przed uruchomieniem JS.
Tak, ustawiłem :js => true
na zawierający opis bloku :)
Wszelkie pomysły będą mile widziane! Mam nadzieję, że nie muszę tu wstawiać celowego opóźnienia, które wydaje się niestabilne i spowolni.
ruby
rspec
capybara
integration-testing
Kevin Davis
źródło
źródło
Odpowiedzi:
Myślę, że
find
tutaj stwierdzenie jest z ukrytym czekaniem, więc Kapibara będzie czekać, aż element znajdzie się na stronie, ale nie będzie czekać, aż stanie się widoczny.Tutaj chciałbyś, aby Kapibara czekała na pojawienie się widocznego elementu, co powinno być osiągalne, określając
visible
opcję:expect(page).to have_selector('#blah', visible: true)
Nie próbowałem tego, ale
ignore_hidden_elements
opcja konfiguracji może się tu również przydać, jeśli chceszfind
zawsze czekać na widoczne elementy.źródło
js:true
blok zawierający, aby to zadziałało.expect(page).to have_selector('#flash-message', visible: false, text: "Signed in Successfully")
- dzięki za wysłanie tej odpowiedziJest to inny sposób, który działa idealnie dla mnie:
find(:css, "#some_element").should be_visible
Szczególnie w przypadku bardziej złożonych znalezisk, takich jak
find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visible
co potwierdzałoby, że element został ukryty.
źródło
should_not be_visible
Nie wygląda dobrze dla mnie jako metę Kapibarawait_until { base.visible? }
kiedy Element # widoczne? przywoływane..should_not be_visible
okładkidisplay: none
ustawione przez jQuery? Wydaje mi się, że to nie działa.Jeśli chcesz sprawdzić, czy element znajduje się na stronie, ale nie jest widoczny,
visible: false
nie będzie działać zgodnie z oczekiwaniami. Trochę się potknąłem.Oto jak to zrobić:
# 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)
źródło
should_not
z kapibarą, z powodu Ajaxahave_css
będzie czekał przez cały limit czasu, zanim się poddaje, ponieważ oczekuje, że znajdzie element. Np. Musisz użyćshould have_no_content
zamiastshould_not have_content
.expect(page).not_to have_selector("#some_element", visible: true)
działało dobrze dla mnie przy użyciujavascript_driver
, bez czekania przez cały limit czasu.should_not
teraz, przepraszam!Za pomocą:
Ruby: ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux] Rails: 3.2.9 Capybara: 2.0.3
Mam aplikację Rails, w której znajduje się link, który po kliknięciu powinien wysłać żądanie wiadomości AJAX i zwrócić odpowiedź JS.
Kod łącza:
link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)
Odpowiedź JS (plik .js.haml) powinna przełączać następujące ukryte div na stronie, do której istnieje łącze:
#notification_status(style='display:none')
Zawartość pliku js.haml:
:plain var notificationStatusContainer = $('#notification_status'); notificationStatusContainer.val("#{@notification_status_msg}"); notificationStatusContainer.show();
Testowałem mój scenariusz wysyłania powiadomienia i wyświetlania komunikatu o statusie powiadomienia do użytkownika za pomocą Cucumber ( klejnot ogórków z wbudowaną obsługą Kapibary )
Próbowałem sprawdzić, czy element mający id: notification_status był widoczny po pomyślnej odpowiedzi w mojej definicji kroku, w tym celu wypróbowałem następujące stwierdzenia:
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)
Żaden z powyższych nie zadziałał dla mnie i nie wykonał mojego kroku. Z 5 wymienionych powyżej fragmentów ostatnie 4 zakończyły się niepowodzeniem z następującym błędem:
'expected to find css "#notification_status" but there were no matches. Also found "", which matched the selector but not all filters. (Capybara::ExpectationNotMet)'
co było dziwne, ponieważ następujące stwierdzenie zostało przekazane poprawnie:
page.has_selector?('#notification_status')
I faktycznie sprawdziłem źródło strony używając
który się pojawił
<div style='' id='notification_status'></div>
co było oczekiwane.
Wreszcie znalazłem ten link kapibara assert atrybuty elementu, który pokazał, jak sprawdzić atrybut elementu w sposób surowy.
Znalazłem też w dokumentacji Kapibary widoczne? metoda ( http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element#visible%3F-instance_method ) następujące informacje:
W ten sposób doszedłem do wniosku, że testując widoczność pierwiastka nie opierasz się na wynikach widzialności Kapibary? przy użyciu selektora CSS i rozwiązania sugerowanego w link capybara assert atrybuty elementu
Wymyśliłem:
module CustomMatchers def should_be_visible(css_selector) find(css_selector)['style'].should_not include('display:none', 'display: none') end end World(CustomMatchers)
Stosowanie:
should_be_visible('#notification_status')
źródło
Nie jest oczywiste, jakie są widoczne środki
Awaria może wynikać z niezrozumienia tego, co jest uważane za widoczne lub nie, ponieważ jest nieoczywiste, nieprzenośne dla kierowcy i niedostatecznie udokumentowane. Niektóre testy:
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>
Jedyną rzeczą, którą test Rack uważa za niewidoczną, jest inline
display: none
(nie wewnętrzny CSS, ponieważ nie obsługuje selektorów):!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
Poltergeist zachowuje się podobnie, ale radzi sobie z wewnętrznymi
style.display
manipulacjami CSS i 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
Selen zachowuje się zupełnie inaczej: jeśli uważa pusty element za niewidoczny, a
visibility-hidden
takżedisplay: 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
Innym częstym haczykiem jest domyślna wartość
visible
:false
(widzi zarówno widoczne, jak i niewidoczne elementy),true
Capybara.ignore_hidden_elements
opcję.Odniesienie .
Pełny test na moim GitHubie .
źródło
Możesz spojrzeć na ten post , który podaje przykładową metodę czekania, aż wszystkie żądania AJAX są kompletne:
def wait_for_ajax(timeout = Capybara.default_wait_time) page.wait_until(timeout) do page.evaluate_script 'jQuery.active == 0' end end
źródło
wait_until
zostało usunięte z Kapibary 2 .Timeout.timeout
Selenium::WebDriver::Wait
Zaakceptowana odpowiedź jest teraz nieco nieaktualna, ponieważ składnia „powinna” jest przestarzała. W dzisiejszych czasach lepiej byłoby zrobić coś podobnego do
expect(page).not_to have_css('#blah', visible: :hidden)
źródło
Pozostałe odpowiedzi tutaj to najlepszy sposób „czekania” na element. Jednak okazało się, że to nie działa w przypadku witryny, nad którą pracuję. Zasadniczo element, który wymagał kliknięcia, był widoczny, zanim funkcja za nim została w pełni załadowana. Odbywa się to w ułamkach sekundy, ale okazjonalnie mój test przebiegł tak szybko, że klikał przycisk i nic się nie stało. Udało mi się to obejść, wykonując to wyrażenie logiczne typu 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
Zasadniczo używa domyślnego czasu oczekiwania kapibary, aby wyszukać coś, co powinno się pojawić, jeśli go tam nie ma, spróbuje ponownie kliknąć.
Ponownie powiem, że
should have_selector
najpierw należy wypróbować metodę, ale jeśli to po prostu nie zadziała, spróbuj tegoźródło