togatttiのエンジニアメモ

過度な期待はしないでください.

Seleniumのテスト対象を別ウィンドウに切り替える

はじめに

Seleniumのテストの最中に、target="_blank"などをクリックして新しくウィンドウを開くとき、 そのウィンドウを対象にしたテストを行う方法について調べた。

Seleniumのバージョンは2.35.0.

言語はPerlを使い、WWW::Selenium::Test,Test::Moreモジュールを使う。

(1)select_windowを使う

WWW::Selenium - search.cpan.orgを見ると、

$sel->select_window($window_id);を使うと対象のウィンドウを切り替えることができると言う記載を見つけたが、 window_idをうまく取得できずにエラーとなった。

(2)get_eval内でjavascriptを実行する

他に方法があるかもしれないが、get_evalを使うことで対応した。

WWW::Selenium - search.cpan.orgより一部抜粋。

$sel->get_eval($script)
Gets the result of evaluating the specified JavaScript snippet. The snippet may have multiple lines, but only the result of the last line will be returned. Note that, by default, the snippet will run in the context of the "selenium"object itself, so this will refer to the Selenium object. Use window to refer to the window of your application, e.g. window.document.getElementById('foo')

If you need to use a locator to refer to a single element in your application page, you can use this.browserbot.findElement("id=foo") where "id=foo" is your locator.

$script is the JavaScript snippet to run
Returns the results of evaluating the snippet

要はget_evalの中でseleniumオブジェクトを対象として、javascriptを実行する事ができる。

そして、これを利用して、this.page().selectWindow("windowの名前"); で指定する。

実装例は実際に動かしたものを抜粋するが、次のような感じにする。

# $sel is selenium object which has the taeget server, port number etc. 
$sel->click_ok("link=Open window");
$sel->pause("5000");
my @blank = grep {/selenium_blank/} $sel->get_all_window_names();
$sel->get_eval("this.page().selectWindow(\"$blank[0]\")");
$sel->title_like(qr/Open window/);
done_testing();

簡単に流れを説明すると、

  • linkを押して、別ページを開く。
  • get_all_window_names()で開いているページの名前のリストを取得する。
  • 開いたページの名前はslenium_blank*という文字列であるため、grepする。
  • get_eval内部で、selectWindowを使い処理する。
  • 開いたページのタイトルをテストする。

こちらで一応正常にテストすることができた。