使用Selenium2和FirefoxDriver关闭Liferay弹出窗口(在新的浏览器窗口中)?

Luc*_*cas 10 debugging firefox popup liferay selenium-webdriver

我试图使用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>
Run Code Online (Sandbox Code Playgroud)

切换到弹出窗口上下文非常简单:

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;
Run Code Online (Sandbox Code Playgroud)

但是,当我完成模拟时,我需要关闭弹出窗口.根据WebDriver.close()的api,它将:

关闭当前窗口,如果它是当前打开的最后一个窗口,则退出浏览器.

如果我正确读取它,那么它应该关闭弹出窗口,而不是Firefox实例(只要我打开另一个窗口,我这样做,因为这只是一个弹出窗口).但是,当我从弹出窗口的上下文中调用close时,它始终会失败:

org.openqa.selenium.WebDriverException:  
org.apache.http.conn.HttpHostConnectException: 
Connection to http://localhost:7055 refused
Run Code Online (Sandbox Code Playgroud)

我发现一些引用是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 );
}
Run Code Online (Sandbox Code Playgroud)

似乎表明这不是FirefoxDriver的真正问题.这表明只需创建一个弹出窗口,切换到它,然后关闭它,然后在主窗口中恢复工作不会导致firefox崩溃.这意味着原因要复杂得多,我想不出一种创建简单测试用例的方法.我的真实代码基本上是与Liferay合作的框架.它旨在成为我所有测试用例的基类,提供impersonateUser(LiferayUser用户)等实用程序方法.我会在这里发布我的代码,但高度怀疑是否有人愿意付出努力来研究这个问题.现在我有一个解决方法,我可以关闭原始窗口,然后继续在弹出窗口中工作.如果我想出一个简化的测试用例来演示这个问题,我会再次编辑这篇文章.

-------------编辑2 --------------

我现在认为这与调试器有关.我正在使用eclipse,如果我正在调试,并且正在逐步执行close()和switchTo()之间的代码,它会一直失败.您应该可以通过在此行上方的简化示例测试用例中插入断点来重现:

System.out.println( "now try to continue working in original window" );
Run Code Online (Sandbox Code Playgroud)

当代码为该断点停止时,您会收到错误...不确定如何处理这个错误.有什么建议?

-------------编辑3 --------------

出于跟踪目的,这是我在此问题上打开的错误:

http://code.google.com/p/selenium/issues/detail?id=1378

Man*_*yas 1

Hello Liferay 弹出窗口不是您可以关闭的单独的 Firefix 弹出窗口。它是 HTML 的 div 元素,看起来像一个弹出窗口。为此,您需要通过 javascript 代码关闭它。

一般情况下,每个弹出窗口都会有一个开发人员制作的关闭按钮,您可以通过selenium IDE找到它的路径,并且可以通过webdriver模拟点击请求。

再次重复。LiferayWindow 弹出窗口不是实际的基于浏览器的浏览器,它们只是相同的幻觉。

我不认为这是错误。

编辑**

我认为这是由于 javascript 窗口弹出造成的,但事实并非如此。