某些特殊情況下,使用selenium的api無法操作頁面元素,點擊、滾動實現的某些功能,可以考慮通過執行js來完成。
為什么不用js寫自動化?——selenium第一版是js寫的,但js兼容性存在問題,所以引入webdriver 現在有用node.js做的cypress框架
一、方法解釋:
executeScript(String script, Object... args);
第一個參數:script 腳本 在瀏覽器console里可直接輸入的js語句
第二個參數:Object... args 可變參數 (0 - n)個; 把args的值傳給前面js腳本,
參數可以是:定位到的定位方式/元素/屬性...
1、使用方式1——不傳參:Object... args為0
JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;//這里也可以不用強轉,因為多態
jsExecutor.executeScript("...");
2、使用方式2——傳參:Object... args個數多個 從arguments[0]開始,arguments[1],arguments[2]......
3、舉例:比如需要刪除12306時間窗口的只讀屬性readonly
//把driver轉換成js對象
JavascriptExecutor jsExexutor = driver;方法一:Object... arg:不傳參數,只有一個js腳本//定義js代碼String js = "document.getElementById(\"train_date\").removeAttribute(\"readonly\")";jsExexutor.executeScript(js);Thread.sleep(2000);driver.findElementById("train_date").sendKeys("123432432");方式二(1):Object... args: 傳一個參數//js腳本中1個占位符String js = "arguments[0].removeAttribute(\"readonly\")";WebElement elementByXPath = driver.findElementByXPath("input[@id='train_date']");jsExexutor.executeScript(js,elementByXPath);方式二(2):Object... args: 傳兩個參數//js腳本中兩個占位符String js = "arguments[0].removeAttribute(arguments[1])";WebElement elementByXPath = driver.findElementByXPath("//input[@id='train_date']");jsExexutor.executeScript(js,elementByXPath,"readonly");driver.findElementById("train_date").sendKeys("123432432");
?二、使用場景:
1 、設置/去除元素屬性
setAttribute/removeAttribute
案例:如上12306時間選擇框
2、?頁面滾動
-
window.scrollTo(0, document.body.scrollHeight) 滾動到頁面最底部
-
window.scrollTo(0, 0) 豎向滾動條置頂
-
window.scrollTo(x-橫坐標,y-縱坐標 )
-
-
element.scrollIntoViewIfNeeded(true) 滾動到指定元素的位置 需要結合js參數來使用
jsExexutor.executeScript("window.scrollTo(0, document.body.scrollHeight+100)");
3、元素無法被點擊,用js可以操作
ElementClickInterceptedException: element click intercepted——元素點擊攔截
Element is not clickable at point ,Other element would receive the click
有時候元素被父節點擋住,通過driver/手動無法點擊,可通過js腳本執行,它不同于驅動driver執行,所以js可以執行
舉例:?
driver.get("https://www.ketangpai.com/");
driver.manage().window().maximize();//?下面這行代碼點擊被攔截 這句代碼是通過驅動driver執行(類似手動操作)——實際是因為被它父節點攔截掉了
driver.findElementByXPath("//span[text()='登錄']").click();//??js代碼,通過js腳本執行,不同于上述的驅動driver執行,所以js可以執行
WebElement element = driver.findElementByXPath("//span[text()='登錄']");
JavascriptExecutor javascriptExecutor = driver;
javascriptExecutor.executeScript("arguments[0].click()",element);