Carpela
Carpela

Reputation: 2195

Traverse the tree with Capybara

I want to do something that I think should be quite simple but can't work it out. Using Cucumber and Capybara

In a table I want to click a button in the same row, but a different cell.

i.e. I want to find the button 'Change Role' that is in the same row as the name "Bob Perkins"

click_button "Change Role" within

I want to do something like

within find("td", text:"Bob Perkins").parent #where this would be the "tr" row
click_link_or_button("Change Role")

But that's giving me an ambigous match on "Change Role". Sure, there are more on the page, but only one of them is in the parent node of where it should be...

Upvotes: 1

Views: 1141

Answers (3)

gtd
gtd

Reputation: 17246

I'm not sure how many people are fluent in xpath, but if you find it as confusing as I do, you can chain finds to utilize xpath only as necessary. So for instance:

find("td", text:"Bob Perkins").find(:xpath, '..') # Gives you the TR

Upvotes: 2

Vijay Chouhan
Vijay Chouhan

Reputation: 4883

You are almost close the answer.

Corrected one is the:

within(find("td", text:"Bob Perkins").parent){ click_link_or_button("Change Role") }

Upvotes: -1

Ben_Slaughter
Ben_Slaughter

Reputation: 256

After having a bit of a play with capybara it looks as if the parent method returns the whole html document

e = find "table > thead"
=> #<Capybara::Element tag="thead">
e.parent
=> #<Capybara::Document>

The default selector type for capybara is CSS and that does not support the parent selector It may be worth looking at XPath as with XPath you can perform a contains

e = find :xpath, "//table[thead]"
=> #<Capybara::Element tag="table">

e = find :xpath, "//table[thead]", text: "TOTAL"
=> #<Capybara::Element tag="table">

So looking at your code you could try this:

e = find :xpath, "//tr[td[contains(text(),'Bob Perkins')]]"
=> #<Capybara::Element tag="tr">

OR

e = find :xpath, "//tr[td]", text: 'Bob Perkins'
=> #<Capybara::Element tag="tr">

So you should get something like this

within find(:xpath, "//tr[td[contains(text(),'Bob Perkins')]]") do
  click_link_or_button("Change Role")
end

Best of luck.

Upvotes: 1

Related Questions