Подтвердить что ты не робот

Каков наилучший способ избежать исключения NoSuchElementException в Selenium?

Я написал несколько тестовых примеров в Selenium WebDriver с помощью Java и выполнил их в сетке (концентратор и несколько узлов). Я заметил, что несколько тестов из-за NoSuchElementException не работают. Каков наилучший и надежный способ избежать NoSuchElementException и убедиться, что элемент всегда найден?

4b9b3361

Ответ 1

Вы никогда не можете быть уверены, что элемент будет найден, на самом деле это цель функциональных тестов - сообщить вам, если что-либо изменилось на вашей странице. Но одна вещь, которая определенно помогает, заключается в добавлении ожиданий элементов, которые часто вызывают NoSuchElementException как

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

Ответ 2

Я полностью согласен с Петром Менсиком выше. Вопрос, который вы никогда не можете сказать, присутствует ли элемент. Вы должны четко понимать, почему, когда это происходит. По моему опыту, я должен сказать, что это происходит по следующим причинам:

  • 1) Страница все еще отображается, и вы уже закончили свой поиск элементов и исключение исключений элемента.
  • 2) Вторая причина - AJAX еще не вернулась, и вы уже получить NoSuchElementException
  • 3) Третий наиболее очевидный: элемент на самом деле не на странице всякий раз, когда.

поэтому наиболее надежный метод IMHO для обработки всех этих трех условий с использованием одного вызова функции - использовать fluentWait, как предлагал Amith003.

поэтому код должен быть следующим:

пусть ур-элемент имеет локатор:

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

Также, если ваша цель - надежный перенос кода fluentWait() с блоком try{} catch{}.

Также не забывайте о

 public boolean isElementPresent(By selector)
   {

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

что также полезно.

Итак, чтобы завершить все упомянутое, если вы хотите избежать исключения NoElement, просто обработайте его должным образом, поскольку никто не может гарантировать наличие элемента на странице.

Надеюсь, теперь вам станет понятнее. Отношения

Ответ 3

вы также можете использовать FluentWait,

Каждый экземпляр FluentWait определяет максимальное время ожидания условия, а также частоту проверки условия.

Кроме того, пользователь может настроить wait для игнорирования определенных типов исключений во время ожидания, например NoSuchElementExceptions при поиске элемента на странице.

// 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"));
     }
   });

Нажмите здесь для получения дополнительной информации

Ответ 4

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

elementToBeClickable ожидает Включить и Видимый элемента

Ответ 5

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

Ответ 6

Я обычно использую эту строку в основной функции

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

Надеюсь, что это поможет.

Ответ 7

Мы можем применить ниже коды для удаления этого условия исключения

  • Применяя WebDriverWait, объект webdriver ждет определенное время (во втором) элемента для его видимости.

          WebDriverWait wait = new WebDriverWait(driver, 10);       
           wait.until(ExpectedConditions.visibilityOf(link));
    
  • Мы можем обрабатывать NoSuchElementException через блок try-catch внутри Generic method

     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

Ответ 8

Иногда можно дождаться загрузки нужного элемента.

driver.get("https://zzzzzzzzz.market/items/mirage_prime_set")

WebDriverWait(driver, 20)
       .until(
        EC.visibility_of_element_located(
          (By.XPATH, ('//div[@class="orders-row__element order__price sell_color"]')
        )))

Иногда вам нужно что-то сделать, чтобы среда пользовательского интерфейса загружала данные. Например, страница прокрутки

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

А затем получить необходимые данные

responsetext=driver.page_source

from lxml import html
parsed_body = html.fromstring(responsetext)

obj1 = parsed_body.xpath('.//div[@class="orders-row__element order__price sell_color"]/span[1]')
print(len(obj1))