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?
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)
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;)
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.
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.
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
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
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