Versatile Cucumber step regarding hovering above elements
Here's a pretty useful steps that hasn't made it into Spreewald yet.
It is best used with the auto-mapper for BEM classes in features/support/selectors.rb
When I hover above [selector] element
When /^I hover above (.*) element$/ do |selector|
page.find(selector_for(selector)).hover
end
Example:
When I hover above the album's image element
→ triggers a hover event on .album--image
postgres: window functions
Good article about window functions. Also note how they use a postgres feature called common table expressions.
An auto-mapper for BEM classes in Cucumber selectors
When you are using the #selector_for
helper in Cucumber steps, as e.g. Spreewald does, the following snippet will save you typing. It recognizes a prose BEM-style selector and maps it to the corresponding BEM class.
For a variation on this idea, see An auto-mapper for ARIA labels and BEM classes in Cucumber selectors.
Examples
"the main menu" -> '.main-menu'
"the item box's header" -> '.item-box--header'
Here are some examples of steps (using Spreewald, too):
T...
Fix error UDPSocket.open: wrong number of arguments (0 for 1)
I got the following error after updating the selenium-webdriver
gem:
wrong number of arguments (0 for 1) (ArgumentError)
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:183:in `open'
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:183:in `ip'
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:196:in `interfaces'
It was caused...
Rails: Running specific migrations
When running migrations with rake db:migrate
, there's the STEP
and VERSION
parameters that you can pass to nearly all commands.
# Migrate
rake db:migrate
rake db:migrate STEP=2
rake db:migrate VERSION=20080906120000
# Redo
rake db:migrate:redo
rake db:migrate:redo STEP=2
rake db:migrate:redo VERSION=20080906120000
# Rollback (starting from latest migration)
rake db:rollback
rake db:rollback STEP=2
# Run the `down` migration path of a certain migration file
rake db:migrate:down VERSION=20080906120000
Cucumber factory 1.10.0 released
I've pushed an update to Cucumber factory that simplifies working with FactoryGirl
factories.
Say you define a factory with the class:
option:
factory :admin, class: User
email
admin true
end
In the past, you had to write
Given there is a user (admin)
Now you can simply write
Given there is an admin
The class is inferred from the factory.
Geordi 1.0 released
Geordi 1.0 features a command line application geordi
, that holds most of Geordi's previous commands.
New features
-
command help and usage examples right within
geordi
(geordi help
andgeordi help <command>
) -
quick command access: type just the first few letters of a command, e.g.
geordi rs
orgeordi dev[server]
-
command dependencies, e.g.
geordi rspec
invokesgeordi bundle-install
(which bundles only if needed) -
no cluttered
/usr/bin
, but all commands in one handy tool -
template for easily adding new...
How to set up database_cleaner for Rails with Cucumber and RSpec
Add gem 'database_cleaner'
to your Gemfile. Then:
Cucumber & Rails 3+
# features/support/database_cleaner.rb
DatabaseCleaner.clean_with(:deletion) # clean once, now
DatabaseCleaner.strategy = :transaction
Cucumber::Rails::Database.javascript_strategy = :deletion
Cucumber & Rails 2
The latest available cucumber-rails
for Rails 2 automatically uses database_cleaner
when cucumber/rails/active_record
is required -- but only if transactional fixtures are off. To have database_cleaner
work correctly:
- Add the ...
Refile: Ruby file uploads, take 3
Jonas Nicklas, the author of Carrierwave and Capybara, has released Refile, a gem for handling file uploads in Rails. It handles direct uploads (also direct uploads to Amazon S3) better than Carrierwave.
The story and reasoning behind some of the decisions in Refile, and how it's different from Carrierwave, by the author himself, is a good read before deciding which way you'll go.
Big Caveat: Refile only stores the original image and r...
Spreewald 1.2.0 released: new "select field should be sorted" step
Usage:
Then the "sorted" select should be sorted
But the "unsorted" select should not be sorted
How to circumvent Firefox's "Document expired" page in Selenium tests
When navigating back to a page that was received from a POST request, undesired side effects may happen. Therefore, modern browsers try to keep users from doing so, i.e. Firefox 24 displays an error page explaining what's wrong. If the user presses "Try Again", it shows an additional alert asking whether the user is certain.
Solution
If you need to circumvent this protection, e.g. to test that your application behaves correctly despite being misused, do this:
page.execute_script 'history.back()'
page.execute_script 'retryThis(this)...
Cucumber: More patience for Selenium features
When running Selenium features with parallel_tests, some browser-server interaction might take longer than usual and the impatient Capybara will not wait enough to see results.
Put the attached file into features/support/
to make Capybara more patient in scenarios tagged @javascript
.
How to upgrade Cucumber on Rails 3+
-
Run
bundle update cucumber capybara cucumber-rails
to update to the newest versions. -
Backup your
features/support/path.rb
to be able to add your own paths again after the cucumber installation script in step 4. -
Backup your
features/support/env.rb
file to be able to reintegrate parts like your blueprints setup:ENV["RAILS_ENV"] ||= "cucumber" require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') require 'spec/support/blueprints'
-
Run `$ rails generate cucumber:install --capyba...
Getter and setter functions for JavaScript properties
JavaScript objects can have getter and setter functions that are called when a property is read from or written to.
For example, if you'd like an object that has a virtual person.fullName
attribute that dynamically composes person.firstName
and person.lastName
:
var person = {
firstName: 'Guybrush',
lastName: 'Threepwood',
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(name) {
var parts = name.split(" ");
this.firstName = parts[0];
this.lastName = parts[1];
}
};
`...
Testing focus/blur events with Cucumber
This is a problem when using Selenium with Firefox. We recommend using ChromeDriver for your Selenium tests.
This setup allows to test focus/blur events in Cucumber tests (using Selenium). For background information, see How to solve Selenium focus issues.
Cucumber step definition:
# This step is needed because in Selenium tests, blur events are not triggered
# when the browser has no focus.
When /^I unfocus the "(.*?)" field to trigger ja...
Taking screenshots in Capybara
Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest.
Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. Screenshots are saved into $APPLICATION_ROOT/tmp/capybara
.
Manually saving a page
Additionally you can trigger the same behavior manually from the test using Capybara::Session#save_and_open_page and [...
Reading an element's attributes with Capybara
capybara_element['attribute_name']
allows accessing an element's attributes in Capybara.
A few examples:
find('#my_element')['class']
# => "first-class second-class"
find('#my_input')['placeholder']
# => "My placeholder value"
find('a#example-link')['href']
# => "http://example.com"
find('#my_element')['missing_attribute']
# => nil
Cucumber: Removing uploaded files after test runs
Cucumber will clean up files you've uploaded in your Cucumber features automatically with the attached code. Put the file in features/support/
.
Cucumber step to test whether a select field is sorted
This step will pass if the specified select is sorted.
Then /^the "(.*?)" select should be sorted$/ do |label, negate|
select = find_field(label)
options = select.all('option').reject { |o| o.value.nil? }
options.collect(&:text).each_cons(2) do |a,b|
(a.text.downcase <=> b.text.downcase).should <= 0
end
end
In conjunction with this custom matcher, the each_cons
block can be replaced with:
options.should be_naturally_sorted
Usage
Then the "Organizations" select should be sorted...
Asset Pipeline Basics
The Rails asset pipeline improves delivery of application assets (javascripts, stylesheets, images, fonts). Here are some basic facts about its inner workings.
No magic
Manifests are the handle on your assets:
app/assets/stylesheets/application.css # use via: stylesheet_link_tag 'application'
The asset pipeline only considers files you explicitly require within your manifest files. The most common directives used in manifests are require some/file
and require_tree some/directory
. Paths may be **relative to the current director...
vague puppet error messages with broken yaml files
If you get one of this errors:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: (<unknown>): found character that cannot start any token while scanning for the next token at line 1297 column 3
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: undefined method `empty?' for nil:NilClass at /etc/puppet/environments/production/manifests/nodes.pp:1 on node example.makandra.de
Warning: ...
How to: Context-dependent word expansion in RubyMine
One of the many useful features of TextMate is autocompletion of words. If I were in TextMate right now, I could write "au[tab]", and it would complete it to "autocompletion". RubyMine can do this, too. When you write a word (e.g. a variable name), just hit ALT + / repeatedly and it will offer all completions for the letters you typed. This action is called Cyclic Expand Word in RubyMine / IntelliJ IDEA.
This feature keeps you from mistyping variable names, saves you keystrokes and speeds up development. ~10 keystrokes to the price ...
How to combine "change", "up", and "down" in a Rails migration
Rails migrations allow you to use a change
method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE
statements) you can not define up
and down
methods at the same time.
If you were to define define all 3 of them, Rails would only run change
and ignore up
and down
. However, Rails 4+ features a helper method called reversible
:
class MyMigration < ActiveRecord::Migration
def cha...
Upgrading a Rails 3.2 application to Ruby 2.1 is really easy
Upgrading from Ruby 1.8.7 to 2.1.2 took me an hour for a medium-sized application. It involved hardly any changes except
- removing the occasional monkey patch where I had backported functionality from modern Rubies
- Migrating from
require
torequire_relative
where I loaded RSpec factories in Cucumber'senv.rb
(the Rails application root is no longer in the load path by default) - replacing the old debugger with
byebug
- removing
sytem_timer
from Gemfile (see [this SO thread](http://stackoverflow.com/questions/7850216/how-to-inst...