柴ブログ

プログラミング奮闘記

Capybaraでテーブルの特定のセルの値をテストする

概要

例えば以下のようなテーブルがあり、指定した列、行に想定した値が表示されているかテストをしたい場合。

  • 例: user1nametanakaが表示されているかテストしたい
/ name country
user1 tanaka japan

メソッド

以下のようなヘルパーメソッドを用意した。

def table_rows(xpath: ".//table[.//tbody]")
   header_tr, *trs = find(:xpath, xpath).all("tr").to_a
   column_names = header_tr.all("th,td").map(&:text)
   trs.map do |tr|
     columns = tr.all("th,td").each_with_object({}).with_index do |(td, hash), i|
       hash[column_names[i]] = td.text
     end
     OpenStruct.new(element: tr, columns: columns)
   end
 end

find(:xpath, xpath).all("tr").to_aでtableタグのthead、tbodyそれぞれのtrタグを取得している。

header_trにはtheadのtrタグの要素、trsにはtbodyのtrタグを配列にして入れている。

さらにcolumn_namesとしてtheadタグのth,tdタグの要素を配列にしている。

p header_tr => #<Capybara::Node::Element tag="tr" path="/HTML/BODY//DIV/TABLE/THEAD/TR">

p column_names #=> "/ name country"


p trs [#<Capybara::Node::Element tag="tr" path="/HTML/BODY/DIV/TABLE/TBODY/TR">]

次に以下の部分。

  trs.map do |tr|
     columns = tr.all("th,td").each_with_object({}).with_index do |(td, hash), i|
       hash[column_names[i]] = td.text
     end
     OpenStruct.new(element: tr, columns: columns)
   end

columnsには、trsのth,tdタグの要素を取得し、先ほどのcolumn_namesの要素をキーとしたハッシュが入る。

pp columns
# =>
{"/"=>"user1",
"name"=>"tanaka",
"country"=>"japan"}

そしてOpenStruct.new(element: tr, columns: columns)でテーブルの情報を格納。

このヘルパーメソッドの最終的な返り値は下記。

配列なので呼び出す際注意。

[#<OpenStruct element=#<Capybara::Node::Element tag="tr" path="/HTML/BODY/DIV/TABLE/TBODY/TR">, columns={"/"=>"user1", "name"=>"tanaka", "country"=>"japan"}>]

テスト

テストコード側でヘルパーメソッドを呼び出して以下のように指定するとテーブルの特定のセルをテストすることができる。

rows = table_rows
expect(rows.first.columns["name"]).to eq("tanaka")

テーブルが複数あるならwithinで対象を絞ればOK。

within(".hoge") do
  rows = table_rows
  expect(rows.first.columns["name"]).to eq("tanaka")
end