Fix warning: Cucumber-rails required outside of env.rb

After installing Bundler 1.1 you will get the following warning when running tests:

WARNING: Cucumber-rails required outside of env.rb. The rest of loading is being defered until env.rb is called.\
To avoid this warning, move 'gem cucumber-rails' under only group :test in your Gemfile

The warning is misleading because it has nothing to do with moving cucumber-rails into a :test group. Instead you need to change your Gemfile to say:

gem 'cucumber-rails', :require => false

validates_acceptance_of is skipped when the attribute is nil

validates_acceptance_of :terms only works if terms is set to a value. The validation is skipped silently when terms is nil.

While this behavior is useful to validate acceptance in the frontend and not the admin backend, it also makes it very easy to unintentionally skip the validation altogether by forgetting to add the checkbox to a form. E.g. validates_acceptance_of :terms_with_typo will be skipped silently even if there is no column with t...

Change how Capybara sees or ignores hidden elements

Short version

  • Capybara has a global option (Capybara.ignore_hidden_elements) that determines whether Capybara sees or ignores hidden elements.
  • Prefer not to change this global option, and use the :visible option when calling page.find(...). This way the behavior is only changed for this one find and your step doesn't have confusing side effects.
  • Every Capybara driver has its own notion of "visibility".

Long version

Capybara has an option (Capybara.ignore_hidden_elements) to configure the default...

Hack-fix Selenium::WebDriver::Element#select is deprecated

In some older Capybara versions (e.g. 0.3.9), we're getting lots of deprecations warnings:

Selenium::WebDriver::Element#select is deprecated. Please use Selenium::WebDriver::Element#click and determine the current state with Selenium::WebDriver::Element#selected?

Hani-elabed on Github helps. Add this code to features/support/env.rb to remove them temporarily:

# June 30th, 2011
# a temporary hack to disable the annoying upstream warnings capybara > selenium-webdriver 0.2.2
# capybara folks know about this and are working on it. S...

Customize path for Capybara "show me the page" files

When you regularly make use of Cucumber's "show me the page" step (or let pages pop up as errors occur), the capybara-20120326132013.html files will clutter up your Rails root directory.

To tell Capybara where it should save those files instead, put this into features/support/env.rb:

Capybara.save_and_open_page_path = 'tmp/capybara'

Fix [RubyODBC]Cannot allocate SQLHENV when connecting to MSSQL 2005 with Ruby 1.8.7. on Ubuntu 10.10

I followed this nice guide Connecting to MSSQL with Ruby on Ubuntu - lambie.org until I ran in the following errors:

irb(main):001:0> require "dbi"; dbh = DBI.connect('dbi:ODBC:MyLegacyServer', 'my_name', 'my_password')

DBI::DatabaseError: INTERN (0) [RubyODBC]Cannot allocate SQLHENV
  from /usr/lib/ruby/1.8/dbd/odbc/driver.rb:36:in `connect'
  from /usr/lib/ruby/1.8/dbi/handles/driver.rb:33:in `connect'
  from /usr/lib/ruby...

Linux: Mount second encrypted HDD automatically without entering a password

This is one possibility to do this. There are other and maybe even better ways to do this.

  1. Generate a key for your encrypted harddisk:

    dd if=/dev/random of=/home/bob/keyfile_sdb1 bs=4096 count=1
    
  2. Then add your keyfile to encrypted harddisk: How to change your dm-crypt passphrase (step 3)

  3. Create a mountpoint:

    mkdir /mnt/space
    
  4. Create a script e.g. in your homedirectory (/home/bob/mount_sdb1.sh):

    #!bin/bash
    
    ...
    

Capybara: Test that a string is visible as static text

This is surprisingly difficult when there is a <textarea> with the same text on the page, but you really want to see the letters as static text in a <p> or similiar.

The step definition below lets you say:

Then I should see the text "foo"

You should not look too closely at the step definition because when you see the light, it will blind you.

