Führen Sie JavaScript mit Selenium WebDriver in C # aus

103

Wie wird das erreicht? Hier heißt es, die Java-Version sei:

WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");

Aber ich kann den C # -Code dafür nicht finden.

JontyMC
quelle

Antworten:

216

Die Objekt-, Methoden- und Eigenschaftsnamen in den .NET-Sprachbindungen entsprechen nicht genau denen in den Java-Bindungen. Eines der Prinzipien des Projekts ist, dass sich jede Sprachbindung für diejenigen, die sich in dieser Sprache wohlfühlen, "natürlich" anfühlt. In C # lautet der Code, den Sie zum Ausführen von JavaScript benötigen, wie folgt

IWebDriver driver; // assume assigned elsewhere
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string title = (string)js.ExecuteScript("return document.title");

Beachten Sie, dass die vollständige Dokumentation der WebDriver-API für .NET unter diesem Link zu finden ist .

JimEvans
quelle
10
Beachten Sie die Großschreibung im Wort Java S cript. Das hat mich erwischt.
Wobei
1
Jims Antwort ist so maßgeblich wie möglich. Schauen Sie sich den Commit-Verlauf für jede Selenium .NET-Datei an :-)
Ross Patterson
Könnten Sie mir bitte sagen, wie ich auf eine Schaltfläche in C # klicken soll? Antworten wie arguments[0].click();funktioniert bei mir nicht? Ich habe keine Ausnahme, wenn ich meinen Code ausführe, aber er klickt nicht auf die Schaltfläche.
Almett
Ich finde es unangenehm, dass ich den Fahrer besetzen muss. Warum ist ExecuteJavascriptnicht nur eine Methode auf dem driver?
Kolob Canyon
Dies ist ein Überbleibsel aus einer Zeit, in der nicht jede Treiberimplementierung die Ausführung von beliebigem JavaScript unterstützte. Die .NET-Bindungen verwenden wie die Java-Bindungen rollenbasierte Schnittstellen, um Funktionen zu modellieren, die möglicherweise von einem Treiber unterstützt werden, jedoch nicht von allen. In der Support-Assembly ( WebDriver.Support.dllverfügbar über NuGet im Selenium.SupportPaket) gibt es eine Erweiterungsmethode, die das Casting für Sie verwaltet und den Eindruck erweckt, dass der Treiber über eine ExecuteJavaScriptMethode verfügt.
JimEvans
51

Ich bevorzuge eine Erweiterungsmethode, um das Skriptobjekt abzurufen:

public static IJavaScriptExecutor Scripts(this IWebDriver driver)
{
    return (IJavaScriptExecutor)driver;
}

Verwendet wie folgt:

driver.Scripts().ExecuteScript("some script");
Morten Christiansen
quelle
Selen sollte dies standardmäßig haben
Kolob Canyon
13

Wie wäre es mit einer leicht vereinfachten Version von @Morten Christiansens netter Idee für eine Erweiterungsmethode:

public static object Execute(this IWebDriver driver, string script)
{
    return ((IJavaScriptExecutor)driver).ExecuteScript(script);
}

// usage
var title = (string)driver.Execute("return document.title");

oder vielleicht die generische Version:

public static T Execute<T>(this IWebDriver driver, string script)
{
    return (T)((IJavaScriptExecutor)driver).ExecuteScript(script);
}

// usage
var title = driver.Execute<string>("return document.title");
agentnega
quelle
1
Kann dies auch verwendet werden, um WebElement und Bool zu erhalten?
Rahoolm
12

Das Nuget-Paket Selenium.Supportenthält bereits eine Erweiterungsmethode, um dies zu unterstützen. Sobald es enthalten ist, ein Liner zum Executer-Skript

  Driver.ExecuteJavaScript("console.clear()");

oder

  string result = Driver.ExecuteJavaScript<string>("console.clear()");
harishr
quelle
Dies ist eine schöne, moderne Lösung. Die Erweiterungsmethode fügt eine Validierung hinzu, die der Treiber implementiert, IJavaScriptExecutorund gibt eine bessere Ausnahmemeldung aus, wenn der Rückgabetyp null ist, wenn er nicht in den gewünschten Rückgabetyp umgewandelt werden soll oder kann.
Jeffrey LeCours
was ist das Driver? VS kann das nicht erkennen
Anatol
Hast du das Nuget installiert?
Harishr
8

Sie könnten auch tun:

public static IWebElement FindElementByJs(this IWebDriver driver, string jsCommand)
{
    return (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(jsCommand);
}

public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand, int timeoutInSeconds)
{
    if (timeoutInSeconds > 0)
    {
        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        wait.Until(d => d.FindElementByJs(jsCommand));
    }
    return driver.FindElementByJs(jsCommand);
}

public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand)
{
    return FindElementByJsWithWait(driver, jsCommand, s_PageWaitSeconds);
}
Perryzheng
quelle
2
Gute Idee. Für andere, die dies lesen, sollte Ihr Javascript-Code ein DOM-Element zurückgeben.
Joel und
Ich habe das nicht einmal für möglich gehalten. Dies ist enorm, da ich jetzt eine Methode mit Javascript erstellen kann, um nextSibling zurückzugeben.
Jibbs
1
public void javascriptclick(String element)
    { 
        WebElement webElement=driver.findElement(By.xpath(element));
        JavascriptExecutor js = (JavascriptExecutor) driver;

        js.executeScript("arguments[0].click();",webElement);   
        System.out.println("javascriptclick"+" "+ element);

    }
Akhilesh Gulati
quelle
0
public static class Webdriver
{        
    public static void ExecuteJavaScript(string scripts)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        js.ExecuteScript(scripts);
    }

    public static T ExecuteJavaScript<T>(string scripts)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        return (T)js.ExecuteScript(scripts);
    }
}

In Ihrem Code können Sie dann tun

string test = Webdriver.ExecuteJavaScript<string>(" return 'hello World'; ");
int test = Webdriver.ExecuteJavaScript<int>(" return 3; ");
Mo D Genesis
quelle
0

Der kürzeste Code

ChromeDriver drv = new ChromeDriver();

drv.Navigate().GoToUrl("/programming/6229769/execute-javascript-using-selenium-webdriver-in-c-sharp");

drv.ExecuteScript("return alert(document.title);");

Ebubekir Bastama
quelle