天天看點

Selenium WebDriver之JavaScript

webdriver提供了方法來同步/異步執行javascript代碼,這是因為javascript可以完成一些webdriver本身所不能完成的功能,進而讓webdriver更加靈活和強大。

  本文中所提到的都是java代碼。

  1. 在webdriver中如何執行javascript代碼

  javascript代碼總是以字元串的形式傳遞給webdriver,不管你的javascript代碼是一行還是多行,webdriver都可以用executescript方法來執行字元串中包含的所有javascript代碼。

  webdriver driver = new firefoxdriver();

  javascriptexecutor driver_js=(javascriptexecutor)driver;

  string js = "alert(\"hello world!\");";

  driver_js.executescript( js);

  2.同步執行javascript和異步執行javascript的差別

  同步執行:driver_js.executescript( js)

  如果javascript代碼的執行時間較短,可以選擇同步執行,因為webdriver會等待同步執行的結果,然後再運作其它的代碼。

  異步執行:driver_js.executeasyncscript(js)

  如果javascript代碼的執行時間較長,可以選擇異步執行,因為webdriver不會等待其執行結果,而是直接執行下面的代碼。

  3. 用javascript實作等待頁面加載的功能

  public void waitforpageload() {

  while(driver_js.executescript("return document.readystate" ).equals ("complete")){

  thread.sleep(500);

  }

  這樣做的缺點是,沒有設定timeout時間,如果頁面加載一直不能完成的話,那麼代碼也會一直等待。當然你也可以為while循環設定循環次數,或者直接采用下面的代碼:

protected function<webdriver, boolean> ispageloaded() {

return new function<webdriver, boolean>() {

@override

public boolean apply(webdriver driver) {

return ((javascriptexecutor) driver).executescript("returndocument.readystate").equals("complete");

}

};

public voidwaitforpageload() {

webdriverwait wait = new webdriverwait(driver, 30);

wait.until(ispageloaded());

  需要指出的是單純的javascript是很難實作等待功能的,因為javascript的執行是不阻塞主線程的,你可以為指定代碼的執行設定等待時間,但是卻無法達到為其它webdriver代碼設定等待時間的目的。有興趣的同學可以研究一下。

  4. javascrpt模拟點選操作,并觸發相應事件

  string js ="$(\"button.ui-multiselect.ui-widget\").trigger(\"focus\");"

  +"$(\"button.ui-multiselect.ui-widget\").click();"

  +"$(\"button.ui-multiselect.ui-widget\").trigger(\"open\");";

  ((javascriptexecutor)driver).executescript( js);

  5. javacript scrollbar的操作

  string js ="var obj = document.getelementsbyid(\“div_scroll\”);”

  +”obj.scrolltop= obj.scrollheight/2;”

  ((javascriptexecutor)driver).executescript(js);

6. javascript重寫confirm

  string js ="window.confirm = function(msg){ return true;}”

  通過執行上面的js,該頁面上所有的confirm将都不再彈出。

  7. 動态載入jquery

  并不是所有的網頁都引入了jquery,如果我們要在這些網頁上執行jquery代碼,就必須動态加載jquery source檔案

  driver.get("file:///c:/test.html");

  boolean flag =(boolean)(driver_js).executescript("return typeof jquery =='undefined'");

  if (flag)

  {

  driver_js.executescript("var jq =document.createelement('script');"

  + "jq.type ='text/javascript'; "

  +"jq.src ='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';"

  +"document.getelementsbytagname('head')[0].appendchild(jq);");

  thread.sleep(3000);

  waiter.waitforpageload();

  driver_js.executescript("$(\"input#testid\").val(\"test\");");

  8. 判斷元素是否存在

  可以通過下面的辦法來判斷頁面元素是否存在,但是缺點就是如果元素不存在,必須在抛出exception後才能知道,是以會消耗一定的時間(需要逾時後才會抛出異常)。

boolean elementexist(by locator){

try{

driver.findelement(locator);

return true;

catch(org.openqa.selenium.nosuchelementexception ex)

{

return false;

  也許我們可以在javascript中判斷頁面元素是否存在,然後再将結果傳回給webdriver的java代碼。

  頁面元素

  string js =" if(document.getelementbyid("xxx")){ return true; } else{ return false; }”

  string result = ((javascriptexecutor)driver).executescript(js);

  或者

  表單元素

  string js =" if(document.theform.###){return true; } else{ return false; }”

  9. 結尾

  javascript在webdriver中還可以做很多事情,但這還不是全部。比如,我們是否可以編寫代碼來監視在整個webdrvier測試代碼運作過程是否産生過javascripterror呢,答案是肯定的,有興趣的同學可以深入研究一下。

最新内容請見作者的github頁:http://qaseven.github.io/