web-dev-qa-db-fra.com

capybara assert les attributs d'un élément

J'utilise RSpec2 et Capybara pour les tests d'acceptation.

Je voudrais affirmer que le lien est désactivé ou non dans Capybara. Comment puis-je faire ceci?

84
kriysna

Comment désactivez-vous le lien? Est-ce une classe que vous ajoutez? Un 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

Les sélecteurs xpath réels peuvent être incorrects. Je n'utilise pas souvent xpath!

91
idlefingers

Une autre solution simple consiste à accéder à l'attribut HTML que vous recherchez avec []:

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

Notez que Capybara tentera automatiquement d'attendre la fin des demandes asynchrones, mais cela peut ne pas fonctionner dans certains cas:

Voici une solution de contournement si vous rencontrez des problèmes avec les assertions sur les éléments mis à jour de manière asynchrone:

141
bowsersenior

C'était un peu compliqué de trouver le bon xpath, voici le bon,
en utilisant capybara 0.4.1.1 

# <a href="/clowns?ordered_by=clumsyness" class="weep">View Clowns</a>  

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

Si vous avez seulement un lien sans classe, utilisez 

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

Quelque chose comme ça ne fonctionnera malheureusement pas:

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

L'option de classe sera ignorée.

4
Clint

Je recommande d'utiliser have_link et find_link(name)[:disabled] dans deux assertions distinctes. Bien que la seconde assertion soit plus simple, les messages d’erreur concernant les liens manquants sont plus agréables, ce qui facilite la lecture des résultats de vos tests.

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

Notez que "Example" peut être modifié en nom ou id du lien.

4
Nick McCurdy

Dans la mesure du possible, vous devriez essayer d'utiliser les wrappers fournis par Capybara, qui fonctionneront de manière plus cohérente pour tous les pilotes.

Dans le cas particulier de disabled, une enveloppe a été introduite dans la version 2.1: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210

Si vous l'utilisez, vous obtiendrez des résultats sensibles à la fois sur RackTest et sur 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>

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

Notez qu'en utilisant ceci au lieu de sélecteurs CSS, les tests Javascript fonctionneront sans changement si vous commencez à utiliser un pilote compatible Js.

Fichier de test exécutable ici .

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

have_link attend un hachage d'options qui est vide si vous n'en fournissez aucune. Vous pouvez spécifier les attributs que le lien devrait avoir - assurez-vous simplement que vous passez toutes les options dans UN hachage.

J'espère que cela t'aides 

PS: Pour des attributs tels que data-method, vous devez transmettre le nom de l'attribut sous forme de chaîne, car le trait d'union rompt le symbole. 

1
kaikuchn

Selon la documentation , vous pouvez utiliser la syntaxe d'accès: [attribut]:

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

Pour les handicapés, vous pouvez aussi faire ceci: 

expect(find('#selector').disabled?).to be(true)
0
pixelearth

En utilisant la syntaxe de Rspec3, je l'ai fait comme suit:

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

Vous pouvez simplement utiliser la méthode page.has_css?

page.has_css?('.class_name') 

cela retournera true si l'élément existe.

Faites des actions basées sur la validation.

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

bowsersenior , merci pour cette remarque

Une autre solution simple consiste à accéder à l'attribut HTML que vous recherchez avec []

Voici un exemple:

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
18augst