Upgrading a Rails app to Cucumber 3

Upgrade gems

You need to update a lof gems. Make sure you don't have any version constraints in your Gemfile or your bundle update won't do anything!

Upgrade cucumber_priority:

bundle update cucumber_priority

Upgrade spreewald:

bundle update spreewald

Upgrade cucumber_factory:

bundle update cucumber_factory

Upgrade parallel_tests:

bundle update parallel_tests

Even on the latest version, parallel_tests will print some deprecation warnings due to using an older formatter A...

Advantages of using appname.daho.im:3000 over localhost:3000

Running rails server will start a local server that you can access via http://localhost:3000.

When you are working on multiple web apps, they will likely set cookies with generic names on localhost. This is annoying, since you will sign out your current user whenever you switch to another app.

A better way is to use our own daho.im service. All daho.im subdomains resolve to your local IP (127.0.0.1). That means you can use a different hostname for different apps, and you will stay logged in in each app:

http://foo-ap...

Chrome: Making high-resolution website screenshots without add-ons

If you want to make a screenshot of a website that works well in print or on a high-DPI screen (like Apple Retina displays), here is how you can capture a high-resolution screenshot.

You can do this without an addon:

  • Open the website
  • If you have multiple monitoros:
    • Resize the Chrome window so it covers multiple monitors (in Linux you can hold ALT and resize by dragging with the right mouse button)
    • Zoom into the page using CTRL + and CTRL - so it covers most of the window area. Leave a little padding on the left and right so...

Form letters with LibreOffice Writer

This is painful. Consider using Microsoft Office or switching careers. If you need to write < 20 letters consider doing it manually.

So you didn't listen and here it comes:

  1. Ignore the Mail Merge Wizard. It will crash or destroy your document.
  2. Export your addresses, recipient names, etc. as a .ods spreadsheet (.xls, .xlsx, .ods). Use any columns that work for you, but be consistent. I like to use one column for the address, one column for the salutation line.
  3. Import the spreadsheet as an address book source: *Tools => Add...

How to fix HTML elements being cut off when printing

When you print (or print preview) and elements are cut off (e.g. after 1st page, or "randomly") you should check your CSS rules for these:

  • Is there an element with "display: inline-block" that surrounds your content? Make sure it has "display: block" for printing.
    This primarily affects Firefox and Internet Explorer. Chrome seems to be able to handle inline-block elements in most cases.

  • Does the element itself, or a container, define "overflow: hidden"? Use "overflow: auto" (or maybe "overflow: visible") instead.

  • Is th...

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

Precondition

  • You are not using javascript tests
  • The file is served from a public folder (not via controller)

Problem description

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)

Solution

One solution...

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 = get('/foo')
print(html)
print('script end')

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

Talking to asynchronous (or "evented") API

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

