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)
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.
Prohibit Git from merging .po-files
Merging .po-files with Git is painful.
There have been attempts of making Git more clever when trying to merge .po-files. I believe however that this is not enough as it can still produce invalid .pos (usually due to double definitions), which can seriously confuse gettext afterwards.
Lacking any more secure solution, I think you should avoid editing po files in different branches at the same time. In order to not accidentally produce invalid merges I additionally ...
Mocks and stubs in Test::Unit when you are used to RSpec
We are maintaining some vintage projects with tests written in Test::Unit instead of RSpec. Mocks and stubs are not features of Test::Unit, but you can use the Mocha gem to add those facilities.
The following is a quick crash course to using mocks and stubs in Mocha, written for RSpec users:
|---------------------------------------------------------|
| RSpec | Mocha |
|---------------------------------------------------------|
| obj = double()
| obj = mock()
|
| obj.stub(:method => 'value')
| `obj.stubs...
Delete all MySQL records while keeping the database schema
You will occasionally need to clean out your database while keeping the schema intact, e.g. when someone inserted data in a migration or when you had to kill -9
a frozen test process.
Old Capybara versions already have the Database Cleaner gem as dependency. Otherwise add database_cleaner
to your *Gemfile`. This lets you say this from the Rails console:
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.cl...
Synchronize a Selenium-controlled browser with Capybara
When you click a link or a press a button on a Selenium-controlled browser, the call will return control to your test before the next page is loaded. This can lead to concurrency issues when a Cucumber step involves a Selenium action and a Ruby call which both change the same resources.
Take the following step which signs in a user through the browser UI and then sets a flag on the user that was just signed in:
Given /^the user "([^"]*)" signed in (\d) days ago$/ do |name, days|
visit new_session_path
fill_in 'Username', :w...
Check that an element is hidden via CSS with Spreewald
If you have content inside a page that is hidden by CSS, the following will work with Selenium, but not when using the Rack::Test driver. The Selenium driver correctly only considers text that is actually visible to a user.
Then I should not see "foobear"
This is because the Rack::Test driver does not know if an element is visible, and only looks at the DOM.
Spreewald offers steps to check that an element is hidden by CSS:
Then "foo" should be hidden
You can also check that an el...
Configuring User Agents with Capybara + Selenium Webdriver
A while ago we were working on an application that had an entire version specially created for mobiles, such as the iPhone. This specific application was entirely tested with Capybara, Steak and Selenium Webdriver. Although the test suite wasn’t the fastest one in the world, the web application was very well tested, and to guarantee that we would also be testing the mobile version, we would have to simulate an iPhone user agent accessing the application.
But wait, you might be thinking that we are not able to change browser headers while ...
Escaping of quotation marks in Cucumber steps and step definitions
Issue
When you have a Cucumber step like
Then I should see "Did you see those \"quotation marks\" over there?"
you'll run into trouble. Cucumber won't take your escaped quotation marks.
Workarounds
One workaround is to write the step as regex (since there is a step taking a regex):
Then I should see /Did you see those "quotation marks" over there\?/
Keep in mind it’s a regex – escape regex characters like '?'.
When you have a Cucumber step like
Then I should fill in "query" with "\"some phrase\""
The fo...