Last Updated: February 25, 2016
·
10.94K
· garrow

Using capybara to select a particular cell within a table.

We use this within our Turnip specs to find a particular cell within a particular column within a table.

def within_cell(row, column)
  within_row(row) do
    within_column(column) { yield }
  end
end

This is composed of two other helpers, within_column and within_row.

I would have liked to make this a single XPath selector, but using two different ones does allow for slightly cleaner composition.

def within_column(column)
  within(:xpath, "//table/tbody/tr/td[count(//table/thead/tr/th[normalize-space()='#{column}']/preceding-sibling::th)+1]") do
    yield
  end
end

def within_row(name)
  within(:xpath, "//tr[td='#{name}']") { yield }
end

Example usage

This checks that row "Mr John Citizen" contains a specific icon in the "Activated" column.

And the item "Mr John Citizen" should be marked Activated

step 'the item :name should be marked :flag' do |name, flag|
  within_cell(name, flag) do
    send 'I should see a Yes badge'
  end
end

Breaking down the XPath

count(
    //table/thead/tr/th[
        normalize-space()='#{column}'
    ]/preceding-sibling::th
)+1

Detects the offset of the column matching the column string, by finding the column, counting its previous siblings then adding 1.

//table/tbody/tr/td[ ...offset... ]

This selects cells within rows matching that offset detected by the inner selector.

See;
https://gist.github.com/garrow/6590179

Adapted from an XPath selector found here;
http://stackoverflow.com/questions/14745478