Script outputs 'script start', `'...

How to fix broken font collisions in wkhtmltopdf

If you are using PDFKit / wkhtmltopdf, you might as well want to use custom fonts in your stylesheets. Usually this should not be a problem, but at times they include misleading Meta-information that leads to a strange error in the PDF.

The setup

  • The designer gave you two fonts named something like BrandonText-Regular and BrandonText-Bold. (With flawed Meta-information)
  • You have a HTML string to be rendered by PDFKit
  • For demonstration purposes, this strin...

Custom Ruby method Enumerable#count_by (use for quick statistics)

I frequently find myself needing a combination of group_by, count and sort for quick statistics. Here's a method on Enumerable that combines the three:

module Enumerable
  def count_by(&block)
    list = group_by(&block)
      .map { |key, items| [key, items.count] }
      .sort_by(&:last)
      
    Hash[list]
  end
end

# Returns a Hash of { key => count } pairs (see below)

Just paste that snippet into a Rails console and use #count_by now!

Usage examples

  • Number of email addresses by domain:
> User.all.co...

Quickly printing data in columns on your Ruby console

Dump this method into your Ruby console to quickly print data in columns. This is helpful for e.g. comparing attributes of a set of Rails records.

def tp(objects, *method_names)
  terminal_width = `tput cols`.to_i
  cols = objects.count + 1 # Label column
  col_width = (terminal_width / cols) - 1 # Column spacing

  Array(method_names).map do |method_name|
    cells = objects.map{ |o| o.send(method_name).inspect }
    cells.unshift(method_name)

    puts cells.map{ |cell| cell.to_s.ljust(col_width) }.join ' '
  end

  nil
end

Usag...

How to view Image Metadata on the Linux Command Line with ImageMagick

ImageMagick has a command line tool called identify which can read image metadata:

>identify -verbose DSC00136.JPG
Image: DSC00136.JPG
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Class: DirectClass
  Geometry: 5472x3648+0+0
  Resolution: 350x350
  Print size: 15.6343x10.4229
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Red:
      min: 0 (0)
      max: 255 (1)
      mean: 11...

Bundler: Gemfile.lock is corrupt & gems are missing from the DEPENDENCIES section

So you're getting this failure when running bundle install on an older project:

Your Gemfile.lock is corrupt. The following gems are missing from the DEPENDENCIES section: 'archive-tar-minitar' 'hoe' 'rcov'

This happens when you are using a new version of Bundler with a project that was bundled with a very old version of Bundler. For reasons unknown, the Bundler dependency API returns different dependencies for some gems (like ruby-debug or rainpress) than the dependencies found in the downloaded gemspecs. While old versi...

Debugging cucumber feature with javascript + firefox vnc

TL;DR Debugging problems with javascript errors in cucumber tests is sometimes easier in the browser. Run the test, stop at the problematic point (with Then pause from Spreewald 1.7+) and open VNC for Firefox.

Features:

Howto: Free disk space when /boot is full

Easy mode

This method will remove automatically installed packages that no other packages depend on any more. This, of course, includes obsolete kernel versions, with the explicit exception of the currently running kernel, the kernel version that was installed on the system before that and, of course, the latest updated version of the kernel. However, it will also remove any and all other packages that have been marked as installed automatically but have no other packages depending on them. This could lead to unexpected removal of package...

Building web applications: Beyond the happy path

When building a web application, one is tempted to claim it "done" too early. Make sure you check this list.

Different screen sizes and browsers

Desktops, tablets and mobile devices have all different screen resolutions. Does your design work on each of them?

  • Choose which browsers to support. Make sure the page looks OK, is usable and working in these browsers.
  • Use @media queries to build a responsive design
    • If you do not suppo...

Testing terminal output with RSpec

When testing Ruby code that prints something to the terminal, you can test that output.
Since RSpec 3.0 there is a very convenient way to do that.

Anything that writes to stdout (like puts or print) can be captured like this:

expect { something }.to output("hello\n").to_stdout

Testing stderr works in a similar fashion:

expect { something }.to output("something went wrogn\n").to_stderr

Hint: Use heredoc to test multi-line output.

expect { something }.to output(<<-MESSAGE.strip_heredoc).to_stdout...

Linux: Open a file with the default application

If you are on a Linux shell and want to open a file with whatever default application is configured for that type, this often works:

xdg-open Quote.odt
xdg-open invoice.pdf
xdg-open index.html

Pro Tip

Make an alias so you have a simpler API (like Mac OS): alias open=xdg-open or alias x=xdg-open.

Background

You can choose your "Default applications" via UI in the Ubuntu "Settings" application (gnome-control-center). This is just a very rough setting (e.g. open Photos with Shotwell Viewer).

If a certain file...

netstat: Sum open connections by IP (and sort it)

The following sums up all connections (ESTABLISHED, TIME_WAIT, FIN_WAIT, etc.) and sorts it:

netstat -n | awk ' $5 ~ /^[0-9]/ {print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

Works on FreeBSD and Linux.

Geordi 1.3 released

Changes:

  • Geordi is now (partially) tested with Cucumber. Yay!
  • geordi cucumber supports a new @solo tag. Scenarios tagged with @solo will be excluded from parallel runs, and run sequentially in a second run
  • Support for Capistrano 2 AND 3 (will deploy without :migrations on Capistrano 3)
  • Now requires a .firefox-version file to set up a test firefox. By default now uses the system Firefox/a test Chrome/whatever and doesn't print warnings any more.
  • geordi deploy --no-migrations (aliased -M): Deploy with `cap ...

bash: print columns / a table

Ever wondered how you can create a simple table output in bash? You can use the tool column for creating a simple table output.

Column gives you the possibility to indent text accurate to the same level. Pipe output to column -t (maybe configure the delimeter with -s) and see the magic happening.

detailed example

I needed to separate a list of databases and their corresponding size with a pipe symbol: |
Here is a example list.txt:

DB	Size_in_MB
foobar	11011.2
barfoo	4582.9
donkey	4220.8
shoryuken	555.9
hadouken	220.0
k...