kapibara przypisuje atrybuty elementu


87

Używam RSpec2 i Capybara do testów akceptacyjnych.

Chciałbym zapewnić, że link jest wyłączony lub nie w Kapibara. Jak mogę to zrobić?

Odpowiedzi:


91

Jak wyłączasz łącze? Czy to klasa, którą dodajesz? Atrybut?

# Check for a link that has a "disabled" class:
page.should have_css("a.my_link.disabled")
page.should have_xpath("//a[@class='disabled']")

# Check for a link that has a "disabled" attribute:
page.should have_css("a.my_link[disabled]")
page.should have_xpath("//a[@class='disabled' and @disabled='disabled']")

# Check that the element is visible
find("a.my_link").should be_visible
find(:xpath, "//a[@class='disabled']").should be_visible

Rzeczywiste selektory xpath mogą być nieprawidłowe. Nie używam często xpath!


Dzięki @idlefingers, chcę również potwierdzić użycie xpath. Jak mogę to zrobić?
kriysna

Zaktualizowałem odpowiedź. Jeśli selektory xpath są złe, będziesz musiał poszukać go w Google lub otworzyć nowe pytanie.
idlefingers

Zauważ, że to nie zadziała w przypadku testowania widoku, ponieważ kapibara nie jest stworzona do pracy z widokami. (Webrat jest.)
Peter Ehrlich

145

Innym prostym rozwiązaniem jest uzyskanie dostępu do szukanego atrybutu HTML za pomocą []:

find('#my_element')['class']
# => "highlighted clearfix some_other_css_class"

find('a#my_element')['href']
# => "http://example.com

# or in general, find any attribute, even if it does not exist
find('a#my_element')['no_such_attribute']
# => ""

Zauważ, że Capybaraautomatycznie spróbuje czekać na zakończenie asynchronicznych żądań, ale w niektórych przypadkach może to nie działać:

Oto jedno obejście, jeśli masz problemy z asercjami dotyczącymi elementów, które są aktualizowane asynchronicznie:


4
Vrey przydatne rozwiązanie. Dzięki!
Alexander Kuznetsov

