在Selenium IDE中我們可以使用runScript命令去執行js代碼片段,以輔助完成一些Selenium不方便達成的任務,同樣,在WebDriver中我們也可以使用JavascriptExecutor工具類去完成js代碼執行,下面詳細闡述該工具的使用及工作原理。
1. JavascriptExecutor執行js代碼的兩種方法介紹。
Object executeScript(String script, Object... args);
Object executeAsyncScript(String script, Object... args);
前一個是異步執行js,後一個是同步執行js
executeScript方法接收兩個參數和一個返回值:
script,javascript代碼片段,這段js代碼片段是作爲js函數的完整方法體,可以使用return語句作爲函數的返回值。
args, 參數數組,參數數組用於將外部數據傳遞給script(js代碼片段),script中可以通過arguments[index]方式索引args數組中的參數;參數數據類型必須是以下幾種(number, boolean, String, WebElement, 或者以上數據類型的List集合),當然無參數可以保留爲空。
返回值,返回值是由js代碼片段計算後通過return語句返回,返回值數據類型可以爲(WebElement,Double,Long,Boolean,String,List或Map),沒有return語句,這裏返回數據爲null。
executeAsyncScript方法接收兩個參數和一個返回值:
script,javascript代碼片段,這段js代碼片段是作爲js函數的完整方法體,與executeScript主要有兩點不同:
1. 此處的script必須在代碼結束時明確調用callback方法以通知webdriver該script執行結束;該callback方法是由webdriver注入到arguments數組中最後一個元素;可以通過arguments[arguments.length-1]獲取到,且可以使用該回調函數返回計算結果(只需要將放回結果作爲回調函數的參數即可)
2. 該script執行會有超時時間,默認爲60s,超時時間內未調用callback方法,JavascriptExecutor會拋出Timeout異常。
args, 規則同executeScript。
返回值,規則同executeScript
2. JavascriptExecutor執行js代碼的使用示例。
對js代碼不熟悉,可以打開瀏覽器-->按F12-->點擊Console-->輸入document或window,後面會聯想一些方法,選擇來試驗一下
下面介紹幾種常用的js執行方法:
①、使用js執行打開https://www.baidu.com功能
一、使用js執行打開https://www.baidu.com功能
js=(JavascriptExecutor)driver;
js.executorScript("window.location='https://www.baidu.com';");
或者直接如下使用;只是可讀性有點差
((JavascriptExecutor) driver).executeScript("window.location='https://www.baidu.com';");
②、通過js查找元素功能
js=(JavascriptExecutor)driver;
return返回的是通過id查找的元素,所以是webElement類型接收
WebElement el=(WebElement) js.executeScript("return document.getElementById('kw');");
el.sendKeys("javascript");
js查找元素的方法還有:getElementsByXxx,
getElementByXxx返回的是webElement,getElementsByXxx返回的是list<WebElement>,例:
js=(JavascriptExecutor)driver;
//打開瀏覽器,輸入百度網址
js.executorScript("window.location='https://www.baidu.com';");
List<WebElement> els = (List<WebElement>) js.executorScript("return document.getElementsByName('kw');");
//因爲上面找到的是一個list,但同時又只有一個元素,
els.get(0).sendkeys("selenium");
③通過js直接set輸入框的值,如下方式也能實現對文本框的輸入,這是對sendKey方法的補充
WebElment el=(WebElement) js.executeScript("reture document.getElementById('kw');");
js.executeScript("arguments[0].value='selenium'", el);
④js執行點擊操作
WebElment el2=(WebElement) js.executeScript("reture document.getElementById('su');");
js.executeScript("arguments[0].click();",el2);
⑤js執行頁面滾動操作
js.executorScript("window.location='http://www.migang.com';");
//向下滾動
js.executeScript("window.scrollBy(0,1900);");
Thread.sleep(2000);
//向上滾動,注意裏面的值,也就是縱橫座標
js.executeScript("window.scrollBy(0,-1900);");
Thread.sleep(2000);
//定位的元素
WebElement element = driver.findElement(By.xpath("//span[contains(text(),'米缸公告')]"));
Thread.sleep(2000);
// js滾動到出現元素的位置
js.executeScript("arguments[0].scrollIntoView(true);",element);
// 這裏向上滾一點,避免上面的元素被其他樣式遮住,導致後面元素操作錯誤。
js.executeScript("window.scrollBy(0,-300);");
3. JavascriptExecutor執行js的原理。
如何理解JavascriptExecutor如何運行js代碼,需要對javascript基礎有一定的認識,首先給大家羅列兩個javascript中三種定義和調用函數的示例,大家看完示例就不難理解webdriver是如何去運行javascript代碼了,同時也能消除(爲何在javascript中使用arguments來接收方法傳入的參數)的困惑。
第一種函數定義方式:
function sum(a, b) {
return a+b;
}
sum(2,3); //輸出5
第二種函數定義方式:
var sum = new Function('a', 'b', 'return a+b;');
sum(2,3) //輸出5
第二種方式我們可以改寫爲:
new Function('a', 'b', 'return arguments[0]+arguments[1]').apply(null,[1,2]); //輸出5
當然函數的定義不限於以上三種寫法,我們這裏重點講解第二種和第三種方法,相信大家在看到這兩種使用方式時,已經理解webdriver是如何調用js代碼了,但還會疑惑爲什麼會使用arguments來接收參數。
我們所有定義的function實質上是對Function類的實現,而Functions類的定義中arguments作爲局部變量,通過arguments索引接收所有參數,即使在方法定義中未指定的參數,大家來看下面的代碼示例:
function add(a) {
var sum =0,
len = arguments.length;
for(var i=0; i<len; i++){
sum += arguments[i];
}
return sum;
}
add(1,2,3,4); //10
參考: