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...

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.

  1. 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.

  2. On a Rails 2 project:

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.

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

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::TestRequests 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 ...

Speed up JSON generation with oj

Using this gem I could get JSON generation from a large, nested Ruby hash down from 200ms to 2ms.

Its behavior differs from the default JSON.dump or to_json behavior in that it serializes Ruby symbols as ":symbol", and that it doesn't like an ActiveSupport::HasWithIndifferentAccess.

There are also some issues if you are on Rails < 4.1 and want it to replace #to_json (but you can always just call Oj.dump explicitely).

Security warning: Oj does not escape HTML entities in JSON
---------...

Downgrade Firefox 6 to Firefox 5 on Ubuntu

Note that if you plan to downgrade Firefox because your Selenium tests broke after a Firefox upgrade, there is a better way that doesn't involve downgrading. Mozilla has stated that they will no longer provide security patches for any but the most recent versions of Firefox. So running an old Firefox should not be a long-term solution for anything.

If you still want to downgrade your Firefox for other reasons, here is how I downgra...

How to access before/after pseudo element styles with JavaScript

Accessing pseudo elements via JavaScript or jQuery is often painful/impossible. However, accessing their styles is fairly simple.

Using getComputedStyle

First, find the element in question.

let element = document.querySelector('.my-element') // or $('.my-element').get(0) when using jQuery

Next, use JavaScript's getComputedStyle. It takes an optional 2nd argument to filter for pseudo elements.

let style = window.getComputedStyle(element, '::before')
let color = style.getPropertyValue('background-color...

NoMethodError: undefined method `cache' for Gem:Module

I got this error when running Rails 2.3 tests for Rails LTS. More stacktrace:

NoMethodError: undefined method `cache' for Gem:Module
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:212:in `each'
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:146:in `to_a'
    /vagrant/rails-2-3-lts-repository/railties/lib/rails_generator/lookup.rb:146:in `cache'
    /opt/vagrant_ruby/lib/ruby/1.8/fileutils.rb:243:in `inject'
    /vagrant/rails-2-3-lts-repository/railties/l...

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...

How to look at hidden X screens

When you have a program running in a hidden X screen (like with Xvfb for Selenium tests) you may want to look at that hidden screen occasionally.

First, find out what X displays are currently active:

netstat -nlp | grep X11

This should give you some results like these:

unix  2      [ ACC ]     STREAM     LISTENING     8029600  4086/Xvfb           /tmp/.X11-unix/X99
unix  2      [ ACC ]     STREAM     LISTENING     8616     -     ...

VCR: An OAuth-compatible request matcher

OAuth requires a set of params to be carried along requests, among which a nonce. Some libraries pass these along as headers, some as query parameters. All fine.

When you're using VCR, the latter case is an issue. By default, requests are matched on method and URI. However, no request URI will equal another when they include a nonce. You won't be able to match these requests with VCR.

Solution

Obviously you need to...

The Easiest Way to Parse URLs with JavaScript

A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.

You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:

var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'

if (pathname[0] != '/')
  pathname = '/' + pathname // Fix IE11

One advantag...

How to fix: Microphone recording levels are too quiet (or get lowered automatically)

If others on a call (Skype, SIP, ...) can not hear you loud enough, your volume levels are probably too low. Also, Skype may be changing your mixer levels.

Set a proper recording volume

  1. Open your mixer software (run pavucontrol).
  2. Switch to input devices.
  3. If you have more than one recording device, find the correct one.
  4. Make a test call to a colleague that can tell you if it's too loud or too quiet.
  5. Drag the volume slider for your input device to an adequate level -- for me, 75% (-7.46dB) work fine. 100% is usually way to...

During deployment: "You are trying to install in deployment mode after changing your Gemfile"

While deploying an Ruby update to an old application these days, we encountered the following misleading error:

*** [err :: some-host.makandra.de] You are trying to install in deployment mode after changing
*** [err :: some-host.makandra.de] your Gemfile. Run `bundle install` elsewhere and add the
*** [err :: some-host.makandra.de] updated Gemfile.lock to version control.
*** [err :: some-host.makandra.de] 
*** [err :: some-host.makandra.de] You have deleted from the Gemfile:
*** [err :: some-host.makandra.de] *

We found out a newe...

About the HTML and the BODY tag

The <html> and <body> tags both come with some non-default behavior that you know from other tags.
Do not try to style html or body for positioning, width/heigth, or similar. Every browser has its own caveats and you can not test them all.

Generally speaking:

  • Use the html tag to define your page's default background color (because on short pages or large screens, your body may not be as tall as the browser window).
  • Use the html tag to define a base font-size so you can use [rem units](https://www.sitepoint.com/underst...

Pierce through Javascript closures and access private symbols

If you are writing any amount of Javascript, you are probably using closures to hide local state, e.g. to have private methods.

In tests you may find it necessary to inspect a variable that is hidden behind a closure, or to mock a private method using Jasmine spies.

You can use the attached Knife helper to punch a hole into your closure, through which you can read, write or mock local symbols:

klass = (->

 privateVariable = 0

 privateMethod = ->
   ...