Selenium – 試行錯誤の末

2010-09-10 (Fri)  •  By 伊藤  •  活用のヒント  •  Selenium 翻訳

今回の記事は、JIRA に関するアトラシアン ブログ「Selenium – push my buttons 」の弊社翻訳版です。原文と差異がある場合は、原文の内容が優先されます。

Selenium – 思い返せばすべてが明白に

Selenium におけるキーの入力やプッシュのシュミレートが なぜこれほど困難であるのか について考察をしてみた。

以下は筆者の結論である。

結論 1 : JavaScript イベントは Firefox では優先されるが、IE ではそうではない

Firefox 上のテキスト フィールドにおいてキーボードのキーが押されるイベントが発生した場合、Firefox は親切にもそのフィールド内に適切な文字を入力する。その後、keyPressEvent に関連する任意のハンドラが発生することになる。

Selenium の Type 関数は実際には JavaScript の replaceText 関数であり、それゆえ、キーボード イベントを発生させずに文字列を直接テキスト領域に吐き出す。また、そのフィールド内のすべての既存のテキストは上書きされる。

そのため、我々は seleniumClient において typeWithFullKeyEvents を作成したわけである。Firefox に対しては、イベントのみを送信する。IE では、すべてのテキストをフィールド内に配置し、その後、各文字に対してイベントを発生させる (おそらくフィールドの該当文字までしかテキストが配置されないが、大した問題ではない)。

typeWithFullKeyEvents の問題点は、IE では常に Type 関数が呼び出されることである。ロケーターがテキストを受け取れないものを指し示している場合、この関数は “undefined” を返すことになる。

結論 2 : JavaScript の keydown および keyup は keyPress イベントとは異なる

キーボードのキーが実際に押された場合、ページ上で現在フォーカスされているエレメントにおいて、通常、以下の 3 種類のイベントが発生する。

  • keyDown
  • keyPress
  • keyUp

(筆者が今のところ知りうる唯一の例外は、フォーカスを移動させる Tab キーである。したがって、フォーカスされているエレメントは、通常、keyDown イベントのみを受け取る。ブラウザーによっては、これが keyPress イベントとなる。)

しかし、これらのイベントの定義を確認してみると、セットされるフィールドが実際には微妙に異なる。

keyPress の場合、charCode および which パラメーターが (同じ値に) セットされる。これは “入力したい” 文字の ASCII コード値である。keyCode パラメーターはセットされたり、されなかったりするが、これはブラウザーに依存する。

keyDown ならびに keyUp イベントの場合、keyCode および which パラメーターが (同じ値に) セットされる。しかし、これは入力したい文字の ASCII コード値ではなく、実際には Virtual keyCode である。(Shift や Option キーなどの) 修飾子キーが押された状態でない場合、通常 (常にではない)、それは入力された文字の文字コードである。. 文字については、修飾子キーが押されていない場合でも、keyDown および keyUp で異なるコードが文字コードに送信される。

実際、( を入力した場合、5 種類のイベントが発生する。shiftKey に keyDown、9 キーに keyDown、文字 ( に keyPress、9 キーに keyUp、そして shiftKey に keyUp である。(そして、keyDown、keyPress、および keyUp イベントに対して shiftKey ブール値が真にセットされるはずである。)

なぜこれが大問題なのか?

Java の ASCII 文字コードは単純に keyDown や keyUp へ送信されるだけであり、さらに Firefox がそれを解釈するので (JavaScript イベントは優先されるため)、Firefox はその keyCode に対応する keyDown や keyUp を通常通り処理しようとする。例えば、( は characterCode 40 だが keyCode 40 は実際にはキーボードの上向き矢印キーである。同様に . は characterCode 46 であるのに対し、keycode 46 は Forward Delete キーである。

Firefox 上でテストを行った際に予期せぬ動作が確認されたため、この件に関する我々の対応策は IE 上では正しく動作しないだろう。

この問題への軽減策

以下のメソッドを Selenium クライアントへ追加し、その変更を Selenium プロジェクトへのプッシュ転送を試みた。

keyDownEventsForCharacter(String locator, Character character)
keyUpEventsForCharacter(String locator, Character character)
keyPressEventsForCharacter(</em><em>String locator, Character character)
simulateKeyPressForCharacter(String locator, Character character)

さらに、以下の行をより正確に書き直す。

typeWithFullKeyEvents(String locator, String string, boolean reset)

このイベントに対するコメントとして、テキストが実際に入力できるエレメントを検索するロケーターでのみ呼び出されるようにする旨を記す。

異なるブラウザー上での JavaScript のキーボード イベントの詳細に関しては「JavaScript Madness: Keyboard Events 」を確認して欲しい。


Related Articles

お気軽にお問い合わせください

お問い合わせ