Selenium (Firefox on Linux with xvfb)

主に、Webアクセスの自動化(管理画面からのダウンロードなど)を目的として Selenium の利用してみる。 (Linux(CentOS5.7+FireFox+Xvfb))

実行環境(サーバ)側の事前準備

CentOS 5.7 では以下の環境を整える必要がある (yum install)

  • Xvfb
  • firefox (24.8)
  • fonts-japanese

また、WebDriver は Ruby を利用するため、Rubyのランタイムを導入しておく。 (yum install ruby や rbenv による導入など)

作業用PCへ Selenium Builder を導入

通常作業を行う環境(WindowsPCなど)で、ブラウザ操作を記録(Selenium Webdriverで実行可能なTestCaseを生成)するために、FirefoxSelenium Builder を導入する。

  • FireFox をインストールし、さらに http://sebuilder.github.io/se-builder/ へアクセスし「Install」をクリック ⇒ Add-on として「Selenium Builder」を導入する
  • ブラウザ(Firefox)上で右クリックし、表示されたコンテキストメニューから「Launch Selenium Builder」を選択 ⇒ 別ウィンドウで Selenium Builder が起動される
  • 「Start recording at」に、操作の基点となるURLを入力し「Selenium 2」をクリックすると、操作(テストケース)の記録が開始される ⇒ その後、元のウィンドウ側で操作を続ける。操作が完了したら、Selenium Builder ウィンドウ側の「Stop recording」をクリック ⇒ 「File」 >「Export」>「Ruby」をクリックし、テストケースをファイル(Ruby Script)としてを保存する

Linux上で Selenium WebDriver 経由でFireFoxを操作する準備

WebDriver (Ruby / FireFox) を実行するために gem を導入しておく

gem install selenium-webdriver

例えば、以下のようなテストケースを準備してみる (proxy.local:80 というプロキシを利用してWebアクセスする場合)

require 'rubygems'
require 'selenium-webdriver'
 
### FireFoxの設定 (Proxy, Language, Locale)
profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = Selenium::WebDriver::Proxy.new(
  :http => 'proxy.local:80',
  :ssl => 'proxy..local:80',
  :no_proxy => nil
)
profile['intl.accept_languages'] = "ja"
profile['general.useragent.locale'] = "ja-JP"
 
wd = Selenium::WebDriver.for :firefox, :profile => profile
 
### 以下、テストケース
wd.get "http://www.yahoo.co.jp/"
wd.find_element(:id, "srchtxt").click
wd.find_element(:id, "srchtxt").clear
wd.find_element(:id, "srchtxt").send_keys "昇龍拳"
wd.find_element(:id, "srchbtn").click
wd.find_element(:link_text, "昇龍拳ってこんなに怖いのか! ストリートファイターをキャラの視点で再現 ").click
wd.quit

テストケースが「testcase1.rb」というファイル名であった場合、以下のようにテストケースを実行する

/usr/bin/Xvfb :1 -ac -screen 0 1024x768x16 &
DISPLAY=:1 ruby ./testcase1.rb
# この場合 WebDriver が 6001 ポート経由で Xvfb に接続してFireFoxを操作

ちなみに、以下のようなエラー出力があるが、現時点では気にしない

FreeFontPath: FPE "built-ins" refcount is 2, should be 1; fixing.
error opening security policy file /usr/lib64/xserver/SecurityPolicy
Could not init font path element unix/:7100, removing from list!

Selenium WebDriver でファイルのダウンロードを自動化

WebDriver 経由でファイルのダウンロードを実行した場合、例えば以下のようなテストケースとする

require 'rubygems'
require 'selenium-webdriver'
 
### FireFoxの設定 (Proxy, Language, Locale)
profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = Selenium::WebDriver::Proxy.new(
  :http => 'proxy.local:80',
  :ssl => 'proxy.local:80',
  :no_proxy => nil
)
profile['intl.accept_languages'] = "ja"
profile['general.useragent.locale'] = "ja-JP"

 
### ダウンロード先を「/tmp/selenium-webdriver」に指定
profile['browser.download.dir'] = "/tmp/selenium-webdriver"
### (folderList=2) ダイアログを出さずにダウンロードを実行する
profile['browser.download.folderList'] = 2
### ダイアログを出さずにダウンロードを実行するcontent-typeを指定
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/plain, application/vnd.ms-excel, text/csv, application/zip, text/comma-separated-values, application/octet-stream'

wd = Selenium::WebDriver.for :firefox, :profile => profile
 
### 以下、テストケース
wd.get "http://www.post.japanpost.jp/zipcode/dl/oogaki/zip/13tokyo.zip"
wd.quit

トラブルシューティング

FireFoxを上手く操作できない

以下のようなエラーがでるケースがある

Selenium::WebDriver::Error::WebDriverError:
  unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)

これは、Selenium の WebDriver からFireFoxを上手く操作できない(WebDriver::FireFoxは7054/7055ポートを使用)状況で発生する。 このエラーが出現する場合、多くの場合は以下の2点のうち、どちらかの問題である。

  • そもそも FireFox が正しく実行できない(FireFox実行に必要な依存ライブラリがインストールされていない、など)
  • Xvfbへ接続する際のディスプレイ番号(環境変数 DISPLAY)が不一致

cygwin (64bit) で selenium-webdriver の gemが上手くインストールできない

上述のLinux環境を Cygwin で実現したい場合に、selenium-webdriver の gem インストールが上手くいかないケースがある。 これは WebDriverのgemがNativeCompileを必要とすることと関連しているらしいので、以下のページを参考に「export PKG_CONFIG_PATH="/lib/pkgconfig"」を行ったうえで再度 gem install を実行して暫定回避。 http://d.hatena.ne.jp/msfukui/20140205/1391560822

その他

Xvfb のスクリーンショットを撮る

以下のパッケージを導入する

Xvfbが起動している状態で、以下のコマンドを実行することでキャプチャ画像を取得できる

# DISPLAY=:1 で Xvfb が起動している場合
 
# スクリーンショットを取得
xwd -root -out -display :1 screen.xwd
# 取得したデータを画像形式に変換
convert screen.xwd screen.gif
 
# 以下でも同様
xwd -root -display :1 | convert screen.gif