Exécuter JavaScript à l'aide de Selenium WebDriver en C #

103

Comment cela est-il réalisé? Ici, il est dit que la version java est:

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

Mais je ne trouve pas le code C # pour faire cela.

JontyMC
la source

Réponses:

216

Les noms d'objet, de méthode et de propriété dans les liaisons de langage .NET ne correspondent pas exactement à ceux des liaisons Java. L'un des principes du projet est que chaque liaison de langue doit «se sentir naturelle» pour ceux qui sont à l'aise avec le codage dans cette langue. En C #, le code que vous souhaitez pour exécuter JavaScript est le suivant

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

Notez que la documentation complète de l'API WebDriver pour .NET se trouve sur ce lien .

JimEvans
la source
10
Notez la majuscule dans le mot Java S cript. Cela m'a surpris.
Wheretheresa:
1
La réponse de Jim est à peu près aussi fiable que possible. Consultez l'historique des commit sur, eh bien, chaque fichier Selenium .NET :-)
Ross Patterson
Pouvez-vous me dire comment cliquer sur un bouton en C #? Des réponses comme ça arguments[0].click();ne marche pas pour moi? Je n'ai aucune exception lorsque j'exécute mon code, mais il ne clique pas sur le bouton.
Almett
Je trouve gênant de devoir lancer le pilote. Pourquoi n'est ExecuteJavascriptpas juste une méthode sur le driver?
Kolob Canyon
C'est un vestige d'une époque où toutes les implémentations de pilote ne prenaient pas en charge l'exécution de JavaScript arbitraire. Les liaisons .NET, comme celles de Java, utilisent des interfaces basées sur les rôles pour modéliser les fonctionnalités qui peuvent être prises en charge par un pilote, mais pas toutes. Dans l'assembly Support ( WebDriver.Support.dll, disponible via NuGet dans le Selenium.Supportpackage), il existe une méthode d'extension qui gère le cast pour vous et donne l'impression que le pilote a une ExecuteJavaScriptméthode.
JimEvans
51

Je préfère utiliser une méthode d'extension pour obtenir l'objet scripts:

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

Utilisé comme ceci:

driver.Scripts().ExecuteScript("some script");
Morten Christiansen
la source
Le sélénium devrait l'avoir par défaut
Kolob Canyon
13

Que diriez-vous d'une version légèrement simplifiée de la belle idée de méthode d'extension 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");

ou peut-être la version générique:

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
la source
1
Cela peut-il également être utilisé pour obtenir WebElement et bool?
rahoolm
12

le paquet nuget Selenium.Supportcontient déjà une méthode d'extension pour vous aider. Une fois qu'il est inclus, une doublure pour exécuter le script

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

ou

  string result = Driver.ExecuteJavaScript<string>("console.clear()");
harishr
la source
C'est une belle solution moderne. La méthode d'extension ajoute la validation que le pilote implémente IJavaScriptExecutoret donne un meilleur message d'exception si le type de retour est nul alors qu'il ne devrait pas ou ne peut pas être converti en type de retour souhaité.
Jeffrey LeCours
quel est le Driver? VS ne peut pas reconnaître cela
anatol
Avez-vous installé le nuget ??
harishr le
8

Vous pouvez également faire:

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
la source
2
Bonne idée. Pour les autres lisant ceci, votre code javascript doit renvoyer un élément DOM.
joelsand
Je n'ai même pas considéré cela comme possible. C'est énorme car je peux maintenant créer une méthode en utilisant javascript pour renvoyer 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
la source
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);
    }
}

Dans votre code, vous pouvez alors faire

string test = Webdriver.ExecuteJavaScript<string>(" return 'hello World'; ");
int test = Webdriver.ExecuteJavaScript<int>(" return 3; ");
Mo D Genèse
la source
0

Le code le plus court

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
la source