PhantomJS + Poltergeist を Selenium + Headless Chrome で置き換える (1) Rails + Capybara による feature spec 編 - valid,invalid の続き。
teaspoon.env の変更内容について
Capybara + Selenium + headless Chrome の設定例はググると結構出てくるものの、Teaspoon + Selenium + headless Chrome の例はぜんぜん出てこなかった…。
それもそのはず、詳細は後述するが Teaspoon 自体のメンテナンスがあまりアクティブでないために組み合わせるためにモンキーパッチを当てなければいけない始末だった。
変更部分
以下はコードの追加分。
require 'teaspoon/driver/selenium'
Teaspoon::Driver::Selenium.class_eval do
def run_specs(runner, url)
driver = ::Selenium::WebDriver.for(driver_options[:client_driver], @options.except(:client_driver))
driver.navigate.to(url)
::Selenium::WebDriver::Wait.new(driver_options).until do
done = driver.execute_script("return window.Teaspoon && window.Teaspoon.finished")
driver.execute_script("return window.Teaspoon && window.Teaspoon.getMessages() || []").each do |line|
runner.process("#{line}\n")
end
done
end
ensure
driver.quit if driver
end
end
Teaspoon.configure do |config|
config.driver = :selenium
options = if ENV['SELENIUM_URL'].present?
http_client = Selenium::WebDriver::Remote::Http::Default.new(read_timeout: 120)
{
client_driver: :remote,
url: ENV['SELENIUM_URL'],
http_client: http_client,
}
else
{ client_driver: :chrome }
end
options.merge!(
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
chrome_options: {
args: %w(headless window-size=1680,1050)
}
)
)
config.driver_options = options
end
driver options あたりは Capybara のときとほぼ同じ。
実際にはこのリプレイスのほか、remote の Selenium Chrome でも動くようにする変更を足したりして大変だったのだが本題ではないので省略する。
driver options 渡せない問題
まずいちばんの問題が Teaspoon v1.1.5 では Selenium::Webdriver
に driver options を渡せないこと。これを改善する PR が提案されているのだが10ヶ月ほど放置されている…。
teaspoon.env
は同様に困っている人々が書いた monkey patch を拝借しつつ書いた。
Net::ReadTimeout 問題
Capybara の設定との大きな違いは HTTP client を渡しているところ。これは remote Chrome -> Teaspoon server へのリクエストがデフォルトの HTTP client だと頻繁に Net::ReadTimeout してしまうため。
最初は Chrome の起動が遅いのかと疑ったが driver の初期化付近にブレイクポイントを張ってデバッグしたところ、driver.navigate.to(url)
が高確率でタイムアウトしていることがわかった。
driver = ::Selenium::WebDriver.for(driver_options[:client_driver], @options.except(:client_driver))
+ binding.pry
driver.navigate.to(url)
Teaspoon の立ち上がりがそれだけ遅いのは実行されるテスト側に問題があるのかもしれないが、ほぼ初めて触るこのレポジトリのテストコードがどんな感じか見定めるのは厳しかったので read_timeout を伸ばした HTTP client を渡すことで回避した。
設定は 30 -> 60 -> 90 -> 120と試したが安定したのは 120 だけだった。
感想
PhantomJS + Poltergeist を Selenium + Headless Chrome で置き換えて多幸感を得たはずが Teaspoon との戦いで疲弊してしまった。次は Teaspoon を消そう。