Beim Versuch, explizit darauf zu warten, dass ein Element mithilfe von ExpectedConditions sichtbar wird, warnt mich Visual Studio, dass es jetzt veraltet ist und bald aus Selenium entfernt wird.

Was ist die aktuelle / neue Methode, um das gleiche Ergebnis zu erzielen?

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));
60
JohnWick 17 Apr. 2018 im 00:14

7 Antworten

Beste Antwort

Ich habe meine eigene Frage gelöst und wollte die Antwort für alle anderen geben, die sich fragen, wie sie dies mit der neuesten Version von Selenium lösen können.

Suchen Sie mit nuget nach DotNetSeleniumExtras.WaitHelpers und importieren Sie diesen Namespace in Ihre Klasse. Jetzt können Sie dies tun:

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("content-section")));

Und die Warnung in der IDE wird weg sein.

102
JohnWick 16 Apr. 2018 im 23:23

Wenn Sie kein zusätzliches Nuget-Paket herunterladen möchten, ist es recht einfach, Ihre eigene Funktion (oder Bedingung) zu deklarieren, insbesondere unter Verwendung eines Lamda-Ausdrucks, z.

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;
    }
});

Dies ist auch sehr vielseitig, da es jetzt möglich ist, jede Art von Bool-Ausdruck zu bewerten.

20
Rob F. 30 Mai 2018 im 11:53

Es ist sehr einfach, ändern Sie einfach

Wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));

Zu

Wait.Until(c => c.FindElement(By.Id("content-section")));
11
Eric Aya 3 Okt. 2018 im 12:25

Die Antwort auf den Wechsel zur anonymen Funktion ist die richtigste. Oder schreiben Sie Ihre eigene Klasse für Ihre eigenen, benötigten Wartebedingungen. Ein Beispiel für die Verwendung einer anonymen Funktion für das obige explizite Szenario wäre etwa ...

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;
});

Und zu diesem Zeitpunkt könnte die Funktion selbst in einer Klasse in Ihrer Lösung, die Sie aufrufen können, von selbst ausgeschaltet sein. Das Schöne daran ist, dass Sie nach Bedarf Änderungen vornehmen können. Ich habe mehrere Fälle gesehen, in denen wirklich schlecht erstellte Websites die Funktionsweise der ExpectedConditions beeinträchtigen, und das wurde gelöst, indem das Team unsere eigene Funktion schrieb.

Gemäß dem C # -Beitragenden:

In Bezug auf ExpectedConditions war dies wiederum ein Zusatz, der in .NET nur erstellt wurde, weil "Java es hat". Zum Zeitpunkt der Erstellung der ExpectedConditions-Klasse in Java war die Syntax zum Erstellen einer Lambda-Funktion (oder einer Funktion, die sich wie eine solche verhält) besonders geheimnisvoll und schwer zu verstehen. In diesem Fall war eine Hilfsklasse für die Java-Bindungen sehr sinnvoll. C # ist jedoch nicht Java. In C # ist die Syntax zum Erstellen von Lambda-Funktionen ("anonyme Methoden" in der Sprache der Microsoft-Dokumentation) von C # -Entwicklern seit vielen Jahren gut verstanden und ein Standardwerkzeug in ihrem Arsenal.

In diesem Fall hat die Frage der Code-Ausführlichkeit einige Vorteile, aber da Wartebedingungen selten eine Einheitsgröße sind, wäre es für Benutzer ein viel saubererer Ansatz, eine eigene Bedingungsklasse zu entwickeln, die die Wartebedingungen hat, die sie haben. Dies ist jedoch etwas, gegen das Benutzer eine Abneigung haben. Darüber hinaus scheint der Gedanke an eine "Standard" -Sammlung von Implementierungen bestimmter Wartebedingungen eine gute Idee zu sein, aber es gibt große Unterschiede in der Art und Weise, wie Benutzer eine bestimmte Bedingung funktionieren lassen möchten. Eine Sammlung von Wartebedingungen zu haben mag eine gute Sache sein, aber das Selenium-Projekt ist nicht der richtige Ort dafür.

http://jimevansmusic.blogspot.com/2018/03/deprecating-parts-of-seleniums-net.html

8
Dave Anderson 23 Sept. 2019 im 23:39

Nuget erforderlich - DotNetSeleniumExtras.WaitHelpers

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("")));

Ich habe gerade das Element anklickbares Ereignis demonstriert. Ebenso können andere Ereignisse mit den erforderlichen Parametern verwendet werden. ich hoffe das hilft

3
Krunal Patel 24 Juni 2019 im 18:18

Basierend auf der Antwort von @Rob F. habe ich meinem Projekt Erweiterungsmethoden hinzugefügt. (Eigentlich habe ich zwei hinzugefügt, WaitUntilVisible(...) und WaitUntilClickable(...)

Diese geben das Element anstelle eines Bools zurück, also eher wie das 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;
}
3
Jamie F 8 Sept. 2019 im 22:45

Überprüfen Sie, welche Version von Selenium.Support und Selenium.WebDriver NuGet Package Sie installiert haben. Ich habe jetzt das gleiche Problem mit der neuesten Version 3.11.2 und habe ein Downgrade auf 3.10.0 durchgeführt, wodurch das Problem behoben wurde.

-1
martin pb 16 Apr. 2018 im 23:02