Выполнение JavaScript с помощью Selenium WebDriver на C #


103

Как этого добиться? Здесь говорится, что версия java:

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

Но я не могу найти для этого код C #.

Ответы:


217

Имена объектов, методов и свойств в привязках языка .NET не совсем соответствуют именам в привязках Java. Один из принципов проекта заключается в том, что каждая языковая привязка должна «казаться естественной» тем, кто умеет писать на этом языке. В C # код, который вам нужен для выполнения JavaScript, выглядит следующим образом

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

Обратите внимание, что полную документацию по API WebDriver для .NET можно найти по этой ссылке .


10
ОБРАТИТЕ ВНИМАНИЕ на заглавные буквы в слове Java S cript. Это меня зацепило.
WheretheresaWill

1
Ответ Джима настолько авторитетен, насколько это возможно. Ознакомьтесь с историей коммитов, ну, ну, в общем, каждого файла Selenium .NET :-)
Росс Паттерсон

Не могли бы вы рассказать мне, как нажимать кнопку в C #? Ответы вроде arguments[0].click();у меня не работают? У меня нет исключений, когда я выполняю свой код, но он не нажимает кнопку.
Almett

Мне неловко, что мне приходится бросать драйвер. Почему ExecuteJavascriptне просто метод driver?
Каньон Колоб

Это пережиток того времени, когда не каждая реализация драйвера поддерживала выполнение произвольного JavaScript. Привязки .NET, как и привязки Java, используют интерфейсы на основе ролей для моделирования функций, которые могут поддерживаться одним драйвером, но не всеми. В сборке Support ( WebDriver.Support.dllдоступной через NuGet в Selenium.Supportпакете) есть метод расширения, который обрабатывает преобразование за вас и делает его похожим на драйвер, имеющий ExecuteJavaScriptметод.
JimEvans

51

Я предпочитаю использовать метод расширения для получения объекта скрипта:

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

Используется как это:

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

У Selenium это должно быть по умолчанию
Каньон Колоб

13

Как насчет слегка упрощенной версии красивой идеи метода расширения @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");

или, может быть, общая версия:

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
Можно ли это использовать для получения WebElement и bool?
rahoolm

12

пакет nuget Selenium.Supportуже содержит метод расширения, помогающий в этом. Как только он будет включен, один лайнер для выполнения скрипта

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

или

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

Это красивое современное решение. Метод расширения добавляет проверку, которую реализует драйвер, IJavaScriptExecutorи дает лучшее сообщение об исключении, если тип возвращаемого значения равен нулю, тогда как он не должен быть или не может быть приведен к желаемому типу возврата.
Джеффри ЛеКурс,

что это Driver? VS не может этого распознать
Анатол

Вы установили nuget ??
harishr

8

Вы также можете:

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
Хорошая идея. Для других, читающих это, ваш код javascript должен возвращать элемент DOM.
joelsand

Я даже не считал это возможным. Это огромно, так как теперь я могу создать метод с использованием javascript для возврата 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);
    }
}

В своем коде вы можете сделать

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

0

Самый короткий код

ChromeDriver drv = new ChromeDriver();

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.