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));
}