How to assert table html in page with rspec/capybara
Rspec
5
Capybara
4
White

hoasung01 viết ngày 31/03/2017

How to assert table html in page with rspec/capybara

Nếu ai đã từng viết cucumber thì mình nghĩ sẽ có nhiều người sử dụng đến thư viện spreewald vì hầu như hỗ trợ sẵn hết các hàm định nghĩa sẵn cần dùng.

Mọi người có thể tìm hiểu thêm tại đây: Spreewald

scenario "table's data after click to sort with '会場名称'", js: true do
  screening_rooms = (1..5).each do |n|
     create :screening_room, m_branch_id: "#{n}", name: "name-#{n}"
  end
  visit screening_rooms_path
  within("table#common_list thead") do
    click_link "会場名称"
  end
  expected_table = <<-EOF
    |拠点|会場名称|会場住所|登録日時|更新日時| |
    | * |name-5 |*      |*     |*      |*|
    | * |name-4 |*      |*     |*      |*|  
    | * |name-3 |*      |*     |*      |*|   
    | * |name-2 |*      |*     |*      |*|   
    | * |name-1 |*      |*     |*      |*|      
  EOF

  document = Nokogiri::HTML(page.body)
  tables = document.xpath('//table').collect {|table| table.xpath('.//tr').collect {|row| row.xpath('.//th|td')}}
  parsed_table = parse_table(expected_table)
  tables.should contain_table(parsed_table)
end  

Ở đây mình tận dụng table_steps bên spreewald và port để sử dụng được cho bên rspec sau:

module TableHelpers
module ArrayMethods
def find_row(expected_row)
find_index do |row|
expected_row.all? do |expected_column|
first_column = row.find_index do |column|
content = normalize_content(column.content)
expected_content = normalize_content(expected_column)
matching_parts = expected_content.split(/\s*\*\s*/, -1).collect { |part| Regexp.escape(part) }
matching_expression = /\A#{matching_parts.join(".*")}\z/
content =~ matching_expression
end
if first_column.nil?
false
else
row = row[(first_column + 1)..-1]
true
end
end
end
end
# Only cross-Ruby way to get a character for its UTF-16 (hex) representation
def character(code)
[code.to_i(16)].pack('U*')
end
def normalize_content(content)
shy = character("00ad") # soft hyphen
nbsp = character("00a0") # non-breaking space
zwsp = character("200b") # zero-width space
content = content.gsub(/[#{shy}#{zwsp}]/, '')
content = content.gsub(/[\r\n\t#{nbsp}]+/, ' ')
content = content.gsub(/ {2,}/, ' ')
content = content.strip
content
end
end
rspec = defined?(RSpec) ? RSpec : Spec
rspec::Matchers.define :contain_table do |*args|
match do |tables|
@last_unmatched_row = nil
@extra_rows = nil
@best_rows_matched = -1
options = args.extract_options!
expected_table = args.first
tables.any? do |table|
skipped_rows = []
rows_matched = 0
match = expected_table.all? do |expected_row|
if @best_rows_matched < rows_matched
@last_unmatched_row = expected_row
@best_rows_matched = rows_matched
end
table.extend ArrayMethods
first_row = table.find_row(expected_row)
if first_row.nil?
false
else
rows_matched += 1
if options[:unordered]
table.delete_at(first_row)
else
skipped_rows += table[0...first_row]
table = table[(first_row + 1)..-1]
end
true
end
end
remaining_rows = skipped_rows + table
if match and options[:exactly] and not remaining_rows.empty?
@extra_rows = remaining_rows
match = false
end
match
end
end
failure_message do
if @extra_rows
"Found the following extra row: #{@extra_rows.first.collect(&:content).collect(&:squish).inspect}"
elsif @last_unmatched_row
"Could not find the following row: #{@last_unmatched_row.inspect}"
else
"Could not find a table"
end
end
failure_message_when_negated do
"Found the complete table: #{args.first.inspect}."
end
end
def parse_table(table)
if table.is_a?(String)
# multiline string. split it assuming a format like cucumber tables have.
table.split(/\n/).collect do |line|
line.gsub!(/\t|\s/, '')
line.sub!(/^\|/, '')
line.sub!(/\|$/, '')
line.split(/\s*\|\s*/)
end
else
table.raw
end
end
end
RSpec.configure do |config|
config.include TableHelpers
end
view raw table_helpers.rb hosted with ❤ by GitHub

Bạn nào có cải tiến hoặc code hay hơn thì góp ý nhé :)

hoasung01 29-03-2017

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

hoasung01

5 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
3 2
Giới thiệu Machenize là một thư viện viết bằng ruby giúp tương tác với web tự động Nếu bạn dùng Nokogiri để scrape data thì Machenize là một de...
hoasung01 viết gần 2 năm trước
3 2
White
3 5
Hoàn cảnh sáng tác :) TIL này mình viết tiếp từ cảm hứng bài (Link) Mình cũng thường rất hay xem phim ở lotte và cũng phải công nhận đây là một t...
hoasung01 viết gần 2 năm trước
3 5
White
2 0
Hướng dẫn deloy lên specific heroku app từ specific branch Mình viết bài này dựa vào một use case thực tế khi làm việc như thế này: Anh A đang ...
hoasung01 viết hơn 1 năm trước
2 0
Bài viết liên quan
White
1 0
Rspec Kiểm tra JSON schema dùng rspec matcher Nay mình có viết TDD để check Repsonse Body của API (ở JSON format) có khớp với mẫu định sẵn hay khô...
Dang Tung Lam viết 2 năm trước
1 0
White
1 5
Chào mọi người, với những bạn sử dụng Vagrant (hoặc các Linux Server) để làm môi trường phát triển thì khi run rspec request test (option :js = tru...
Dinh Hoang Hiep viết hơn 3 năm trước
1 5
White
0 1
TL;DR Cần thu thập thông tin của các đối tượng search theo keyword trên google = Viết script trên frameword (Link) để làm tự động, thay vì làm bằn...
ManhDV viết gần 2 năm trước
0 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
5 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!