我正在尝试检查元素是否存在,并以此为条件。
long starttime = System.currentTimeMillis();
long endtime = starttime + 60*1000; // 60 seconds * 1000 ms/sec;
while(System.currentTimeMillis() < endtime)
{
notcount = driver.findElement(By.id(AppConstants.notificationcount));
}
if(notcount.equals(null))
{
System.out.println("No Element found");
}
else
{
//SOME ANOTHER STEPS
}
这里的问题是元素不存在时,而是重定向到ELSE部分,硒停止执行并引发异常。
我不想使用List- findelements在这里,因为要花很长时间才能找到元素。
#1 楼
使用findElements
代替findElement
。如果未找到匹配的元素而不是异常,则
findElements
将返回一个空列表。要检查是否存在某个元素,可以尝试this
Boolean isPresent = driver.findElements(By.yourLocator).size() > 0
如果找到至少一个元素,则返回true;如果不存在,则返回false。
从以下位置复制文本:https ://stackoverflow.com/questions/7991522/selenium-webdriver-test-if-element-is-present
另一种可能性是使用Try / Catch构造,有关更多信息,请参见此:https ://stackoverflow.com/questions/6521270/webdriver-check-if-an-element-exists
评论
是的,我同意并且已经尝试了此解决方案,但是即使元素不存在也要花很长时间搜索,这就是为什么我提到我不想为此使用LIST或findelements的原因。
–伸出援助之手
2015年8月10日在2:59
请改用try / catch结构。但是,实际需要多长时间?除非您发现数百个元素,否则不会太多。我也想知道您是否真的想继续测试,如果找不到元素,那么为什么要寻找它呢?让测试失败。
– Niels van Reijmersdal
15年8月10日在6:40
我也很惊讶,我发现只有1个元素,并且只有webdriver需要花费很长时间。我希望测试继续进行,就像找不到元素,然后转到ELSE部分。
–伸出援助之手
15年8月10日在7:12
在测试中使用if / then / else构造对我来说是反模式。该测试应描述一个执行路径,并避免任何逻辑。如果某些东西阻塞了此执行路径,则按照建议快速失败。如果要涵盖多个执行路径,请创建多个测试,每个测试涵盖一个执行路径。
– dzieciou
15年8月19日在5:35
#2 楼
当您使用.findElement
时,您遇到的是一种快速失败的行为。您实际上并不需要使用.findElements(el)
来获得软故障行为。您可以执行以下操作:protected void checkElementPresence(final WebDriver driver,final By by,final String errorMsg){
new WebDriverWaitWithMessage(driver,10).failWith(errorMsg).until(new ExpectedCondition<Boolean>(){
@Override public Boolean apply( WebDriver webDriver){
try {
return driver.findElement(by).isDisplayed();
}
catch ( NoSuchElementException ignored) {
return false;
}
catch ( StaleElementReferenceException ignored) {
return false;
}
}
}
);
,但需要此支持类:
protected static class WebDriverWaitWithMessage extends WebDriverWait {
private String message;
public WebDriverWaitWithMessage(WebDriver driver, long timeOutInSeconds) {
super(driver, timeOutInSeconds);
}
public WebDriverWait failWith(String message) {
if (message == null || message.length() == 0) {
throw new IllegalArgumentException("Error message must not be null nor empty");
}
this.message = message;
return this;
}
@Override
public <V> V until(Function<? super WebDriver, V> isTrue) {
if (message == null) {
return super.until(isTrue);
} else {
try {
return super.until(isTrue);
} catch (TimeoutException e) {
throw new TimeoutException(message, e);
}
}
}
}
#3 楼
(请注意,我没有在Java中尝试过此操作,但这是在C#中的操作方法)。您应该将findelement放在try / catch块中,以便如果找不到该元素,可以捕获异常并执行正确的操作。
看起来像这样:
try
{
driver.FindElement(By.CssSelector("selector"));
}
catch(NoSuchElementException)
{
Console.WriteLine("Element does not exist!");
}
编辑:
我会请注意,您似乎正在尝试实现自己的webdriver等待行为,因此请在此处查看第一个答案:https://stackoverflow.com/questions/11736027/webdriver-wait-for-element,其中说明了如何等待Java中具有显式等待的元素。
#4 楼
使用该代码行的异常处理块。尝试
{
}
赶上
{
最后
{
}
如果找不到元素,然后执行finally块中的代码,并继续执行其他代码行
评论
请扩展您的答案,以说明它对现有答案(尤其是已接受的答案)的改进。
–凯特·保罗(Kate Paulk)
17年12月13日在12:18
#5 楼
public void sellProduct(){
try {
for(int i=0; i< 5 ;i++){
try {
if(!driver.findElements(By.xpath("/html/body/div[@class='container']/table[@class='table table-striped'][2]/tbody[@id='bought']/tr[@id="+i+"]/th[4]/button")).isEmpty()) {
try {
driver.findElement(By.xpath("/html/body/div[@class='container']/table[@class='table table-striped'][2]/tbody[@id='bought']/tr[@id="+i+"]/th[4]/button")).click();
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
else{
try {
System.out.println("no products to sell ");
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我编写了这段代码,但继续获取问题目标寡妇已关闭,我希望在找不到Web元素时退出循环。
评论
这个问题的公认答案对您有帮助吗?如果不是,请将此问题作为自己的问题发布,并解释为什么此处接受的答案无济于事。请不要发布“我有相同的问题”作为答案-您的帖子可能会被删除。
–凯特·保罗(Kate Paulk)
18年1月24日在16:53
#6 楼
我使用C#,但这是我使用的方法:/// <summary>
/// Looks to see if the passed in element is on the webpage or not. Returns true or false.
/// </summary>
/// <param name="by"></param>
/// <param name="element"></param>
/// <param name="driver"></param>
/// <returns></returns>
public static bool tryToFindElement(By by, out IWebElement element, IWebDriver driver)
{
try
{
element = driver.FindElement(by);
}
catch (NoSuchElementException)
{
element = null;
return false;
}
return true;
}
/// <summary>
/// Checks to see if the web element is displayed and enabled.
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public static bool isElementVisible(IWebElement element)
{
return element.Displayed && element.Enabled;
}
我这样称呼它:
if (tryToFindElement(By.CssSelector("<CSS Selector>"), out element, driver))
{
bool visible = isElementVisible(element);
if (visible == true)
{
//Do something
}
}
#7 楼
我已经尝试过获得布尔响应的答案,但是正如我所看到的,只有当我们设置了驱动程序的超时时,这才可能实现。我有20秒的超时时间,并且我遵循上述公认的答案。
因此,不仅要检查
boolean isPresesnt = driver.findElements(by).size() > 0;
,还是建议设置驱动程序的隐式超时。driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
希望有帮助!
#8 楼
只需将搜索元素的时间设置为隐式短时间,这将导致列表返回为空
androidDriver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
List<AndroidElement> yesterdaysImage = androidDriver.findElementsById("MOBILE_PACKAGE_NAME:id/goals_item_yesterday");
(我知道这是Selenium,我发布了Appium,但是Appium是源自Selenium,因此此代码仍然有效)
评论
我用谷歌搜索“硒等待,如果找不到,做点事”的头两个结果就解决了:)请参阅我的答案。