Mam ciąg z lokalizacją css, np. find('a#my_element[href]'), czy byłoby możliwe pobranie wartości tego atrybutu? Próbowanie z wyrażeniami takimi jak, find('a#my_element[href]').valueale wydaje się nie działać :(
mickael

@mickael Wypróbuj find('a#my_element[href]').textlub find('a#my_element[href]').native. Daj mi znać, jeśli którykolwiek z tych wyników przyniesie oczekiwane rezultaty.
bowsersenior

1
Zdaję sobie sprawę, że te komentarze są naprawdę stare, ale użyłem ich w ten sposób: page.find ('# my_element') ['href = "<href_value>"'] i zadziałało
Dono

Nie będzie to czekać, aż zapytanie stanie się prawdziwe, jeśli chcesz dokonać asercji o asynchronicznej zmianie.
sj26

4

Znalezienie właściwej ścieżki xpath było trochę
kłopotliwe , tutaj jest poprawna, używając kapibary 0.4.1.1

# <a href="https://stackoverflow.com/clowns?ordered_by=clumsyness" class="weep">View Clowns</a>  

page.should have_xpath("//a[@class='weep'][@href='/clowns?ordered_by=clumsyness']", :text => "View Clowns")

Jeśli masz tylko link bez zajęć, użyj

page.should have_link('View Clowns', :href => '/clowns?ordered_by=clumsyness')

Coś takiego niestety nie zadziała:

page.should have_link('This will not work!', :href => '/clowns?ordered_by=clumsyness', :class => "weep")

Opcja klasy zostanie zignorowana.


4

Polecam użycie have_linki find_link(name)[:disabled]w dwóch oddzielnych asercjach. Chociaż samo wykonanie drugiego potwierdzenia jest prostsze, to sprawia, że ​​komunikaty o błędach dotyczące brakujących linków wyglądają ładniej, dzięki czemu wyniki testów są łatwiejsze do odczytania.

expect(page).to have_link "Example"
expect(find_link("Example")[:disabled]).to be false

Pamiętaj, że "Example"można to zmienić na nazwę lub identyfikator łącza.


1
page.should have_link('It will work this way!', {:href => '/clowns?ordered_by=clumsyness', :class => "smile"})

have_link oczekuje skrótu opcji, który jest pusty, jeśli żadnych nie podasz. Możesz określić dowolne atrybuty, które powinien mieć link - po prostu upewnij się, że przekazałeś wszystkie opcje w JEDNYM hashu.

Mam nadzieję że to pomoże

PS: W przypadku atrybutów, takich jak metoda danych, musisz przekazać nazwę atrybutu jako ciąg, ponieważ łącznik przerywa symbol.


6
To nigdy nie działało i nie działa z Kapibarą. Nie wiem, dlaczego głosowało za to 9 osób.
Andrei Botalov

To już nie działa w Kapibara 2. Osoby używające Kapibary <2 mogą używać powyższego
Tian

@Tian to nie zadziałało w Kapibara <2. Proponuję zignorować tę odpowiedź.
Andrei Botalov

class:nie jest ważny
Amir Raminfar

1

O ile to możliwe, należy spróbować użyć opakowań dostarczonych przez Kapibarę, które będą działać bardziej konsekwentnie we wszystkich sterownikach.

W tym konkretnym przypadku disabledopakowanie zostało wprowadzone w wersji 2.1: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210

Jeśli go użyjesz, uzyskasz rozsądne wyniki zarówno w RackTest, jak i Poltergeist:

HTML:

<input type="text" id="disabled-false"            ></div>
<input type="text" id="disabled-true"     disabled></div>
<input type="text" id="disabled-js-true"          ></div>
<input type="text" id="disabled-js-false" disabled></div>
<script>
  document.getElementById('disabled-js-true').disabled = true
  document.getElementById('disabled-js-false').disabled = false
</script>

Testy:

!all(:field, 'disabled-false',    disabled: false).empty? or raise
 all(:field, 'disabled-false',    disabled: true ).empty? or raise
 all(:field, 'disabled-true',     disabled: false).empty? or raise
!all(:field, 'disabled-true',     disabled: true ).empty? or raise
 all(:field, 'disabled-js-true',  disabled: true ).empty? or raise
 all(:field, 'disabled-js-false', disabled: false).empty? or raise

Capybara.current_driver = :poltergeist
!all(:field, 'disabled-false',    disabled: false).empty? or raise
 all(:field, 'disabled-false',    disabled: true ).empty? or raise
 all(:field, 'disabled-true',     disabled: false).empty? or raise
!all(:field, 'disabled-true',     disabled: true ).empty? or raise
!all(:field, 'disabled-js-true',  disabled: true ).empty? or raise
!all(:field, 'disabled-js-false', disabled: false).empty? or raise

Zauważ, że używając tego zamiast selektorów CSS, testy Javascript będą działać bez żadnych zmian, jeśli zaczniesz używać sterownika obsługującego js.

Plik testowy do uruchomienia tutaj .


0

bowsersenior , dzięki za podpowiedź

Innym prostym rozwiązaniem jest dostęp do szukanego atrybutu HTML za pomocą []

Oto przykład:

let(:action_items) { page.find('div.action_items') }

it "action items displayed as buttons" do
  action_items.all(:css, 'a').each do |ai|
    expect(ai[:class]).to match(/btn/)
  end
end

0

Używając składni Rspec3 zrobiłem to w ten sposób:

expect(page).not_to have_selector(:link_or_button, 'Click here')

0

Po prostu możesz użyć page.has_css?metody

page.has_css?('.class_name') 

to zwróci, truejeśli element istnieje.

Wykonaj jakąś czynność w oparciu o walidację.

page.has_css?('.class_name') do
  #some code
end

0

Zgodnie z dokumentacją możesz użyć składni akcesora [atrybut]:

find('#selector')['class'] => "form-control text optional disabled"

W przypadku osób niepełnosprawnych możesz również zrobić to:

expect(find('#selector').disabled?).to be(true)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.