web-dev-qa-db-fra.com

Comment cliquer sur le deuxième lien avec le même texte en utilisant Capybara dans Rails 3?

Dans un fichier de vue, j'ai:

= link_to 'View', post
= link_to 'View', comment

Dans un fichier de spécifications (j'utilise Capybara):

click_on 'View'

Il clique sur le premier lien, mais je veux qu'il clique sur le second. Comment puis-je le faire?

34
Aleksandr Shvalev

Il y a probablement plusieurs façons, mais je vis habituellement quelque chose comme ça.

within(".comment") do
  click_on("View")
end

Il existe également des alternatives. Je fais généralement mes tests d'acceptation à partir de concombre, donc mes étapes ressemblent généralement à

When I follow "View" within the comment element

Où j'ai une étape qui traduit within the comment element à un appel limité à l'étape elle-même (qui, je pense, est intégré dans les derniers capybara web_steps)

37
karmajunkie

Vous pouvez essayer de trouver toutes les entrées et gérer un tableau:

page.all('a')[1].click

Serait utile d'avoir une classe ou d'utiliser dans pour étendre votre recherche;)

56
Gabriel F. Engel

Il existe de nombreuses façons de résoudre ce type de problèmes.
Fais-le comme ça

if(page.find("a")[:href] == "comment")
    click_on("View")

ou

page.find("a:eq(2)").click

N'oubliez pas que l'indexation javascript commence par 0 tandis qu'à Capybara, l'indexation commence par 1. Utilisez donc a: eq (2) ici pour le deuxième href.

15
RohitPorwal

La pire chose à propos du "deuxième" lien est qu'il peut devenir le troisième ou le premier ou même le vingt-cinquième jour. Ainsi, la portée avec un bloc within est la meilleure façon. Exemple:

within(".comment") do
  click_on("View")
end

Mais s'il est difficile de spécifier le lien avec une portée within (ce qui est parfois le cas), je suppose que la façon de cliquer sur le deuxième lien avec un certain texte est:

 find(:xpath, "(//a[text()='View'])[2]").click

Dans les versions ultérieures de capybara (2.0.2, par exemple) --- click_on 'View' et click_link 'View' lèveront une erreur de correspondance ambiguë:

 Failure/Error: click_on 'View'
 Capybara::Ambiguous:
   Ambiguous match, found 2 elements matching link or button "View"

Donc, cela ne fonctionnera pas même si vous souhaitez cliquer sur le premier lien (ou si un lien serait correct, ce qui est mon cas).

Autant que je sache, cela est fait pour forcer les gens à écrire des tests plus spécifiques où des liens particuliers sont cliqués.

Il peut certainement être difficile de déboguer le code si vous placez accidentellement deux ou plusieurs liens avec un texte identique et essayez de voir ce qui se passe. Il est bon de s'appuyer sur quelque chose qui ne changera probablement pas et spécifier un lien avec un bloc within est une bonne façon de le faire.

15
installero

Pour la solution capybara 2:

within(".comment") do
  click_on("View")
end

n'aiderait pas si vous en avez quelques-uns .comment. Utilisation si simple: page.first(:link, "View").click

7
Michael Nikitochkin

Cela fonctionne pour moi si vous avez plusieurs lignes de classes identiques et que vous souhaitez trouver la deuxième ligne. Comme un auteur précédent l'a mentionné, l'indexation capybara commence à 1.

within all(".trip-row")[2] do
   assert page.has_content?("content")
end
2
Jwan622

Si vous utilisez capybara-ui vous pouvez définir le widget, ou la référence DOM réutilisable, pour chaque widget.

# define your widget. in this case,
# we're defining it in a role
widget :view_post, ['.post', text: 'View']
widget :view_comment, ['.comment', text: 'View']

# then click that widget in the test
role.click :view_post
role.click :view_comment
1
steel