1
votes

I'm using Watir-5.0.0, selenium-webdriver-2.40 and testing on IE-8. When I execute the following code:

puts "@browser.tables.length=#{@browser.tables.length}"
@browser.tables.each { |t| puts t.to_s }
[email protected](:class => "jrPage")
puts "jrPage=#{t}"
t.rows.each do |row|
  # do something
end

I get the following results:

@browser.tables.length=5
#<Watir::Table:0x3921cc0>
#<Watir::Table:0x3921c48>
#<Watir::Table:0x3921c00>
#<Watir::Table:0x3921bd0>
#<Watir::Table:0x3921b88>
jrPage=#<Watir::Table:0x39219d8>

Selenium::WebDriver::Error::StaleElementReferenceError: Element is no longer valid

Any thoughts on why is table I explicitly locate, Watir::Table:0x39219d8, is not in the @browser.tables.each collection?

I can understand why I get the StaleElementReferenceError (table not found) but not why the table I explicit locate isn't in the tables list.

I can find this table in the HTML.

1
Am adding this comment under my username .. it's similar to my answer below: The real, real issue is the StaleElement exception which I figured I shouldn't get if I successfully get a specific table (jrTable) and then immediately iterate through its rows. I thought the reason I received the exception was because the specific table was not in the list of the browser's table though your reply seems to point to some other problem. Thoughts?Robert Lewkovich
Which element is giving the stale reference error - eg is it one of the tables or something else in the table? As well, it would probably help to share the code that is run against each row. I presume something in there is the cause the the exception.Justin Ko

1 Answers

1
votes

The code is calling to_s for the table object. Watir-webdriver does not specifically define this method for elements. Therefore, it calls Ruby's default Object#to_s method:

Returns a string representing obj. The default to_s prints the object’s class and an encoding of the object id. As a special case, the top-level object that is the initial execution context of Ruby programs returns “main.”

As you can see, this is what Watir is doing - Watir::Table is the object's class and 0x39219d8 is an encoding of the object id.

When iterating through the tables or getting a table, you are retrieving the table from scratch. In other words, a new table object is created for each of these commands. Even if you run the collection again, you will see that you get 4 different table object ids each time.

Note that while the table objects you are seeing are unique, the jsPage is referring to one of the elements in the collection. You can use the == method to check if two objects are referencing the same html element.

For example, you can see this with:

# Get the specific jrPage
jrPage = browser.table(:class => "jrPage")

# Check which element in the collection is the jrPage
browser.tables.each { |t| puts t == jrPage }
#=> false
#=> false
#=> true
#=> false
#=> false

The above tells you that the jrPage is the 3rd table on the page.