ruby からSelenium をぱぱっと使う
つかいかたは、とっても簡単。
require 'selenium-webdriver' driver = Selenium::WebDriver.for :chrome driver.close()
要素辿る系はちょっとコマンドタイプ量がおおくなり手順が多いので、Rubyなら watir を使うほうが楽かもしれないよ。
終了するには
driver.quit()
Chromeはquit()が必要だった。Firefoxはclose()で終了した。OSXだけ?
プロファイルを指定するには
Capabilities を使うことで実現する。
Chromeの起動オプションを書いている。
require 'selenium-webdriver' caps = Selenium::WebDriver::Remote::Capabilities.chrome( "chromeOptions" => { "args" => ["--user-data-dir=/path/to/Google/Chrome/profile"] }) driver = Selenium::WebDriver.for :chrome , :desired_capabilities => caps
特定のサイトを表示する
driver.navigate.to "http://www.yahoo.co.jp/"
ページのロード待ち時間を設定する
driver.manage.timeouts.implicit_wait = 10 # seconds
たしか、readyState を見てたと思う。
javascript の実行
driver.execute_script("alert()")
スクリーンショットを保存する
driver.navigate.to "http://www.yahoo.co.jp/" driver.save_screenshot "path/to/out.png"
要素を探す(最初に見つかった要素を返す)
driver.find_element(:id => "name-of-id")
要素を探す(見つかった要素をすべて返す)
driver.find_elements(:id => "name-of-id")
単数形 element と 複数形 elements で区別する
特定の要素が出てくるまで待機する。
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds begin element = wait.until { driver.find_element(:id => "name-of-id") } ensure driver.quit end
この方法は、要素がDOMにあるか判断するので、display:none や height:0pxや visibility:hidden は待機できない。
検索(クエリ)の言語を指定する。
driver.find_element(:css => "#name-of-id") driver.find_element(:xpath => "id(name-of-id)") driver.find_element(:xpath => "/path/to/node[ conditions ]") driver.find_element(:tag_name => "form") # css/xpath アレば使うことないかも driver.find_element(:class => "enabled") # css/xpath アレば使うことないかも
単数形 element と 複数形 elements で区別するので注意
属性を取得するには
element.attribute("href")
a.href
などは不可。めんどくさいんだね。
ブラウザを操作する。(=要素を操作する)
element = driver.find_element(:xpath => "id(name-of-id)") element.click()
ブラウザを操作する(戻る・進む)
driver.navigate.back driver.navigate.forward
この辺は、JS実行でいいよね。
フォームを操作する
フォームを操作する。
element.send_keys("takuya");
イベント送信で操作することになる。要素を直接いじるわけではなさそう
JSで直接要素を触ると怒られる面倒くさいサイトがあるのでsend_key 使ったほうが無難かも
値のクリア
element.clear
select ボックスの操作
options = driver.find_elements(:css => "select[name=age] option") options.each{| option | option.click if option.attribute("value") == "10" #型に注意 }
window.alert() などのブラウザ・ダイアログを処理する。
driver.switch_to.alert.accept
prompt の処理
OSXの場合、入力文字が画面に反映されないが、確かに入力文字が送信されている。
driver.execute_script("alert(prompt('enter your name'))") a = driver.switch_to.alert a.send_keys "aaa" a.text #=> enter your name とプロンプトの文字が出てくる a.accept ##ok a.dissmiss ##ng
なお、BASIC認証には非対応なのだそうだ。(試すの面倒だから試してない)
ポップアップなど複数ウインドウを操作する。
window_handlesで取得し、その後、switch_to で切り替える。
>> driver.window_handle => "CDwindow-90E486B1-FD10-4251-90B2-75A66C524182" >> driver.window_handles => ["CDwindow-90E486B1-FD10-4251-90B2-75A66C524182"....] >> driver.switch_to driver.window_halders[2]
DragDropについて
element = driver.find_element(:name => 'source') target = driver.find_element(:name => 'target') driver.action.drag_and_drop(element, target).perform
要素をDragDrop出来るらしいけど、、、、JSでマウスイベントを送ったほうが細い制御出来る気がしなくもないが、JSめんどくさそうなので、出番もあるだろう。
java/C# や ruby とのメソッド読み替え規則
ただしrubyでは、ruby のメソッド名の命名規則が優先される。
ruby
a.text
java
a.getText()
その他の例
ruby
a.send_key
java
a.sendKey
知っておくと、ググった時に便利。
名前空間とかも
Stackoverflowで見てた限りでは、java 系はimport するので省略されちゃうことが多いみたい
Selenium::WebDriver::Remote::Capabilities.chrome #ruby Capabilities.chrome # java
このように名前空間をつけるつけないはその実行スコープの名前空間によるね。
関連資料
HTMLフォームにキーボードイベントでキー値を突っ込む(出来ないから代替案 - それマグで!