Complex table approval in Capybara

I have a table in my application.

enter image description here

Using Capybara and Cucumber, how can I assert that the values ​​4.5 and 1.1 only occur in Mike's line?
Is such a statement possible in Capybara?

Thank!

+3


source to share


2 answers


Yes, it is possible and easy:

def td_text(n)
  find(:xpath, "./td[#{n}]").text
end

h = {2 => 4.5, 3 => 1.1}

all('table tr').each do |row|
  within row do
    if td_text(1) == 'Mike'
      h.each { |i, value| td_text(i).should == value.to_s }
    else
      h.each { |i, value| td_text(i).should_not == value.to_s }
    end
  end
end

      

Here's the complete script you can use for testing

Update: I've thought about this more. The above code will be very slow, as each call find

and text

in td_text

will make a new request in the browser.



The only way to mitigate it that I can see is using JS and Nokogiri:

source = page.evaluate_script("document.getElementsByTagName('table')[0].innerHTML")

doc = Nokogiri::HTML(source)

def td_text(row, n)
  row.xpath("./td[#{n}]").text
end

h = {2 => 4.5, 3 => 1.1}

doc.css('tr').each do |row|
  if td_text(row, 1) == 'Mike'
    h.each { |i, value| td_text(row, i).should == value.to_s }
  else
    h.each { |i, value| td_text(row, i).should_not == value.to_s }
  end
end

      

The first version of the code runs for about 200 milliseconds on my machine, while the second takes 8 milliseconds. Nice optimization!

+3


source


You can use within for the scope you are looking for a specific value:

For example, to argue that 4.5 occurs in the second column of Mike's row, try this:

within("table tr:nth-child(2)") do
  find("td:nth-child(2)").text.should == 4.5
end

      

You can wrap them with helper methods for ease of use if you like:



def within_row(num, &block)
  within("table tr:nth-child(#{num})", &block)
end

def column_text(num)
  find("td:nth-child(#{num})").text
end

      

Now you can make the same statement about Mike's string by doing the following:

within_row(2) do
  column_text(2).should == 4.1
end

      

I hope you find one of these methods helpful for what you are trying to do.

+4


source







All Articles