Using the page-object gem and Watir webdriver, we occasionally come across a Selenium::WebDriver::Error::StaleElementReferenceError on a page that loads some basic stuff, makes an ajax request, and repopulates with more info (for the illusion of speed on the page).
This happens because there will be an HTML element there, it disappears quickly and reappears again before the user is really aware of it.
We use page-object's ".when_present" method to wait until the object's on the page the first time before accessing it. However, even after the code finds the element, usually it will get the stale element error because the original HTML element gone and the other one has reappeared by the time it tries to access it.
We found a way using just straight Watir (not page-object) around this. We basically catch the StaleElementReferenceError inside of a Watir::Wait.until block. If it gets an exception, the block returns false, and the Wait.until tries again until it either becomes true, or times out eventually. What we've found is that this usually gets the Stale Element the first time (on line 3 below), returns false from the rescue, Wait.until executes the block again, and the 2nd time it's true and the test moves on and passes.
1 Watir::Wait.until {
2 begin
3 tds = page.my_element.when_present.element.tds
4 table_data_classes = tds.map{|cell| cell.attribute_value("class") }
5
6 # Should have at least one with a class of "xyz"
7 xyz = table_data_classes.select{|data| data.include?("xyz")}
8 xyz.size > 0
9 rescue Selenium::WebDriver::Error::StaleElementReferenceError
10 false
11 end
12 }
I'm really just wondering if there's any kind of page-object wrapper for this kind of thing. I couldn't find anything. If not, that's ok because the above works. Just curious.
Thanks