您的位置:首页 > 其它

如何使用Holmos处理模态窗口(ModalDialog)

2014-06-27 19:38 253 查看
在自动化测试过程中发现点击某个按钮后弹出了一个特别的窗口。

特点一,该窗口不关闭就无法切换到其他窗口。

特点二,该窗口无法使用开发人员工具进行探测。

 

这个特别的窗口就是模态窗口:

 对话框一般分为两种类型:模态类型(modal)与非模态类型(modeless)。

所谓模态对话框,就是指除非采取有效的关闭手段,用户的鼠标焦点或者输入光标将一直停留在其上的对话框。

非模态对话框则不会强制此种特性,用户可以在当前对话框以及其他窗口间进行切换。(引用) 

 

Holmos自带的跳转窗口的方法都需要一个参数url地址或者窗口title作为跳转依据,但是模态窗口无法使用开发人员工具进行探测,意味着拿不到url或者title就无法跳转到该窗口上。

 

这种情况下应该怎么办?如何跳转到一个没有跳转依据的窗口上?

 

已知Holmos提供可根据浏览器窗口handle属性确定窗口的唯一性。

而窗口的弹出一般都是由单击事件触发的,点击事件触发后,浏览器窗口的数量肯定会多一个。

抓取点击事件后handle的集合减去点击事件之前handle的集合,即得到新的窗口handle。

 

方法代码如下:

public void clickAndSelectModalDialog()  throws BusinessException{

String popupWindowHandle  =  getPopupWindowHandle();
BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
WebDriverBrowserWindow webDriverBrowserWindow=new WebDriverBrowserWindow(currentWindow.getDriver());
webDriverBrowserWindow.setWidowHandle(popupWindowHandle);
List<BrowserWindow> windows = new ArrayList<BrowserWindow>();
windows.add(webDriverBrowserWindow);
for(BrowserWindow window:windows){
if(window.getHandle().equalsIgnoreCase(popupWindowHandle)){
System.out.println("逮住窗口了");
window.focus();
break;
}
}
}

public String getPopupWindowHandle() throws BusinessException {
String popupHandle = null;
int maxTimeToWait = 15000;
int timeInterval = 1000;
int timeElasped = 0;
int attempt;
// 先拿到点击事件之前的窗口集合
BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
Set<String> beforePopup = ((WebDriver)currentWindow.getDriver().getEngine()).getWindowHandles();
// 点击
if(isExist()&&isDisplay()){
click();
}
attempt = 1;
while (timeElasped < maxTimeToWait) {
// 拿到点击事件之后的窗口集合
Set<String> afterPopup = ((WebDriver)currentWindow.getDriver().getEngine()).getWindowHandles();
// 之后的集合-之前的集合=新窗口
afterPopup.removeAll(beforePopup);
// 确认一下拿到新窗口了
if(afterPopup.size() == 1) {
popupHandle = (String)afterPopup.toArray()[0];
break;
}
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timeElasped = timeInterval * attempt;
attempt++;
}
if ( popupHandle.isEmpty() || popupHandle == null  )
{
System.out.println("窗口根本没弹出来");
}
return popupHandle;
}


相信各位通过代码注释就能看懂。

以下提供两个测试页面来验证一下

页面Noname1.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>模态窗口和非模态窗口</TITLE>
<script language="javascript">
var sColor="yyyy";
var sName="xmddl369";
function showModalWindow(){
window.showModalDialog('Noname2.html',window,'dialogWidth:400px;dialogHeight:400px');
}
function showModellessWindow(){
window.showModelessDialog('Noname2.html',window,'dialogWidth:400px;dialogHeight:400px;edge:sunken');
}
function update()
{
oColor.innerText = sColor;
}
document.write("sColor="+sColor+"<br>");
document.write("sName="+sName+"<br>");
</script>
</HEAD>

<BODY>
<form>
<input type="button" name="button1" value="打开一个模态窗口" onclick="showModalWindow()">
<input type="button" name="button2" value="打开一个非模态窗口" onclick="showModellessWindow()">
<BR>
<P>输入你最喜欢的颜色: <SPAN ID="oColor" STYLE="color:red;font-size:24">Yellow</SPAN></P>
</form>
</BODY>
</HTML>


