Search code examples
rubywatirpage-object-gem

how to combine a table headers and rows in to a map using ruby?


While using the pageobject gem am able to get the a headers and rows of a table but am unable to convert it into a hash using the below code am able to get only first row mapped to headers but I need complete table rows mapped to the header.

How to do this using nokogiri as table is huge and taking long time to load

Here is the link for the table data: https://www.w3schools.com/html/html_tables.asp

I have tried the below code:

class WbPage
  include PageObject

  page_url 'https://www.w3schools.com/html/html_tables.asp'

  table(:customers, id: 'customers')

  def get_table_data
    headers = customers_element.ths.collect { |th| th.inner_html }
    rows = customers_element.tds.collect { |td| td.inner_html }
    data = {}
    headers.zip(rows) { |header,row| data[header.to_sym] = row }
    puts data
  end

end

am getting the below output for the above code:

{:Company=>"Alfreds Futterkiste", :Contact=>"Maria Anders", :Country=>"Germany"}

But I need to get like this:

{:Company => "Alfreds Futterkiste", "Centro comercial Moctezuma", "Ernst Handel", "Island Trading", "Laughing Bacchus Winecellars", "Giovanni Rovelli"
:Contact => "Maria Anders", "Francisco Chang", "Roland Mendel", "Helen Bennett", "Yoshi Tannamuri", "Magazzini Alimentari Riuniti"
:Contry => "Germany", "Mexico", "Austria", "UK", "Canada", "Italy"}

What if I have the table like this

--------------------------------------------------
 Location     |       Time     |           Miles   <-- First tr with headers (I need to ignore it)
--------------------------------------------------
Fuel | Inspection | State | Zone | ETA | ETD |     <-- Second tr with headers (from here i need the data)
--------------------------------------------------
F | I | Omaha | Nebraska | 27 08:00 | 27 08:30 | 
F | I | Omaha | Nebraska | 27 08:00 | 27 08:30 |
F | I | Omaha | Nebraska | 27 08:00 | 27 08:30 |
F | I | Omaha | Nebraska | 27 08:00 | 27 08:30 |
F | I | Omaha | Nebraska | 27 08:00 | 27 08:30 |

Solution

  • The problem is that rows is actually the individual data cells rather than the column of data. When you zip it with the headers, you have a mismatch on the size/data.

    I think the simplist solution is to use Watir's Table#strings method to convert the table data to an Array of row data, which can be transposed to get the column data:

    def get_table_data
      data = {}
      customers_element.strings.transpose.each { |col| data[col.shift.to_sym] = col }
      data
    end