Je teste une interface utilisateur dans laquelle l'utilisateur clique sur un bouton Supprimer et une entrée de tableau disparaît. En tant que tel, je veux pouvoir vérifier que l'entrée de table n'existe plus.
J'ai essayé d'utiliser ExpectedConditions.not()
pour inverser ExpectedConditions.presenceOfElementLocated()
, en espérant que cela signifierait "s'attendre à ce qu'il n'y ait pas de présence de l'élément spécifié". Mon code est comme ça:
browser.navigate().to("http://stackoverflow.com");
new WebDriverWait(browser, 1).until(
ExpectedConditions.not(
ExpectedConditions.presenceOfElementLocated(By.id("foo"))));
Cependant, j'ai trouvé que même en faisant cela, j'obtiens un TimeoutExpcetion
provoqué par un NoSuchElementException
disant que l'élément "foo" n'existe pas. Bien sûr, ne pas avoir un tel élément est ce que je veux, mais je ne veux pas qu'une exception soit levée.
Alors, comment puis-je attendre qu'un élément n'existe plus? Je préférerais un exemple qui ne repose pas sur la capture d'une exception si possible (si je comprends bien, des exceptions doivent être levées pour un comportement exceptionnel).
Vous pouvez aussi utiliser -
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator));
Si vous en parcourez la source, vous pouvez voir que NoSuchElementException
et staleElementReferenceException
sont traités.
/**
* An expectation for checking that an element is either invisible or not
* present on the DOM.
*
* @param locator used to find the element
*/
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return !(findElement(locator, driver).isDisplayed());
} catch (NoSuchElementException e) {
// Returns true because the element is not present in DOM. The
// try block checks if the element is present but is invisible.
return true;
} catch (StaleElementReferenceException e) {
// Returns true because stale element reference implies that element
// is no longer visible.
return true;
}
}
La solution reposerait toujours sur la gestion des exceptions. Et c'est à peu près correct, même Conditions attendues standard reposent sur des exceptions levées par findElement()
.
L'idée est de créer une condition attendue personnalisée :
public static ExpectedCondition<Boolean> absenceOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
driver.findElement(locator);
return false;
} catch (NoSuchElementException e) {
return true;
} catch (StaleElementReferenceException e) {
return true;
}
}
@Override
public String toString() {
return "element to not being present: " + locator;
}
};
}
Pourquoi ne trouvez-vous pas simplement la taille de elements
. Nous savons que la taille de la collection d'éléments serait si l'élément n'existe pas.
if(driver.findElements(By.id("foo").size() > 0 ){
//It should fail
}else{
//pass
}
J'ai trouvé une solution de contournement pour résoudre ce problème pour moi de manière efficace, utilisé en suivant le code C # pour gérer cela, vous pouvez le convertir en Java
public bool WaitForElementDisapper(By element)
{
try
{
while (true)
{
try
{
if (driver.FindElement(element).Displayed)
Thread.Sleep(2000);
}
catch (NoSuchElementException)
{
break;
}
}
return true;
}
catch (Exception e)
{
logger.Error(e.Message);
return false;
}
}
// pseudo code
public Fun<driver,webelement> ElemtDisappear(locator)
{
webelement element=null;
iList<webelement> elemt =null;
return driver=>
{
try
{
elemt = driver.findelements(By.locator);
if(elemt.count!=0)
{
element=driver.findelement(By.locator);
}
}
catch(Exception e)
{
}
return(elemnt==0)?element:null;
};
// call function
public void waitforelemDiappear(driver,locator)
{
webdriverwaiter wait = new webdriverwaiter(driver,time);
try
{
wait.until(ElemtDisappear(locator));
}
catch(Exception e)
{
}
}
Comme findelement lève une exception sur l'élément non-fiabilité, j'ai donc implémenté l'aide de findelements. n'hésitez pas à le corriger et à l'utiliser selon vos besoins.