yujiro's blog

「インターネット上で正しい答えを得る最善の方法は、質問することではない。間違った答えを投稿することだ」by ウォード・カニンガム。 辛辣なコメントお待ちしております。

サブドメイン環境でCircleCI でCapybara, Poltergeist を使うとき、hosts と Capybara.app_host に気をつける

事の発端

ローカルでは動く feature spec が circle ci 上で動かなかった。 circle ci 上で確認したエラーは以下。

Capybara::Poltergeist::StatusFailError

      Request to 'http://admin.lvh.me:3000/admin_users/sign_in' failed to reach server, check DNS and/or server status
./spec/features/admin/hoge_spec.rb:47:in `block (3 levels) in <top (required)>' 

これは、名前解決できていないということで、調べた所、circle.yml に hosts の指定ができるらしい。

machine:
  hosts:
    admin.lvh.me: 127.0.0.1

上記のようにかくことで circle ci サーバーの /etc/hosts に記述されるっぽい。


また、管理画面などサブドメインのテストをするときは

Capybara.app_host = "http://admin.lvh.me:3000"

のように書くと思いますが、ポートを3000番と指定すると js: true のテストをするときにうまくいかない。

これは poltergeist の github README にも書かれてるけど、ランダムにport が使用されるため。

:port (Fixnum) - The port which should be used to communicate with the PhantomJS process. Defaults to a random open port.

GitHub - teampoltergeist/poltergeist: A PhantomJS driver for Capybara

なので、js: true のテストをするときは、Capybara.current_session.server.port でポートを取得し、そうでない場合は 3000 番を使えば良い。 (port は指定できるみたいだけど、今回は下記で解決しました。)

port = Capybara.current_session.server.present? ? Capybara.current_session.server.port : "3000"
Capybara.app_host = "http://admin.lvh.me:#{port}"

これでバッチリ動きます。


この件はcircle ci 関係ないじゃん、って話なんだけど

今まで僕はローカルで

$ bundle exec rails s -e test

としてから、js: true の feature スペックを実行していました。

それはどっちにしろcircle ci では動かないね、って話です。

参考

subdomainでrspecしたいがハマる。 - railsがんばる子

ruby on rails 3 - How can I get the current hostname and port when running Capybara with Poltergeist? - Stack Overflow

Rails+Rspec+Capybaraでサブドメイン指定のE2Eテストをする - Qiita