Webdriver Как подождать, пока элемент будет доступен для кликов в webdriver С#

Существует блок Ui, который охватывает все элементы в течение нескольких секунд после того, как элемент был создан в браузере, из-за этого я столкнулся с проблемой. Поскольку появился элемент, веб-драйвер пытается щелкнуть элемент, но клик получен с помощью пользовательского интерфейса блока. Я пытался использовать ожидание До тех пор, пока я не помог, так как я могу найти isClickAble в С# webdriver

   var example = _wait.Until<IWebElement>((d) => d.FindElement(By.XPath("Example")));
   var example2 = _wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(By.XPath("Example")));
example.click();
example2.click();

Есть ли эквивалент С# для isClickAble, спасибо заранее

Ответ 1

Ну, взглянув на источник Java, он говорит, что в основном делает две вещи, чтобы определить, можно ли это "clickable":

https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java

Во-первых, он проверяет, "видимо ли это", используя стандартный ExpectedConditions.visibilityOfElementLocated, тогда он просто проверяет, есть ли element.isEnabled() true или нет.

Это может быть слегка сжато, это в основном означает (упрощенное в С#):

  • Подождите, пока элемент не будет возвращен из DOM
  • Дождитесь, пока свойство element .Displayed будет истинным (что, по существу, проверяет visibilityOfElementLocated).
  • Подождите, пока свойство element .Enabled не будет истинным (что, по существу, проверяет elementToBeClickable).

Я бы реализовал это так (добавление к текущему набору ExpectedConditions, но есть несколько способов сделать это:

/// <summary>
/// An expectation for checking whether an element is visible.
/// </summary>
/// <param name="locator">The locator used to find the element.</param>
/// <returns>The <see cref="IWebElement"/> once it is located, visible and clickable.</returns>
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
    return driver =>
    {
        var element = driver.FindElement(locator);
        return (element != null && element.Displayed && element.Enabled) ? element : null;
    };
}

Используется в чем-то вроде:

var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementIsClickable(By.Id("id")));

Однако у вас может быть другое представление о том, что может означать clickable, и в этом случае это решение может не работать, но это прямой перевод того, что делает Java-код.

Ответ 2

Здесь код, который я использую, чтобы проверить, является ли он интерактивным, иначе перейдите к другому URL-адресу.

if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
            {
                logOutLink.Click();
            }
            else
            {
                Browser.Goto("/");
            }

Ответ 3

Если у вас возникла такая проблема, как "Другой элемент получил бы щелчок", путь вокруг этого - использовать цикл while, который ждет, чтобы этот оверлейный блок ушел.

//The below code waits 2 times in order for the problem element to go away.
int attempts = 2;
var elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
while (attempts > 0 && elementsWeWantGone.Count > 0)
{
    Thread.Sleep(500);
    elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
}

Ответ 4

Вот код с небольшим количеством контекста, который, кажется, улучшил мои тесты Selenium на С#. Также используется SpecFlow и xUnit.

На более медленных компьютерах, запускающих тестирование, казалось, что элемент ввода сначала будет доступен для поиска, но к тому моменту, когда сценарий попытается отправить ключи или щелчок элементу управления вводом, щелчок не будет активен. Помогло ожидание "ElementToBeClickable". По состоянию на май 2019 года пакет NuGet, содержащий это, называется DotNetSeleniumExtras.WaitHelpers.

Ключевая строка это:

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable (К...

Сделайте это для первого поля ввода на новой странице, используя селектор, который указывает на первое поле ввода, с которым вы хотите взаимодействовать. (By.XPath( "")

[Given(@"I have selected the link to the OrgPlus application")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusApplication()
{
    _driver.Navigate().GoToUrl("http://orgplus.myorg.org/ope?footer");
}

[Given(@"I have selected the link to the OrgPlus Directory lookup")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusDirectoryLookup()
{
    var wait = new WebDriverWait(_driver, new TimeSpan(0, 0, 30));
    var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id=\"lnkDir\"]")));
    IWebElement btnSearch = _driver.FindElement(By.XPath("//*[@id=\"lnkDir\"]"));
    btnSearch.SendKeys(Keys.Enter);
}