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, `...
How to mount a legacy database to migrate data
There are many approaches out there how you can import data from a legacy application to a new application. Here is an approach which opens two database connections and uses active record for the legacy system, too:
1. Add you database information to you config/database.yml
.
data_migration:
database: your_application_data_migration
2. Create a separate application record for the data migration, e.g. in app/data_migration/migration_record.rb
. You will need to create an app/data_migration.rb
class first.
class DataMig...
Show the character set and the collation of your MySQL tables
To show the collation of your tables you have to login to the MySQL console and execute SHOW TABLE STATUS FROM database;
mysql> SHOW TABLE STATUS FROM test;
+-------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_leng...
Cucumber Webrat steps
Most of these will not work in newer projects because these use the Capybara/Rack::Test combo in lieu of Webrat.
Find input fields
Then /^there should be a "([^"]+)" field$/ do |name|
lambda { webrat.current_scope.send(:locate_field, name) }.should_not raise_error(Webrat::NotFoundError)
end
Then /^there should be no "([^"]+)" field$/ do |name|
lambda { webrat.current_scope.send(:locate_field, name) }.should raise_error(Webrat::NotFoundError)
end
Find html content
Then /^I should see "([^\"]*)...
Cucumber may complain about cucumber.yml being invalid when it is valid
Running Cucumber tests while your cucumber.yml is 100% valid may still produce the following error.
cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.
This may in fact be due to your rerun file (e.g. tmp/rerun.txt
) being invalid. Delete it and try again.
Performance analysis of MySQL's FULLTEXT indexes and LIKE queries for full text search
When searching for text in a MySQL table, you have two choices:
- The LIKE operator
- FULLTEXT indexes (which currently only work on MyISAM tables, but will one day work on InnoDB tables. The workaround right now is to extract your search text to a separate MyISAM table, so your main table can remain InnoDB.)
I always wondered how those two methods would scale as the number of records incr...
Copy to clipboard without flash (clipboard.js)
We used zeroclipboard.js
in some of our projects but now we switched to clipboard.js
because it does not rely on flash. Flash support of the major browsers has ended.
Some more advantages of clipboard.js:
- it consists only of a single javascript file, so it does not trigger additional requests with rails
- it automagically provides user feedback by selecting the text it has copied
- it provides callbacks for success and error which make it easier to add custom behaviour after copying to the clipboar...
ActiveRecord::Store: migrate data in store
When you need to store structured data (like Ruby hashes) in a single database column with ActiveRecord, a simple way is to use PostgreSQL's jsonb
columns. ActiveRecord will automatically serialize and deserialize your Hash to and from JSON, and you can index JSON paths for fast reads.
As an alternative, ActiveRecord::Store
offers a way to store hashes in a single database column. This card will show you how to migrate those hashes in an ActiveRecord::Migration
by example:
...
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...
Freeze (vendor, unpack) a single Ruby gem with and without Bundler
When you need to patch an existing gem, one way is to "vendor" the gem by copying it into the vendor/gems
directory of your Rails project. You can then make any changes you require and Rails will use the vendored version of the gem after a server restart. Unfortunately you need to perform some additional steps to marry Rails and the copied gem. This notes describes what to do.
With Bundler
This is super-painful. If you just copy the gem to vendor/gems
, Rails will complain:
Unpacked gem foolib in vendor/gems has no s...
Rails logs are not flushed automatically (in Rake tasks)
The Rails logger will store its content in a buffer and write it into the file system every 1000 lines. This will come back to bite you when using Rails.logger.info
to write log output during Rake tasks or on a production console.
You often won't notice this because for the development
and test
environments auto_flushing
is set to write after each line. On production environments the Rails logger writes only every 1000 lines -- and not upon shell or script ter...
Consul 0.9 lets you optimize records checks
Consul 0.9 comes with many new features to optimize powers that only check access to a given record. e.g. Power.current.post?(Post.last)
. See below for details.
Powers that only check a given object
Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
checks whether a given object is accessible.
To do so, simply define a power that ends in a question mark:
class Power
...
power :upd...
Quick HTML testing with RubyMine
If you need to test some HTML, e.g. an embed code, you can use RubyMine's "scratch files":
- File > New Scratch File (or
Ctrl + Shift + Alt + Ins
) - Select "HTML" as file type
- Write or paste the HTML
- Move your mouse to the upper right corner of the scratch file editor. Pick a browser to instantly open your file.
How to inspect RSS feeds with Spreewald, XPath, and Selenium
Spreewald gives you the <step> within <selector>
meta step that will constrain page inspection to a given scope.
Unfortunately, this does not work with RSS feeds, as they're XML documents and not valid when viewed from Capybara's internal browser (e.g. a <link>
tag cannot have content in HTML).
Inspecting XML
If you're inspecting XML that is invalid in HTML, you need to inspect the page source instead of the DOM. You may use Spreewald's "... in the HTML" meta step, or add this proxy step fo...
New Firefox and gem versions for our Selenium testing environment (Ubuntu 14.04+)
Firefox 5.0.1, which we were using for most Rails 2.3 projects, does not run on Ubuntu 14.04 any more. Here is how to update affected projects.
-
Update (or create)
.firefox-version
with the content:24.0
If you haven't installed Firefox 24 yet, the next time you run tests with Geordi, it will tell you how to install it. -
On a Rails 2 project:
-
Update your Cucumber-related gems as described in Upgrading Cucumber and Capybara, including
cucumber_spinner
andlaunchy
. -
If you...
-
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.
Cerberus: Home
Cerberus is a lightweight and easy-to-use Continuous Builder software for Ruby. It could be run periodically from a scheduler and check if application tests are broken. In case of failed tests Cerberus sends notification to developers.
The WHATWG Blog » Blog Archive » The longdesc lottery
It turned out that the test subject didn't know that longdesc even existed before the tester told him about it. Can you blame him?
jasonm's parallel_specs at master - GitHub
Rake tasks to run specs and tests in parallel, to use multiple CPUs and speedup test runtime.
http://mockito.org/
Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with clean & simple API. Mockito doesn't give you hangover because the tests are very readable and they produce clean verification errors.
rest-client - Project Hosting on Google Code
RESTClient is a Java application to test RESTful webservices. It can be used to test variety of HTTP communications.
thoughtbot's bourne at master - GitHub
Test spies are a form of test double that preserves the normal four-phase unit
Take care of existing users when upgrading Clearance
When upgrading Clearance, pay attention whether the password hashing strategy might have changed. Old clearance versions (< 1.0) used SHA1-encrypted passwords by default. Current versions default to BCrypt.
If you simply upgrade without taking this into account, users will get a BCrypt::Errors::InvalidHash
when trying to sign in. Your tests will not notice this, since they create new users for each scenario.
To fix it, you'll either have to force all users to reset their passwords, or you can allow old users to keep signing in with t...
Controller specs do not persist the Rails session across requests of the same spec
In specs, the session never persists but is always a new object for each request. Data put into the session in a previous request is lost. Here is how to circumvent that.
What's going on?
You are making ActionController::TestRequest
s in your specs, and their #initialize
method does this:
self.session = TestSession.new
This means that each time you say something like "get :index
", the session in your controller will just be a new one, and you won't see ...