硒 - 第二次无法找到元素

时间:2015-04-29 02:32:41

标签: selenium xpath selenium-webdriver nosuchelementexception

我正在尝试找到这样的元素 -

Select servTypeDA = new Select (driver.findElement(By.xpath("//select[@id='ServicesType']")));
servTypeDA.selectByVisibleText(servTypeData);

当我加载此页面时,这首次完美无缺。 我正在尝试做一个工作流程,所以当这个页面加载几个步骤后,对于同一行它会抛出错误 -

  

org.openqa.selenium.NoSuchElementException:无法找到元素

但我能够看到屏幕中的元素及其可见但仍无法通过代码访问。 我试图添加等待时间,仍然会抛出错误。 为什么第二次无法访问相同的元素?

3 个答案:

答案 0 :(得分:0)

dir()无法在DOM中找到元素时,会抛出

NoSuchElement。造成这种情况的主要原因可能是您过早地搜索元素。我建议使用一些明确的等待,并定期检查元素。

webdriver

答案 1 :(得分:0)

或者您可以隐式设置等于默认值0。 通过设置它,Webdriver将在抛出NoSuchElementException

之前等待给定的时间
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

它将节省您在每个元素之前添加webdriverWait的工作量。

答案 2 :(得分:0)

webdriver的工作方式是每个页面加载它复制页面。所以显示的内容不一定是webdriver实例中加载的内容。例如,如果您通过JavaScript更改网页,则webdriver不会意识到它。

这些往往是

的理所
  

NoSuchElementException异常

  

StaleElementReferenceException

我发现解决这个问题的唯一方法就是抓住异常并再试一次。我必须为每种类型的动作创建一个新函数。我将向您展示我的例子" selectByVisibleText"

public void selectByLabel(final By by, final String label){
act(by, 3, new Callable<Boolean>() {
  public Boolean call() {
    logger.trace("Trying to select label: "+label+" in select box "+stripBy(by) );

    Boolean found = Boolean.FALSE;
    int attempts = 0;

    wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(by)));

    Select select = new Select(driver.findElement(by));
    select.selectByVisibleText(label);   

    if(isLabelSelected(by,label)){
      found = Boolean.TRUE; // FOUND IT
      logger.info("Selected value "+label+" in select box "+stripBy(by));
    }

    return found;
  }
});

}

它会重试几次。

我所有特殊的行动实施都使用一种捕捉异常的功能

private void act(By by, int tryLimit, boolean mode, Callable<Boolean> method){
logger.trace( "Looking for element: " + stripBy(by) );
driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
boolean unfound = true;
int tries = 0;
while ( unfound && tries < tryLimit ) {
  tries += 1;
  try {

    WebDriverWait wait = new WebDriverWait(driver, 500);
    unfound = !method.call(); // FOUND IT, this is negated since it feel more intuitive if the call method returns true for success
  } catch ( StaleElementReferenceException ser ) {
    logger.error( "ERROR: Stale element exception. " + stripBy(by) );
    unfound = true;
  } catch ( NoSuchElementException nse ) {
    logger.error( "ERROR: No such element exception. " + stripBy(by)+"\nError: "+nse );
    unfound = true;
  } catch ( Exception e ) {
    logger.error( e.getMessage() );
  }
}

driver.manage().timeouts().implicitlyWait( Constants.DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );

if(unfound)
  Assert.assertTrue(false,"Failed to locate element by locator " + stripBy(by));

}