簡體   English   中英

在 Selenium 中避免 NoSuchElementException 的最佳方法是什么?

[英]What is the best way to avoid NoSuchElementException in Selenium?

我使用 Java 在 Selenium WebDriver 中編寫了一些測試用例,並在網格(集線器和多個節點)上執行它們。 我注意到一些測試用例由於NoSuchElementException而失敗。 避免NoSuchElementException並確保始終找到元素的最佳和健壯的方法是什么?

您永遠無法確定會找到該元素,實際上這是功能測試的目的 - 告訴您頁面上是否有任何更改。 但是絕對有幫助的一件事是添加對經常導致NoSuchElementException的元素的等待,例如

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

我完全同意上面的 Petr Mensik。 你永遠不能說元素是否存在。 當它發生時,您應該清楚地了解原因。 根據我的經驗,我應該說它的發生是由於以下原因:

  • 1)頁面仍在渲染中,您已經完成了元素搜索並且沒有獲得元素異常。
  • 2)第二個原因是AJAX還沒有返回,你已經獲得了NoSuchElementException
  • 3)第三個是最明顯的:該元素真的不在頁面上。

因此,使用一個函數調用來處理所有這三個條件的最健壯的恕我直言的方法是使用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異常,只需正確處理它,因為沒有人可以確保頁面上的元素存在。

希望現在你更清楚了。 問候

你也可以使用FluentWait

每個FluentWait實例定義等待條件的最長時間,以及檢查條件的頻率。

此外,用戶可以配置等待以在等待時忽略特定類型的異常,例如在頁面上搜索元素時的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"));
     }
   });

單擊此處了解更多信息

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;
}
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));

elementToBeClickable等待元素的啟用可見

NoSuchElementException 當定位器(即 id/xpath/css 選擇器)無法在網頁上找到 Web 元素時發生。

原因可能是:

  1. 定位器不正確

  2. Web 元素在網頁上不可用

    為了避免這個異常,我們可以使用Fluent Wait。 此等待允許我們定義最大超時、輪詢頻率並定義要忽略的異常。

請在下面找到 Fluent wait 的示例用法:

.withTimeout(50, TimeUnit.SECONDS)
.pollingevery(3, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);

我通常在主函數中使用這一行

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

希望這會有所幫助。

我們可以應用以下代碼來刪除此異常條件

  1. 通過應用 WebDriverWait,webdriver 對象等待元素的特定時間(以秒為單位)以使其可見。

     WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(link));
  2. 我們可以通過泛型方法中的 try-catch 塊處理 NoSuchElementException

     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

有時可以等待所需項目的下載。

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"]')
        )))

有時您需要做一些事情以便 UI 框架加載數據。 例如滾動頁面

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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM