CentOS上にてRSpec+Turnip+Capybara+Selenium Webdriver+Headlessでスクリーンショットを撮るまで


CUIのみのLinuxでseleniumを使おうとした所ちょっと手順を踏む必要がありました。

#インストールするもの
##Xvfb

[Xvfb 仮想フレームバッファ・サーバ - insomnia](http://yasuda.homeip.net/insomnia/2010/04/xvfb-install.html)より
>
Xvfb はディスプレイのないサーバ機などで X Window System の画面入出力をシミュレートする X11 のサーバ・ソフトウェアである。 例えば，あるサイトのリンクにそのページ画面のサムネイル画像を掲げているのをよく目にするが，これをサーバで自動的にやろうとすると，JavaServlet などでサイトのページを取得し，ブラウザと同様にレンダリングし，画面イメージを生成するわけだ。 このとき Awt などの「ディスプレイ」の存在を仮定するライブラリを使うのが常である。 そこで，ディスプレイ・レスの UNIX サーバ機でもそれをエミュレートする，仮想フレームバッファなるインタフェースを提供するのが Xvfb である。

これによりSeleniumをヘッドレスに動かすことができます。

```bash
$ sudo yum install xorg-x11-server-Xvfb
```

##ImageMagick
スクショを取るのに必要だそうです。
自分の場合別途インストールしてたのでよく覚えてないです()

```bash
# これだけで大丈夫なはず...
$ sudo yum install ImageMagick
```



##Firefox
今回Firefoxでテストしたいのでyumで入れます。

```bash
$ sudo yum install firefox
```


##日本語化
ブラウザの文字化けを防ぐため日本語化します

```bash
$ sudo yum groupinstall "Japanese Support"
```


##各種gemたち

```ruby:Gemfile
group :test do
  gem 'rspec-rails'
  gem 'capybara'
  gem 'turnip'
  gem 'selenium-webdriver'
  gem 'headless'
  # あと factory_girl_rails とか database_cleaner とか適宜どうぞ
end
```

`headless`はrubyからXvfbの起動終了を行うためのgemです。
めっちゃ簡単なので入れておくといいと思います。


#Xvfb準備
bash_profileなどに以下を追加します。

```bash:.bash_profile
export DISPLAY=:99
```

`headless`がデフォルトで`DISPLAY=:99`を使用するのでそれに合わせて`:99`にします。

上記追加したら`source ~/.bash_profile`などで設定を反映。
動作テストをしてみます。

```bash
$ Xvfb :99 -screen 0 1024x768x24 &
$ firefox &
```

これで変なエラーが出なければok。
終了する際は`killall Xvfb`などで。

###自分が嵌ったエラー

```bash
$ Xvfb :99 -screen 0 1024x768x24 &

...

The XKEYBOARD keymap compiler (xkbcomp) reports:
> Internal error:   Could not resolve keysym XF86AudioMicMute
Errors from xkbcomp are not fatal to the X server
```

↑これが出ても特に問題ないみたいなので無視しても大丈夫...?

```bash
$ firefox &
Error cannot open display: :99
```

↑環境変数`DISPLAY`が`Xvfb`起動時に引数で渡したものと一致してるか・設定が反映されてるか確認して下さい。
また、もちろんXvfbが起動してないとfirefox使えません。


#RSpec設定
`spec_helper.rb`などの設定ファイルにて

```ruby:spec_helper.rb
# (適当に必要なものrequireして下さい)
require 'selenium-webdriver'
require 'headless'
require 'capybara/rspec'
require 'turnip'
require 'turnip/capybara'

...

RSpec.configure do |config|

...

  # selenium-webdriver
  # 名前は任意。今回は selenium_firefox とします。
  Capybara.register_driver :selenium_firefox do |app|
    Capybara::Selenium::Driver.new(app, browser: :firefox)
  end
  Capybara.javascript_driver = :selenium_firefox
  # 常時使用の場合は Capybara.default_driver = :selenium_firefox
  
  # headless
  config.before(:all) do
  	# デフォルトだとウインドウサイズが心もとないので大きくしときます。
    @headless = Headless.new(dimensions: "1920x1080x24")
    @headless.start
  end

  config.after(:all) do
    @headless.destroy
  end
end

```

`Headless.new`の引数は[こちら](http://www.rubydoc.info/gems/headless/Headless:initialize)をどうぞ。
listenする`DISPLAY`変えたりとかもできます。


#スクショを撮る
準備完了なのでスクショとります。

```screen_shot.feature
# encoding: utf-8
# language: ja

# Capybara.javascript_driver = :selenium_firefoxなら
# @javascriptタグが必要
@javascript 
機能: スクリーンショットをとる
  シナリオ: google先生のスクショを撮る
  もし "http://google.com"にアクセスする
  ならば スクリーンショットを撮る
```

```ruby:screen_shot_steps.rb
step ':urlにアクセスする' do |url|
  visit url
end

step 'スクリーンショットを撮る' do
  # 引数には 適当なパス/ファイル名.png
  page.save_screenshot("/vagrant/google.png")
end
```

で実行すると

![150105_google_screen_shot.png](https://qiita-image-store.s3.amazonaws.com/0/64633/99d37058-2373-13b4-2205-290a083d5177.png "150105_google_screen_shot.png")

ちゃんとスクリーンショットが撮れました!