Wednesday, February 07, 2007

Viewing data in a Table

I have been meaning to post this code for awhile. There have been some recent posts on the WATIR forum about looking data in a table cell, so I thought I would share this code. I can not promise it meets all table needs, but it has worked well for us.

I typically evaluate are tables in this manner.

@ie.show_tables

The I pick the table I believe contains the data I am attempting to access and call this method:

@Table.new(@ie.table(:index, 40)).printPretty

Print Pretty code is placed in a library file and I require it for the scripts that need to evaluate tables.

Here is an example as to how you could use this.

Create a file called MSNTest.rb with this code:

# CLS February 7,2007 Example for finding table data
#includes:
require 'watir' # the watir controller
require "rexml/document"
require "date"
require '/apps/ruby/lib/ruby/1.8/test/unit'
require '/apps/ruby/lib/ruby/1.8/test/unit/ui/console/testrunner'
require 'watir/testUnitAddons'
require 'watir/WindowHelper'
require '/Apps/watir_bonus/examples/Stuff.rb'
include REXML
include Watir
include Stuff

puts "## Begin Test - MSN Table Test"



class MSN_Test < Test::Unit::TestCase
include Watir


def setup
@ie = IE.new
@ie.goto("http://www.msn.com")

end

def test1

assert(@ie.link(:text, "Sports").exists?)

# @ie.show_all_objects

@ie.show_tables

Table.new(@ie.table(:index, 1)).printPretty
end
end

#

#
# END - MSN test

In the same directory create a file called Stuff.rb with this code:


# This module uses REXML to parse the XML.
# REXML is available at http://www.germane-software.com/software/rexml/
require "rexml/document"
require "date"
include REXML

# There is no need for the test to require or include REXML.
module Stuff

# The Table class provides convenience methods for accessing data in
# WATIR tables
class Table
#The constructor for Table takes a WATIR table and
# assigns it to the instance variable @table
def initialize(table)
@table = table
end

#Takes a string and two integers. Returns the contents of
# the table cell at the index of the second integer for the
# row where the string is in the cell at the index of the
# first integer.
# Example: myTable.assoc("findMe",2,4) finds the row of
# the table where the text "findMe" is in the second column,
# and returns the contents of the 4th column
def assoc(text,rowFinder,targetCell)
@table.each { |row|
if row[rowFinder].to_s.include? text
return row[targetCell].to_s
end
}
return nil
end

def printPretty()
rows = 0
@table.each { |row|
rows += 1
puts "row " + rows.to_s + ":"
print "\t"
cells = 0
row.each { |cell|
cells += 1
print "cell " + cells.to_s + ": [" + cell.to_s + "]\t"
}
print "\n"
}
puts "-----------------------------------------------------------------------------------------"
end

end
end

Execute the MSNTest..rb script to see the results of the content of the table on the MSN home page. This site happens to only have one table, but if there were multiple tables just use the index value of the table your target data resides (Table.new(@ie.table(:index, ??)).printPretty).

Enjoy!