开发者

How to click on the second link with the same text using Capybara in Rails 3?

In a view file I have:

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

In开发者_如何学JAVA a spec file (I'm using Capybara):

click_on 'View'

It clicks on the first link, but I want it to click on the second one. How can I do it?


You could try to find all entries and deal with an array:

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

Would help to have a class or use within to scope your search ;)


There's probably a few ways but I usually scope something like this.

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

There's quite possibly/probably alternatives as well. I usually do my acceptance testing from cucumber, so my steps typically look like

When I follow "View" within the comment element

Where I have a step that translates within the comment element to a scoped call to the step itself (which I think is built into the latest capybara web_steps)


The worst thing about "the second" link is that it can become the third or the first or even the twenty fifth someday. So, scoping with a within block is the best way. Example:

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

But if it is difficult to specify the link with a within scope (which sometimes it really is), I guess the way to click the second link with a certain text is:

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

In later versions of capybara (2.0.2, for example) both click_on 'View' and click_link 'View' will raise an ambiguous match error:

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

So this won't do even if you want to click the first link (or if any link would be ok, which is my case).

As far as I understand this is made to force people write more specific tests where particular links are clicked.

It definitely could be tricky to debug the code if you accidentally placed two or more links with identical text and try to see what is happening. It's good to rely on something that is unlikely to change and specifying a link with a within block is a nice way to do this.


There are many ways for solving this type of problems.
Do it like this

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

or

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

Remember javascript indexing starts with 0 while In Capybara, indexing starts with 1. So use a:eq(2) here for second href.


For capybara 2 solution:

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

would not help if you have a few .comment. So simple use: page.first(:link, "View").click


This works for me if you have several rows of identical classes and you want to find the second row. Like a previous author mentioned, capybara indexing starts at 1.

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


If you use capybara-ui you could define the widget, or reusable DOM reference, for each 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