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

103

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

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

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

JontyMC
источник

Ответы:

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; ");
Mo D Genesis
источник
0

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

ChromeDriver drv = new ChromeDriver();

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

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

Эбубекир Бастама
источник