Handling Rails Date Selects in Capybara and RSpec

There are multiple ways to present dates in a Rails form. The default approach when scaffolding an object is to present the date as 3 dropdowns for date year, month and day.  How to generate a test with Capybara in RSpec isn’t always obvious, so we’ll going to cover that here. We’re also going to show how to style the html a bit, since that is not obvious either.

Here’s a date selection in a rails form.

The Controller

We’re working with coupons in this form, you know, $1.00 off a 9-pack of Charmin.  Coupons have a belong_to relationship with User, who has_many coupons. While our main focus is on testing the date selections in Capybara and RSpec, a quick visit to the controller’s CREATE action may provide a helpful processing tip. Coupon, as we just mentioned, belongs to Users.  It may be initially confusing how we’re going to extract the form contents of this nested resource.  The trick here is to first define the @user object then use it to build the @coupon from the form parameters.

Testing in Capybara and RSpec

Now onto the tests. It would be nice if you could do a simple

select “Expiration Date”, from: “coupon_expiration_date”

but you can’t. The key here is to select the date values from the individual dropdown selections.

As you can see we just selected the selection.text. If you want the selection.values, here’s a way of retrieving those.

Hm, I suppose find_field(…).text would work for the text items, but I haven’t tested that.

Html Stylings

If you’re interested in how the dropdowns are styled it’s okay since that isn’t obvious either.  To shorten the width of the date element dropdowns we’re passing the CSS class to each of them.

<%= f.date_select :expiration_date,
{:order => [:day, :month, :year], :start_year => 2013, :end_year => 2015},
{ :class => ‘date-select’}  %>

I don’t plan on staying with the multiple date-part selection approach on the Coupon form indefinitely, so there will no doubt be a future blog post titled Alternatives to the Default Rails
or something along those lines…