ASP.NET では、Form や asp:Panel コントロールの DefaultButton プロパティにボタンコントロールの ID を指定することで、そのページ(またはPanel)内での Enter キー押下時に、指定したボタンをクリックしたのと同じ動作となるようにできる。
マウスによる操作だけでなく、キーボードによる操作についてもその妥当性に気を遣っているため、この Enter キーによるデフォルトボタン押下も
Selenium Remote Control (以下、Selenium RC) を使った自動機能テストに組み込むことにした。
さて、Selenium RC (テスター側はC#)を使って、Enter キー押下をエミュレートするにはどうしたらよいだろう?
ちょっと調べてみたところ、
ISelenium.keyPress メソッドが使えそう。
"Enterキー" を指定するには引数に何を指定すればよいのかすぐにはわからなかったが、非文字キーを指定するには、バックスラッシュに続けてキーコードを10進数で記述すればよいらしい。
つまり、Enter キーであれば、"\13" ということだ(テスター側は C# なので、実際に C# ソースコード中ではエスケープシーケンスに気をつけて、"\\13" あるいは @"\13" と記述する必要がある)。
こうして作成したテストを実行してみたところ、Firefox 2 では期待どおりちゃんと動作が再現した。
ところが、IE6/7 ではうまくいかない。
ISelenium.keyPress メソッドで Enter キー押下を実行しても、IE 上ではなにも起こらないのだ。
ISelenium.keyDown や keyUp、およびこれらメソッドの組み合わせなどいろいろ試したが、結局、IE では何も起こらずじまい。
ISelenium.keyPress が最終的にどのような JavaScript コードの発動につながっているのか調べていないが、まぁ、本当に OS のキー押下をエミュレートしているわけではないので、この IE の挙動もわからないでもない。
とはいえ、これでは機能テストを自動化できない。
仕方がないので、ISelenium.keyPress に頼るのはやめ、
WScript.Shell COM コンポーネントの SendKeys を利用することとした。
ただし WScript.Shell の SendKeys を使うなら、今度はフォーカスに注意しなくてはならない。
ISelenium にはウィンドウ単位でしかフォーカスを指定するメソッドがないようなので、ここは自作。
テスト対象の Web アプリは、Selenium のテストハーネスの IFRAME に埋め込まれている。
この IFRAME 要素の name は "myiframe" なので、これを手がかりに、指定の要素にフォーカスを与える JavaScript コードを ISelenium 経由で実行することにする。
コードは次のような感じ。
selenium.GetEval("frames('myiframe').focus();");
selenium.GetEval("frames('myiframe').document.getElementById('" + elementId + "').focus();");
もっとも、ここまで手を尽くしても、テスト実行時にアクティブウィンドウをブラウザ以外に切り替えてしまうと破綻してしまう(そのときアクティブな、おそらくはテスト中のブラウザではないウィンドウに SendKeys でキーストロークが送信されてしまう)。
その気になれば、アクティブウィンドウを必ずテスト中のブラウザに矯正するコードを足すこともできると思うが、実用上・実際上は重要な問題にはならないので、これで解決とした。