Ejecute JavaScript usando Selenium WebDriver en C #


103

¿Cómo se logra esto? Aquí dice que la versión de Java es:

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

Pero no puedo encontrar el código C # para hacer esto.

Respuestas:


216

Los nombres de objeto, método y propiedad en los enlaces del lenguaje .NET no se corresponden exactamente con los de los enlaces Java. Uno de los principios del proyecto es que cada enlace de idioma debe "sentirse natural" para quienes se sientan cómodos codificando en ese idioma. En C #, el código que desea para ejecutar JavaScript es el siguiente

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

Tenga en cuenta que la documentación completa de la API de WebDriver para .NET se puede encontrar en este enlace .


10
NOTA las mayúsculas en la palabra Java S cript. Esto me sorprendió.
WheretheresaWill el

1
La respuesta de Jim es lo más autoritaria posible. Consulte el historial de confirmaciones en, bueno, todos los archivos .NET de Selenium :-)
Ross Patterson

¿Podría decirme cómo hacer clic en un botón en C #? ¿Respuestas como si arguments[0].click();no me funciona? No tengo ninguna excepción cuando ejecuto mi código, pero no hace clic en el botón.
Almett

Me resulta incómodo tener que lanzar el controlador. ¿Por qué ExecuteJavascriptno es solo un método en el driver?
Kolob Canyon

Eso es un vestigio de una época en que no todas las implementaciones de controladores admitían la ejecución de JavaScript arbitrario. Los enlaces .NET, como los de Java, utilizan interfaces basadas en roles para modelar la funcionalidad que puede ser compatible con un controlador, pero no con todos. En el ensamblado de Soporte ( WebDriver.Support.dlldisponible a través de NuGet en el Selenium.Supportpaquete), hay un método de extensión que maneja la conversión por usted y hace que parezca que el controlador tiene un ExecuteJavaScriptmétodo.
JimEvans

51

Prefiero usar un método de extensión para obtener el objeto scripts:

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

Usado como este:

driver.Scripts().ExecuteScript("some script");

El selenio debería tener esto por defecto
Kolob Canyon

13

¿Qué tal una versión ligeramente simplificada de la bonita idea del método de extensión de @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");

o tal vez la versión genérica:

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

1
¿Se puede usar esto para obtener WebElement y bool también?
rahoolm

12

el paquete nuget Selenium.Supportya contiene un método de extensión para ayudar con esto. Una vez que se incluye, una línea para ejecutar el script

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

o

  string result = Driver.ExecuteJavaScript<string>("console.clear()");

Esta es una solución moderna y agradable. El método de extensión agrega la validación que implementa el controlador IJavaScriptExecutory proporciona un mejor mensaje de excepción si el tipo de retorno es nulo cuando no debería ser o no se puede convertir al tipo de retorno deseado.
Jeffrey LeCours

¿cuál es el Driver? VS no puede reconocer eso
anatol

¿Has instalado el nuget?
harishr

8

También puedes hacer:

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

2
Buena idea. Para otros que lean esto, su código javascript debería devolver un elemento DOM.
joelsand

Ni siquiera consideré esto como posible. Esto es enorme, ya que ahora puedo crear un método usando javascript para devolver 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);

    }

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

En su código puede hacer

string test = Webdriver.ExecuteJavaScript<string>(" return 'hello World'; ");
int test = Webdriver.ExecuteJavaScript<int>(" return 3; ");

0

El código más corto

ChromeDriver drv = new ChromeDriver();

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

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.