Stubbed class methods in RSpec 1 remain stubbed in other examples

I encountered a bug in RSpec 1.x where stubbed class methods ("static methods") would not be unstubbed before the next example, causing it to fail. This behavior can come and go as you edit your specs, since this can change the order in which RSpec evaluates your .rb files.

I was not able to find a fix for this behavior. Calling #rspec_reset und #unstub!(:method) on the class after the example did not help. I know for sure that stubbing static methods has not been a problem in many other projects. I encountered the bug while working o...

New Cucumber Factory makes it easier to associate records

I pushed a new version of the Cucumber Factory gem. This new release lets you refer to a previously created record by any string attribute:

Given there is a movie with the title "Before Sunrise"
And there is a movie with the title "Limitless"
And there is a movie with the prequel "Before Sunrise"

Note how we didn't have to explicitly give the prequel a name in the example above. This is still possible, but will rarely be necessary now:

Given "Before Sunrise" is a movie with...

A nicer way to run RSpec and/or Cucumber

geordi, our collection of awesome shell scripts, has been extended by three scripts to help you call RSpec or Cucumber:

cuc

This script runs Cucumber the way you want it:

  • Prints some line feeds to easily find your test results when you come back to the console later
  • Configures Cucumber to use cucumber_spinner if it is available in your Gemfile
  • Runs Cucumber under bundle exec
  • Uses an old version of Firefox for Selenium (Javascript) features...

SSL: Build a Certificate signing request (CSR)

In order to request a SSL certificate from any dealer, you usually need a CSR certificate. As both the CSR as well as key are created in this step, make sure you save this certificate on a trusted, secure machine only. Usually this is your production environment.

Run this on the server (not on your machine) as root.\
Replace your-domain.tld with the domain you request the certificate for and YYYY with the current year so you will not have any conflicts when requesting a certificate next year.

openssl req -new -sha256 -out www.your-dom...

Matching elements on complex web pages with Webrat

XPath matchers can be combined with CSS-selector matchers. This is really useful if not, for example, the content of an element should be matched but the element itself like in the following example. Here a form is used to display data as default value in its input elements. This can be the case in web applications in which data should be edited easily without additional clicks.

How to employ and run your tests with parallel_tests to speed up test execution

When your cucumber features grow massively over time, the test execution can take a lot of time.
One easy way to speed up your test execution is to use the parallel_tests gem.
It comes along with some useful rake tasks that let you setup your local test environment shortly to run your features, specs or unit-tests in parallel.

Follow these steps to get it to work.

  1. Add the parallel_tests gem to your Gemfile test sections like that:

    # ./Gemfile
    
    group :development, :test do
    

...

Test that a number or money amount is shown with Cucumber

This is an awful way to test whether a number is shown on the screen:

Then I should see "5"

It is awful because the step above is green for 5, 5123 and -51.

This step definition below makes sure this doesn't happen. You can use it like this:

Then I should see the number 5

The step also works if you you'd like to test that the number is followed by a unit:

Then I should see the amount 5 €

