#SeleniumWebdriverでWaitを入れてみる
例えば、画面上に名前やメールアドレスを登録し、
登録内容と入力内容が間違っていないことを確認する時、
登録ボタンをクリックしてから画面に反映されるまで多少時間がかかることがありますね。
そんな時にwaitを入れずに確認しようとすると、Seleniumさんは要素が見つからないと発狂します。
なので、waitを考慮する必要があります。
##sleep
1番手っ取り早いのは指定した秒数だけ待つというもの。
以下の例の場合、10秒待ちます。
・対象の要素が表示されるのに、2、3秒しかかからなかった。
・対象の要素が表示されるのに、20秒かかった。
こういった時、歯がゆさを感じます。
sleep 10
##wait.until
事前にタイマーを設け、対象の要素が指定した状態になるまで待つというものです。多用してます。
以下の例は、タイマーを60秒設定して、その間に要素が表示される(要素が見えなくなる)まで待ち、変化があったらタイマーを中断し、次の処理に移行します。
# $waitに60秒のタイマーを持たせる
$wait = Selenium::WebDriver::Wait.new(:timeout => 60)
# 要素が表示されるのを60秒待つ
$wait.until{driver.find_element(:id,'OK_btn').displayed?}
# 要素が表示されなくなるのを60秒待つ
$wait.until{!driver.find_element(:id,'OK_btn').displayed?}
ちょっと細かく解説すると、
.displayed? は対象の要素が表示されているか否かを確認してくれます。
表示されていれば "true"、表示されていなければ "false" を返します。
これをwait.untilと組み合わせることで、.displayed? の結果が "true" になるか、60秒経過するまで待ってくれます。
60秒経過した場合は Timeout になるので、適宜処理を追加して fail としてカウントできますね。
wait に「$」をつけているのはグローバル変数として扱う為です。
グローバル変数にすることで、タイマーの設定が1ヶ所でもいろんなところから呼び出せるので便利です。
##begin-rescue
wait というよりは、例外処理ですね。
例外処理なので、fail としてカウントさせることも出来ます。
以下の例では、OKボタンがクリック出来るまでリトライし続けます。
つまり、OKボタンがクリック出来なかったらそこで次元の狭間に取り込まれる事になりますので、rescue からの脱出ルートが必要になります。
begin
driver.find_element(:id,'ok_btn').click
rescue
retry
end
##その他
for や while などのループを設けてその中で処理することも可能です。
Selenium を触り始めた初期の頃にこんな感じの組んでモジュール化してましたが、
wait.until を知ってしまってからは使わなくてなりました。
timer = 0;
while timer <= 60 do
if(driver.find_element(:id,'ok_btn').displayed?=="true" then
driver.find_element(:id,'ok_btn').click
break
else
timer += 1 ;
end
end
##まとめ
個人的には wait.until でほぼほぼ賄えそうですが、終了条件さえきちんと設定すれば begin-rescue も便利だと思います。
とは言えこれらは私が良く使用する(使用した)ものなので、他にももっと便利なものがあるかもしれません。
と言うか、既出感凄いのでまぁ復習程度でしょうかね。