前回の記事、
Dockerを使ってHeadless Chromeを動かしてみるでDockerからHeadless Chromeを使う環境が出来たので、これをベースにCapybaraからHeadless Chromeを使う環境を構築してみます。
Docker Imageの構築
前回からの変更点としては、chromium-chromedriverの追加とRuby関連のライブラリの追加です。nokogiri等も入れてbunlde install時に
困らないようにしておきます。
FROM alpine:edge
RUN apk add --update \
udev \
ttf-freefont \
chromium \
chromium-chromedriver
RUN mkdir /noto
ADD https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip /noto
WORKDIR /noto
RUN unzip NotoSansCJKjp-hinted.zip && \
mkdir -p /usr/share/fonts/noto && \
cp *.otf /usr/share/fonts/noto && \
chmod 644 -R /usr/share/fonts/noto/ && \
fc-cache -fv
WORKDIR /
RUN rm -rf /noto
RUN apk add --update ruby \
ruby-bundler \
ruby-irb \
ruby-dev \
build-base \
libxml2-dev \
libxslt-dev \
libffi-dev \
zlib-dev
RUN gem install nokogiri --no-doc --no-ri
RUN gem install ffi --no-doc --no-ri
ENTRYPOINT tail -f /dev/null
Capybaraのインストール
前段落で構築したイメージをコンテナを起動して、Capybaraをインストールします。
下記のようなGemfileを作成してbundle installを行います。
# frozen_string_literal: true
source "https://rubygems.org"
gem "rspec"
gem "json"
gem "capybara"
gem "selenium-webdriver"
Capybaraの設定
ここはseleniumを使うときと大きな違いはありませんが、
webdriverからchromeに渡すオプションにheadlessで必要な
項目を渡します。
require 'capybara/rspec'
require 'selenium-webdriver'
RSpec.configure do |config|
config.include Capybara::DSL
end
base_args = %w{headless no-sandbox disable-gpu}
Capybara.register_driver :headless_chromium do |app|
args = base_args.dup << "--window-size=1900,1080"
caps = Selenium::WebDriver::Remote::Capabilities.chrome(
"chromeOptions" => {
'binary' => "/usr/bin/chromium-browser",
'args' => args
}
)
driver = Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities: caps
)
end
Capybara.default_driver = :headless_chromium
chomeOptionsのbinaryのところには、Headless Chomeのバイナリ
のパスを指定します。今回の環境では/usr/bin/chrominm-browserが
Headless Chomeのパスになっていました。
Capybaraを使ったテストの実行
ここは通常のCapybara+Seleniumの時の処理を同じように
記述します。
Capybara.app_host = 'http://qiita.com/'
describe "http://qiita.com" do
before do
visit '/'
end
it "we can see top page" do
expect(page).to have_content('Qiitaは、プログラマのための
技術情報共有サービスです。')
expect(page.driver.browser.current_url).to match /qiita/
page.save_screenshot('screenshot.png')
end
end
ただし、[2017/6最新]RubyとSeleniumでHeadless chromeを動かす on Ubuntu/Linuxにあるとの同じエラーは当然発生するためにCapybaraでも以下のような
コードはエラーになってしまいます。
Capybara.app_host = 'http://qiita.com/'
describe "http://qiita.com" do
before do
visit '/'
end
it "input identity" do
fill_in('identity', :with => "dd511805")
expect(page.driver.browser.current_url).to match /qiita/
end
end
javascriptでのキー入力はできるようなので、この場合では
fill_inとは別の関数(下の例ではfill_in_val)を定義しておいて、
テストを書き換えることで、エラーを回避しつつ、テストが
実行できます。
module HeadlessAction
def fill_in_val(id, options)
with = options.delete(:with)
page.execute_script "document.getElementById(\"#{id}\").value = \"#{with}\";"
end
end
RSpec.configure do |config|
config.include HeadlessAction
end
Capybara.app_host = 'http://qiita.com/'
describe "http://qiita.com" do
before do
visit '/'
end
it "input identity" do
fill_in_val('identity', :with => "dd511805")
expect(page.driver.browser.current_url).to match /qiita/
end
end