Selenium 處理 modal 對話框(轉)

原文地址:http://www.myexception.cn/open-source/969585.html


Selenium目前沒有提供對IE模態對話框(即通過showModalDialog方法打開的彈出對話框)的處理。原因在於,模態對話框會將父頁面的JS掛起,直至對話框處理完畢纔會繼續執行父頁面JS。因爲Selenium的底層實現是基於JS的,所以模態對話框會同時將selenium掛起,selenium無法選中模態對話框,直至超時。

但是很多系統往往有大量的模態對話框應用。這些應用分爲兩類:一類是選人、選業務類型等操作,這些操作的目的是填充父頁面相應的字段,不會觸發其他操作;另外一類比較特殊,例如工作流的派發,這類操作在模態對話框選人返回值後還會繼續執行一系列的操作(即showModalDialog方法的調用被夾在一堆JS操作中間)。

對於第一種情況,可以在測試代碼裏建立相應的數據常量,通過直接賦值的方式避免調用showModalDialog方法;

對於第二種情況,則只能hack。


在當前的測試用例裏,採用以下的hack方法:
典型的模態對話框會在點擊一個頁面元素後打開(例如button),在第一次點擊該頁面元素時,我們對showModalDialog方法進行覆蓋,改打開模態對話框爲window.open打開網頁,並將selenium選中該彈出網頁:

Java代碼  
public void clickAndSelectModalDialog(String locator){   
clickForModalDialog(locator);   
selenium.selectWindow(“name=modal”);   
}   

private void  clickForModalDialog(String locator){   
String overrideShowModalDialogJs=="if(selenium.browserbot.getCurrentWindow().showModalDialog){";   
   
   overrideShowModalDialogJs += "selenium.browserbot.getCurrentWindow().showModalDialog = function( sURL, vArguments, sFeatures)";   
 
 overrideShowModalDialogJs +="selenium.browserbot.getCurrentWindow().open(sURL, 'modal', sFeatures);";   
  
 overrideShowModalDialogJs += "};}";   
   //showModalDialog方法進行覆蓋   
 selenium.getEval(overrideShowModalDialogJs);   
 selenium.click(locator);   
 selenium.openWindow(“”,”modal”);   
 selenium.waitForPopUp(“modal”,”15000”);   
 
 }  
public void clickAndSelectModalDialog(String locator){
    clickForModalDialog(locator);
     selenium.selectWindow(“name=modal”);
}

private void  clickForModalDialog(String locator){
    String overrideShowModalDialogJs=="if(selenium.browserbot.getCurrentWindow().showModalDialog){";

overrideShowModalDialogJs += "selenium.browserbot.getCurrentWindow().showModalDialog = function( sURL, vArguments, sFeatures)";

overrideShowModalDialogJs +="selenium.browserbot.getCurrentWindow().open(sURL, 'modal', sFeatures);";

overrideShowModalDialogJs += "};}";
//showModalDialog方法進行覆蓋
selenium.getEval(overrideShowModalDialogJs);
selenium.click(locator);
selenium.openWindow(“”,”modal”);
selenium.waitForPopUp(“modal”,”15000”);

}  


接下來就可以在彈出網頁裏進行操作,獲取需要返回給父頁面的值,這些值一般是一個數組。獲取值後關閉彈出網頁並返回父頁面。在父頁面裏再次點擊打開模態對話框的元素,對showModalDialog方法進行第二次覆蓋,將上面獲取的值直接返回。

Java代碼  
 public void  acceptModalValue(String locator,String[] values){   
   String overrideShowModalDialogJs=="if(selenium.browserbot.getCurrentWindow().showModalDialog){";   
  
 overrideShowModalDialogJs += "selenium.browserbot.getCurrentWindow().showModalDialog = function( sURL, vArguments, sFeatures)";   
 
 overrideShowModalDialogJs +="{ "+generateModalDialogReturnObject(values)+”return temp”;   
 
 overrideShowModalDialogJs += "};}";   
 //showModalDialog方法進行覆蓋   
 selenium.getEval(overrideShowModalDialogJs);   
 selenium.click(locator);   
 }   
  
 private void  generateModalDialogReturnObject (String[] values){   
  StringBuffer returnObject=new StringBuffer();   
  returnObject.append(“var temp=new Array();”);   
 for(int i=0;i<values.length;i++){   
     returnObject.append(“temp[”+i+”]=’”+values[i]+”’;”);   
  }   
    return returnObject.toString();   
 }  
public void  acceptModalValue(String locator,String[] values){
    String overrideShowModalDialogJs=="if(selenium.browserbot.getCurrentWindow().showModalDialog){";

overrideShowModalDialogJs += "selenium.browserbot.getCurrentWindow().showModalDialog = function( sURL, vArguments, sFeatures)";

overrideShowModalDialogJs +="{ "+generateModalDialogReturnObject(values)+”return temp”;

overrideShowModalDialogJs += "};}";
//showModalDialog方法進行覆蓋
selenium.getEval(overrideShowModalDialogJs);
selenium.click(locator);
}

private void  generateModalDialogReturnObject (String[] values){
    StringBuffer returnObject=new StringBuffer();
    returnObject.append(“var temp=new Array();”);
    for(int i=0;i<values.length;i++){
        returnObject.append(“temp[”+i+”]=’”+values[i]+”’;”);
    }
    return returnObject.toString();
}  


這樣就完成了整個過程。看一個示例,該示例打開一個選部門的模態對話框,從部門樹裏選擇部門,然後返回:

Java代碼  
 //點擊後彈出部門選擇框的圖片   
 String depChooseLocator=”…/img”;   
 <SPAN style="COLOR: #000000">//點擊並選中該彈出網頁   
 clickAndSelectModalDialog(depChooseLocator);</SPAN>   
 //執行部門樹的操作   
   
 //獲取該對話框要返回給父頁面的值   
 String name=selenium.getEval(“window.seltree.GetAllCheckText();”);   
 String id=selenium.getEval(“window.seltree.GetAllNodeId();”);   
 <SPAN style="COLOR: #000000">//關閉部門選擇對話框   
 closeModalDialog();</SPAN>   
 //返回父頁面   
 Selenium.selectWindow(“name=main95598”);   
 //組裝返回值   
 String returnValues=new String[2];   
 returnValues[0]=name;   
 returnValues[1]=id;   
 <SPAN style="COLOR: #000000">//父頁面獲取對話框返回值   
 acceptModalValue(depChooseLocator, returnValues);</SPAN>  
//點擊後彈出部門選擇框的圖片
String depChooseLocator=”…/img”;
//點擊並選中該彈出網頁
clickAndSelectModalDialog(depChooseLocator);
//執行部門樹的操作
….
//獲取該對話框要返回給父頁面的值
String name=selenium.getEval(“window.seltree.GetAllCheckText();”);
String id=selenium.getEval(“window.seltree.GetAllNodeId();”);
//關閉部門選擇對話框
closeModalDialog();
//返回父頁面
Selenium.selectWindow(“name=main95598”);
//組裝返回值
String returnValues=new String[2];
returnValues[0]=name;
returnValues[1]=id;
//父頁面獲取對話框返回值
acceptModalValue(depChooseLocator, returnValues);  


可以進一步抽象爲模板回調方法,略。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章