執行js-----Selenium快速入門(十四)


  Selenium能夠執行js,這使得Selenium擁有更為強大的能力。既然能執行js,那么js能做的事,Selenium應該大部分也能做。這應該得益於JavascriptExecutor這個接口,而ChromeDriverEdgeDriverEventFiringWebDriverFirefoxDriverInternetExplorerDriverOperaDriverRemoteWebDriverSafariDriver均實現了這個接口。跟使用WebDriver一樣,我們可以這樣使用該接口: 

 WebDriver driver=new ChromeDriver();
 JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;

  該接口十分簡單,只有兩個方法:

  1.java.lang.Object executeScript(java.lang.String script, java.lang.Object... args)   同步執行js

  2.java.lang.Object executeAsyncScript(java.lang.String script, java.lang.Object... args)  異步執行js

  對於返回值:

  1.如果js返回的是html元素,那么方法返回WebElement

  2.如果js返回的是小數,方法返回Double

  3.如果js返回的是非小數,方法返回Long

  4.如果js返回的是布爾,方法返回Boolean

  5.如果js返回的是其他,方法返回String

  6.如果js返回的是數組,方法返回List<Object>,可以嵌套,Object的值的類型是根據上面5條而定。

  7.如果js返回的是map,方法返回Map<String, Object>,Object值類型的定義同上。

  8.如果js返回null或沒有返回,方法返回null

 

  對於 arg參數:

  js會用一個“魔法”變量arguments來接收。參數的類型可以是:數字,布爾,字符串,元素(WebElement)以及List<Object>,Object類型為上述類型

 

  下面通過一些簡單的例子,來說明用法

  首先,我們在項目的html文件夾增加一個空白的html文件,jsTest.html

  html的代碼如下:這是一個空白的html

<html>
<head>

</head>

<body>

</body>

</html>

  我們的代碼:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //調用js,彈出信息
        ((JavascriptExecutor) driver).executeScript("alert('hello,selenium');");

  執行的效果如下:

  

  是不是非常簡單,我們嘗試使用帶有參數的調用:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //調用js,"11111","22222"等參數將會被arguments接收,成為一個數組,此處arguments[0]表示調用第一個參數
        ((JavascriptExecutor) driver).executeScript("alert(arguments[0]);","1111111","222222");

 

  執行的效果:

  

 

   我們再修改一下jsTest.html,增加一個js方法,代碼如下:

<html>
<head>
    <script>
        function sayHello()
        {
            alert("hi,Selenium");
        }
    </script>
</head>

<body>

</body>

</html>

  調用的java改成如下:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //調用頁面上的方法
        ((JavascriptExecutor) driver).executeScript("sayHello()");

  發現依然可以執行成功,效果如下:

  對於異步執行,使用的方法是類似的。更詳細的可參考官網:http://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html

  但是對於異步執行,Selenium提供了一個時間限制的方法:

  WebDriver.Timeouts setScriptTimeout(long time, java.util.concurrent.TimeUnit unit)

  該方法是針對 executeAsyncScript 方法的執行,對executeScript無效。官方的文檔說: If the timeout is negative, then the script will be allowed to run indefinitely.如果timeout的時間設為負數,表示不限執行時間,但我發現,設置為負數,一樣會拋出異常(當然,官方沒有說不會拋出異常,但拋出異常后,后面的代碼就無法執行,除非自己去捕捉這個異常進行額外的處理)。 

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
       
        //設置超時時間為-1秒
        driver.manage().timeouts().setScriptTimeout(-1, TimeUnit.SECONDS);
        
        JavascriptExecutor js=(JavascriptExecutor) driver;
        //3秒后執行
        js.executeAsyncScript("setTimeout(\"alert('本信息3秒后彈出!')\",3000)");

  3秒后,js依然能彈出框,但之前就已經先拋出異常。也就是說,超時並未停止js的執行,只是拋出異常。

    異常信息為:Exception in thread "main" org.openqa.selenium.ScriptTimeoutException:asynchronous script timeout: result was not received in -1 seconds

  如果將超時時間設置為3或以上,則js能順利執行,並且不會拋出異常。

  如果是executeScript,則無論setScriptTimeout如何設置,都不會對它有任何影響。

    當然,我們一般不會將超時時間設為負數,否則無任何意義,這里只是想驗證一下官方的說法而已,結果說明與官方文檔的說法稍有些出入。所以,如果想使設置異步腳本超時的這句代碼無效,最好的方法還是將它注釋掉,而非將超時時間改成負數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM