Skip to content

Instantly share code, notes, and snippets.

@mcmire
Last active December 18, 2015 23:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcmire/5860315 to your computer and use it in GitHub Desktop.
Save mcmire/5860315 to your computer and use it in GitHub Desktop.
Helper for use in RSpec/Capybara feature tests to find a table on a page and convert it into an array of arrays, so that you can make an assertion on it. Similar to Cucumber's #tableize but is better about stringifying cell content.
module TableHelpers
VALID_FORMATS = [:html, :text]
# Find a table on the page and convert it to an array of arrays.
#
# selector_or_node - A String CSS selector to find the table, or a
# Nokogiri::XML::Node object (if you already have a
# reference to the table).
# options - Optional hash:
# columns - An Integer or Range of Integers. Lets you
# select a slice of columns. Useful if one of
# the columns is used solely for interaction
# purposes (e.g., contains buttons or
# checkboxes).
# as - A Symbol. How to convert cell content. :html
# will get the content as HTML, :text will strip
# the HTML. (Default: :text)
#
# Returns an Array of Arrays. Each outer Array is a row, each inner Array is a
# cell.
#
def table_contents(selector_or_node, options = {})
format = options[:as] || :text
selected_columns = options[:columns]
selected_rows = options[:rows]
unless VALID_FORMATS.include?(format)
raise ArgumentError, "Invalid format #{format}. Format must be one of: #{VALID_FORMATS.join(', ')}"
end
if selected_columns && !selected_columns.is_a?(Range)
selected_columns = Range.new(selected_columns, selected_columns)
end
if selected_rows && !selected_rows.is_a?(Range)
selected_rows = Range.new(selected_rows, selected_rows)
end
# Wait for the element to appear on the page
find(selector_or_node)
if selector_or_node.is_a?(Nokogiri::XML::Node)
trs = selector_or_node.css('tr')
else
doc = Nokogiri::HTML.parse(page.html)
trs = doc.css("#{selector_or_node} tr")
end
rows = []
trs.each_with_index do |tr, i|
if selected_rows.nil? || selected_rows.include?(i)
cells = []
tr.css('th, td').each_with_index do |td, j|
if selected_columns.nil? || selected_columns.include?(j)
cells << case format
when :html then td.inner_html
when :text then td.content.strip.squish
end
end
end
rows << cells
end
end
rows
end
end
RSpec.configure do |c|
c.include(TableHelpers, type: :feature)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment