How to provoke Selenium focus issues in parallel test processes

As attachments to this card you will find a Cucumber feature and supplementing step definition that you can use to provoke Selenium focus issues that only occur when two focus-sensitive Selenium scenarios run at the same time (probably with parallel_tests). This can help you to detect and fix flickering integration tests.

The attached feature works by going to your root_path and focusing a random form element every 5...

Analyse TCP/UDP traffic with netcat

Sometimes you want to see what data you get through a TCP or UDP connection.
For example, you want to know how a HTTP Request look like.

It's very easy with netcat.

Example to listen on port 80 and the output gets to stdout.

sudo nc -kl 80

It's also possible write it into a file:

sudo nc -kl 80 > output.txt

If you use Ports higher than 1000 you don't need to be root (sudo).

Custom bash autocompletion

The bash offers control over the behavior of autocompletion.

The most primitive example is this (just run it in your bash; if you want it available everywhere, put the complete ... line into your .bashrc):

> complete -W "list of all words for an automatic completion" command_to_be_completed
> command_to_be_completed a<TAB>
all an automatic

With complete you define how the specified command shall be completed. For basic needs, -W (as in "word list") should be enough, but you may also specify a function, a glob patte...

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

Custom error pages in Rails

Basic error pages

To add a few basic styles to the default error pages in Rails, just edit the default templates in public, e.g. public/404.html.

A limitation to these default templates is that they're just static files. You cannot use Haml, Rails helpers or your application layout here. If you need Rails to render your error pages, you need the approach below.

Advanced error pages

  1. Register your own app as the applicatio...

Render Sass stylesheets dynamically

If - for whatever reason - you have to render stylesheets dynamically, the following snippet might be of help. It emulates what "sprockets" would to when precompiling your assets, and give your stylesheets access to all the regular bells and whistles (like asset_path, proper @imports etc):

class DynamicStylesheetsController < ApplicationController

    def show
      logical_path = RELATIVE_PATH_TO_YOUR_TEMPLATE
      path = File.join(Rails.root, logical_path)
      template = Sass::Rails::SassTemplate.new(path)
      environment = ...

Git: Improve your commits by reviewing changes one-by-one

Git commits should be very deliberate, and only contain changes that you really want to be in there. In order to reduce the chance to accidentally commit something you didn't intend, review your changes before committing.

My preferred way of doing this is (only using git)

git add -N . # Add all paths, but not their contents
git add -p

Git will now show you all your changes in small chunks and ask you in an interactive mode whether you really want to add them.

The most helpful commands are

  • y: yes (add the change)
  • ...

Firefox makes an OPTIONS request you don't expect

If some AJAX functionality does not work, but you see Firefox making an OPTIONS request, the reasons is most likely this:

You're accidently trying to talk to a different domain (or switching from http to https), and Firefox tries to find out if that is okay, according to the "Cross-Origin Resource Sharing" standard.

Force absolute URLs for parts of a view or controller

You know that you can force absolute URLs throughout a response. Now you want to modify URLs similarly, but only in parts of a view (or controller) logic. Here is how.


Note: this has only been tested on a Rails 2 application. It should work similarly for Rails 3.


Put this into your ApplicationController:

def rewrite_options(*args)
  options = super
  options.merge!(:only_path => false) if @with_full_urls
  options
end...

How to change the hostname in Cucumber features

Capybara uses www.example.com as the default hostname when making requests.
If your application does something specific on certain hostnames and you want to test this in a feature, you need to tell Capybara to assume a different host.

Given /^our host is "([^\"]+)"$/ do |host|
  page.config.stub app_host: "http://#{host}"
  
  # In older Capybaras (< 2.15) you needed to do this instead:
  Capybara.stub app_host: "http://#{host}"
end

You can now say:

When I go to the start page
Then I should not see "Home ...

Capybara 2.0 has been released

The gem author Jonas Nicklas highlights in a Google Groups post that the release

  • is not backwards compatible to 1.x versions of Capybara
  • does not support Ruby 1.8.x anymore
  • removes confusion with Rails' built in integration tests (you put capybara rspec integration tests into the spec/feature/... folder) and the :type metadata has been changed from :request to :feature
  • throws exceptions when trying to interact with an element whose identifier is...

How to move a window to the next monitor on Xfce, Mate and other X Window Managers

Since I use this a lot in my daily work and there were no scripts working properly for me, I made one myself.
It's actually not bound to Xfce but should work on any window manager (haven't tried it, though).

