WebDriver Selenium API:Element明显存在时出现ElementNotFoundErrorException!
Posted
技术标签:
【中文标题】WebDriver Selenium API:Element明显存在时出现ElementNotFoundErrorException!【英文标题】:WebDriver Selenium API: ElementNotFoundErrorException when Element is clearly there ! 【发布时间】:2011-05-05 23:02:06 【问题描述】:有时在关闭 javascript 的情况下在 WebDriver 上运行测试时,WebDriver 在找到元素并尝试单击它时会由于 ElementNotFound 错误而崩溃。
但是,元素显然存在!
阅读后:http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_My_XPath_finds_elements_in_one_browser,_but_not_in_others._Wh
我得出的结论是 webdriver 一定不能等到网页完成加载。如何使用 Webdriver 等待类?有人可以举个例子吗?
【问题讨论】:
【参考方案1】:这个例子was posted on Google Groups。根据 Google 开发人员的说法:
1 使用隐式等待。司机会在这里等到指定时间 超时直到找到元素。请务必阅读 javadoc 警告。用法:
driver.get("http://www.google.com");
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
WebElement element = driver.findElement(By.name("q"));
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
// continue with test...
2 使用org.openqa.selenium.support.ui.WebDriverWait
类。这会
轮询直到预期的条件为真,返回该条件的结果
(如果它正在寻找一个元素)。这比隐式灵活得多
等待,因为您可以定义任何自定义行为。用法:
Function<WebDriver, WebElement> presenceOfElementLocated(final By locator)
return new Function<WebDriver, WebElement>()
public WebElement apply(WebDriver driver)
return driver.findElement(locator);
;
// ...
driver.get("http://www.google.com");
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3);
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));
【讨论】:
你能解释一下“功能”吗?没有这样的对象称为“函数”,想知道是否可以更好地把它放在上下文中?【参考方案2】:进一步了解 nilesh 的回答,您还可以通过使用 SearchContext 接口进行更精细的搜索(例如,在 WebElement 的上下文中):
Function<SearchContext, WebElement> elementLocated(final By by)
return new Function<SearchContext, WebElement>()
public WebElement apply(SearchContext context)
return context.findElement(by);
;
执行由 FluentWait
/**
* @return The element if found before timeout, otherwise null
*/
protected WebElement findElement(SearchContext context, By by,
long timeoutSeconds, long sleepMilliseconds)
@SuppressWarnings("unchecked")
FluentWait<SearchContext> wait = new FluentWait<SearchContext>(context)
.withTimeout(timeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(sleepMilliseconds, TimeUnit.MILLISECONDS)
.ignoring(NotFoundException.class);
WebElement element = null;
try
element = wait.until(elementLocated(by));
catch (TimeoutException te)
element = null;
return element;
/**
* overloaded with defaults for convenience
*/
protected WebElement findElement(SearchContext context, By by)
return findElement(context, by, DEFAULT_TIMEOUT, DEFAULT_POLL_SLEEP);
static long DEFAULT_TIMEOUT = 3; // seconds
static long DEFAULT_POLL_SLEEP = 500; // milliseconds
示例用法:
WebElement div = this.findElement(driver, By.id("resultsContainer"));
if (div != null)
asyncSubmit.click();
WebElement results = this.findElement(div, By.id("results"), 30, 500);
if (results == null)
// handle timeout
【讨论】:
你的例子没有解释什么是“elementLocated”。 是的。它是一个方法(在我的第一个代码块中定义),它返回一个函数,而 FluentWait 又会重复调用该函数,直到返回一个对象、超时到期或抛出一个不可忽略的异常(以先到者为准)。【参考方案3】:Fluent Wait - 最佳方法,因为它是最灵活且可即时配置的(具有忽略异常选项、轮询每次、超时):
public Wait<WebDriver> getFluentWait()
return new FluentWait<>(this.driver)
.withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(500, TimeUnit.MILLISECONDS)
.ignoring(StaleElementReferenceException.class)
.ignoring(NoSuchElementException.class)
.ignoring(ElementNotVisibleException.class)
这样使用:
WebElement webElement = getFluentWait().until(x -> return driver.findElement(elementBy); );
显式等待 - 与FluentWait
相同,但预先配置了pollingEvery
和等待类型,例如FluentWait<WebDriver>
(使用更快):
WebDriverWait wait = new WebDriverWait(driver, 30000);
WebElement item = wait.until(ExpectedConditions.visibilityOfElementLocated(yourBy));
ImplicitWait - 不推荐,因为它为所有会话配置一次。这也用于每个 find 元素并仅等待存在(无 ExpectedConditions
等...):
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
【讨论】:
以上是关于WebDriver Selenium API:Element明显存在时出现ElementNotFoundErrorException!的主要内容,如果未能解决你的问题,请参考以下文章
python+selenium自动测试之WebDriver的常用API(基础篇一)
selenium webdriver API是像JAVA API一样的吗?
java+selenium3-常用的WebDriver API