Закрытие всплывающего окна Liferay (в новом окне браузера) с использованием Selenium2 с FirefoxDriver? - PullRequest
10 голосов
/ 08 марта 2011

Я пытаюсь автоматизировать некоторые тестовые случаи на сервере портала Liferay с помощью Selenium 2. Многие действия 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;

Однако, когда я закончу с подражанием, мне нужно закрыть всплывающее окно. Согласно API для WebDriver.close (), он будет:

Закрыть текущее окно, выйдя из браузер, если это последнее окно в настоящее время открыт.

Если я правильно читаю, то оно должно просто закрыть всплывающее окно, а не экземпляр 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). Я опубликую свой код здесь, но очень сомневаюсь, что кто-то захочет приложить усилия для изучения этого. На данный момент у меня есть обходной путь, в котором я могу закрыть исходное окно и просто продолжать работать во всплывающем окне с этого момента. Если я продемонстрирую упрощенный тестовый пример, чтобы продемонстрировать эту проблему, я снова отредактирую этот пост.

------------- РЕДАКТИРОВАТЬ 2 --------------

Теперь я думаю, что это как-то связано с отладчиком. Я использую Eclipse, и если я отлаживаю и прошагаю по коду между close () и switchTo (), он последовательно завершается ошибкой. Вы должны быть в состоянии воспроизвести, вставив точку останова в моем упрощенном примере теста выше в этой строке:

System.out.println( "now try to continue working in original window" );

Когда код останавливается для этой точки останова, вы получаете сообщение об ошибке ... Не уверен, что делать с этим, насколько это возможно, для сообщения об ошибке. Есть предложения?

------------- РЕДАКТИРОВАТЬ 3 --------------

Для отслеживания, вот ошибка, которую я открыл по этому вопросу:

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

1 Ответ

1 голос
/ 09 июля 2012

Hello Liferay popup - это не отдельное всплывающее окно firefix, которое вы сможете закрыть. Это элемент div HTML, который выглядит как всплывающее окно. Для этого вам нужно закрыть его с помощью кода JavaScript.

В общих сценариях каждое всплывающее окно будет иметь кнопку закрытия, созданную разработчиком, вы можете найти его путь в IDE Селена и можете имитировать запрос на клик на том же самом через веб-драйвер.

Повторение снова. Всплывающее окно LiferayWindow не является браузером, основанным на браузере, оно просто иллюзия.

Я не думаю, что это ошибка.

редактировать **

Я думал, что это из-за всплывающего окна javascript, но это не так.

...