如何使用Selenium 2 检查元素是否过期?

6 投票
2 回答
3396 浏览
提问于 2025-04-17 08:31

在使用selenium 2的时候,有没有办法测试一个元素是否过时了?

假设我从一个页面跳转到另一个页面(从A到B)。然后我选择了元素X并对它进行测试。假设元素X在A和B两个页面都有。

有时候,我在页面跳转之前就从A选择了X,但直到跳转到B后才进行测试,这样就会出现一个叫做StaleElementReferenceException的错误。其实检查这种情况很简单:

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()

但我更想这样做:

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

2 个回答

0

在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

上面的代码是将ExpectedConditions中提供的stalenessOf方法翻译成Ruby的版本。你也可以用Python或者其他Selenium支持的语言写类似的代码,然后在WebDriverWait的代码块中调用它,以等待某个元素变得过时。

1

我不知道你用的是什么语言,但要解决这个问题,你需要明白基本的思路是:

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

注意:当然,大多数人不会这样做。大部分情况下,人们会使用ExpectedConditions这个类。不过在需要更好处理异常的情况下,上面提到的方法可能会更有效。

撰写回答