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---------------
追跡の目的で、この問題で私が開いたバグは次のとおりです。