Capybara: Easiest way to get the parent of an element

If you already selected an element and want to get its parent, you can call find(:xpath, '..') on it.
To get the parents parent, call find(:xpath, '../..').


Find a link which contains a twitter icon and check that it links to the correct page:

<a href="">
  <i class="icon is-twitter"></i>
link = page.find("a").find(:xpath, '..')
link[:href].should == ""

There is a good overview on xpath syntax on [w3schools](…

RSpec: Running a single shared example

When an Rspec example fails, I usually investigate by running rspec <file:line>. However, this does not work with shared examples, since Rspec doesn't know in which context the example should be run.

But there is a different way: You can run the shared example by specifying the example name. Let the following setup:

# my_model_spec.rb
describe MyModel do
  it_behaves_like 'something shared'

# something_shared.rb
shared_examples_for 'something shared' do
  it 'does something'

When the shared example "it does something" f…


How to: Use git bisect to find bugs and regressions

Git allows you to do a binary search across commits to hunt down the commit that introduced a bug.

Given you are currently on your branch's HEAD that is not working as expected, an example workflow could be:

git bisect start # Start bisecting
git bisect bad # Tag the revision you are currently on (HEAD) as bad. You could also pass a commit's SHA1 like below:
git bisect good abcdef12345678 # Give the SHA1 of any commit that was working as it should
# shorthand:
git bisect start HEAD abcdef12345678

Git will fetch a commi…

Be careful to use correct HTTP status codes for maintenance pages

When your public-facing application has a longer downtime for server maintenance or long migrations, it's nice to setup a maintenance page to inform your users.

When delivering the maintenance page, be very careful to send the correct HTTP status code. Sending the wrong status code might get you kicked out of Google, or undo years of SEO work.

Here are some ways to shoot yourself in the foot durign maintenance:

  • If all your routes send a "200 OK" with a HTML body "We're b…

How to fix font collisions in wkhtmltopdf with FontForge

If you are using PDFKit / wkhtmltopdf, you might as well want to use custom fonts in your stylesheets. Save yourself a couple of bug-tracking hours and read this card first.

The setup

  • The designer gave you two fonts named something like BrandonText-Regular and BrandonText-Bold
  • You have a HTML string to be rendered by PDFKit
  • For demonstration purposes, this string also contains CSS styles in a tag. They are referencing to your fonts.

The problems

Take care of your current timezone when you convert date times to date

When you convert a non-UTC date time you can't just drop the time. Convert the time to utc first and then drop the time.


DateTime.parse('2017-02-01 00:00:00 +0100').to_date #=> 2017-02-01
DateTime.parse('2017-02-01 00:00:00').to_date #=> 2017-02-01


DateTime.parse('2017-02-01 00:00:00 +0100').utc.to_date #=> 2017-01-31
DateTime.parse('2017-02-01 00:00:00').utc.to_date #=> 2017-02-01

Fix Slack call overlay on Awesome WM

If you use awesome and make a Slack call, you'll constantly have an overlay window pop up taking over half of your screen.

To fix this, add the following rule to your awful.rules.rules section in your rc.lua:

awful.rules.rules = {
  -- ...
  { rule = { name = "Slack Call Minipanel" }, properties = { floating = true, ontop = true } },
Auto-destruct in 57 days

Updated: Clicking issues with chromedriver

Another issue appeared as consequence of the chrome driver way of clicking.
Updated the card.


Capybara steps to match stuff within any selector

These steps are now part of Spreewald.

Since Capybara 0.4.1 a within scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.

In order to perform a test or action in all matching elements, do not use within but prefer the attached "inside any" Cucumber steps like these:

When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"
Auto-destruct in 50 days

Updated: Your database tables should always have timestamps

For > Rails 4.2 you need to set the timestamps in the migration. Otherwise you will see:

ERROR: column "created_at" contains null values

This can be missed in development where you might have an empty table.

class AddMissingTimestamps < ActiveRecord::Migration
def change
add_timestamps :shows, null: true

update "UPDATE shows SET created_at = '#{Time.current}'"
update "UPDATE shows SET updated_at = '#{Time.current}'"

change_column_null :shows, :created_at, false
change_column_null :shows, :updated_at, fa...
External contentRepeats

Thread-safe collections in Ruby

When using threads, you must make your code thread-safe. This can be done by either locking (mutexes) all data shared between threads, or by only using immutable data structures. Ruby core classes like String or Array are not immutable.

There's several gems providing thread-safe collection classes in Ruby.


The thread_safe gem provides thread-safe versions of Array and Hash:

sa = # supports standard forms
sh = ThreadSafe::Hash…

Async control flow in JavaScript: Promises, Microtasks, async/await

Slides for Henning's talk on Sep 21st 2017.

Understanding sync vs. async control flow

Talking to synchronous (or "blocking") API

print('script start')
html = http_get('/foo')
print('script end')

Script outputs 'script start', (long delay), '<html>...</html>', 'script end'.

Talking to asynchronous (or "evented") API

print('script start')
http_get('foo', done: function(html) {
print('script end')

Script outputs `'script st…

Spreewald: Content-Disposition not set when testing a download's filename

If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:

Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
     got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)

One solution is to check the Content-Type header only with the following spreewald step:

Then I should get a response wi…

Fixing flaky integration tests

This card shows basic techniques for fixing a flaky integration test suite that sometimes passes and sometimes fails. "Integration test" is a test script that remote-controls a web browser with tools like Selenium WebDriver.

Although the examples in this card use Cucumber and Selenium, the techniques are applicable to all languages and testing tools.

Why tests are flaky

Your tests probably look like this:

When I click on A
When I click on B
When I click on C
Then I should see effects of C

A test like this works fine most of t…

Be very careful with 301 redirects

Browsers support two kinds of redirects:

  • 301 moved permanently
  • 302 moved temporarily

Be very careful with the 301 type. Most browsers seem to cache these redirects forever, unless you set different Cache-Control headers. If you don't have any cache control headers, you can never change them without forcing users to empty their cache.

The only fix is to keep redirecting the user to the correct page, so if you had

/page-1 --301--> /page-2

but you want

/page-1 --301-> /page-3

your only fix is to change it to

Auto-destruct in 54 days

Updated: How to change the locale of a PostgreSQL cluster

  • Added instructions on backing up and restoring entire cluster data.
  • Card has been rewritten a bit.

Simulate limited bandwidth

When testing mobile applications, it is sometimes helpful to simulate limited bandwith.


  • Open the dev tools (CTRL+SHIFT+J or F12)
  • Open the network tab
  • In the row below the dev tool tabs, there's a throttling dropdown

Note that there is currently no way to limit the upload bandwidth.


There is a utility called "trickle" that allows you to do limit the bandwidth available to a process.

Simply do

trickle -d 50 -u 20 firefox

to start a firefox with only 50 kB/s download and 20 kB/s uplo…

3379 cards