簡體   English   中英

如何等到 Selenium 中不再存在元素

[英]How to wait until an element no longer exists in Selenium

我正在測試用戶單擊刪除按鈕並且表條目消失的 UI。 因此,我希望能夠檢查表條目是否不再存在。

我曾嘗試使用ExpectedConditions.not()來反轉ExpectedConditions.presenceOfElementLocated() ,希望這意味着“期望不存在指定的元素”。 我的代碼是這樣的:

browser.navigate().to("http://stackoverflow.com");
new WebDriverWait(browser, 1).until(
        ExpectedConditions.not(
                ExpectedConditions.presenceOfElementLocated(By.id("foo"))));

然而,我發現即使這樣做,我也會得到一個由NoSuchElementException引起的TimeoutExpcetion ,說元素“foo”不存在。 當然,沒有這樣的元素是我想要的,但我不希望拋出異常。

那么我怎么能等到一個元素不再存在呢? 如果可能的話,我更喜歡一個不依賴於捕獲異常的示例(據我所知,異常行為應該拋出異常)。

您還可以使用 -

new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator));

如果您查看它的源代碼,您可以看到NoSuchElementExceptionstaleElementReferenceException都被處理了。

/**
   * An expectation for checking that an element is either invisible or not
   * present on the DOM.
   *
   * @param locator used to find the element
   */
  public static ExpectedCondition<Boolean> invisibilityOfElementLocated(
      final By locator) {
    return new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          return !(findElement(locator, driver).isDisplayed());
        } catch (NoSuchElementException e) {
          // Returns true because the element is not present in DOM. The
          // try block checks if the element is present but is invisible.
          return true;
        } catch (StaleElementReferenceException e) {
          // Returns true because stale element reference implies that element
          // is no longer visible.
          return true;
        }
      }

該解決方案仍將依賴於異常處理。 這幾乎沒問題,即使是標准的預期條件也依賴於findElement()拋出的異常。

這個想法是創建一個自定義的預期條件

  public static ExpectedCondition<Boolean> absenceOfElementLocated(
      final By locator) {
    return new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          driver.findElement(locator);
          return false;
        } catch (NoSuchElementException e) {
          return true;
        } catch (StaleElementReferenceException e) {
          return true;
        }
      }

      @Override
      public String toString() {
        return "element to not being present: " + locator;
      }
    };
  }

你為什么不簡單地找到elements的大小。 我們知道如果元素不存在,元素集合的大小將為0

if(driver.findElements(By.id("foo").size() > 0 ){
    //It should fail
}else{
    //pass
}

我不知道為什么但ExpectedConditions.invisibilityOf(element)是我唯一的工作,而ExpectedConditions.invisibilityOfElementLocated(By) , !ExpectedConditions.presenceOfElementLocated(By) ... 不是。 嘗試一下!

希望這有幫助!

// pseudo code
public Fun<driver,webelement> ElemtDisappear(locator)
{
    webelement element=null;
    iList<webelement> elemt =null;
    return driver=>
    {
    try
    {
    elemt = driver.findelements(By.locator);
    if(elemt.count!=0)
    {
    element=driver.findelement(By.locator);
    }
    }
    catch(Exception e)
    {
    }
    return(elemnt==0)?element:null;
};

// call function
public void waitforelemDiappear(driver,locator)
{
    webdriverwaiter wait = new webdriverwaiter(driver,time);
    try
    {
    wait.until(ElemtDisappear(locator));
    }
    catch(Exception e)
    {
    }
}

由於 findelement 在元素 unaviability.so 上引發異常,所以我使用 findelement 實現。 請隨時根據您的需要更正和使用它。

我找到了一種解決方法以有效的方式為我解決此問題,使用以下 C# 代碼來處理此問題,您可以將其轉換為 Java

    public bool WaitForElementDisapper(By element)
    {
        try
        {
            while (true)
            {
                try
                {
                    if (driver.FindElement(element).Displayed)
                        Thread.Sleep(2000);
                }
                catch (NoSuchElementException)
                {
                    break;
                }
            }
            return true;
        }
        catch (Exception e)
        {
            logger.Error(e.Message);
            return false;
        }
    }

好消息,它現已內置(我在 2021 年使用 Node.js)

看起來elementIsNotVisible已被添加到until的答案給出之后。 我正在使用 selenium webdriver 4.0.0-beta.3

一探究竟:

const timeout = 60 * 1000; // 60 seconds
const element = await driver.findElement(By.id(elementId));

// this is the important line 
await driver.wait(until.elementIsNotVisible(element), timeout);

暫無
暫無

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

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