Search code examples
rubywatir

Ruby - no implicit conversion of Array into String


I am getting an error when executing my test.

 Failure/Error: expect(industry_sic_code).to include page.sic_code

 TypeError:
   no implicit conversion of Array into String
 # ./spec/os/bal/company/company_filter_clean_harbors_industries_stub.rb:62:in `block (2 levels) in <top (required)>'

The Method:

def sic_code
  subtables = @b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
  subtables.each do |subtable|
    if subtable.tbody.h4.text == "US SIC 1987:"
      subtable.tr.next_siblings.each do |tr|
       codes = tr.cell
       puts codes.text.to_s
      end
    end
  end
end

The Test:

  it 'Given I search for a random Clean Harbors Industry' do

  #Pick a random clean industry from the file
    data = CSV.foreach(file_path, headers: true).map{ |row| row.to_h }
    random = data.sample

    random_industry = random["Class"]
    industry_sic_code = random["SIC Code"]
  end

  it 'Then the result has the expected SIC code' do
    page = DetailPage.new(@b)
    page.view

    expect(industry_sic_code).to include page.sic_code
  end

I have tried to implicitly change each variable to a string but it still complain about the array issue.

When I include some puts statments, I get some really wonky responses. The method itself returns the expected result.

When I used the method in the test I end up with the code gibberish below.

here are the sic codes from the method
5511

Here are the codes from the test
#<Watir::Table:0x00007fa3cb23f020>
#<Watir::Table:0x00007fa3cb23ee40>
#<Watir::Table:0x00007fa3cb23ec88>
#<Watir::Table:0x00007fa3cb23ead0>
#<Watir::Table:0x00007fa3cb23e918>
#<Watir::Table:0x00007fa3cb23e738>
#<Watir::Table:0x00007fa3cb23e580>

Solution

  • Your sic_code method returns subtables array, that's why you have this error. It doesn't matter that the method puts something, every method in ruby implicitly returns result of its last line, in your case it is subtables.each do ... end, so you have an array.

    You need to explicitly return needed value. Not sure if I correctly understood what are you doing in your code, but try something like this:

    def sic_code
      subtables = @b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
      result = [] # you need to collect result somewhere to return it later
      subtables.each do |subtable|
        if subtable.tbody.h4.text == "US SIC 1987:"
          subtable.tr.next_siblings.each do |tr|
            codes = tr.cell
            result << codes.text.to_s
          end
        end
      end
      result.join(', ') 
    end