Then /^I should see the text "(.*?)"$/ do |text|
  elements = page.all('*', :text => text).reject { |element| element.tag_name == 'textarea' || element.all('*', :text => text...

Spec "content_for" calls in helpers

This only applies to RSpec below version 1.3.2. The issue has been fixed in RSpec 1.3.2, and most likely RSpec 2 and later versions.


When you have a helper that calls content_for and want to check its behavior you should probably write a feature instead. If you still want to do it, mind the following.

Consider this helper:

module LayoutHelper
  def title(string)
    content_for :title, string
    string
  end
end

Somewhere in the layout we'd then say something like this: `<%= yield :title %...</p>

TodoMVC - A common learning application for popular JavaScript MV* frameworks

Developers these days are spoiled with choice when it comes to selecting an MV* framework for structuring and organizing JavaScript web apps. Backbone, Spine, Ember (SproutCore 2.0), JavaScriptMVC... the list of new and stable solutions goes on and on, but just how do you decide on which to use in a sea of so many options?

To help solve this problem, we created TodoMVC - a project which offers the same Todo application implemented using MV* concepts in most of the popular JavaScript MV* frameworks of today.

Solutions look and feel the same...

Gatekeeping: Guide for developer

If your project manager wants to do gatekeeping on a project, as a developer you need to follow the following guidelines (e.g. by using something like this issue checklist template).

In order to reduce the number of rejects we get from clients, we want to review all code written before it goes to the staging server.

Note

This process is tailored to our specific needs and tools at makandra. While it will certainly not apply to all (especially larger teams), we think it...

Gatekeeping: Guide for gatekeeper

If you're responsible for gatekeeping in a projects, here is a guide, what to do.
In order to reduce the number of rejects we get from clients, we want to review all code written before it goes to the staging server.

Note: This process is tailored to our specific needs and tools at makandra. While it will certainly not apply to all (especially larger teams), we think it is a helpful starting point.


First, read the [Gatekeeping for developers](https://makandracards.com/makandra/6579-gatekeeping-guide-for...

Issues with has_select?

The handy method has_select?(field, :selected => text) does not behave as expected with Cucumber 0.10.2, Capybara 0.4.1.2 and Selenium 0.2.2. It may not recognize a select field if the selected option with the text has no value. If you don't have the possibility to upgrade these Gems, probably the best way to go is to distinguish the current Capybara driver:

Then /^"([^"]*)" should be selected for "([^"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
  with_scope(selector) do

    # currently needed due to different behav...

Nicer alternatives to def_delegator or def_delegators

Delegating methods to other objects is often helpful but the syntax of both def_delegators and def_delegator is a complete mess that makes your code hard to read.

Consider these classes:

class Topic < ActiveRecord::Base
  def title
    "A title"
  end
  
  def category
    "Topic category"
  end
end

class Post < ActiveRecord::Base
  belongs_to :topic
  def_delegato...

Run your own code before specific RSpec examples

You probably know about the possibility to tag scenarios in Cucumber to run your own piece of code before the actual scenario is run which looks like that:

@foo
Scenario: Do something
...

and you place the following snippet into support/env.rb:

Before('@foo') do
  puts "This is run every time a @foo tagged scenario is hit"
end    

You can tag RSpec examples like this:

it 'does something', :foo => true do
  ...
end

What you need is the following within the RSpec.configure do |config| block wit...

Auto-generate Cucumber navigation paths

Don't you just hate to write Cucumber path helpers to be able to say this?

When I go to the user form for "foo@bar.de"               # goes to edit_user_path(User.find_by_anything!('foo@bar.de'))
When I go to the form for the user "foo@bar.de"           # goes to edit_user_path(User.find_by_anything!('foo@bar.de'))
When I go to the form for the user above"                 # goes to edit_user_path(User.last)
When I go to the project page for "World Domination"      # goes to project_path(Project.find_by_anything!('World Domination')
...

Find an ActiveRecord by any column (useful for Cucumber steps)

The attached patch lets you find a record by a string or number in any column:

User.find_by_anything('carla')
User.find_by_anything('email@domain.de')
User.find_by_anything(10023)

There's also a bang variant that raises ActiveRecord::NotFound if no record matches the given value:

User.find_by_anything!('carla')

Boolean and binary columns are excluded from the search because that would be crazy.

I recommend copying the attachment to features/support/find_by_anything.rb, since it is most useful in Cucumber step def...

High-level Javascript frameworks: Backbone vs. Ember vs. Knockout

This is a very general introduction to MV* Javascript frameworks. This card won't tell you anything new if you are already familiar with the products mentioned in the title.

As web applications move farther into the client, Javascript frameworks have sprung up that operate on a higher level of abstraction than DOM manipulation frameworks like jQuery and Prototype. Such high-level frameworks typically offer support for client-side view rendering, routing, data bindings, etc. This is useful, and when you write a moderately complex Javascript ...

How to overwrite and reset constants within Cucumber features

In order to save the original value of a constant, set the new value and restore the old value after a scenario was completed, you can use the following helper. It takes care of saving the old constant value, setting the new one without throwing warnings and resets the value with an After hook.

This module also enables you to introduce new global constants.
Since these newly defined constants do not have any value to be reset to,
they simply are deleted (remove_const) once the respective Cucumber step finishes.

You can copy the file at...

New cards feature: Cite other cards

We've made it easier to link other cards:

  • You can now find a button Cite other card above the main text area
  • Clicking this button lets you search for another card
  • Clicking on a search result will paste a Markdown link into the text area

New cards feature: Github-style code blocks

You can now add code blocks without indentation, by using triple-backticks:

```
Code block goes here.
```

Cucumber step to test that a tooltip text exists in the HTML

Tooltips that are delivered through HTML attributes are encoded. Decode entities before checking for their presence.

Capybara:

Then /^there should( not)? be a(n encoded)? tooltip "([^"]*)"$/ do |negate, encoded, tooltip|
  tooltip = HTMLEntities.new.encode(tooltip) if encoded
  Then "I should#{negate} see \"#{tooltip}\" in the HTML"
end

Note

This step uses the htmlentities gem described in another card.

Ma...

nruth/show_me_the_cookies - GitHub

Some helpers for poking around at your Capybara driven browser's cookies in integration tests.

Supports Capybara's bundled drivers (rack-test, Selenium Webdriver), and adapters for other drivers may be added.

Mysql::Error: SAVEPOINT active_record_1 does not exist: ROLLBACK TO SAVEPOINT active_record_1 (ActiveRecord::StatementInvalid)

Possible Reason 1: parallel_tests - running more processes than features

If you run old versions of parallel_tests with more processes than you have Cucumber features, you will get errors like this in unexpected places:

This is a bug caused by multiple processes running the same features on the same database.

The bug is fixed in versions 0.6.18+.

Possib...