Wykonaj JavaScript przy użyciu Selenium WebDriver w C #

103

Jak to się osiąga? Tutaj jest napisane, że wersja java to:

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

Ale nie mogę znaleźć kodu C #, aby to zrobić.

JontyMC
źródło

Odpowiedzi:

217

Nazwy obiektów, metod i właściwości w powiązaniach języka .NET nie odpowiadają dokładnie tym w powiązaniach Java. Jedną z zasad projektu jest to, że każde powiązanie języka powinno być „naturalne” dla tych, którzy potrafią programować w tym języku. W języku C # kod, który chcesz wykonać do wykonywania JavaScript, jest następujący

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

Należy zwrócić uwagę, że pełną dokumentację interfejsu API WebDriver dla platformy .NET można znaleźć pod tym łączem .

JimEvans
źródło
10
UWAGA na wielkie litery w słowie Java S cript. To mnie zaskoczyło.
Wheretheresa Will
1
Odpowiedź Jima jest tak autorytatywna, jak tylko możesz. Sprawdź historię zmian w każdym pliku Selenium .NET :-)
Ross Patterson
Czy mógłbyś mi powiedzieć, jak kliknąć przycisk w C #? Odpowiedzi typu arguments[0].click();nie działają dla mnie? Nie mam wyjątku, kiedy wykonuję kod, ale nie klikam przycisku.
Almett
Uważam za niezręczne, że muszę obsadzić kierowcę. Dlaczego ExecuteJavascriptnie jest to tylko metoda driver?
Kolob Canyon
To pozostałość z czasów, gdy nie każda implementacja sterownika obsługiwała wykonywanie dowolnego kodu JavaScript. Powiązania .NET, podobnie jak te w języku Java, wykorzystują interfejsy oparte na rolach do modelowania funkcji, które mogą być obsługiwane przez jeden sterownik, ale nie wszystkie. W zestawie pomocy technicznej ( WebDriver.Support.dlldostępnym za pośrednictwem Selenium.Supportpakietu NuGet w pakiecie) istnieje metoda rozszerzenia, która obsługuje rzutowanie i sprawia, że ​​wygląda na to, że sterownik ma ExecuteJavaScriptmetodę.
JimEvans
51

Wolę użyć metody rozszerzenia, aby uzyskać obiekt skryptów:

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

Używany w ten sposób:

driver.Scripts().ExecuteScript("some script");
Morten Christiansen
źródło
Selen powinien mieć to domyślnie
Kolob Canyon
13

Co powiesz na nieco uproszczoną wersję pomysłu na ładną metodę rozszerzenia @Morten Christiansen:

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

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

a może wersja ogólna:

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
źródło
1
Czy można tego użyć do pobrania WebElement i bool?
rahoolm
12

pakiet NuGet Selenium.Supportzawiera już metodę rozszerzenia, która pomaga w tym. Po dołączeniu jedna linijka do skryptu wykonawczego

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

lub

  string result = Driver.ExecuteJavaScript<string>("console.clear()");
harishr
źródło
To ładne, nowoczesne rozwiązanie. Metoda rozszerzająca dodaje walidację implementowaną przez sterownik IJavaScriptExecutori zapewnia lepszy komunikat o wyjątku, jeśli typ zwracany jest null, gdy nie powinien lub nie może być rzutowany na żądany typ zwracany.
Jeffrey LeCours
co to jest Driver? VS nie może tego rozpoznać
anatol
Czy zainstalowałeś nuget?
harishr
8

Możesz też:

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
źródło
2
Dobry pomysł. Dla innych, którzy to czytają, Twój kod javascript powinien zwrócić element DOM.
joelsand
Nawet nie uważałem tego za możliwe. To jest ogromne, ponieważ mogę teraz utworzyć metodę przy użyciu javascript, aby zwrócić nextSibling.
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
źródło
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);
    }
}

W swoim kodzie możesz to zrobić

string test = Webdriver.ExecuteJavaScript<string>(" return 'hello World'; ");
int test = Webdriver.ExecuteJavaScript<int>(" return 3; ");
Mo D Genesis
źródło
0

Najkrótszy kod

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
źródło