Configuring host and port for Selenium/Capybara

I’m using Capybara and Selenium together with RSpec to test the Web Interface for VersionEye. That works very well. For an integration test I needed a callback on localhost:3000/auth/*. By Default Capybara is starting the tests on an odd host and port name to avoid conflicts with locahost:3000, which is the default host and port for Rails Apps in development. It took me something like 30 min. to find out how to force capybara to run all Tests on localhost:3000. That’s why I think it’s worth blogging 🙂

Either in your `spec_helper.rb` or in `spec/support/capybara.rb` you will have this imports:

require 'capybara/rails'
require 'capybara/rspec'
require 'capybara/firebug'

Below that you can configure Capybara like this.

Capybara.app_host = "http://localhost:3000"
Capybara.server_host = "localhost"
Capybara.server_port = "3000"

That worked for me.

Testing AJAX with Capybara and Selenium

In the past days I migrated my tests from WebRat to Capybara and I wrote a couple new acceptance tests with RSpec, Capybara and the selenium-webdriver. All in one it’s pretty cool.

You can just keep writing your acceptance tests as usual with RSpec and Capybara. Here is a small example.

describe "Empty Payment History", :js => true do
  it "shows correct message when there's no history" do
    visit "/settings/payments"
    have_css "#payment_history", text: "You dont have any Payment history"
  end
end

This test is sending a request to “/settings/payments” and is testing if on the page the CSS class “payment_history” occurs. Pretty easy. This you could also do with WebRat. But the magic is in the first line. “:js => true” that tells Capybara that it should execute the test with the selenium-webdriver. That will basically start your browser (Firefox) and you can see how the test gets executed. This is not possible with WebRat.

It’s just getting a little bit tricky if you do a lot of AJAX requests on the page. In the Capybara documentation they write that you should use the “find” methods, because they wait until an element appears on the page. That didn’t worked out for me. The test always failed. Somebody on Stackoverflow wrote that this construct would work for AJAX pages.

within('#payment_history') do
  page.all('a',  :text => 'View receipt')
end

And he was right! This test always succeeded. ALWAYS! Even if the test was completely wrong! 😀 Yeah. Very funny! *LOL* Seems like a bug. I did a little bit more research and finally I found a solution which worked correctly.

using_wait_time 10 do
  page.should have_content("View receipt")
end

With “using_wait_time” you can force Selenium to wait for a couple seconds, until the AJAX requests are done. That finally worked out and the tests are working now correctly.

Testing SSL with Capybara and Selenium

I am using Capybara with Selenium as JS engine to write acceptance tests for a Ruby on Rails application. In some controllers I am forcing SSL with the “force_ssl” filter from Rails. By running the tests with Selenium this caused some problems. Selenium is launching Firefox and calls the URL https://127.0.0.1:3000/signin. Of course there is no SSL for localhost! This causes an error and the test fails.

I did some research for this. There are some tickets on GitHub and StackOverflow to this. but nothing what actually solves the core problem. For right now I just solved it, with running the filter only in production mode and not in test mode.

force_ssl if Rails.env.production?

Now Firefox is launching on http://127.0.0.1:3000/signin.