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”);
}
接下來就可以在彈出網頁裡進行操作,獲取需要返回給父頁面的值,這些值一般是一個數組。獲取值後關閉彈出網頁並返回父頁面。在父頁面裡再次點擊打開模態對話框的元素,對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();
}
這樣就完成了整個過程。看一個示例,該示例打開一個選部門的模態對話框,從部門樹裡選擇部門,然後返回:
Java代碼
//點擊後彈出部門選擇框的圖片
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);
可以進一步抽象為模板回調方法,略。