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.

has_secure_password with Rails 4.1

I just started a new project with Rails 4.1 and explored the has_secure_password feature. Really awesome stuff!

I hope you are not storing passwords in clear text to your database! You should always store some kind of hashed values instead of clear text passwords. In case somebody steals your database he/she still doesn’t has the passwords.

There are a couple good tutorials how to hash and store passwords in a secure way. I implemented it a couples times by myself with Ruby.

A more sophisticated solution is devise, a very robust gem for security and authentication.

However. Since Rails 3.1 you can take advantage of has_secure_password. This mechanism in Rails takes care of password validation and encryption. It requires a field ‘password_digest’ in your model, where it will store the encrypted password. Let’s generate a simple model.

rails g model user username:string password_digest:string

Let’s add this line to the user model.

has_secure_password

This will add an attribute password and password_confirmation to your model. This 2 fields are now part of your model but not part of the database schema! Because we don’t want to store cleartext passwords.

Let’s add some tests.

require 'spec_helper'

describe User do

  it "fails because no password" do
    User.new({:username => "hans"}).save.should be_false
  end

  it "fails because passwrod to short" do
    User.new({:username => "hans", :password => 'han'}).save.should be_false
  end

  it "succeeds because password is long enough" do
    User.new({:username => "hans", :password => 'hansohanso'}).save.should be_true
  end

end

3 very simple tests. Persisting a new user without password should fail. Persisting a new user with too short password should fail as well. And creating a new user with a long password should succeed. If you run this tests with RSpec the 2nd test will fail. By default Rails doesn’t has a validation for the length of the password. So let’s add it to our user model.

class User < ActiveRecord::Base

  has_secure_password
  validates :password, :length => { :minimum => 5 }

end

If you run the tests again, they will be green. If you take a look into your database you will see that the user table/collection has a column password_digest with a very cryptical value. But there are no columns for password! That’s exactly what we wanted.

Now lets do the authentication. Assume a new user signed up at your portal and now he wants to login. This is how you authenticate him.

user = User.find_by_username("USERNAME").authenticate("CLEAR_TEXT_PASSWORD")

If the username and the clear text password from the HTTP Request is correct it will return a valid user from the database. Otherwise it will return nil!

has_secure_password validates the password on creation time, the very first time you persist it. It doesn’t check the password field after that, for updates for example. And that’s OK. Because that means you can load a user later from db, change it and persist it without knowing the password.

Another feature of this mechanism is password confirmation. has_secure_password also adds an attribute password_confirmation to your model. This attribute gets only validated if it’s not nil. If it’s not nil it must be equal to the password attribute. Let’s add 2 more tests for that one.

  it "fails because password confirmation doesnt match" do
    User.new({:username => "hans",
      :password => 'hansohanso',
      :password_confirmation => 'aa'}).save.should be_false
  end

  it "succeeds because password & confirmation match" do
    User.new({:username => "hans",
      :password => 'hansohanso',
      :password_confirmation => 'hansohanso'}).save.should be_true
  end

To make this tests pass you have to add one more line to the model.

class User < ActiveRecord::Base   
  has_secure_password   
  validates :password, :length => { :minimum => 5 }
  validates_confirmation_of :password
end

The line “validates_confirmation_of :password” will check the password confirmation.

Rails doesn’t force you to have a password confirmation for your model, but if you want it you can turn it on.

I really like this feature because it saves me a lot of code and development time. And for most applications this is really enough.

Let me know what you think about this, either in the comments or on Twitter.

Comparison of Application Level Package Managers

I have to work with a lot (9) of different package managers at my daily work at VersionEye. Part of our mission is it to make manual updating of dependencies extinct, because it’s a manual and time consuming task which nobody enjoys. That’s why we are building a notification system for open source software libraries to make Continuous Updating easy and fun. And since we support several programming languages – 8 at this point! – I get to write crawlers and parsers for all of them. To give you a better overview over the strengths and weaknesses of these package managers, I picked the most popular one for each language and will compare them. The contenders are:

  • RubyGems / Bundler (Ruby)
  • PIP / PyPI (Python)
  • Packagist / Composer (PHP)
  • NPM (Node.JS)
  • Bower (JS, CSS, HTML)
  • CocoaPods (Objective-C)
  • Maven (Java)
  • Lein (Clojure)

Comparison Matrix

Here are the results of my comparison.

Comparison of Package Managers

You can read the complete article on the VersionEye Blog and follow the discussion on hacker news and Reddit.

Semantic Versioning

Do you know semantic versioning? You should! It describes how to name version numbers. Check it out here: semver.org.

This is the pattern it describes:

MAJOR.MINOR.PATCH

MAJOR version when you make incompatible API changes 
MINOR version when you add functionality in a backwards-compatible manner
PATCH version when you make backwards-compatible bug fixes

The cool thing here is that on the version number itself you can already see how big the changes are in the new release. A typical semantic version number is this:

3.2.1 

Let’s say I am using version “3.2.0” in my project. Now I can immediately see that the new version of the package “only” contains a patch. That means for me that I can update without worrying. On the other side if this version comes out:

4.0.0 

And I am using version “3.2.1” of the package in my project, I can now immediately see that this update will very likely break my build! In this case I have to look into the change logs and follow the migration paths.

Semantic versioning even addresses alpha and beta versions. If you are working on version “4.0.0” but it’s not quiet ready but you wanna release anyway something, you can name it like this:

4.0.0-a

That means that is version “4.0.0” alpha. And this here would be the beta version:

4.0.0-b 

Another convention is “RC”, that means “Release Candidate”. You can use it like this:

4.0.0-RC1 
4.0.0-RC2

The complete order over all of them is like this, the highest and newest version is on the top.

4.0.0
4.0.0-RC2 
4.0.0-RC1
4.0.0-b
4.0.0-a

That basically means 4.0.0 > 4.0.0-RC2 > 4.0.0-RC1 > 4.0.0-b > 4.0.0-a.

I’m the author of naturalsorter. That is an open source library to sort semantic version numbers in the correct way.

HTTP_REFERER for RSpec is missing

Currently got this error message after executing my RSpec tests:

ActionController::RedirectBackError:
 No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].

The error message and Stackoverflow tells you to set request.env[“HTTP_REFERER”]. I did that:

request.env["HTTP_REFERER"] = "/signin"

But that didn’t helped. Instead of that I set the HTTP_REFERRER directly in the post. Here is the snippet from my test code:

post "/sessions", {:session => {:email => user.email, :password => user.password}}, {"HTTPS" => "on", 'HTTP_REFERER' => '/signin'}

That fixed my problem.

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.