Skip to content

Instantly share code, notes, and snippets.

@denmarkin
Created November 2, 2011 17:15
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save denmarkin/1334262 to your computer and use it in GitHub Desktop.
Save denmarkin/1334262 to your computer and use it in GitHub Desktop.
Cucumber + Capybara HTML table comparison from http://railscasts.com/episodes/186-pickle-with-cucumber
Then(/^I should see (.+) table$/) do |table_id, expected_table|
html_table = table_at("##{table_id.parameterize.tableize}").to_a
html_table.map! { |r| r.map! { |c| c.gsub(/<.+?>/, '').gsub(/[\n\t\r]/, '') } }
expected_table.diff!(html_table)
end
Scenario: Adding a promo code
Given an administrator exists with email: "admin@example.com", password: "testing"
And I am logged in as "admin@example.com" with password "testing"
Given I am on path "/admin/promo_codes"
When I follow "+ Add code"
Then I should see "Create Promo Code"
When I fill in the following:
| Code | 50OFF |
| Percentage off | 50 |
And I select "2015-01-01" as the "Expire at" date
And I press "Create"
Then I should see "Promo Code '50OFF' has been added."
And I should see promo codes table
| Code | Expire at | Percentage off | Actions |
| 50OFF | January 01, 2015 00:00 | 50% | Delete |
module HtmlSelectorsHelpers
#....
def table_at(selector) # see https://gist.github.com/1149139
Nokogiri::HTML(page.body).css(selector).map do |table|
table.css('tr').map do |tr|
tr.css('th, td').map { |td| td.text }
end
end[0].reject(&:empty?)
end
end
@denmarkin
Copy link
Author

example_table.feature demonstrates example usage of comparison html table vs. cucumber expected table

@hoasung01
Copy link

how you define step below in step definition:

When I fill in the following:
| Code | 50OFF |
| Percentage off | 50 |

@nimblestart
Copy link

I want to use the above for html tabular data which doesn't use table element instead div and p tags, how would I go about doing that.

@compwron
Copy link

In case this is useful to anyone, this is still in use, but needs some changes to be used in capybara 2.6.0

module JavascriptHelpers
  def show_header
    if page.driver.class == Capybara::Poltergeist::Driver
      page.execute_script 'document.querySelector("#header").style.display = "block"'
    end
  end

  #see https://gist.github.com/denmarkin/1334262
  def table_at(selector) # see https://gist.github.com/1149139
    Nokogiri::HTML(page.body).css(selector).map do |table|
      table.css('tr').map do |tr|
        tr.css('th, td').map { |td| td.text }
      end
    end[0].reject(&:empty?)
  end

  def check_simple_table_data(table_data, options = {})
    options.reverse_merge!(:headers => true)
    table_selector = "table"
    table = page.all(table_selector).last
    expect(table).to be

    within(table) do
      if !options[:headers]
        header_map = (0...table_data.rows.first.length).to_a
        row_count = table_data.raw.length
        table_rows = table_data.raw
      else
        header_map = []
        row_count = table_data.raw.length - 1

        first_tr = page.all("tr").first
        within(first_tr) do
          columns = all("th").collect{ |column| column.text.downcase.strip }
          columns.size.should >= table_data.headers.size

          table_data.headers.each_with_index do |header, index|
            column = columns.index(header.downcase.strip)
            column.should_not be_nil
            header_map << column
          end
        end
        table_rows = table_data.raw[1...table_data.raw.length]
      end

      within("tbody") do
        all("tr").size.should == row_count

        xpath_base = './/tr[%i]/td[%i]';
        table_rows.each_with_index do |row, index|
          row.each_with_index do |value, column|
            find(:xpath, xpath_base % [index + 1, header_map[column] + 1]).should have_content(value)
          end
        end
      end
    end
  end
end

World JavascriptHelpers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment