4

I am trying to access some text that is located in a DIV.
I need to check to see if the page holds the text so I can return a true or false.
The code I am using is below:

cancel = browser.text.include?("Current Cancelled")
if cancel == true
puts "Line item cancelled"
else
puts "****Line item not cancelled****"
end

But it returns false every time.
Here is a code snippet of what I am looking into:

enter image description here

Curtis Miller
  • 580
  • 1
  • 9
  • 31
  • 1
    I don't know ruby but my first (and only) guess is that it's not recognized because it has different styles ("current" is in a span while "cancelled" isn't) – BlackBear Mar 12 '11 at 22:01
  • Wow. That makes sense. I wonder how I could split these up and get them to combine for my check. – Curtis Miller Mar 12 '11 at 22:38
  • 3
    In the future, it'd help get answers if you'd use the actual source, rather than a screen capture. There's no way I'd bother typing in a full XML sample, while having it available to copy and paste when working on a solution makes it easy. – the Tin Man Mar 13 '11 at 07:23

6 Answers6

5

I'd really recommend using Nokogiri to parse the content.

require 'nokogiri'

doc = Nokogiri::HTML('<div><span class="label">Current</span>Cancelled</div>')
doc.at('//div/span[@class="label"]/../text()').text # => "Cancelled"

(doc.at('//div/span[@class="label"]/../text()').text.downcase == 'cancelled') # => true
!!(doc.at('//div/span[@class="label"]/../text()').text.downcase['cancelled']) # => true

Something like one of the two bottom statements will get you a usable true/false.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • I attempted at this 'Nokogiri' stuff but it isn't really giving me what I wanted. Thanks for showing me what Nokogiri is, I might be able to use it for something in the future. – Curtis Miller Mar 15 '11 at 22:38
4

The probable reason this isn't working is because the string you're testing for contains a newline character and a non breaking space.

This could work...

if browser.div(:text, /Current.*Cancelled/).exists?
  puts "Line item cancelled"
else
  puts "****Line item not cancelled****"
end

or

if browser.text =~ /Current.*Cancelled/
  puts "Line item cancelled"
else
  puts "****Line item not cancelled****"
end

etc.

kinofrost
  • 768
  • 6
  • 16
1

Watir's Browser object has now the #elements_by_xpath method... See Watir's API

Just pin-point your DIV and ask for its #text method. Pretty much like what the Tin Man suggests but without requiring nokogiri.

AFIK Watir uses internally exactly for the purpose of locating elements (it's a dependency gem that Watir installs) anyway.

Community
  • 1
  • 1
Georgi
  • 11
  • 1
1

I believe the fact that the text is inside a table is causing this problem.

You might consider drilling into the table doing:

cancel = browser.table(:class, 'basic-table').each { |row|
  test = row.text.include?("Current Cancelled")
  return test if test == true
}
Mike Cornell
  • 5,909
  • 4
  • 29
  • 38
  • 1
    Is there anything stopping one from using browser.table(:class, 'basic-table').text.include?("Current Cancelled") instead? Would be quicker. Also, to check this, one could try accessing the DIV from irb. – kinofrost Mar 15 '11 at 13:04
  • @kinofrost Probably not, I just wanted to have something I thought would work for sure. Your suggestion is cleaner. – Mike Cornell Mar 15 '11 at 13:30
1

Wow. That makes sense. I wonder how I could split these up and get them to combine for my check.

Okay, here's a really quick draft:

div = browser.table(:class, 'basic-table').div(:text, /Cancelled/)

cancel = div.exist? and div.span(:index, 1).text == 'Current'
if cancel
   puts "Line item cancelled"
else
   puts "****Line item not cancelled****"
end
kinofrost
  • 768
  • 6
  • 16
  • 1
    This ought to work also, but frankly I think the use of the regular expression to look for a single match (the other post you made at about the same time) reads a lot cleaner and is easier to understand. – Chuck van der Linden Mar 15 '11 at 16:17
1

You could also combine a few of the regular expression approaches below (mostly those from Kinofrost), with the idea of narrowing it down to looking just inside a single cell within the table. That should be faster, and less prone to a false alert should the words 'Current' and 'Cancelled' occur in that order with anything between them, elsewhere on the page.

if browser.table(:class, 'basic-table').cell(:text, /Current.*Cancelled/).exists?
   puts "Line item cancelled"
else
   puts "****Line item not cancelled****"
end
Chuck van der Linden
  • 6,660
  • 2
  • 28
  • 43