Как добавить пользовательские ExpectedConditions для Selenium?

Я пытаюсь написать свои собственные ExpectedConditions для Selenium, но я не знаю, как добавить новый. У кого-нибудь есть пример? Я не могу найти учебники для этого онлайн.

В моем текущем случае я хочу подождать, пока элемент не будет существовать, будет виден, включен и не имеет attr "aria-disabled". Я знаю, что этот код не работает:

var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(seconds));
return wait.Until<IWebElement>((d) =>
    {
        return ExpectedConditions.ElementExists(locator) 
        && ExpectedConditions.ElementIsVisible 
        &&  d.FindElement(locator).Enabled 
         && !d.FindElement(locator).GetAttribute("aria-disabled")
    }

EDIT: немного дополнительной информации: проблема, с которой я сталкиваюсь, - это вкладки jQuery. У меня есть форма на вкладке disabled, и она начнет заполнять поля на этой вкладке до того, как вкладка станет активной.

Ответ 1

"Ожидаемое условие" - это не что иное, как анонимный метод с использованием выражения лямбда. Они стали основным продуктом разработки .NET с .NET 3.0, особенно с выпуском LINQ. Поскольку подавляющее большинство разработчиков .NET удобны с синтаксисом С# лямбда, реализация Webdriver.NET bindings ExpectedConditions имеет только несколько методов.

Создание ожидания, как вы просите, будет выглядеть примерно так:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until<IWebElement>((d) =>
{
    IWebElement element = d.FindElement(By.Id("myid"));
    if (element.Displayed &&
        element.Enabled &&
        element.GetAttribute("aria-disabled") == null)
    {
        return element;
    }

    return null;
});

Если вы не знакомы с этой конструкцией, я бы рекомендовал это сделать. Он скорее всего будет более распространен в будущих версиях .NET.

Ответ 2

Я понимаю теорию, стоящую за ExpectedConditions (я думаю), но я часто нахожу их громоздкими и трудными в использовании на практике.

Я бы пошел с таким подходом:

public void WaitForElementPresentAndEnabled(By locator, int secondsToWait = 30)
{
   new WebDriverWait(driver, new TimeSpan(0, 0, secondsToWait))
      .Until(d => d.FindElement(locator).Enabled
          && d.FindElement(locator).Displayed
          && d.FindElement(locator).GetAttribute("aria-disabled") == null
      );
}

Я с удовольствием узнаю из ответа, который использует все ExpectedConditions здесь:)

Ответ 3

Я преобразовал пример WebDriverWait и ExpectedCondition/s из Java в С#.

Версия Java:

WebElement table = (new WebDriverWait(driver, 20))  
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("table#tabletable")));

Версия С#:

IWebElement table = new WebDriverWait(driver, TimeSpan.FromMilliseconds(20000))
.Until(ExpectedConditions.ElementExists(By.CssSelector("table#tabletable")));