capybara assert les attributs d'un élément

87

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

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

Kriysna
la source

Réponses:

91

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!

idlefingers
la source
Merci @idlefingers, je veux aussi affirmer en utilisant xpath. Comment puis-je faire cela?
kriysna
J'ai mis à jour ma réponse. Si les sélecteurs xpath sont incorrects, vous devrez faire quelques recherches sur Google ou ouvrir une nouvelle question.
idlefingers
Notez que cela ne fonctionnera pas pour les tests de vue, car capybara n'est pas conçu pour fonctionner avec les vues. (Webrat est.)
Peter Ehrlich
145

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 Capybaracela essaiera automatiquement d'attendre la fin des requêtes 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 qui sont mis à jour de manière asynchrone:

bowsersenior
la source
4
Vrey solution utile. Merci!
Alexander Kuznetsov
J'ai une chaîne avec l'emplacement css, par exemple. find('a#my_element[href]'), serait-il possible de récupérer la valeur de cet attribut? Essayer avec des expressions comme find('a#my_element[href]').valuemais ne semble pas fonctionner :(
mickael
@mickael Essayez find('a#my_element[href]').textou find('a#my_element[href]').native. Faites-moi savoir si l'un ou l'autre donne les résultats que vous attendez.
bowsersenior
1
Je me rends compte que ces commentaires sont vraiment vieux, mais je les ai utilisés de cette façon: page.find ('# my_element') ['href = "<href_value>"'] et cela a fonctionné un régal
Dono
Cela n'attendra pas que la requête devienne vraie si vous souhaitez faire une assertion sur une modification asynchrone.
sj26
4

C'était un peu compliqué de trouver le bon xpath, voici le bon, en
utilisant 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")

Si vous n'avez qu'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.

Clint
la source
4

Je recommande d'utiliser have_linket find_link(name)[:disabled]dans deux assertions distinctes. Bien que l'exécution de la deuxième assertion seule soit plus simple, cela rend les messages d'erreur concernant les liens manquants plus jolis, ce qui facilite la lecture des résultats de votre test.

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

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

Nick McCurdy
la source
1
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 tous les attributs que le lien devrait avoir - assurez-vous simplement de passer toutes les options dans UN hachage.

J'espère que cela t'aides

PS: Pour les attributs comme data-method, vous devez passer le nom de l'attribut sous forme de chaîne car le trait d'union brise le symbole.

Kaikuchn
la source
6
Cela n'a jamais fonctionné et ne fonctionne pas avec Capybara. Je ne sais pas pourquoi 9 personnes ont voté pour cela.
Andrei Botalov
Cela ne fonctionne plus dans Capybara 2. Les personnes utilisant Capybara <2 peuvent utiliser ce qui précède
Tian
@Tian ça n'a pas fonctionné à Capybara <2. Je vous suggère de voter contre cette réponse.
Andrei Botalov
class:n'est pas valide
Amir Raminfar
1

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

Pour le cas particulier de disabled, un wrapper a été introduit en 2.1: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210

Si vous l'utilisez, vous obtiendrez des résultats raisonnables sur RackTest et 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 des sélecteurs CSS, les tests Javascript fonctionneront sans aucune modification si vous commencez à utiliser un pilote compatible Js.

Fichier de test exécutable ici .

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
0

bowsersenior , merci pour un indice

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
18août
la source
0

En utilisant la syntaxe de Rspec3, je l'ai fait de cette façon:

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

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

page.has_css?('.class_name') 

cela retournera truesi l'élément existe.

Faites une action basée sur la validation.

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

Selon la documentation, vous pouvez utiliser la syntaxe d'accesseur [attribut]:

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

Pour les personnes handicapées, vous pouvez également faire ceci:

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