Как подождать, пока элемент не будет существовать в Selenium

Я тестирую пользовательский интерфейс, в котором пользователь нажимает кнопку удаления, и запись в таблице исчезает. Поэтому я хочу проверить, что запись в таблице больше не существует.

Я попытался использовать ExpectedConditions.not() для инверсии ExpectedConditions.presenceOfElementLocated(), надеясь, что это будет означать "ожидать, что не существует указанного элемента". Мой код выглядит так:

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

Тем не менее, я обнаружил, что даже делая это, я получаю TimeoutExpcetion вызванный TimeoutExpcetion, в NoSuchElementException говорится, что элемент "foo" не существует. Конечно, отсутствие такого элемента - это то, что я хочу, но я не хочу, чтобы было исключено исключение.

Итак, как я могу подождать, пока элемент больше не будет существовать? Я бы предпочел пример, который не полагается на вынимание исключения, если это вообще возможно (как я понимаю, исключения должны быть брошены за исключительное поведение).

Ответ 1

Вы также можете использовать -

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

Если вы NoSuchElementException источником, вы увидите, что NoSuchElementException как NoSuchElementException и staleElementReferenceException.

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

Ответ 2

Решение по-прежнему будет полагаться на обработку исключений. И это довольно хорошо, даже стандартные ожидаемые условия полагаются на исключения, которые 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;
      }
    };
  }

Ответ 3

Почему бы вам просто не найти размер elements. Мы знаем, что размер элементов коллекции будет равен 0, если элемент не существует.

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

Ответ 4

// 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 выдает исключение из непримиримости элемента. Я реализовал использование findelements. пожалуйста, не стесняйтесь исправить и использовать его в соответствии с вашими потребностями.

Ответ 5

Я нашел обходное решение, чтобы исправить это для меня эффективным образом, используя следующий код С# для его обработки, вы можете преобразовать его в 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;
        }
    }

Ответ 6

Я не знаю почему, но ExpectedConditions.invisibilityOf(element) - единственная работа для меня, в то время как ExpectedConditions.invisibilityOfElementLocated(By), !ExpectedConditions.presenceOfElementLocated(By)... нет. Попробуй это!

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