Capybara JS Finders

Capybara JS Finders is a set of additional finders for capybara. Currently it only contains cell finder which allows you to find a table cell based on column and row descriptions.

Installation

Simply add it to your Gemfile and bundle it up:

gem 'capybara-js_finders', '~> 0.4'
gem 'capybara'

Make sure to add it before capybara in your Gemfile!

API

Use it like any other capybara finder.

find_cell

Allows you to find table cell (td, th) based on cell and row descriptions. The method is colspan and rowspan attribute-aware which means it will be able to find a cell even if it is under collspaned th containing a description.

Example

<table>
  <tr>
    <th>
      User
    </th>
    <th>
      Email
    </th>
    <th>
      Permissions
    </th>
  </tr>

  <tr>
    <td>
      John Smith
    </td>
    <td>
      [email protected]
    </td>
    <td>
      Admin
    </td>
  </tr>

  <tr>
    <td>
      Andrew Bon
    </td>
    <td>
      [email protected]
    </td>
    <td>
      Moderator
    </td>
  </tr>

</table>
assert find_cell(:row => "John Smith", :column => "Permissions").has_content?("Admin")
assert find_cell(:row => "Andrew Bon", :column => "Email").has_no_content?("john")

Example

assert find_cell(:row => "John Smith", :column => "January", :text => "28").has_text?("Present at work")

Multicolumn and multirow support

If there are many rows and/or columns matching :row and/or :column parameter you can wider the search to include all of them by using :multirow and/or :multicolumn action.

Example
<table>
  <tr>
    <th>
      User
    </th>
    <th>
      Email
    </th>
    <th>
      Permissions
    </th>
  </tr>

  <tr>
    <td>
      John Smith
    </td>
    <td>
      [email protected]
    </td>
    <td>
      Admin
    </td>
  </tr>

  <tr>
    <td>
      John Smith
    </td>
    <td>
      [email protected]
    </td>
    <td>
      Moderator
    </td>
  </tr>

</table>
find_cell(:row => "John Smith", :column => "Permissions", :text => "Moderator") # raises an exception
find_cell(:multirow => true, :row => "John Smith", :column => "Permissions", :text => "Moderator") # will find the proper cell

Performance

Current implementation calculates the position of every th or td element on a page. This might be slow especially when there are many such elements on the page. You if you have multiple subsequent find_cell invocations and you know that the page does not change between them you might use static_page(&block) method to improve the overall performance. Only first call to find_cell will calculate cells' positions and the following checks will reuse those values.

Example:

click_link("Permissions")

static_page do
  find_cell(:row => "John Smith", :column => "Permissions") # execute JS to calculate elements' positions
  find_cell(:row => "Andrew Bon", :column => "Email")       # JS is not executed
end

click_link("Posts")

static_page do
  find_cell(:row => "Ruby is Awesome", :column => "Published at")       # execute JS to calculate elements' positions
  find_cell(:row => "And CoffeScript too", :column => "Published at")   # JS is not executed
end

click_link("Visitors")

find_cell(:row => "June 2011", :column => "Visitors")   # JS script is always executed outside static_page block
find_cell(:row => "July 2011", :column => "Page views") # JS script is always executed outside static_page block

License

MIT License

Integration

Integrates nicely with bbq

user = Bbq::TestUser.new(:driver => :selenium, :session_name => :default)
user.visit '/page'
assert user.find_cell(:row => "RowDescription", :column => "ColumnDescription").has_content?("CellContent")