页面Noname2.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<script language="javascript">
function getInfoAndUpdate() {
var callerWindowObj = dialogArguments; //得到文档的引用
callerWindowObj.sColor = document.all("oEnterColor").value;
callerWindowObj.update();
}
function cancel() {
var callerWindowObj = dialogArguments;
callerWindowObj.sColor = "Yellow";
callerWindowObj.update();
}
</script>
</HEAD>
<BODY>
<form>
输入你最喜欢:<INPUT type="text" name="oEnterColor" ID="oEnterColor"><BR><BR>
<INPUT VALUE="Apply" TYPE=button onclick="getInfoAndUpdate();">
<INPUT VALUE="Ok" TYPE=button onclick="getInfoAndUpdate();window.close();">
<INPUT VALUE="Cancel" TYPE=button onclick="cancel();window.close();">

</form>
</BODY>
</HTML>


测试用例:

1.打开Noname1页面,点击打开一个模态窗口

2.跳转到该模态窗口,拿到该窗口内的文字

使用Holmos实现代码:

public class ModalDialogBoxTest2 {
public ModalDialogBoxPage modal=new ModalDialogBoxPage();
@Test
public void modalTest() throws BusinessException{
HolmosWindow. openNewWindow(EngineType.WebDriverIE, "C:/Users/yuanwei3-iri/Desktop/testhtml/Noname1.html" );
HolmosWindow.sleep(5000);
modal.modalButton1.clickAndSelectModalDialog();
HolmosWindow.getModalDialogText();
//HolmosWindow.getModalDialogHtml();
HolmosWindow.closeAllWindows();
}
}


Page类文件:

public class ModalDialogBoxPage extends Page {
public ModalDialogBoxPage() {
super();
this.init();
}
public Button modalButton1 = new Button( "" );
{
modalButton1.addNameLocator("button1");
}
public Button modalButton2 = new Button( "" );
{
modalButton2.addNameLocator("button2");
}
}


其中有个延伸方法getModalDialogText()用来获取页面文字内容:

//	获取模态框窗口的文字内容
public static String getModalDialogText() throws BusinessException{
String Mtext=null;
StringBuilder message=new StringBuilder();
BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
if(currentWindow instanceof WebDriverBrowserWindow){
String js="var a= window.document.body.innerText;return a;";
WebDriver driver=(WebDriver) currentWindow.getDriver().getEngine();
Mtext=	(String) ((JavascriptExecutor)driver).executeScript(js);
}
message.append(Mtext+"获取模态框窗口的文字内容成功!");
logger.info(message);
return Mtext;
}


延伸方法getModalDialogHtml()

//	获取模态框窗口的HTML
public static String getModalDialogHtml() throws BusinessException{
String Mhtml=null;
StringBuilder message=new StringBuilder();
BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
if(currentWindow instanceof WebDriverBrowserWindow){
String js="var a= window.document.body.innerHTML;return a;";
WebDriver driver=(WebDriver) currentWindow.getDriver().getEngine();
Mhtml=	(String) ((JavascriptExecutor)driver).executeScript(js);
}
message.append(Mhtml+"获取模态框窗口的html内容成功!");
logger.info(message);
return Mhtml;
}
}

延伸方法closeModalDialog()

//关闭模态窗口
public static void closeModalDialog() throws BusinessException{
BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
if(currentWindow instanceof WebDriverBrowserWindow){
String js="window.close();";
WebDriver driver=(WebDriver) currentWindow.getDriver().getEngine();
((JavascriptExecutor)driver).executeScript(js);
}
Neo4TestLogger.info("模态窗口关闭成功!");
}


以上三个延伸方法从本质上来说是一样的,通过执行脚本来达到特定的目的。在经过方法封装后,就不必每次调用时手写HolmosWindow.runJavaScript("*********");

从而达到降低使用门槛,节省编写用例时间的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息