Feedforce Developer Blog

フィードフォース開発者ブログ

chromedriver-helper gem のバグを調査したが解決しなかった

エンジニアの id:kielze です。最近の趣味はBaroccoのキー配置をプログラミングして良い感じにすることです。

僕の所属するチームで作っているアプリケーションでは、manifest.json を良い感じにすることによってReact + ReduxをRails上で動かしています。 それもあって、E2EテストをCapybara + Selenium + Chromeで動かすことになりました。

capybaraからchromeを動かすのにはchromedriverが必要なのですが、chromedriver-helper というGemを使ってインストールやアップデートを自動化しようと試みました。最初はうまく動作していたのですが、しばらくして手元でcapybaraを動かした際によくわからないエラーに遭遇してしまいました。

今回はその原因を調査し解決しなかったので、調査したことをメモがてらまとめたいと思います。これを読んで原因が分かる方がいましたら、是非優しく教えて頂けると僕が喜びます!

chromedriver-helper gemは何をしているの?

chromedriverはmacであれば普通にHomebrewでインストールできるのですが、chromedriver-helperを用いてインストールすると ~/.chromedriver-helper 以下に実行ファイルがインストールされます。例えばchromedriverのバージョンが2.33の場合だと、~/.chromedriver-helper/2.33/mac/chromedriverのような感じです。

また、chromedriver-helperをbundlerでインストールするとbinstubが作成されます。
$ bundle install --path vendor/bundleでインストールした場合だとvendor/bundle/ruby/2.4.0/bin/chromedriverです。

つまり、chromedriver-helperをインストールすると、パスの通ったchromedriverを直接起動するのではなく、chromedriverのbinstubを経由してホームディレクトリ以下にインストールされているchromedriverを起動します。

chromedriverを起動すると http://127.0.0.1:9515/ でサーバーが立ちます。

どんなエラーが起こったのか

chromedriverを起動しhttp://127.0.0.1:9515/にアクセスした状態で、rails console上でcapybaraを起動しようとすると、9515ポートに繋がらないということでエラーになります。これは、chromedriverが起動済みなのにも関わらずcapybaraが新しくchromedriverを立ち上げようとしてエラーになっています。想定される通常の動作ですね。

Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9515

問題はここからで、起動済みのchromedriverを停止した後に改めてrails console上でcapybaraを起動すると、なぜか同じエラーで落ちてしまいます。psコマンドで見てみても停止したchromedriverがゾンビ化している様子もありません。これはおかしいです。

とりあえずchromedriverが単体で動作するかチェックするために、ターミナルからchromedriverを直接起動してみました。すると普通に動作したので、chromedriver自体に問題はなさそうです。

そこで、rails console上から system 'vendor/bundle/ruby/2.4.0/bin/chromedriver' のような感じでchromedriver-helperによって作成されたchromedriverのbinstubを実行してみました。すると、本来であればchromedriverが起動するはずがエラーで落ちてしまいました。

/Users/yosuke/.anyenv/envs/rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/bundler-1.16.0/lib/bundler/rubygems_integration.rb:458:in `block in replace_bin_path': can't find executable chromedriver for gem chromedriver-helper. chromedriver-helper is not currently included in the bundle, perhaps you meant to add it to your Gemfile? (Gem::Exception)
    from /Users/yosuke/.anyenv/envs/rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/bundler-1.16.0/lib/bundler/rubygems_integration.rb:478:in `block in replace_bin_path'
    from vendor/bundle/ruby/2.4.0/bin/chromedriver:23:in `<main>'

Gem.bin_path('chromedriver')を実行しても同じエラーが返ってきます。

なぜかchromedriverのbinstubが実行できなくなってしまいました。

試しにchromedriverのbinstubを消して、brewでインストールしたchromedriverが起動する状態にしたところ、上記のエラーが起こることなく正常に動作しました。

うーん、わからない...。

解決策

  1. ローカルではchromedriverのインストールをHomebrewで行う
  2. CircleCI上では既にブラウザの入っているコンテナを使う(circleci/ruby:2.4.2-node-browsersなど)

以上です。

いや、本当はbinstubが実行できなくなってしまった原因をきちんと解明したかったのですが、調査に思ったより時間がかかってしまったため、えー...はい...。(未解決!)
すみません🙇

この問題は以下でも報告されていて、僕の環境以外でも起こっているようでした。

ちなみにこのGemを作られた方がNokogiriの作者で少しびっくりしました。

普段からライブラリのソースコードを読んでおくことの大切さが身に沁みた出来事でした。