The separator between the number and its unit is allowed to be either a space or a [nbsp](https://makandracards.com/makandra/838-generate...

Don't call #node on a Capybara element

Capybara allows you to select DOM elements, e.g. by using field, find_field(...) or field_labeled(...):

role_select = field_labeled('Role')

In the example above, role_select is now a Capybara::Driver::Node. You can call a number of methods on such a node, e. g. in order to click it or to make a selection on its descendants. These methods should be the same regardless of the driver Capybara is using (drivers are e.g. the headless Rack::Test or Selenium).

It i...

Cucumber steps to travel through time with Timecop

These steps are now part of Spreewald.


Here are some useful examples how to use the attached Cucumber Timecop steps:

When the date is 2011-05-06
When the time is 2011-05-06 17:30

There is also one really awesome step that lets you travel to the past or to the future:

When /^it is (\d+|a|some) (seconds?|minutes?|hours?|days?|months?|years?) (later|earlier)$/

As yo...

Fix randomly failing PDF cucumber tests

Sometimes PDF cucumber tests fail at the first test run and succeed at the second run. You can fix this with this step:

When PDF generation is ready
And I follow "Save as PDF"
# Checks for PDF contents go here

Here is the step definition:

When /^PDF generation is ready$/ do
  Then 'I should see ""'
end

Getting started with Puppet

When you simply want to get to know Puppet, follow puppetlabs’ Learning Puppet Docs. They give you a handy introduction inside a virtual machine they provide. You can watch the talk by Garrett Honeycutt 'Expanded Introduction to Puppet'.

Do not miss their cheatsheat and their [learn-puppet virtual machine](http://info.puppetl...

Bash script to run specs and features

Run rspec-and-cucumber from any project directory to run both RSpec and Cucumber. If available, rspec_spinner or cucumber_spinner are used.

Note that features are not run when specs fail.\
If you prefer to run them in parallel or run features regardless of the spec results, please adjust it for yourself accordingly.


This script is part of our geordi gem on github.

Git: Advisory for cherry-picks to production branches

We often have a separate production branch that lags a bit behind the more cutting edge main branch. Sometimes you want to move some, but not all commits from main to production. This can be done with a git cherry-pick.

However, this may lead to considerable pain later, since git does not understand the commits are actually "the same". Hazards are unnecessary and hard to resolve conflicts as well as incorrect auto-merges.

In order to avoid this, always merge the production branch back to the main after the cherry-pick. Even t...

HTML5 Presentation

Awesome presentation for the new HTML5 features we will get to play with. This presentation should probably be viewed in Chrome only.

Saving application objects in your session will come back to haunt you

If you save a non-standard object (not a String or Fixnum, etc) like the AwesomeClass from your application in the session of visitors be prepared that some time you will get this exception:

ActionController::SessionRestoreError: Session contains objects whose class definition isn't available. Remember to require the classes for all objects kept in the session. (Original exception: ...)

This happens when you remove your AwesomeClass but users come back to your site and still have the serialization of such objects in their session....

Use CSS attribute selectors with Capybara

You can use CSS attribute selectors in your step definitions like this:

Then /^the page should have a meta description "([^"]+)"$/ do |description|
  page.should have_css("meta[name=\"description\"][content=\"#{description}\"]")
end

Note that you need to always quote attribute values or you will get a Nokogiri parsing error like this:

unexpected 'foo' after 'equal' (Nokogiri::CSS::SyntaxError)

thoughtbot/capybara-webkit

A capybara driver that uses WebKit via QtWebKit.

How to send HTTP requests using cURL

  • Reading a URL via GET:

    curl http://example.com/
    
  • Defining any HTTP method (like POST or PUT):

    curl http://example.com/users/1 -XPUT
    
  • Sending data with a request:

    curl http://example.com/users -d"first_name=Bruce&last_name=Wayne"
    

    If you use -d and do not set an HTTP request method it automatically defaults to POST.

  • Performing basic authentication:

    curl http://user:password@example.com/users/1
    
  • All together now:

    curl http://user:password@example.com/users/1 -XPUT -d"screen_name=batman"
    

...

Imperative vs Declarative Scenarios in User Stories

Bryan talked about the differences between imperative and declarative scenarios. In my opinion, both styles have benefits and should be used appropriately based on the situation. The majority of examples on rspec's story runner currently on the web, including mine, are of the imperative type. Since the declarative type has many advantages I thought it would be worth while to present some examples and contrast the differences between the two styles.

Where to put custom RSpec matchers

When you write a custom RSpec matcher a good place to store them is to create one file per matcher in spec/support/matchers:

spec/support/matchers/be_same_numbers_as.rb
spec/support/matchers/be_same_second_as.rb
spec/support/matchers/exist_in_database.rb
spec/support/matchers/include_hash.rb

You can include all matchers in the support directory by adding the following line to your spec_helper.rb:

Dir[File.expand_path(File.join(File.dirname(__FI...

Different CSS for IE using Sass

At times, it might be unavoidable to have different CSS rules for Internet Explorer than for sane browsers. Using Sass, this can be achieved in a relatively non-hackish way without CSS hacks.

Step 1

Move your current Sass file into a partial. Let's assume it was called screen.sass. Rename it _screen.sass.

Step 2

Create two new Sass files:

Call this one screen.sass:
$ie = false
@import screen

Call this one screen_for_ie.sass:
$ie = true
@import screen

Step 3

Change y...

Acceptance testing using Capybara's new RSpec DSL

Back when Steak was first released, Capybara didn’t have any of the nice RSpec helpers it does now. A lot has changed since. Besides the helpers, it got its own RSpec acceptance testing DSL recently, essentially eating Steak’s functionality and turning it into a complete acceptance testing solution (on top of RSpec).

Upgrading Cucumber and Capybara to the latest versions available for Rails 2

Specify these gem versions in your Gemfile:

gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'

With these versions set, `...

Skip Selenium scenarios in a Cucumber run

Cucumber scenarios that are tagged with @javascript so they run with Selenium are very slow. You might not want to run them every time.

In order to skip all Selenium scenarios, call Cucumber like this:

cucumber --tags ~@javascript

Note that you should still run all the scenarios, including the Selenium ones, before you push a change.