Odpowiedz

23

Nigdy nie można być pewnym, że element zostanie znaleziony, w rzeczywistości jest to celem testów funkcjonalnych - aby powiedzieć, czy coś zmieniło się na twojej stronie. Ale jedna rzecz, która zdecydowanie pomaga jest dodanie czeka na elementach, które są często powodując NoSuchElementException jak

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds); 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>)); 
+0

Jest to z pewnością pomocne. Czy możemy mieć ogólne warunki oczekiwania, abyśmy nie musieli sprawdzać, który warunek ExpectedConditions ma być używany? –

+1

Istnieje również dostęp do 'niejawnego' oczekiwania oferowanego przez 'API Webdriver'a' ale ponieważ po prostu ustawia on arbitralny okres 'nic nie rób', bardzo podobny do' snu', zachęca się do używania 'wyraźnego oczekiwania', jak wyżej dla niezawodności i szybkości. –

+0

To jest rzeczywiście najczystszy i najprostszy kod jaki widziałem ze wszystkich próbek kodu. Dzięki! – mkorman

4

można również wykorzystać FluentWait,

Każda instancja FluentWait określa maksymalną ilość czasu, aby czekać na warunek , a także częstotliwość, z jaką należy sprawdzać stan.

Ponadto użytkownik może skonfigurować oczekiwanie na ignorowanie określonych typów wyjątków podczas oczekiwania, takich jak NoSuchElementExceptions podczas wyszukiwania elementu na stronie.

// Waiting 30 seconds for an element to be present on the page, checking 
    // for its presence once every 5 seconds. 
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) 
     .withTimeout(30, SECONDS) 
     .pollingEvery(5, SECONDS) 
     .ignoring(NoSuchElementException.class); 

    WebElement foo = wait.until(new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
     return driver.findElement(By.id("foo")); 
    } 
    }); 

Click here for more info

+0

Jest to z pewnością pomocne. Ale czy możemy mieć ogólną metodę nakładania ... tj. Na przykład, która czeka na załadowanie strony całkowicie, następnie znajduje element i jeśli element nie zostanie znaleziony odświeża stronę i to trwa aż do upływu czasu fluentwait. –

+0

możesz spróbować połączyć "wyraźne oczekiwanie otoczone przez próbę i złap" z płynnym oczekiwaniem .. – Amith

+0

spróbuj {"używaj wyraźnego czekania"} catch (wyjątek e) {odśwież stronę i korzystaj płynnie} – Amith

3

Całkowicie zgadzam się Petr Menšík powyżej. Sprawa, której nigdy nie można powiedzieć, czy element jest obecny. Powinieneś jasno zrozumieć, dlaczego tak się dzieje. Z mojego doświadczenia mogę powiedzieć, że powinno to się dzieje z powodu następujących powodów:

  • 1) Na stronie jest wciąż renderowane i już zakończył swoją elementu szukanie i uzyskać żadnego wyjątku elementu.
  • 2) Drugim powodem jest to, AJAX nie powrócił jeszcze i masz już uzyskać NoSuchElementException
  • 3) trzeci jest najbardziej oczywiste: Element nie jest naprawdę na stronie kiedykolwiek.

Najbardziej niezawodny sposób, aby IMHO obsłużyć wszystkie te trzy warunki za pomocą jednego wywołania funkcji, to użyć fluentWait zgodnie z sugestią Amith003.

więc kod jest następująca:

niech ur element ma lokalizatora:

String elLocXpath= "..blablabla"; 
WebElement myButton= fluentWait(By.xpath(elLocXpath)); 
myButton.click(); 

public WebElement fluentWait(final By locator){ 
     Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) 
       .withTimeout(30, TimeUnit.SECONDS) 

       .pollingEvery(5, TimeUnit.SECONDS) 

     .ignoring(org.openqa.selenium.NoSuchElementException.class); 
     WebElement foo = wait.until(
       new Function<WebDriver, WebElement>() { 
        public WebElement apply(WebDriver driver) { 
         return driver.findElement(locator); 
        } 
       } 
     ); 
     return foo; 
    }; 

Także, jeśli twoim celem jest solidne kod okład fluentWait() z try{} catch{} bloku.

także nie zapomnieć o

public boolean isElementPresent(By selector) 
    { 

       return driver.findElements(selector).size()>0; 
} 

że jest również przydatna.

Podsumowując wszystkie powyższe, jeśli chcesz uniknąć wyjątku NoElement, po prostu zrób to poprawnie, ponieważ nikt nie może zapewnić obecności elementu na stronie.

Mam nadzieję, że teraz jest dla ciebie bardziej przejrzyste.Pozdrowienia

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

elementToBeClickable czeka Włącz i Visible elementu

1
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) { 

    FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(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; 
} 
0

Zwykle używam tej linii w funkcji main

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

nadzieję, że to pomaga.

0

Możemy zastosować poniżej kodów, aby usunąć ten warunek wyjątku

  1. Stosując WebDriverWait, webdriver obiektu oczekiwania na określony czas (w sekundach) elementu do jego widoczności.

     WebDriverWait wait = new WebDriverWait(driver, 10);  
         wait.until(ExpectedConditions.visibilityOf(link)); 
    
  2. Możemy obsłużyć NoSuchElementException przez blok try-catch wewnątrz metody Generic

    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