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

前端 未结 7 873
北海茫月
北海茫月 2020-12-24 11:25

In a view file I have:

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

In a spec file (I\'m using Capybara):

click_on          


        
相关标签:
7条回答
  • 2020-12-24 12:05

    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)

    0 讨论(0)
  • 2020-12-24 12:08

    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.

    0 讨论(0)
  • 2020-12-24 12:12

    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 讨论(0)
  • 2020-12-24 12:16

    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

    0 讨论(0)
  • 2020-12-24 12:18

    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.

    0 讨论(0)
  • 2020-12-24 12:28

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

    0 讨论(0)
提交回复
热议问题