使用 Selenium2 和 FirefoxDriver 关闭 Liferay 弹出窗口(在新的浏览器窗口中)?
我正在尝试使用 Selenium 2 在 Liferay 门户服务器上自动化一些测试用例。许多 Liferay 操作会弹出新的浏览器窗口(如用户模拟)。这是一个示例链接(注意 target="_blank"
):
<a title="(Opens New Window)" target="_blank" id="_125_xafr"
href="/web/guest?doAsUserId=xBRUWI85MvM%3D" class="taglib-icon aui-focus"
tabindex="0" role="menuitem">
<img alt="" src="/html/themes/control_panel/images/common/impersonate_user.png" class="icon">
Impersonate User
<span class="opens-new-window-accessible">(Opens New Window)</span>
</a>
切换到弹出窗口上下文相当简单:
String currentWindowHandle = driver.getWindowHandle();
if ( log.isDebugEnabled() ) log.debug( "currentWindowHandle='" + currentWindowHandle + "'" );
for ( String windowHandle : driver.getWindowHandles() ) {
if ( ! windowHandle.equals( currentWindowHandle ) ) {
boolean impersonationSuccess = false;
if ( log.isDebugEnabled() ) log.debug( "checking '" + windowHandle + "' impersonation alert notice" );
driver.switchTo().window( windowHandle );
try {
// wait for body to ensure page has loaded before checking to see if its impersonation page.
WebElement body = waitForElement( driver, By.xpath( "//body" ) );
WebElement noticeMessage = body.findElement(
By.xpath( "div[@class='popup-alert-notice' and a='Be yourself again.']/span[@class='notice-message']" ) );
if ( noticeMessage.getText().indexOf( "You are impersonating " + user.firstName + " " + user.lastName ) >= 0 ) {
impersonationSuccess = true;
break;
}
}
catch ( NoSuchElementException e ) {
if ( log.isDebugEnabled() ) {
log.debug( "did not find impersonation window '" + windowHandle + "'" );
}
}
finally {
if ( ! impersonationSuccess ) {
driver.switchTo().window( currentWindowHandle );
}
}
}
}
return currentWindowHandle;
但是,当我完成模拟后,我需要关闭弹出窗口。根据 WebDriver.close() 的 api,它将:
关闭当前窗口,退出 浏览器(如果是最后一个窗口) 目前已开放。
如果我正确地阅读了这篇文章,那么它应该只关闭弹出窗口,而不是 Firefox 实例(只要我打开另一个窗口,我就会这样做,因为这只是一个弹出窗口)。但是,当我从弹出窗口的上下文中调用 close 时,它总是失败:
org.openqa.selenium.WebDriverException:
org.apache.http.conn.HttpHostConnectException:
Connection to http://localhost:7055 refused
我发现一些引用表明这是 FirefoxDriver 中的错误。有人有建议或解决方法吗?我想我可以让弹出窗口保持打开状态,直到整个测试用例完成,但是由于在我的测试套件中导致弹出窗口的操作数量很多,这可能很快就会变得不可行。
------------- 编辑 --------------
一个极其简化的测试用例:
@Test
public void testPopupClose() {
WebDriver driver = new FirefoxDriver();
driver.get( "http://lucastheisen.com/test/lucas_test_page.html" );
driver.findElement( By.id( "popup_link" ) ).click();
String mainWindowHandle = driver.getWindowHandle();
System.out.println( "currentWindowHandle='" + mainWindowHandle + "'" );
boolean foundPopup = false;
for ( String windowHandle : driver.getWindowHandles() ) {
if ( !windowHandle.equals( mainWindowHandle ) ) {
System.out.println( "checking '" + windowHandle + "' for taunt" );
driver.switchTo().window( windowHandle );
try {
driver.findElement( By.id( "taunt" ) );
foundPopup = true;
break;
}
catch ( NoSuchElementException e ) {
System.out.println( "'" + windowHandle + "' is not taunt window" );
}
finally {
if ( !foundPopup ) {
driver.switchTo().window( mainWindowHandle );
}
}
}
}
if ( foundPopup ) {
System.out.println( "found my popup, now try to close it..." );
driver.close();
}
System.out.println( "now try to continue working in original window" );
driver.switchTo().window( mainWindowHandle );
driver.findElement( By.id( "popup_link" ) );
driver.close();
assertTrue( true );
}
似乎表明这并不是一个真正的测试用例FirefoxDriver 的问题。这表明,仅创建一个弹出窗口,切换到它,然后关闭它,然后恢复主窗口中的工作不会导致 Firefox 崩溃。这意味着原因要复杂得多,我想不出一种方法来创建一个简单的测试用例。我真正的代码基本上是一个使用 Liferay 的框架。它旨在成为我所有测试用例的基类,提供像 impersonateUser( LiferayUser user ) 这样的实用方法。我将在这里发布我的代码,但非常怀疑是否有人愿意花精力来研究这个问题。现在我有一个解决方法,我可以关闭原始窗口,然后继续在弹出窗口中工作。如果我想出一个简化的测试用例来演示这个问题,我将再次编辑这篇文章。
------------- 编辑 2 --------------
我现在认为这与调试器有关。我正在使用 eclipse,如果我正在调试,并且单步执行 close() 和 switchTo() 之间的代码,它会始终失败。您应该能够通过在上面的简化示例测试用例中的这一行插入一个断点来进行重现:
System.out.println( "now try to continue working in original window" );
当代码在该断点处停止时,您会收到错误...不知道该怎么办,尽可能提交一个错误。有什么建议吗?
------------- 编辑 3 --------------
出于跟踪目的,以下是我在此问题上提出的错误:
I am attempting to automate some test cases on a Liferay portal server using Selenium 2. Many Liferay actions open up new browser window pop up (like user impersonation). Here is an example link (notice the target="_blank"
):
<a title="(Opens New Window)" target="_blank" id="_125_xafr"
href="/web/guest?doAsUserId=xBRUWI85MvM%3D" class="taglib-icon aui-focus"
tabindex="0" role="menuitem">
<img alt="" src="/html/themes/control_panel/images/common/impersonate_user.png" class="icon">
Impersonate User
<span class="opens-new-window-accessible">(Opens New Window)</span>
</a>
Switching to the pop up window context is fairly straight forward:
String currentWindowHandle = driver.getWindowHandle();
if ( log.isDebugEnabled() ) log.debug( "currentWindowHandle='" + currentWindowHandle + "'" );
for ( String windowHandle : driver.getWindowHandles() ) {
if ( ! windowHandle.equals( currentWindowHandle ) ) {
boolean impersonationSuccess = false;
if ( log.isDebugEnabled() ) log.debug( "checking '" + windowHandle + "' impersonation alert notice" );
driver.switchTo().window( windowHandle );
try {
// wait for body to ensure page has loaded before checking to see if its impersonation page.
WebElement body = waitForElement( driver, By.xpath( "//body" ) );
WebElement noticeMessage = body.findElement(
By.xpath( "div[@class='popup-alert-notice' and a='Be yourself again.']/span[@class='notice-message']" ) );
if ( noticeMessage.getText().indexOf( "You are impersonating " + user.firstName + " " + user.lastName ) >= 0 ) {
impersonationSuccess = true;
break;
}
}
catch ( NoSuchElementException e ) {
if ( log.isDebugEnabled() ) {
log.debug( "did not find impersonation window '" + windowHandle + "'" );
}
}
finally {
if ( ! impersonationSuccess ) {
driver.switchTo().window( currentWindowHandle );
}
}
}
}
return currentWindowHandle;
However, when I am done with impersonation, I need to close the pop up. According to the api for WebDriver.close(), it will:
Close the current window, quitting the
browser if it's the last window
currently open.
If I am reading this correctly, then it should just close the pop up window, not the Firefox instance (as long as I have another window open, which I do, because this was just a pop up). However, when I call close from the context of the pop up it always fails with:
org.openqa.selenium.WebDriverException:
org.apache.http.conn.HttpHostConnectException:
Connection to http://localhost:7055 refused
I found some references to this being a bug in the FirefoxDriver. Does anyone have suggestions or perhaps a workaround? I guess I could leave the pop up open until the entire test case is complete, but with the number of operations that cause pop ups in my test suite, this could rapidly become infeasible.
------------- EDIT --------------
An extremely simplified test case:
@Test
public void testPopupClose() {
WebDriver driver = new FirefoxDriver();
driver.get( "http://lucastheisen.com/test/lucas_test_page.html" );
driver.findElement( By.id( "popup_link" ) ).click();
String mainWindowHandle = driver.getWindowHandle();
System.out.println( "currentWindowHandle='" + mainWindowHandle + "'" );
boolean foundPopup = false;
for ( String windowHandle : driver.getWindowHandles() ) {
if ( !windowHandle.equals( mainWindowHandle ) ) {
System.out.println( "checking '" + windowHandle + "' for taunt" );
driver.switchTo().window( windowHandle );
try {
driver.findElement( By.id( "taunt" ) );
foundPopup = true;
break;
}
catch ( NoSuchElementException e ) {
System.out.println( "'" + windowHandle + "' is not taunt window" );
}
finally {
if ( !foundPopup ) {
driver.switchTo().window( mainWindowHandle );
}
}
}
}
if ( foundPopup ) {
System.out.println( "found my popup, now try to close it..." );
driver.close();
}
System.out.println( "now try to continue working in original window" );
driver.switchTo().window( mainWindowHandle );
driver.findElement( By.id( "popup_link" ) );
driver.close();
assertTrue( true );
}
Seem to indicate that this is not really an issue with the FirefoxDriver. This shows that just creating a popup, switching to it, then closing it, then resuming work in the main window does not cause firefox to crash. This means the cause is much more complicated and I cant think of a way to create a simple test case. My real code is basically a framework for working with Liferay. It is intended to be a base class of all my test cases providing utility methods like impersonateUser( LiferayUser user ). I will post my code here, but highly doubt anyone would want to put the effort into looking into this. For now i have a workaround in that i can close the original window and just continue to work in the popup window from there on out. If I come up with a simplified test case to demonstrate this issue, I will edit this post again.
------------- EDIT 2 --------------
I am now thinking this has something to do with the debugger. I am using eclipse and if I am debugging, and am stepping through the code between the close() and the switchTo(), it fails consistently. You should be able to reproduce by inserting a break point in my simplified example test case above at this line:
System.out.println( "now try to continue working in original window" );
When the code stops for that breakpoint, then you get the error... Not sure what to do about this as far as possibly filing a bug. Any suggestions?
------------- EDIT 3 --------------
For tracking purposes, here is the bug I opened on this issue:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Hello Liferay 弹出窗口不是您可以关闭的单独的 Firefix 弹出窗口。它是 HTML 的 div 元素,看起来像一个弹出窗口。为此,您需要通过 javascript 代码关闭它。
一般情况下,每个弹出窗口都会有一个开发人员制作的关闭按钮,您可以通过selenium IDE找到它的路径,并且可以通过webdriver模拟点击请求。
再次重复。 LiferayWindow 弹出窗口不是实际的基于浏览器的浏览器,它们只是相同的幻觉。
我不认为这是错误。
编辑**
我以为这是由于 javascript 窗口弹出造成的,但事实并非如此。
Hello Liferay popup isnot a seperate popup window of firefix that you will be able to close. It is a div element of HTML that seems like a popup. For that you need to close it via javascript code.
In general scenarios every popup will have a developer made close button, you can find its path through selenium IDE and can can simulate click request on same through webdriver.
Repeating again. LiferayWindow popup are not actual browser based browser, they are just illusion to same.
I don't think this is bug.
edit**
I thought this was due to javascript window popup but this is not the case.