6

Using selenium 2, is there a way to test if an element is stale?

Suppose I initiate a transition from one page to another (A -> B). I then select element X and test it. Suppose element X exists on both A and B.

Intermittently, X is selected from A before the page transition happens and not tested until after going to B, raising a StaleElementReferenceException. It's easy to check for this condition:

try:
  visit_B()
  element = driver.find_element_by_id('X')  # Whoops, we're still on A
  element.click() 
except StaleElementReferenceException:
  element = driver.find_element_by_id('X')  # Now we're on B
  element.click()

But I'd rather do:

element = driver.find_element_by_id('X') # Get the elment on A
visit_B()
WebDriverWait(element, 2).until(lambda element: is_stale(element))
element = driver.find_element_by_id('X') # Get element on B
Claire Nielsen
  • 1,881
  • 1
  • 14
  • 31
Michael Mata
  • 126
  • 1
  • 8

2 Answers2

1

I don't know what language you are using there but the basic idea you need in order to solve this is:

boolean found = false
set implicit wait to 5 seconds
loop while not found 
try
  element.click()
  found = true
catch StaleElementReferenceException
  print message
  found = false
  wait a few seconds
end loop
set implicit wait back to default

NOTE: Of course, most people don't do it this way. Most of the time people use the ExpectedConditions class but, in cases where the exceptions need to be handled better this method ( I state above) might work better.

djangofan
  • 28,471
  • 61
  • 196
  • 289
0

In Ruby,

$default_implicit_wait_timeout = 10 #seconds

def element_stale?(element)
  stale = nil  # scope a boolean to return the staleness

  # set implicit wait to zero so the method does not slow your script
  $driver.manage.timeouts.implicit_wait = 0

  begin ## 'begin' is Ruby's try
    element.click
    stale = false
  rescue Selenium::WebDriver::Error::StaleElementReferenceError
    stale = true
  end

  # reset the implicit wait timeout to its previous value
  $driver.manage.timeouts.implicit_wait = $default_implicit_wait_timeout

  return stale
end

The code above is a Ruby translation of the stalenessOf method provided by ExpectedConditions. Similar code could be written in Python or any other language Selenium supports, and then called from a WebDriverWait block to wait until the element becomes stale.

emery
  • 8,603
  • 10
  • 44
  • 51