2010-07-19 12 views
34

Nei test che scrivo, se voglio affermare una WebElement è presente sulla pagina, non posso fare un semplice:affermano che un WebElement non è presente con selenio WebDriver con Java

driver.findElement(By.linkText("Test Search")); 

questo passerà se esiste e bombarderà se non esiste. Ma ora voglio affermare che esiste un collegamento non. Non sono chiaro come farlo poiché il codice sopra riportato non restituisce un valore booleano.

EDIT Questo è il modo in cui mi è venuta la mia correzione, mi chiedo se c'è ancora una soluzione migliore.

public static void assertLinkNotPresent (WebDriver driver, String text) throws Exception { 
List<WebElement> bob = driver.findElements(By.linkText(text)); 
    if (bob.isEmpty() == false) { 
    throw new Exception (text + " (Link is present)"); 
    } 
} 

risposta

8

Non saprei quale versione di selenio si fa riferimento, tuttavia alcuni comandi in selenio * può ora fare questo: http://release.seleniumhq.org/selenium-core/0.8.0/reference.html

  • assertNotSomethingSelected
  • assertTextNotPresent

Ecc ..

+0

Collegamento interrotto ora – Andrejs

+0

Il problema originale di OP sembra indicare che è stata generata un'eccezione quando l'elemento non è presente. – DMart

12

penso che si può solo prendere org.openqa.selenium.NoSuchElementException che sarà lanciato dal driver.findElement se non c'è tale elemento:

import org.openqa.selenium.NoSuchElementException; 

.... 

public static void assertLinkNotPresent(WebDriver driver, String text) { 
    try { 
     driver.findElement(By.linkText(text)); 
     fail("Link with text <" + text + "> is present"); 
    } catch (NoSuchElementException ex) { 
     /* do nothing, link is not present, assert is passed */ 
    } 
} 
+0

bella idea. Per quanto strano non ci sia un meccanismo per gestire questo tipo di asserzione già disponibile in Web Driver – DevDave

+1

per rendere questo più genetico possibile passare in un By.id/cssSelector ecc. Al posto del Testo String. – Dave

+1

I blocchi di fermo vuoti non sono mai una buona idea. – aimbire

1
boolean titleTextfield = driver.findElement(By.id("widget_polarisCommunityInput_113_title")).isDisplayed(); 
assertFalse(titleTextfield, "Title text field present which is not expected"); 
2

Prova questo -

private boolean verifyElementAbsent(String locator) throws Exception { 
    try { 
     driver.findElement(By.xpath(locator)); 
     System.out.println("Element Present"); 
     return false; 

    } catch (NoSuchElementException e) { 
     System.out.println("Element absent"); 
     return true; 
    } 
} 
+0

Sospetto che ciò non funzioni. Io uso i collegamenti Perl e ho provato ad usare questo approccio e il problema era che l'istanza del driver è morta quando nessun elemento è stato trovato. Non sono sicuro se lo stesso accada con Java. – user907860

-1

findElement verificherà la sorgente html e tornerà vero anche se non viene visualizzato l'elemento. Per verificare se viene visualizzato un elemento o non usare -

private boolean verifyElementAbsent(String locator) throws Exception { 

     boolean visible = driver.findElement(By.xpath(locator)).isDisplayed(); 
     boolean result = !visible; 
     System.out.println(result); 
     return result; 
} 
24

E 'più facile fare questo:

driver.findElements(By.linkText("myLinkText")).size() < 1 
+0

Grazie, questo sembra l'approccio migliore anche per i binding non Java. – user907860

+1

Questa è di gran lunga la risposta migliore per evitare l'eccezione generata da findElement. – DMart

6

C'è una classe chiamata ExpectedConditions:

By loc = ... 
    Boolean notPresent = ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(loc)).apply(getDriver()); 
    Assert.assertTrue(notPresent); 
+0

Per qualche motivo questo non funziona per me (almeno in Selenium '2.53.0'). Invece ho dovuto usare la presenza di ** tutti ** elementi come questo: 'ExpectedConditions.not (ExpectedConditions.presenceOfAllElementsLocatedBy (locator)));'. – stiemannkj1

0

È possibile utlilize Arquillian Graphene quadro per questo. Così, ad esempio per il vostro caso potrebbe essere

Graphene.element(By.linkText(text)).isPresent().apply(driver)); 

IS fornisce anche gruppo di API piacevoli di per lavorare con l'Ajax, attende fluenti, oggetti della pagina, frammenti e così via. Sicuramente facilita molto lo sviluppo di un test basato sul selenio.

4

Con Selenio WebDriver sarebbe qualcosa di simile:

assertTrue(!isElementPresent(By.linkText("Empresas en Misión"))); 
0

Per node.js ho trovato il seguente per essere modo efficace per aspettare che un elemento di non essere più presente:

// variable to hold loop limit 
    var limit = 5; 
// variable to hold the loop count 
    var tries = 0; 
     var retry = driver.findElements(By.xpath(selector)); 
      while(retry.size > 0 && tries < limit){ 
       driver.sleep(timeout/10) 
       tries++; 
       retry = driver.findElements(By.xpath(selector)) 
      } 
+0

Il codice può cadere nel ciclo infinito se l'elemento non scompare – algot

+0

Un punto eccellente. Risolto il problema. Non aggiungerò la gestione degli errori. – QualiT

-1

Per appio 1.6.0 e sopra

WebElement button = (new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//XCUIElementTypeButton[@name='your button']")))); 
    button.click(); 

    Assert.assertTrue(!button.isDisplayed()); 
1

Sembra findElements() restituisce solo in fretta se trova almeno un elemento. Altrimenti attende il timeout di attesa implicito, prima di restituire zero elementi - proprio come findElement().

Per mantenere la velocità del test bene, questo esempio accorcia temporaneamente l'attesa implicita, in attesa che l'elemento di scomparire:

static final int TIMEOUT = 10; 

public void checkGone(String id) { 
    FluentWait<WebDriver> wait = new WebDriverWait(driver, TIMEOUT) 
      .ignoring(StaleElementReferenceException.class); 

    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); 
    try { 
     wait.until(ExpectedConditions.numberOfElementsToBe(By.id(id), 0)); 
    } finally { 
     resetTimeout(); 
    } 
} 

void resetTimeout() { 
    driver.manage().timeouts().implicitlyWait(TIMEOUT, TimeUnit.SECONDS); 
} 

Stai ancora cercando un modo per evitare il timeout del tutto però ...