watir-webdriverメモ - なるべく新規ウィンドウを作らないための小技

前置き

Webアプリのテストなど、Webブラウザを使ってのルーチンワークの自動化にしばらく FireWatir を使っていましたが、

といった点が不満であったので、Watir 2.0 と目されている、Webdriverベースの watir-webdriver に乗り換えました。

watir-webdriver

そのままで日本語も通るし、動作も軽快だし、専用のまっさらなプロファイルでブラウザを起動してくれるし*3で概ね気に入っているのですが、一点ちょっと難儀なことがあって、

Watir::Browser.attach がない

それは attach がないこと。

例えば form要素の target属性が "_blank" になっていたりすると、submit と同時に新規ウィンドウができますが、attach がないのでそのウィンドウの参照を Watir::Browserオブジェクトとして取得できません。すなわち、そのウィンドウ上で行われるべき、それ以降の操作ができなくなるのです。*4

Watir::Browser#execute_script が生命線

で、どうしたらいいかとあれこれ考えた結果、以下のような方法で submit時の新規ウィンドウの作成を回避しました。

      def kill_target_blank!
        @browser.execute_script(%{
          (function() {
            var forms = document.forms;
            for (var i = 0; i < forms.length; i++) {
              forms[i].setAttribute('target', '_self');
            }
          })();
        })
      end

あってよかった execute_script

DOM要素の属性値を直接書き換えるようなメソッドはありませんが、これがあったので助かりました。document のコンテキストで JavaScript を eval してくれます。これで form の target属性を "_self" にしてから submit すれば、その後の操作も引き続き今いるウィンドウ上で行えます。

このように、watir-webdriver を使う場合は、なるべく新規ウィンドウを作らずに操作を実行する工夫が必要になります。

*1:モンキーパッチ、あるいは gem のソースを直に修正

*2:ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
firewatir (1.6.5)

*3:Ubuntu上の Firefox でしか試してないので、他のプラットフォームまたはブラウザではそうなっていないかも。

*4:自分が何か重大なことを見落としている可能性もなきにしもあらず。その場合はツッコミ希望。