今天在用web driver的方法:driver.getWindowHandles()只能得到一个句柄,但是明明打开了一个父窗口和一个子窗口,而子窗口是模态窗口。这是怎么一回事呢?
看到网上的这篇文章http://17test.info/?p=712的回复后,我得到了答案。原来是2.21版本的问题。于是就从seleniumhq.com下载了新的版本2.24.
句柄终于拿到了。
普及一下模态和非模态,也是回顾一下:
对话框一般分为两种类型:模态类型(modal)与非模态类型(modeless)。所谓模态对话框,就是指除非采取有效的关闭手段,用户的鼠标焦点或者输入光标将一直停留在其上的对话框。非模态对话框则不会强制此种特性,用户可以在当前对话框以及其他窗口间进行切换。
同时分享方法,得到已知标题的web page的driver
public boolean SwitchToWindowUsingTitle(WebDriver driver, String windowTitle) {
String currentWindow = driver.getWindowHandle();
Set<String> availableWindows = driver.getWindowHandles();
if(availableWindows.size() != 0) {
Iterator<String> windowIDIterator = availableWindows.iterator();
while(windowIDIterator.hasNext()) {
if(driver.switchTo().window(windowIDIterator.next()).getTitle().equals(windowTitle)) {
return true;
}
}
driver.switchTo().window(currentWindow);
}
return false;
}
=======================================================美丽的分割线==================================================================
在折腾了一天之后,我终于得到了更完美的解决方案。
这个问题是这样的:完成了上面的方法之后,我做了几次的测试,通过。转天过来再试,就不行了。每当我debug看handles值,没问题。但是当我运行而不是debug。就无法得到所有的句柄。这个问题跟版本无关。我现在运行的版本还是2.21.
工夫不负苦心人。我终于从一篇文章中得到了答案。先贴出代码和网页
Address: https://groups.google.com/forum/?fromgroups#!topic/webdriver/Wi1-1U9snTs 最后的留言
public boolean switchToWindowFromGoogle(WebDriver driver, WebElement elementToTRModal, final String windowTitle) {
final Set<String> handles = driver.getWindowHandles();
elementToTRModal.click();
return (new WebDriverWait(driver, 1000))
.until(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver arg0) {
// TODO Auto-generated method stub
Set<String> newHandles = arg0.getWindowHandles();
newHandles.removeAll(handles);
if(newHandles.size() > 0) {
if(arg0.switchTo().window(newHandles.iterator().next())
.getTitle().contains(windowTitle)) {
System.out.println("driver switch to pop up window.");
return true;
}
}
System.out.println("Not find any other handle. Go to current window.");
return false;
}
});
}
这段代码的区别就是加入了WebDriverWait,通过回放我发现"Not find any other handle. Go to current window."这句话执行了两遍。第三次的时候才成功得到所有的句柄。当然我还不明白是为什么。但是我看WebDriverWait是很好的解决方法。
根据我之前商业工具的经验,应该是对象库或者说反射时,句柄不是一下就能得到的,需要等一段时间。而等多长时间呢?之前我们是定一个比较长的值。但是有一回,我们在一个非常慢的机器上进行脚本回放时,出事了。等待时间长度不够。导致程序找不到对象,然后一次次失败。
Web Driver提供的Wait方法,可以手动写条件,条件不满足则继续等待。这样的方式比较好。
===================================================================================================================================
上面的方案在对付一个模态窗口时可以,但是在打开多个模态时fail。因为拿到iterator之后,没有循环。补充
public boolean switchToWindowFromGoogle(final String windowTitle) {
final String currentHandle = this.driver.getWindowHandle();
return (new WebDriverWait(this.driver, 1000))
.until(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver arg0) {
// Get handles to set
Set<String> newHandles = arg0.getWindowHandles();
// Remove current window
newHandles.remove(currentHandle);
// Iterate with handles
Iterator<String> handlesIterator = newHandles.iterator();
while (handlesIterator.hasNext()) {
// If it is the expect window matching title.
if (arg0.switchTo()
.window((String) handlesIterator.next())
.getTitle().contains(windowTitle)) {
System.out
.println("driver switch to pop up window.");
return true;
}
}
System.out
.println("Not find any other handle. Go to current window.");
return false;
}
});
}