teaspoon.env の変更内容について
Capybara + Selenium + headless Chrome の設定例はググると結構出てくるものの、Teaspoon + Selenium + headless Chrome の例はぜんぜん出てこなかった…。
それもそのはず、詳細は後述するが Teaspoon 自体のメンテナンスがあまりアクティブでないために組み合わせるためにモンキーパッチを当てなければいけない始末だった。
変更部分
以下はコードの追加分。
# spec/teaspoon_env.rb # Teaspoon doesn't allow you to pass client driver options to the Selenium WebDriver. This monkey patch # is a temporary fix until this PR is merged: https://github.com/jejacks0n/teaspoon/pull/519. require 'teaspoon/driver/selenium' Teaspoon::Driver::Selenium.class_eval do def run_specs(runner, url) # この1行のためのモンキーパッチ 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 # test suite の記述が続く 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 を消そう。