2015-03-16 16 views
15

Sto testando un'interfaccia utente in cui l'utente fa clic su un pulsante di eliminazione e una voce di tabella scompare. In quanto tale, voglio essere in grado di verificare che la voce della tabella non esista più.Come attendere che un elemento non esista più in Selenium

Ho provato a utilizzare ExpectedConditions.not() per invertire ExpectedConditions.presenceOfElementLocated(), sperando che significherebbe "aspettarsi che non ci sia una presenza dell'elemento specificato". Il mio codice è in questo modo:

browser.navigate().to("http://stackoverflow.com"); 
new WebDriverWait(browser, 1).until(
     ExpectedConditions.not(
       ExpectedConditions.presenceOfElementLocated(By.id("foo")))); 

Tuttavia, ho scoperto che anche facendo questo, ho un TimeoutExpcetion causato da un NoSuchElementException dicendo che l'elemento "foo" non esiste. Certo, non avere questo elemento è ciò che voglio, ma non voglio che venga lanciata un'eccezione.

Quindi, come posso aspettare che un elemento non esista più? Preferirei un esempio che non faccia affidamento su un'eccezione se possibile (a quanto ho capito, le eccezioni dovrebbero essere lanciate per un comportamento eccezionale).

risposta

26

È inoltre possibile utilizzare -

new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator)); 

Se si passa attraverso la fonte di esso si può vedere che sia NoSuchElementException e staleElementReferenceException vengono gestiti.

/** 
    * 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; 
     } 
     } 
+0

errore di sintassi dispari nel codice precedente: Errore di sintassi, inserire"; " per completare BlockStatements –

4

La soluzione si baserebbe ancora sulla gestione delle eccezioni. E questo va bene, anche standard Expected Conditions si basa su eccezioni generate da findElement().

L'idea è quella di creare una condizione Previsto personalizzato:

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; 
     } 
    }; 
    } 
+0

tua risposta grandi opere, ma ho deciso di accettare un'altra risposta dal sembra esserci una versione integrata che fa esattamente quello che voglio. Tuttavia, la tua risposta è un'ottima guida! – Thunderforge

+1

@Thunderforge grazie, ero consapevole del metodo. Anche se stavo dando per scontato che devi aspettare che un elemento non sia presente in DOM anziché essere invisibile. Ad ogni modo, felice che sia risolto! – alecxe

+0

Ho scoperto che il metodo gestisce anche l'assenza dal DOM, non solo se è invisibile. Dal momento che il primo è il mio caso d'uso e non mi interessa quest'ultimo, funziona per me e salva lo sforzo di far girare il mio. – Thunderforge

1

Perché non è sufficiente trovare la dimensione di elements. Sappiamo che la collezione di elementi 'dimensioni sarebbe se elemento non esiste.

if(driver.findElements(By.id("foo").size() > 0){ 
    //It should fail 
}else{ 
    //pass 
} 
+1

Sfortunatamente, questa soluzione non attende che l'elemento non esista più; lo controlla solo una volta. – Thunderforge

+0

La soluzione di @VivekSingh è la soluzione migliore per non reinventare la ruota, ma questa soluzione sarebbe ottima se combinata con una condizione prevista se la situazione fosse leggermente diversa. Assomiglierebbe a questo: '(nuovo WebDriverWait (driver, 30)). WithMessage (" l'elemento era ancora visualizzato dopo il timeout "). Until ((ExpectedCondition ) d -> d.findElements (By.id (" foo ") .size()> 0)); ' – mrfreester

0
// 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) 
    { 
    } 
} 

Come findelement genera un'eccezione in elemento unaviability.so ho implementato utilizzando findelements. non esitate a correggerlo e usarlo secondo le vostre necessità.

0

ho trovato una soluzione per risolvere questo problema per me in modo efficiente, utilizzare secondo C# codice per gestire questo, è possibile convertirlo in 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; 
     } 
    } 
Problemi correlati