Qual è il modo migliore per evitare NoSuchElementException in Selenium?

Ho scritto alcuni casi di test in Selenium WebDriver utilizzando Java e li eseguo sulla griglia (hub e nodes multipli). Ho notato che alcuni casi di test falliscono a causa di NoSuchElementException . Qual è il modo migliore e più efficace per evitare NoSuchElementException e garantire che l’elemento venga sempre trovato?

Non puoi mai essere sicuro che quell’elemento sarà trovato, in realtà questo è lo scopo dei test funzionali – per dirti se qualcosa è cambiato nella tua pagina. Ma una cosa che sicuramente aiuta è aggiungere attese per gli elementi che spesso causano NoSuchElementException

 WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds); wait.until(ExpectedConditions.visibilityOfElementLocated(By.id)); 

Sono completamente d’accordo con Petr Mensik sopra. La questione non puoi mai dire se l’elemento è presente. Dovresti capire chiaramente perché quando succede. Dalla mia esperienza dovrei dire che succede a causa dei seguenti motivi:

  • 1) La pagina è ancora in fase di rendering e hai già terminato la ricerca di elementi e non hai ottenuto alcuna eccezione di elemento.
  • 2) Il secondo motivo è che AJAX non è ancora stato restituito e hai già ottenuto NoSuchElementException
  • 3) Il terzo è più ovvio: l’elemento non è realmente sulla pagina ogni volta.

quindi il metodo IMHO più robusto per gestire tutte queste tre condizioni usando una chiamata a una funzione è usare fluentWait come suggerito da Amith003.

quindi il codice è il seguente:

lascia che l’elemento abbia il localizzatore:

 String elLocXpath= "..blablabla"; WebElement myButton= fluentWait(By.xpath(elLocXpath)); myButton.click(); public WebElement fluentWait(final By locator){ Wait wait = new FluentWait(driver) .withTimeout(30, TimeUnit.SECONDS) .pollingEvery(5, TimeUnit.SECONDS) .ignoring(org.openqa.selenium.NoSuchElementException.class); WebElement foo = wait.until( new Function() { public WebElement apply(WebDriver driver) { return driver.findElement(locator); } } ); return foo; }; 

Inoltre, se il tuo scopo è un robusto codice wrap fluentWait() con un blocco try{} catch{} .

Inoltre, non dimenticare

  public boolean isElementPresent(By selector) { return driver.findElements(selector).size()>0; } 

anche questo è utile.

Quindi, per concludere tutto ciò che è stato detto, se vuoi evitare NoElement eccezione di NoElement correttamente in quanto nessuno può garantire la presenza degli elementi nella pagina.

Spero che ora sia più chiaro per te. Saluti

puoi anche usare FluentWait ,

Ogni istanza di FluentWait definisce la quantità massima di tempo di attesa per una condizione, nonché la frequenza con cui controllare la condizione.

Inoltre, l’utente può configurare l’attesa per ignorare determinati tipi di eccezioni durante l’attesa, come NoSuchElementExceptions durante la ricerca di un elemento nella pagina.

 // Waiting 30 seconds for an element to be present on the page, checking // for its presence once every 5 seconds. Wait wait = new FluentWait(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS) .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("foo")); } }); 

Clicca qui per maggiori informazioni

 WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds); wait.until(ExpectedConditions.elementToBeClickable(By.id)); 

elementToBeClickable attende Abilita e Visibile di un elemento

 public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) { FluentWait fWait = new FluentWait(driver).withTimeout(timoutSec, TimeUnit.SECONDS) .pollingEvery(pollingSec, TimeUnit.SECONDS) .ignoring(NoSuchElementException.class, TimeoutException.class); for (int i = 0; i < 2; i++) { try { //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']"))); fWait.until(ExpectedConditions.visibilityOf(element)); fWait.until(ExpectedConditions.elementToBeClickable(element)); } catch (Exception e) { System.out.println("Element Not found trying again - " + element.toString().substring(70)); e.printStackTrace(); } } return element; } 

Di solito uso questa linea nella funzione principale

 public static void main(String[] args) throws ParseException { driver= new ChromeDriver(); driver.manage().window().maximize(); **driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);** 

Spero che questo ti aiuti.

Possiamo applicare i seguenti codici per rimuovere questa condizione di eccezione

  1. Applicando WebDriverWait, l’object webdriver attende un tempo specifico (in secondi) di un elemento per la sua visibilità.

      WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(link)); 
  2. Siamo in grado di gestire NoSuchElementException tramite blocco try-catch all’interno del metodo Generico

      public boolean isElementPresent(By by) { boolean isPresent = true; try { driver.findElement(by); } catch (NoSuchElementException e) { isPresent = false; } return isPresent } 

http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html