Thực thi JavaScript bằng Selenium WebDriver trong C #


103

Làm thế nào điều này đạt được? Ở đây nó cho biết phiên bản java là:

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

Nhưng tôi không thể tìm thấy mã C # để thực hiện việc này.

Câu trả lời:


216

Tên đối tượng, phương thức và thuộc tính trong liên kết ngôn ngữ .NET không hoàn toàn tương ứng với những tên trong liên kết Java. Một trong những nguyên tắc của dự án là mỗi ràng buộc ngôn ngữ phải "cảm thấy tự nhiên" với những người viết mã thoải mái bằng ngôn ngữ đó. Trong C #, mã bạn muốn thực thi JavaScript như sau

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

Lưu ý rằng bạn có thể tìm thấy tài liệu đầy đủ về API WebDriver cho .NET tại liên kết này .


10
LƯU Ý cách viết hoa trong từ Java S cript. Điều này đã khiến tôi bị cuốn hút.
WheretheresaWill

1
Câu trả lời của Jim có thẩm quyền như bạn có thể nhận được. Kiểm tra lịch sử cam kết trên mọi tệp Selenium .NET :-)
Ross Patterson

Bạn có thể vui lòng cho tôi biết cách nhấp vào một nút trong C # không? Các câu trả lời như arguments[0].click();không phù hợp với tôi? Tôi không có ngoại lệ khi tôi thực thi mã của mình, nhưng nó không nhấp vào nút.
Almett

Tôi thấy thật khó xử khi phải ép tài xế. Tại sao ExecuteJavascriptkhông chỉ là một phương pháp trên driver?
Kolob Canyon

Đó là phần còn sót lại từ thời không phải mọi triển khai trình điều khiển đều hỗ trợ thực thi JavaScript tùy ý. Các ràng buộc .NET, giống như các liên kết Java sử dụng giao diện dựa trên vai trò để mô hình hóa chức năng có thể được hỗ trợ bởi một trình điều khiển, nhưng không phải tất cả. Trong hợp ngữ Hỗ trợ ( WebDriver.Support.dll, có sẵn qua NuGet trong Selenium.Supportgói), có một phương thức mở rộng xử lý quá trình truyền cho bạn và làm cho nó trông giống như trình điều khiển có một ExecuteJavaScriptphương thức.
JimEvans

51

Tôi thích sử dụng một phương thức mở rộng để lấy đối tượng script:

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

Được sử dụng như sau:

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

Selenium nên có này theo mặc định
Kolob Canyon

13

Còn về một phiên bản đơn giản hơn một chút của ý tưởng về phương pháp mở rộng hay ho của @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");

hoặc có thể là phiên bản chung:

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
Điều này có thể được sử dụng để tải WebElement và bool không?
rahoolm

12

gói nuget Selenium.Supportđã chứa một phương thức mở rộng để trợ giúp việc này. Khi nó được bao gồm, một lớp lót cho tập lệnh thực thi

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

hoặc là

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

Đây là một giải pháp tốt, hiện đại. Phương thức mở rộng bổ sung xác thực mà trình điều khiển thực hiện IJavaScriptExecutorvà đưa ra một thông báo ngoại lệ tốt hơn nếu kiểu trả về là null khi nó không nên hoặc không thể được chuyển thành kiểu trả về mong muốn.
Jeffrey LeCours

là gì Driver? VS không thể nhận ra điều đó
anatol 27/09/18

Bạn đã cài đặt nuget chưa ??
harishr 27/09/18

8

Bạn cũng có thể làm:

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
Ý kiến ​​hay. Đối với những người khác đọc nội dung này, mã javascript của bạn phải trả về một phần tử DOM.
joelsand

Tôi thậm chí đã không coi điều này là có thể. Điều này rất lớn vì bây giờ tôi có thể tạo một phương thức sử dụng javascript để trả về 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);
    }
}

Trong mã của bạn, sau đó bạn có thể làm

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

0

Mã ngắn nhất

ChromeDriver drv = new ChromeDriver();

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

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.