In one of my earlier posts, I showed you how to reuse cucumber step definitions inside other step definitions. Today, I came across a simple “gotcha” that took me a few minutes to debug… so I think it’s something that you should know about if you plan on using that technique.
Here is the faulty code (assume all the reused step definitions exist and don’t contain any errors):
Given /^I am logged in with email "([^\"]*)" and password "([^\"]*)"$/ do |email, password|
Given 'I go to the login page'
And 'I fill in "email" with "#{email}"'
And 'I fill in "password" with "#{password}"'
And 'I press "Login"'
Then 'I should see "Login successful"'
endThe funky thing was that it didn’t really raise an error. However, later in the code when I try to login, it wouldn’t do it and the page contains this error:
1 error prohibited this user session from being savedThere were problems with the following fields:Email does not exist
Can you see the error? The problem is that I’m trying to use #{} inside a single quoted string (i.e: ’string’ ) which takes everything inside it literally. If it were a double quoted string (i.e. “string”), it would evaluate whatever was inside the #{} and mix it in with the string.
So here’s what’s happening. When I tell it:
Given I am logged in with email "my@email.com" and password "secret"
It fills in the email field with “#{email}” instead of “my@email.com”.
There is a simple fix:
Given /^I am logged in with email "([^\"]*)" and password "([^\"]*)"$/ do |email, password| Given 'I go to the login page' And 'I fill in "email" with "' + email + '"' And 'I fill in "password" with "' + password + '"' And 'I press "Login"' Then 'I should see "Login successful"' end
I don’t like it but it works. Also, a better way to write the above might be to not reuse the webrat step definitions and write it with webrat’s ruby methods like this:
Given /^I am logged in with email "([^\"]*)" and password "([^\"]*)"$/ do |email, password| visit login_path fill_in "email", :with => email fill_in "password", :with => password click_button "Login" Then 'I should see "Login successful"' end
I’m not sure which one I prefer more. I’m leaning towards the plain English version even if it means manually joining strings using +. What are your thoughts?

{ 2 comments… read them below or add one }
We can use the % delimiter to avoid using quotes. Here's an example from Thoughtbot's Clearance:
When /^I sign in( with “remember me”)? as “(.*)/(.*)”$/ do |remember, email, password|
When %{I go to the sign in page}
And %{I fill in “Email” with “#{email}”}
And %{I fill in “Password” with “#{password}”}
And %{I check “Remember me”} if remember
And %{I press “Sign In”}
end
Oh I like that. Thanks for pointing that out.