Comment vérifier si un élément existe avec le pilote Web?
Est-ce que l'utilisation d'une prise d'essai est vraiment le seul moyen possible?
boolean present;
try {
driver.findElement(By.id("logoutLink"));
present = true;
} catch (NoSuchElementException e) {
present = false;
}
Vous pouvez aussi faire:
driver.findElements( By.id("...") ).size() != 0
Qui sauve le méchant essayer/attraper
Je suis d'accord avec la réponse de Mike mais il y a une attente implicite de 3 secondes si aucun élément ne peut être activé, ce qui est utile si vous effectuez beaucoup cette action:
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
boolean exists = driver.findElements( By.id("...") ).size() != 0
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Le fait de le mettre dans une méthode utilitaire devrait améliorer les performances si vous exécutez de nombreux tests.
Comme le commentaire l'a indiqué, ceci est en C # pas Java mais l'idée est la même. J'ai effectué des recherches approfondies sur ce problème et, finalement, le problème est que FindElement renvoie toujours une exception lorsque l'élément n'existe pas. Il n’existe pas d’option surchargée permettant d’obtenir null ou quoi que ce soit d’autre. Voici pourquoi je préfère cette solution aux autres.
C'est en fait très simple et élégant une fois la méthode créée. En utilisant FindElementSafe au lieu de FindElement, je ne "vois" pas le bloc try/catch et je peux utiliser une méthode simple Exists. Cela ressemblerait à ceci:
IWebElement myLink = driver.FindElementSafe(By.Id("myId"));
if (myLink.Exists)
{
myLink.Click();
}
Voici comment étendre 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;
}
Vous pouvez utiliser le polymorphisme pour modifier l'instance de la classe IWebDriver de FindElement, mais c'est une mauvaise idée du point de vue de la maintenance.
Cela fonctionne pour moi à chaque fois:
if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
//THEN CLICK ON THE SUBMIT BUTTON
}else{
//DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}
vous pouvez faire une affirmation.
voir l'exemple
driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);
vous pouvez utiliser ceci c'est natif:
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);
}
}
Ecrivez la méthode suivante en utilisant Java:
protected boolean isElementPresent(By by){
try{
driver.findElement(by);
return true;
}
catch(NoSuchElementException e){
return false;
}
}
Appelez la méthode ci-dessus lors de l'assertion.
J'ai étendu l'implémentation de Selenium WebDriver, dans mon cas, HtmlUnitDriver pour exposer une méthode
public boolean isElementPresent(By by){}
comme ça:
Voici mon code:
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);
}
}
Usage:
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");
}
String link = driver.findElement(By.linkText(linkText)).getAttribute("href")
Cela vous donnera le lien vers lequel l'élément pointe.