我是Selenium webdriver的新手,也许这个问题很明显。我是这样的情况:
如果元素存在,请单击它并返回索引页面:
driver.findElement(By.id("...."])).click();
如果不退出,请跳过它并返回索引页面。测试仍在继续,没有任何异常抛出。
我知道一个解决方案:
driver.findElements( By.id("...") ).size() != 0
所以我试过了:
if(driver.findElements(By.id("....")).size() > 0)
{
driver.findElement(By.id("....")).click();
driver.findElement(By.cssSelector("...")).click();
}
else
{
driver.findElement(By.cssSelector("....")).click();
}
但事实证明这很难看,因为如果我有10个要验证的元素,这个IF条件需要写10次。
任何变通方法都可以使它变得干净吗?
答案 0 :(得分:1)
解决方案可能很多,但这可能会妨碍您的架构。
最简单的解决方案如下:
只需在某个实用程序类或某个地方创建一个类似optionalClick()
的方法,其参数为:
locator_keyword
:{values:id或cssSelector或xpath etc} locator
:{values:“q”} 方法步骤:
locator_keyword
和locator
此方法可用作任何类型对象的通用类型。
答案 1 :(得分:1)
通过在循环内使用try-catch条件,有一些方法可以在不抛出异常的情况下查找元素。例如,我编写的这个方法(可以根据你使用的内容进行简化)将返回一个WebElement,它确保在返回给你之前它是可点击的:
public static WebElement getElementByLocator( By locator ) {
driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
WebElement we = null;
boolean unfound = true;
int tries = 0;
while ( unfound && tries < 10 ) {
tries += 1;
try {
we = driver.findElement( locator );
unfound = false; // FOUND IT
} catch ( StaleElementReferenceException ser ) {
unfound = true;
} catch ( NoSuchElementException nse ) {
unfound = true;
} catch ( Exception e ) {
staticlogger.info( e.getMessage() );
}
}
driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT,
TimeUnit.SECONDS );
return we;
}
答案 2 :(得分:0)
感谢使用findelements的指针。如果您不希望它过早返回,我认为您还需要等待逻辑。
这是我在c#中的解决方案。
它基本上重新实现了selenium库中的等待逻辑 - 不幸的是,等待的方法没有暴露(令人烦恼的是它也rethrows exceptions the wrong way并且丢失了堆栈跟踪!)。
你可能不得不为java修改一下 - 当你不能传递函数时,不确定selenium API是什么。
等待重新实现:
private IWebElement WaitAndSeeIf(Func<IWebElement> canGet)
{
var end = DateTime.Now.AddSeconds(1);
IWebElement element;
while (true)
{
element = canGet();
if (element != null)
break;
var time = DateTime.Now;
if (time > end)
break;
Thread.Sleep(200);
}
return element;
}
调用代码:
var dashboardButton = WaitAndSeeIf(() =>
{
var elements = Driver.FindElements(By.XPath("//button[contains(.//*,'Dashboard')]"));
return elements.Any() ? elements.Single() : null;
});
到目前为止,我发现这在几个地方都很有用(检查extjs中是否存在对话框等),但是还是需要捣乱并使其可配置。我认为最好的办法是让它采取其他答案中提到的隐含等待时间。