C# Selenium "Ожидаемые условия устарели"
При попытке явно дождаться, пока элемент станет видимым с помощью ExpectedConditions, Visual Studio предупреждает меня, что он устарел и скоро будет удален из Selenium.
Каков текущий / новый метод для достижения того же результата?
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));
10 ответов
Я решил свой собственный вопрос и хотел дать ответ для всех, кто интересуется, как решить эту проблему с помощью последней версии Selenium.
Используя nuget, найдите DotNetSeleniumExtras.WaitHelpers, импортируйте это пространство имен в свой класс. Теперь вы можете сделать это:
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("content-section")));
И предупреждение в IDE исчезнет.
Если вы не хотите загружать дополнительный пакет nuget, довольно просто объявить вашу собственную функцию (или условие), особенно с использованием выражения lamda, например
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(condition =>
{
try
{
var elementToBeDisplayed = driver.FindElement(By.Id("content-section"));
return elementToBeDisplayed.Displayed;
}
catch (StaleElementReferenceException)
{
return false;
}
catch (NoSuchElementException)
{
return false;
}
});
Это также очень удобно, так как теперь можно оценить любой тип выражения bool.
Это очень просто, просто изменить
Wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));
в
Wait.Until(c => c.FindElement(By.Id("content-section")));
The answers to change to anonymous function is the most correct one. Or write your own class of your own, needed, wait conditions. An example of using an anonymous function for the explicit scenario above would be something like...
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(ElementNotVisibleException));
var element = wait.Until(() =>
{
var e = Driver.FindElement(By.Id("content-section"));
if(e.Displayed)
return e;
});
And at that point, the function itself could be off on its own in some class in your solution that you can call. The nice thing with this is that you can modify as needed; I have seen several cases where really poorly made websites end up breaking how the ExpectedConditions work, and that was solved with the team writing our own function.
As per the C# contributor:
With respect to ExpectedConditions, again, this was an addition that was created in.NET solely because "Java has it." At the time the ExpectedConditions class in Java was created, the syntax for creating a lambda function (or something that acted like one) was particularly arcane and difficult to understand. In that case, a helper class made lots of sense for the Java bindings. However, C# isn't Java. In C#, the syntax for creating lambda functions ("anonymous methods" in the language of Microsoft's documentation) has been well understood by C# developers for many years, and is a standard tool in their arsenal.
In this case, the question of code verbosity does have some merit, but since wait conditions are rarely one-size-fits-all, it would be a much cleaner approach for users to develop their own conditions class that has the wait conditions they're interested in. This, however, is something users have an aversion to. Additionally, the thought of a 'standard' collection of implementations of specific wait conditions seems to be a good idea on its face, but there is a great deal of variation on the way users want any given condition to work. Having a collection of wait conditions might be a good thing, but the Selenium project is not the place for it.
http://jimevansmusic.blogspot.com/2018/03/deprecating-parts-of-seleniums-net.html
Основываясь на ответе @Rob F., я добавил в свой проект методы расширения. (На самом деле я добавил два,WaitUntilVisible(...)
а также WaitUntilClickable(...)
Они возвращают элемент вместо bool, так что больше похоже на Wait.Until(ExpectedConditions...)
// use: element = driver.WaitUntilVisible(By.XPath("//input[@value='Save']"));
public static IWebElement WaitUntilVisible(
this IWebDriver driver,
By itemSpecifier,
int secondsTimeout = 10)
{
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, secondsTimeout));
var element = wait.Until<IWebElement>(driver =>
{
try
{
var elementToBeDisplayed = driver.FindElement(itemSpecifier);
if(elementToBeDisplayed.Displayed)
{
return elementToBeDisplayed;
}
return null;
}
catch (StaleElementReferenceException)
{
return null;
}
catch (NoSuchElementException)
{
return null;
}
});
return element;
}
Требуется Nuget - DotNetSeleniumExtras.WaitHelpers
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("")));
Я только что продемонстрировал событие кликабельности элемента. аналогично другие события могут использоваться с необходимыми параметрами. надеюсь, это поможет
У меня работает следующий код C#:
new WebDriverWait(webDriver, TimeSpan.FromSeconds(10)).Until(c => c.FindElement(By.Id("name")));
Проверьте, какие версии пакетов Selenium.Support и Selenium.WebDriver NuGet вы установили. У меня возникла та же проблема с последней версией 3.11.2, и я понизил ее до 3.10.0, и она устранила проблему.
вы можете импортировать такую библиотеку
using ExpectedConditions = SeleniumExtras.WaitHelpers.ExpectedConditions;
то предупреждение исчезнет.
Вы можете использовать пакет NuGet Gravity.Core - он поддерживается сообществом Gravity API и содержит НАМНОГО больше, чем просто класс ExpectedConditions.
Как использовать
- Загрузите NuGet с помощью диспетчера пакетов NuGet.
- Добавлять
using OpenQA.Selenium.Extensions