それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Selenium の基本的な使い方のサンプル集

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 とのメソッド読み替え規則

Seleniumメソッド名は、各言語で共通。

ただし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フォームにキーボードイベントでキー値を突っ込む(出来ないから代替案 - それマグで!

参考資料

https://www.qoosky.net/techs/58