2012-03-21 10 views
6

Sono nuovo al web selenio Selenium, forse questa domanda è ovvia. Sono dopo situazione come questa:Utilizzo del webdriver per vedere se esiste un elemento SENZA lanciare un'eccezione?

Se l'elemento esiste, clic su di esso e tornare alla pagina indice:

driver.findElement(By.id("...."])).click(); 

se non lo fa uscire, saltare e tornare alla pagina indice. Il test continua ancora senza alcuna eccezione lanciata.

so una soluzione a questo:

driver.findElements(By.id("...")).size() != 0 

così ho provato:

if(driver.findElements(By.id("....")).size() > 0) 
    { 
     driver.findElement(By.id("....")).click(); 
     driver.findElement(By.cssSelector("...")).click(); 
    } 
else 
    { 
     driver.findElement(By.cssSelector("....")).click(); 
    } 

Questo si è davvero brutto, però, perché se io ho 10 elementi per verificare, questa condizione se ha bisogno di essere scritto 10 volte.

Qualsiasi soluzione per renderlo ordinato?

risposta

1

La soluzione potrebbe essere molte ma potrebbe ostacolare la tua architettura.

Così soluzione più semplice potrebbe essere la seguente:

Basta creare un metodo come optionalClick() in qualche classe di utilità o da qualche parte con gli argomenti come:

  1. locator_keyword: {valori: id o CssSelector o XPath etc}
  2. locator: {valori: "q"}

procedura descritta nel metodo:

  1. Get elemento sulla base del locator_keyword e locator
  2. Controllare se elemento è lì e fare clic
  3. Altrimenti non facciamo nulla

Questo metodo può essere utilizzato come un genere generico di cose per qualsiasi tipo di oggetti.

+0

grazie per il feedback !! un altro problema è, usando se la sintassi è orribilmente lenta ... c'è un modo per renderlo più veloce? – user1282634

+0

Ok, quindi non utilizzare se istruzione invece di usare il blocco try/catch come segue: try {WebElement elemnt = driver.findElement (By.ID ("..")); elemnt.click();} catch (Eccezione e) {// Niente da fare} – Nayan

+0

capito ~~ grazie !! – user1282634

1

Esistono modi per trovare gli elementi senza generare eccezioni utilizzando le condizioni try-catch all'interno dei loop. Ad esempio, questo metodo che ho scritto (che può essere semplificata a seconda di quello che si utilizza se per) restituirà un WebElement e fa in modo che sia cliccabile, prima di tornare a voi:

public static WebElement getElementByLocator(By locator) { 
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 
    WebElement we = null; 
    boolean unfound = true; 
    int tries = 0; 
    while (unfound && tries < 10) { 
    tries += 1; 
    try { 
     we = driver.findElement(locator); 
     unfound = false; // FOUND IT 
    } catch (StaleElementReferenceException ser) {       
     unfound = true; 
    } catch (NoSuchElementException nse) {       
     unfound = true; 
    } catch (Exception e) { 
     staticlogger.info(e.getMessage()); 
    } 
    } 
    driver.manage().timeouts().implicitlyWait(DEFAULT_IMPLICIT_WAIT, 
     TimeUnit.SECONDS); 
    return we; 
} 
+1

erm in che modo non usare le eccezioni ?! –

+0

Ho detto "senza buttare", non "senza usare". – djangofan

0

Grazie per il puntatore sull'uso findelements. Penso che dovrai anche aspettare la logica se non vuoi che ritorni troppo presto.

ecco la mia soluzione in C#.

In pratica, reimplementa la logica di attesa nella libreria del selenio - sfortunatamente il metodo che fa l'attesa non è esposto (fastidiosamente anche rethrows exceptions the wrong way e perde le tracce dello stack!).

Probabilmente dovresti modificarlo un po 'per java - non so cosa sia l'API del selenio quando non riesci a passare le funzioni.

Attendere reimplementazione:

private IWebElement WaitAndSeeIf(Func<IWebElement> canGet) 
    { 
     var end = DateTime.Now.AddSeconds(1); 

     IWebElement element; 
     while (true) 
     { 
      element = canGet(); 

      if (element != null) 
       break; 

      var time = DateTime.Now; 
      if (time > end) 
       break; 

      Thread.Sleep(200); 
     } 
     return element; 
    } 

codice chiamando:

 var dashboardButton = WaitAndSeeIf(() => 
               { 
                var elements = Driver.FindElements(By.XPath("//button[contains(.//*,'Dashboard')]")); 
                return elements.Any() ? elements.Single() : null; 
               }); 

Finora ho trovato questo utile in un paio di posti (controllo per la presenza di finestre di dialogo in ExtJS, ecc), ma hanno eppure aveva il bisogno di andare in giro e renderlo configurabile. Suppongo che la cosa più bella da fare sia quella di avere il tempo di attesa implicito come menzionato nell'altra risposta.

Problemi correlati