class FindTableRow::TableRowFinder

Attributes

column_expectations[R]
page[R]

Public Class Methods

call(page, column_expectations) click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 23
def self.call(page, column_expectations)
  new(page, column_expectations).call
end
new(page, column_expectations) click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 18
def initialize(page, column_expectations)
  @page = page
  @column_expectations = column_expectations
end

Public Instance Methods

call() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 27
def call
  verify_table_ambiguity!
  find_row
end
header_key_to_column_index(key) click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 32
def header_key_to_column_index(key)
  key.is_a?(String) ? existing_header_labels.index(key) : key
end

Private Instance Methods

compare(cell, expectation) click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 102
def compare(cell, expectation)
  return expectation.matches?(cell) if expectation.respond_to?(:matches?)
  cell.text.strip == expectation.to_s.strip
end
ensure_headers_presence!() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 66
def ensure_headers_presence!
  expected_header_labels = column_expectations.keys.select { |v| v.is_a? String }
  missing_headers = expected_header_labels - existing_header_labels

  if missing_headers.present?
    raise Capybara::ElementNotFound, "Could not find columns: #{missing_headers.join(', ')}"
  end
end
existing_header_labels() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 62
def existing_header_labels
  @existing_header_labels ||= page.all('thead > tr > th').map(&:text)
end
find_row() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 75
def find_row
  matching_rows = page.all('tbody > tr').find_all do |row|
    normalized_column_expectations.all? do |column_index, expectation|
      cell = row.find(:xpath, "./td[#{column_index + 1}]")
      compare(cell, expectation)
    end
  end

  if matching_rows.count > 1
    raise Capybara::Ambiguous, "Ambiguous match, found #{matching_rows.count} rows"
  elsif matching_rows.empty?
    raise Capybara::ElementNotFound, "Row with #{formatted_expected_attributes} not found"
  else
    matching_rows.first
  end
end
formatted_expected_attributes() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 92
def formatted_expected_attributes
  if column_expectations.is_a?(Array)
    column_expectations.join(', ')
  else
    column_expectations.map do |header_name, expected_value|
      "#{header_name}: #{expected_value}"
    end.join(', ')
  end
end
normalized_column_expectations() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 40
def normalized_column_expectations
  @normalized_column_expectations ||= begin
    if column_expectations.is_a? Array
      column_expectations.each_with_index.each_with_object({}) do |(value, index), result|
        result[index] = value
      end
    else
      ensure_headers_presence!

      column_expectations.transform_keys do |key|
        header_key_to_column_index(key)
      end
    end
  end
end
verify_table_ambiguity!() click to toggle source
# File lib/rspec_tapas/locators/find_table_row.rb, line 56
def verify_table_ambiguity!
  if page.all('table').count > 1
    raise Capybara::Ambiguous, 'Ambiguous match, there is more than one table'
  end
end