capybara behauptet Attribute eines Elements


86

Ich verwende RSpec2 und Capybara für Abnahmetests.

Ich möchte behaupten, dass der Link in Capybara deaktiviert ist oder nicht. Wie kann ich das machen?

Antworten:


90

Wie deaktivierst du den Link? Ist es eine Klasse, die Sie hinzufügen? Ein Attribut?

# 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

Die tatsächlichen xpath-Selektoren sind möglicherweise falsch. Ich benutze xpath nicht oft!


Danke @idlefingers, ich möchte auch mit xpath behaupten. Wie kann ich das machen?
Kriysna

Ich habe meine Antwort aktualisiert. Wenn die xpath-Selektoren falsch sind, müssen Sie etwas googeln oder eine neue Frage öffnen.
Idlefingers

Beachten Sie, dass dies für Ansichtstests nicht funktioniert, da Capybara nicht für Ansichten geeignet ist. (Webrat ist.)
Peter Ehrlich

144

Eine andere einfache Lösung besteht darin, auf das gesuchte HTML-Attribut zuzugreifen []:

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']
# => ""

Beachten Sie, dass Capybaraautomatisch versucht wird, auf den Abschluss asynchroner Anforderungen zu warten. In einigen Fällen funktioniert dies jedoch möglicherweise nicht:

Hier ist eine Problemumgehung, wenn Sie Probleme mit Zusicherungen für Elemente haben, die asynchron aktualisiert werden:


4
Sehr nützliche Lösung. Vielen Dank!
Alexander Kuznetsov

Ich habe eine Zeichenfolge mit dem CSS-Speicherort, z. find('a#my_element[href]')Wäre es möglich, den Wert dieses Attributs abzurufen? Versuchen mit Ausdrücken wie find('a#my_element[href]').value, scheint aber nicht zu funktionieren :(
mickael

@mickael Versuch find('a#my_element[href]').textoder find('a#my_element[href]').native. Lassen Sie mich wissen, ob einer von beiden die erwarteten Ergebnisse liefert.
Bowsersenior

1
Mir ist klar, dass diese Kommentare wirklich alt sind, aber ich habe sie so verwendet: page.find ('# my_element') ['href = "<href_value>"'] und es hat gut geklappt
Dono

Dies wartet nicht darauf, dass die Abfrage wahr wird, wenn Sie eine Aussage über eine asynchrone Änderung machen möchten.
Sj26

4

Es war ein bisschen chaotisch, den richtigen xpath herauszufinden, hier ist der richtige
mit capybara 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")

Wenn Sie nur einen Link ohne Klasse haben, verwenden Sie

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

So etwas wird leider nicht funktionieren:

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

Die Klassenoption wird ignoriert.


4

Ich empfehle die Verwendung von have_linkund find_link(name)[:disabled]in zwei getrennten Aussagen. Während das Ausführen der zweiten Behauptung allein einfacher ist, sehen Fehlermeldungen über fehlende Links dadurch besser aus und Ihre Testergebnisse sind leichter zu lesen.

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

Beachten Sie, dass "Example"dies in den Namen oder die ID des Links geändert werden kann.


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

have_link erwartet einen Hash von Optionen, der leer ist, wenn Sie keine angeben. Sie können alle Attribute angeben, die der Link haben soll - stellen Sie einfach sicher, dass Sie alle Optionen in EINEM Hash übergeben.

Hoffe das hilft

PS: Für Attribute wie die Datenmethode müssen Sie den Attributnamen als Zeichenfolge übergeben, da der Bindestrich das Symbol durchbricht.


6
Es hat nie funktioniert und funktioniert nicht mit Capybara. Ich weiß nicht, warum 9 Leute dies positiv bewertet haben.
Andrei Botalov

Dies funktioniert nicht mehr in Capybara 2. Leute, die Capybara <2 verwenden, können das oben genannte verwenden
Tian

@Tian es hat in Capybara <2 nicht funktioniert. Ich schlage vor, dass Sie diese Antwort ablehnen.
Andrei Botalov

class:ist nicht gültig
Amir Raminfar

1

Wann immer möglich, sollten Sie versuchen, die von Capybara bereitgestellten Wrapper zu verwenden, die für alle Treiber gleichmäßiger funktionieren.

Für den speziellen Fall von disabledwurde in 2.1 ein Wrapper eingeführt: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210

Wenn Sie es verwenden, erhalten Sie sowohl bei RackTest als auch bei Poltergeist sinnvolle Ergebnisse:

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>

Tests:

!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

Beachten Sie, dass bei Verwendung dieser Option anstelle von CSS-Selektoren die Javascript-Tests ohne Änderungen funktionieren, wenn Sie einen Js-fähigen Treiber verwenden.

Ausführbare Testdatei hier .


0

Bowsersenior , danke für einen Hinweis

Eine andere einfache Lösung besteht darin, mit [] auf das gesuchte HTML-Attribut zuzugreifen.

Hier ist ein Beispiel:

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

Mit der Syntax von Rspec3 habe ich es so gemacht:

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

0

Sie können einfach die page.has_css?Methode verwenden

page.has_css?('.class_name') 

Dies wird zurückgegeben, truewenn ein Element vorhanden ist.

Führen Sie eine Aktion basierend auf der Validierung aus.

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

0

Gemäß den Dokumenten können Sie die Accessorsyntax [attribute] verwenden:

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

Für Behinderte können Sie auch Folgendes tun:

expect(find('#selector').disabled?).to be(true)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.