Testing drag&drop with Selenium

When using jQueryUI's Sortable plugin (either directly or via Angular's ui.sortable), you might struggle testing your nice drag&drop GUI since Selenium webdriver does not support native dragging events.

But jQueryUI uses jquery.simulate for their testing, so why shouldn't you? There is even an extension to it that makes testing drag & drop quite easy.

Here is what you need:

  1. jquery.simulate.js
  2. [`jquery.simula...

Interacting with a Microsoft Exchange server from Ruby

Microsoft Exchange service administrators can enable Exchange Web Services (EWS) which is a rather accessible XML API for interacting with Exchange. This allows you to read and send e-mails, create appointments, invite meeting attendees, track responses, manage to-do tasks, check user availability and all other sorts of things that are usually only accessible from Outlook.

You can implement an EWS by hand-rolling your XML (the [docs](http://msdn.microsoft.com/en-us/...

Feedjira

Great gem to consume RSS feeds. I was missing some features on Ruby's RSS::Parser that I found in Feedjira:

  • Speed
  • Does not break on slightly malformed RSS feeds (like a missing length attribute on an <enclosure> tag on gizmodo.de's feed)
  • It automatically resolves Feedburner-mangled URLs (hooray!)

The GitHub project has only a minimalistic readme. You can find its documentation on their homepage.

Iterating over a Ruby Hash while tracking the loop index

You know each_with_index from arrays:

    ['hello', 'universe'].each_with_index do |value, index|
      puts "#{index}: #{value}"
    end
    # 0: hello
    # 1: universe

This also works on hashes. However, mind the required syntax:

    { hello: 'universe', foo: 'bar' }.each_with_index do |(key, value), index|
      puts "#{index}: #{key} => #{value}"
    end
    # 0: hello => universe
    # 1: foo => bar

The reason is that each_with_index yields 2 elements to the block, and you need to deconstruct the first el...

Cucumber: Skipping steps in a scenario outline, based on the current example

In Cucumber, scenario outlines help avoiding tests that are basically the same, except for a few variables (such as different inputs). So far, nothing new.

The problem

Now what if your test should (or should not) do something, like filling in a field only for some tests?

    Scenario Outline: ...
      When I open the form
        And I fill in "Name" with "<name>" # <= we want to do this only occasionally
      Then everybody should be happy
      
    Examples:
      | name  |
      | Alice |
      | Bob   |

You could o...

RSpec 3 no longer chooses a spec's type based on its directory

While RSpec 1 and 2 decided that specs inside spec/model are model specs, and those inside spec/features are feature specs (and so on), RSpec 3 will no longer do that by default.

This will result in errors such as missing routing helpers, etc.

There are 2 ways to fix this:

  • Explicitly set the type on each spec. For example:

    describe '...', type: 'feature' do
      # ...
    end
    
  • Add this to your spec_helper.rb (inside the RSpec.configure block) to restore the old behavior:

    ...

Test if all your favicons exist

When you don't only have a favicon.ico in your project but also PNGs of different sizes and backgrounds, you should test if all those files are actually reachable.

Here are a few selectors to get you started:

    'link[rel~="icon"]' # regular ones, matches "shortcut icon" and "icon"
    'link[rel="apple-touch-icon"]' # iOS
    'meta[content][name="msapplication-TileImage"]' # IE11
    'meta[content][name^="msapplication-square"]' # IE11

A s...

Use byebug on Ruby 2+

The debugger gem does not seem to be properly working on Ruby 2. Use byebug instead!

Byebug is a simple to use, feature rich debugger for Ruby 2. It uses the new TracePoint API for execution control and the new Debug Inspector API for call stack navigation, so it doesn't depend on internal core sources. It's developed as a C extension, so it's fast. And it has a full test suite so it's reliable. Note that byebug works only for ruby 2.0.0 or newer. For...

Device sizing and network throttling are coming to Chrome DevTools

See screenshot here.

This is great news because network throttling is very painful in Linux.

The features are already in Chrome Canary, so expect them to come to your Chrome sources soon.

How to test bundled applications using Aruba and Cucumber

Aruba is an extension to Cucumber that helps integration-testing command line tools.

When your tests involve a Rails test application, your tool's Bundler environment will shadow that of the test application. To fix this, just call unset_bundler_env_vars in a Cucumber Before block.

Previously suggested solution

Put the snippet below into your tool's features/support/env.rb -- now any command run through Aruba (e.g. via #run_simple) will have a clean Bundler envir...

Cucumber step to manually trigger javascript events in Selenium scenarios (using jQuery)

When you cannot make Selenium trigger events you rely on (e.g. a "change" event when filling in a form field), trigger it yourself using this step:

When /^I manually trigger a (".*?") event on (".*?")$/ do |event, selector|
  page.execute_script("jQuery(#{selector}).trigger(#{event})")
end

Note that this only triggers events that were registered through jQuery. Events registered through CSS or the native Javascript registry will not trigger.

Tearing Down Capybara Tests of AJAX Pages

An all-in-approach to fix the problem of pending AJAX requests dying in the browser when the server ends a test or switches scenarios.


We were able to work around this issue in most projects by doing this instead:

After '@javascript' do
  step 'I wait for the page to load'
end

Hover an element with Capybara < 2

You need this awkward command:

page.driver.browser.action.move_to(page.find(selector).native).perform

Note that there are better ways for newer Capybaras.

mattheworiordan/capybara-screenshot

Using this gem, whenever a Capybara test in Cucumber, Rspec or Minitest fails, the HTML for the failed page and a screenshot (when using capybara-webkit, Selenium or poltergeist) is saved into $APPLICATION_ROOT/tmp/capybara.

Link via Binärgewitter Podcast (German).

Atomic Grouping in regular expressions

A little-known feature of modern Regexp engines that help when optimizing a pattern that will be matched against long strings:

An atomic group is a group that, when the regex engine exits from it, automatically throws away all backtracking positions remembered by any tokens inside the group.

rbenv: How to update list of available Ruby versions on Linux

When you tell rbenv to install a Ruby it does not know about, you will get an error message.

$ rbenv install 2.1.2
ruby-build: definition not found: 2.1.2

You can list all available versions with `rbenv install --list'.

If the version you're looking for is not present, first try upgrading
ruby-build. If it's still missing, open a request on the ruby-build
issue tracker: https://github.com/sstephenson/ruby-build/issues

(Fun fact: Recent versions of ruby-build will give you a more helpful error message which...

About "unexpected '#' after 'DESCENDANT_SELECTOR' (Nokogiri::CSS::SyntaxError)"

The error unexpected 'x' after 'DESCENDANT_SELECTOR' (Nokogiri::CSS::SyntaxError) (where x may be basically any character) occurs when the Nokogiri parser receives an invalid selector like .field_with_errors # or td <strong>.

In Cucumber, the culprit will be an invalid step definition that builds an invalid selector:

# inside some step definition:
field = find_field(label)
page.send(expectation, have_css(".field_with_errors ##{field[:id]}"))

The above raises the mentioned error if field[:id] is nil, i.e. the foun...

Github Cheat Sheet

All the hidden and not hidden features of Git and GitHub.

No more file type confusion in TextMate2

When using TextMate2 with the cucumber bundle, it does not recognize step definitions (e.g. custom_steps.rb) as such but believes they are plain Ruby files. But there is help!

Solution

Add these lines to the bottom of your .tm_properties file (in ~/ for global settings, in any directory for per-project settings):

[ "*_steps.rb" ]
fileType = "source.ruby.rspec.cucumber.steps"

Apparently, this works for any files. Define a regex and specify custom settings. The attached article lists all available configuration options (whic...

Ruby on Rails 4 and Batman.js

Batman is an alternative Javascript MVC with a similar flavor as AngularJS, but a lot less features and geared towards Ruby on Rails.

The attached link leads to a tutorial for a small blog written with Rails / Batman.js.

I'm collecting other Batman.js resources in my bookmarks.

How Ruby method lookup works

When you call a method on an object, Ruby looks for the implementation of that method. It looks in the following places and uses the first implementation it finds:

  1. Methods from the object's singleton class (an unnamed class that only exists for that object)
  2. Methods from prepended modules (Ruby 2.0+ feature)
  3. Methods from the object's class
  4. Methods from included modules
  5. Methods from the class hierarchy (superclass and its an...

Collection of Rails development boosting frameworks

Development environment setup

Rails Composer

Basically a comprehensive Rails Template. Prepares your development environment and lets you select web server, template engine, unit and integration testing frameworks and more.

Generate an app in minutes using an application template. With all the options you want!

Code generators

Rails Bricks

A command line wizard. Once you get it running, it creates sleek applications.

RailsBricks enables you to cre...

Your Rails sandbox console

Just found out about a great feature in Rails that seems to be around since Rails 2. Start a console with the --sandbox (or -s) parameter:

rails console --sandbox

All changes you make to the database will be rolled back on exit.

Warning

Changes beyond the database (deleting files, sending emails, etc) cannot be rolled back!

String#indent: Know your definitions!

String#indent is not a standard Ruby method. When you use it, be sure to know where this method comes from. Many Gems shamelessly define this method for internal usage, and you'll never know when it may be removed (since it's usually not part of the Gem's API).

Unless you're using Rails 4 (which brings String#indent in ActiveSupport), you'll be best of defining it yourself. This card has it for you.

Gems that define String#indent (incomplete)
----------------------------...