Esegui JavaScript utilizzando Selenium WebDriver in C #


103

Come si ottiene questo? Qui dice che la versione java è:

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

Ma non riesco a trovare il codice C # per farlo.

Risposte:


216

I nomi di oggetto, metodo e proprietà nei collegamenti del linguaggio .NET non corrispondono esattamente a quelli nei collegamenti Java. Uno dei principi del progetto è che ogni associazione linguistica dovrebbe "sembrare naturale" a coloro che si sentono a proprio agio nel programmare in quella lingua. In C #, il codice che desideri per eseguire JavaScript è il seguente

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

Si noti che la documentazione completa dell'API WebDriver per .NET è disponibile a questo collegamento .


10
NOTA le maiuscole nella parola Java S cript. Questo mi ha colto di sorpresa.
Dov'è il

1
La risposta di Jim è quanto più autorevole puoi ottenere. Controlla la cronologia dei commit su, beh, ogni file Selenium .NET :-)
Ross Patterson

Potresti dirmi come fare clic su un pulsante in C #? Risposte come arguments[0].click();se non funzionasse per me? Non ho eccezioni quando eseguo il mio codice, ma non fa clic sul pulsante.
Almett

Trovo imbarazzante dover lanciare il driver. Perché ExecuteJavascriptnon è solo un metodo sul driver?
Kolob Canyon,

Questo è un residuo di un tempo in cui non tutte le implementazioni dei driver supportano l'esecuzione di JavaScript arbitrario. I collegamenti .NET, come quelli Java, utilizzano interfacce basate sui ruoli per modellare funzionalità che possono essere supportate da un driver, ma non da tutti. Nell'assembly di supporto ( WebDriver.Support.dll, disponibile tramite NuGet nel Selenium.Supportpacchetto), c'è un metodo di estensione che gestisce il casting per te e fa sembrare che il driver abbia un ExecuteJavaScriptmetodo.
JimEvans

51

Preferisco utilizzare un metodo di estensione per ottenere l'oggetto scripts:

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

Usato come questo:

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

Il selenio dovrebbe avere questo per impostazione predefinita
Kolob Canyon,

13

Che ne dici di una versione leggermente semplificata della simpatica idea del metodo di estensione di @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 forse la versione generica:

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
Può essere utilizzato anche per ottenere WebElement e bool?
rahoolm

12

il pacchetto nuget Selenium.Supportcontiene già un metodo di estensione per aiutare con questo. Una volta incluso, una riga per eseguire lo script

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

o

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

Questa è una bella soluzione moderna. Il metodo di estensione aggiunge la convalida che il driver implementa IJavaScriptExecutore fornisce un messaggio di eccezione migliore se il tipo restituito è nullo quando non dovrebbe essere o non può essere eseguito il cast al tipo restituito desiderato.
Jeffrey LeCours

qual è il Driver? VS non può riconoscerlo
anatol

Hai installato il nuget ??
harishr

8

Potresti anche fare:

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
Bella idea. Per gli altri che leggono questo, il tuo codice javascript dovrebbe restituire un elemento DOM.
joelsand

Non l'ho nemmeno considerato possibile. Questo è enorme in quanto ora posso creare un metodo utilizzando javascript per restituire 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);
    }
}

Nel tuo codice puoi quindi fare

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

0

Il codice più breve

ChromeDriver drv = new ChromeDriver();

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

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.