Installation

  1. If you don't yet have xdotool, install it:

    sudo apt-get install xdotool
    
  2. If you don't yet have wmctrl, install it:

    sudo apt-get install wmctrl
    
  3. Store the attached file in some place that's in your PATH.
    The cool kids use ~/bin/.

  4. Make it executable: `chmod +x ~/bin/move-to-next-mo...

Internet Explorer will download CSS files twice, if referenced via scheme-less URLs

You can use scheme-less URLs (or protocol-relative URLs) to have browsers use the current protocol (HTTP or HTTPS) when loading content referenced with such an URL.

A protocol relative URL doesn’t contain a protocol. For example, http://stevesouders.com/images/book-84x110.jpg becomes //stevesouders.com/images/book-84x110.jpg

Browsers substitute the protocol of the page itself for the resource’s missing protocol. Problem solved!

But:

Internet Explorer 7 & 8 will download st...

Firefox: Inspecting mixed content warnings (and how to enable them)

Having your site run on SSL is worthless when you include content over an unsafe connection (HTTP).

Here is how to hunt down mixed content with Firefox.

How to enable mixed content alerts

If your Firefox does not warn you about mixed content on pages (mine did not), you can enable it again:

Visit about:config and search for security.warn_viewing_mixed. If it's set to false, set it back to true again.

Seeing which URLs are fetched from unsecured connections

Firefox 16+ will show you mixed content in its "Web Console".
Open it ...

Cucumber: Wait for any requests to finish before moving on to the next scenario

Background

Generally, Selenium tests use the browser to interact with the page. If it's unavailable, a timeout error is thrown.

Now, consider a scenario like this:

@javascript
Scenario: Receive an e-mail after clicking the fancy link
  When I follow "fancy link"
  Then I should have an e-mail with the subject "Hello"

When the last step in the scenario passes, you are done. Right? Wrong.

Why it's not enough

What if clicking our "fancy link" above sends the e-mail that we expect, but it also does stuff on the server...

Waiting for page loads and AJAX requests to finish with Capybara

If you're using the Capybara webdriver, steps sometimes fail because the browser hasn't finished loading the next page yet, or it still has a pending AJAX request. You'll often see workarounds like

When I wait for the page to load
Then ...

Workarounds like this do not work reliably, will result in flickering tests and should be avoided. There is no known reliable way to detect if the browser has finished loading the page.

Solution

Instead you should wait until you can observe the result of a page load. E.g. if y...

Ruby: Extract the hostname from a URL

url = 'http://www.foocorp.com/foo/bar'
URI.parse(url).host
# => www.foocorp.com

Note that this will raise an error if the given argument is not a URL.

If you need the host's full URL without path, query, fragment etc., use URI.join with a clever twist:

url = 'http://www.foocorp.com:33546/foo/bar?query=foobar#hash'
URI.join url, '/'
# => http://www.foocorp.com:33546/

Manually requiring your application's models will lead to trouble

In a nutshell:

If you require your Rails models manually, pay attention to the path you use. Unless you have to, don't do it at all.

Background

Consider these classes:

# app/models/user.rb

class User < ActiveRecord::Base
  validate :magic

  def magic
    errors.add_to_base('failed') if bad_things?
  end
end

^
# app/models/foo.rb

require 'user'

class Foo
  # something happens here
end

Now, when your environment is booted, Rails will automatically load your models, like User...

CSS-Style

Richard Powell presents a collection of CSS styling advice that's mainly taken from SMACSS. Although at makandra we're using BEM instead of SMACSS, here's my favorites.

Do not use ID's in CSS Selectors

It is never safe to assume there will only ever be one of something on a page so do not use ID's for CSS. Id's are much better used as javascript hooks so use them for this instead.

.list {…} instead of #list {…}

Animate an interface using classes not inline styles

Inline styles added by javascript are h...

Howto transfer a single mysql table between several deployment stages

Example task: Multiply the table holidays between several stages.

  1. Open two terminals:

    shell-for stage_1
    shell-for stage_2
    
  2. Get the stage1 and stage2 MySQL credentials:

    cat /opt/www/the_stage.host.tld/current/config/database.yml
    cat config/database.yml # should do it
    
  3. Dump the table to a path reachable by the stage2 user (e.g. home):

    mysqldump -h mysql1 -u stage_1_user -p stage_1_database table_name > ~/table_name_dump.mysql # Select certain records using --where "some_id > 666"
    

    (-...

Paperclip: undefined method `to_file' for #<Paperclip::Attachment:0000> (NoMethodError)

to_file has been removed in Paperclip 3.0.1.

Instead of using File to access Paperclip storage objects (like this: File.read(file.to_file.path)) you can use

Paperclip.io_adapters.for(file).read

Git basics: checkout vs. reset

Today I got a better understanding of how git works, in particular what git checkout and git reset do.

Git basics

  • A commit holds a certain state of a directory and a pointer to its antecedent commit.
  • A commit is identified by a so-called ref looking something like 7153617ff70e716e229a823cdd205ebb13fa314d.
  • HEAD is a pointer that is always pointing at the commit you are currently working on. Usually, it is pointing to a branch which is pointing to that commit.
  • Branches are nothing but pointers to commits. Y...

Distribute files from a private bucket on AWS S3

Given you store files on Amazon S3 and you need to stream those files out to people while you don't want them to be able to distribute the content simply by sharing the S3 URL.

You could either mark the bucket as private and fetch the appropriate files from S3 to your application server and stream them to the client finally. While this is possible, I'd recommend to use what AWS calls "Query String Authentication".

If you're using Paperclip you can chose between two sto...

Create autocompletion dropdown for Cucumber paths in Textmate

Ever wanted autocompletion for paths from paths.rb in Cucumber? This card lets you write your steps like this:

When I go to path *press tab now* # path is replaced with a list of all known Cucumber paths

This is how you do it

(key shortcuts apply for TextMate2)

  1. Open the bundle editor (ctrl + alt +  + B)

  2. Create a new Item ( + N), select "Command"

  3. Paste this:
    ^
    #!/usr/bin/env ruby -wKU
    require File.join(ENV['TM_SUPPORT_PATH'], 'lib', 'ui.rb')

    cucumber_paths = File.join ENV['TM_PROJECT_DIRECTORY'], 'features'...