WebDriver:检查一个元素是否存在?
如何检查Web驱动程序是否存在元素?
是真的使用try catch唯一可能的方法吗?
boolean present; try { driver.findElement(By.id("logoutLink")); present = true; } catch (NoSuchElementException e) { present = false; }
你也可以做:
driver.findElements( By.id("...") ).size() != 0
这节省了讨厌的try / catch
我同意迈克的回答,但是如果没有find可以打开/closures的元素,则隐含3秒的等待,如果您执行此操作很有用,
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS); boolean exists = driver.findElements( By.id("...") ).size() != 0 driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
如果你正在进行大量的testing,把它变成实用的方法应该会提高性能
正如评论所说,这是在C#不是Java,但这个想法是一样的。 我已经广泛研究了这个问题,最终问题是,当元素不存在时,FindElement总是返回一个exception。 没有一个重载的选项,允许你得到空或其他任何东西。 这就是为什么我比别人更喜欢这个解决scheme。
- 返回一个元素列表,然后检查列表大小是否有效,但是这样就失去了function。 即使集合大小为1,也不能对链接集合执行.click()。
- 你可以断言该元素存在,但往往会停止你的testing。 在某些情况下,我有一个额外的链接点击,取决于我如何到达该页面,我想点击它,如果存在或移动,否则。
- 如果你没有设置超时驱动程序,则速度很慢。pipe理()。Timeouts()。ImplicitlyWait(TimeSpan.FromSeconds(0));
-
一旦创build方法,它实际上是非常简单和优雅的。 通过使用FindElementSafe而不是FindElement ,我不“看到”丑陋的try / catch块,我可以使用简单的Exists方法。 这看起来像这样:
IWebElement myLink = driver.FindElementSafe(By.Id("myId")); if (myLink.Exists) { myLink.Click(); }
这里是你如何扩展IWebElement和IWebDriver
IWebDriver.FindElementSafe
/// <summary> /// Same as FindElement only returns null when not found instead of an exception. /// </summary> /// <param name="driver">current browser instance</param> /// <param name="by">The search string for finding element</param> /// <returns>Returns element or null if not found</returns> public static IWebElement FindElementSafe(this IWebDriver driver, By by) { try { return driver.FindElement(by); } catch (NoSuchElementException) { return null; } }
IWebElement.Exists
/// <summary> /// Requires finding element by FindElementSafe(By). /// Returns T/F depending on if element is defined or null. /// </summary> /// <param name="element">Current element</param> /// <returns>Returns T/F depending on if element is defined or null.</returns> public static bool Exists(this IWebElement element) { if (element == null) { return false; } return true; }
您可以使用多态性来修改FindElement的IWebDriver类实例,但从维护angular度来看这是一个坏主意。
你可以做一个断言。
看到这个例子
driver.asserts().assertElementFound("Page was not loaded", By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);
你可以使用这个是原生的:
public static void waitForElementToAppear(Driver driver, By selector, long timeOutInSeconds, String timeOutMessage) { try { WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); wait.until(ExpectedConditions.visibilityOfElementLocated(selector)); } catch (TimeoutException e) { throw new IllegalStateException(timeOutMessage); } }
这每次都适用于我:
if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){ //THEN CLICK ON THE SUBMIT BUTTON }else{ //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE }
我扩展了Selenium WebDriver实现,在我的情况下HtmlUnitDriver公开一个方法
public boolean isElementPresent(By by){}
喜欢这个:
- 检查页面是否在超时时间内加载。
- 一旦加载页面,我将WebDriver的隐含等待时间降低到几毫秒,在我的情况下为100个磨机,可能也应该与0个磨机一起工作。
- 调用findElements(By),WebDriver即使不会查找元素也只会等待上面的时间量。
- 回升未来页面加载的隐含等待时间
这是我的代码:
import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; public class CustomHtmlUnitDriver extends HtmlUnitDriver { public static final long DEFAULT_TIMEOUT_SECONDS = 30; private long timeout = DEFAULT_TIMEOUT_SECONDS; public long getTimeout() { return timeout; } public void setTimeout(long timeout) { this.timeout = timeout; } public boolean isElementPresent(By by) { boolean isPresent = true; waitForLoad(); //search for elements and check if list is empty if (this.findElements(by).isEmpty()) { isPresent = false; } //rise back implicitly wait time this.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS); return isPresent; } public void waitForLoad() { ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver wd) { //this will tel if page is loaded return "complete".equals(((JavascriptExecutor) wd).executeScript("return document.readyState")); } }; WebDriverWait wait = new WebDriverWait(this, timeout); //wait for page complete wait.until(pageLoadCondition); //lower implicitly wait time this.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS); } }
用法:
CustomHtmlUnitDriver wd = new CustomHtmlUnitDriver(); wd.get("http://example.org"); if (wd.isElementPresent(By.id("Accept"))) { wd.findElement(By.id("Accept")).click(); } else { System.out.println("Accept button not found on page"); }
使用Java编写以下方法:
protected boolean isElementPresent(By by){ try{ driver.findElement(by); return true; } catch(NoSuchElementException e){ return false; } }
断言期间调用上述方法。
String link = driver.findElement(By.linkText(linkText)).getAttribute("href")
这会给你链接元素指向。
使用selenium-2.jar,你可以这样做;
driver.findElement(By.id("...")).isDisplayed()
据我所知,这是使用networking驱动程序的默认方式。