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;
}
});
}
它會重試幾次。
我所有的行動的特殊implementetation使用功能,捕獲異常
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));
}