Rspec 3: what to do when `describe` is undefined

When tests might not run with skipping RSpec in the RSpec.describe failing with the error undefined method 'describe' for main:Object this card will help you out!

In RSpec 3 the DSL like describe is exposed globally by default. Therefore it is not necessary to write Rspec.describe.

However, there is a config option to disable this beavior, which also disables the old should-syntax:

RSpec.configure do |config|
  config.disable_monkey_patching!...

Resources for working with the Youtube API

You can use the Youtube API to get data from youtube. Here are some resources and some things that are good to know.

You need to create an API key and each request will cost a certain amount of Request-Points (depending on the kind of query).

It may help to understand youtube's domain model before starting.

It's best to just try out your requests in the browser to see what you will get.
A request can look like this (note that you have to replace the playlis...

Defining "partials" in pure HTML without additional rendering helpers

A while ago I tweeted a thread about how a small JavaScript snippet, one that can fit in a single tweet in fact, can be used to allow defining custom elements purely in HTML. This post will expand on the idea, show how the snippet works, and argue for why you might want to actually use this.

A nice trick that lets you define "partials" in HTML without any additional rendering technology on the server or client.

Pattern: Disabling a certain feature in tests

There is a kind of features in web applications that hinder automated integration tests. Examples include cookie consent banners or form captchas. Clearly, these should be disabled so you do not have to explicitly deal with them in each and every test (like, every test starting with accepting the cookies notice). On the other hand, they must be tested as well.

A good feature disabling solution should therefore meet these requirements:

  • The feature is generally disabled in tests. A test does not need to do anything manually.

  • It is *...

Can I Email: Check what styling email clients support

The french Tilt Studio built a caniuse clone for email clients.

Note that while checking styling support helps using (or not using) certain features, it cannot substitute for checking the actual rendering in real clients. Make sure you follow Designing HTML Emails.

ActiveSupport includes Timecop-like helpers

ActiveSupport (since 4.1) includes test helpers to manipulate time, just like the Timecop gem:

  • To freeze the current time, use freeze_time (ActiveSupport 5.2+):

    freeze_time
    
  • To travel to a specific moment in time, use travel_to:

    travel_to 1.hour.from_now
    

    Important

    When freezing time with #travel_to, time will be frozen (like with freeze_time). This means that your application can't detect passage of time by using Time.now.

  • To travel a re...

Capybara: Execute asynchronous JavaScript

Capybara provides execute_script and evaluate_script to execute JavaScript code in a Selenium-controlled browser. This however is not a good solution for asynchronous JavaScript.

Enter evaluate_async_script, which allows you to execute some asynchronous code and wait until it finishes. There is a timeout of a couple of seconds, so it will not wait forever.

Use it like this:

page.evaluate_async_script(<<~JS)
  let [done] = arguments
  doSomethingAsynchronous().then(() => {
    done() // call this to indicate we're done
  })
J...

Rails: Verify the CSRF token

Rails uses a CSRF token in forms and AJAX requests to verify a user request. Internally it compares the injected CSRF token of the form data with the CSRF token in the encrypted user session. To prevent SSL BREACH attacks, the CSRF token from the form data is masked.

To better debug issues, when these tokens do not match, it is useful to unmask the CSRF token from the form da...

Guidelines for Pull Requests and Code Reviews

Projects with more than one developer should always consider to enforce code review even for small changes to improves the overall code health of the system. Here are some guidelines that can help you to accomplish this task.

Github

How to write the perfect pull request

Google

Google's Engineering Practices documentation
Modern Code Review: A Case Study at Google

Though...

A collection of useful design resources for developers

This collection contains some useful design resources for developers. Many of them were mentioned in the Refactoring UI tutorials.

Tutorials

Checking database size by row count

As an application exists, data accumulates. While you'll be loosely monitoring the main models' record count, some supportive database tables may grow unnoticed.

To get a quick overview of database table sizes, you can view the row count like this:

PostgreSQL

SELECT schemaname,relname,n_live_tup 
FROM pg_stat_user_tables 
ORDER BY n_live_tup DESC
LIMIT 12;

 schemaname |                    relname                     | n_live_tup 
------------+------------------------------------------------+------------
 public     | images...

Rails: Invoking a view helper from the console

There are a few ways to access view helpers from the Rails console. The easiest way is the helper shortcut:

helper.translate 'i18n.string'
helper.your_helper_method

If the desired helper renders a view template, you need this setup:

view_paths = Rails::Application::Configuration.new(Rails.root).paths["app/views"]
av_helper = ActionView::Base.new(view_paths).extend YourHelperModule

av_helper.your_helper_method

Rails routing: Using constraints to avoid "Missing template" errors

You can use constraints in your routes.rb to avoid getting ActionView::MissingTemplate errors when wrong routes are called. Instead, the user will see a 404.

If you want multiple routes to use the same constraint you can use the block syntax:

constraints(format: 'html') do
  resources :pages
  resources :images
end

If you want constraints only on certain routes, you can do:

get '/users/account' => 'users#account', constraints: { format: 'html' }

Tip

You can also avoid this error type through [format con...

Using CSS transitions

CSS transitions are a simple animation framework that is built right into browsers. No need for Javascript here. They're supported by all browsers.

Basic usage

Transitions are used to animate the path between to property values. For example, to let the text color fade from red to green on hover, the following SASS is used (shorthand syntax):

.element
  color: red
  transition: color .1s
  
  &:hover
    color: green

This tells the browser "whenever the color of an .element changes...

Joining PDFs with Linux command line

There are several ways to merge two (or more) PDF files to a single file using the Linux command line.

If you're looking for graphical tools to edit or annotate a PDF, we have a separate card for that.

PDFtk (recommended)

PDFtk is a great toolkit for manipulating PDF documents. You may need to install it first (sudo apt install pdftk).
Merging multiple files works like this:

pdftk one.pdf two.pdf cat output out.pdf

Unlike pdfjam, PDFtk should not mess with page sizes but simply joins pages as they are.

...

Controlling how your website appears on social media feeds

When a user shares your content, a snippet with title, image, link and description appears in her timeline. By default social networks will use the window title, the first image, the current URL and some random text snippet for this purpose. This is often not what you want.

Luckily Facebook, Twitter, etc. lets you control how your content appears in the activity streams. They even have agreed on a common format to do this: OpenGraph <meta> tags that go into your HTML's <head>:

<meta property="og:url" content="http://start.m...

Unpoly: Showing the better_errors page when Rails raises an error

When an AJAX request raises an exception on the server, Rails will show a minimal error page with only basic information. Because all Unpoly updates work using AJAX requests, you won't get the more detailled better_errors page with the interactive REPL.

Below is an event listener that automatically repeats the request as a full-page load if your development error shows an error page. This means you get...

How to inspect the HTML of an email in Thunderbird

Inspecting the source of an email does not always reveal the plain HTML source, but some encoded byte mess. In order to inspect the HTML anyways, you can use a little trick:

While composing a message, select all (Ctrl + A), then navigate to Insert > HTML on the message window.

If you need to inspect a received message, hit "Reply" to turn it into composition mode.

Jasmine: using async/await to write nice asynchronous specs

Jasmine has long standing support for writing asynchronous specs. In days gone by we used the done callback to achieve this, but these days it is possible to write much more readable specs.

Async specs

As a first example, say we want to check that some form disables the submit button while working.

// bad (how we used to do it)

beforeEach(() => {
  this.form = setupMyForm()
  this.submitButton = findTheSubmitButton()
})

it('disables the submit button while working', (done) => {
  expect(this.submitButton.disabled).toBe(false)
...

Adding Jasmine JavaScript specs to a Webpack(er) project

The goal is to get Jasmine specs running in a Rails project using Webpacker, with the browser based test runner. Should be easily adaptable to a pure Webpack setup.

Image

Step 1: Install Jasmine

yarn add jasmine-core

Step 2: Add two separate packs

Since we do not want to mix Jasmine into our regular Javascript, we will create two additional packs. The first only contains Jasmine and the test runner. The second will contain our normal application code and the specs themselves.

We cannot...

ActiveType 1.2 supports "change_association"

With ActiveType 1.2 you can modify associations (has_many etc.) after they have been defined.

One common use case for this is to change an association inside a form model, like this:

class Credential < ActiveRecord::Base
end

class User < ActiveRecord::Base
  has_many :credentials
end

class SignUpCredential < ActiveType::Record[Credential]
end

class SignUp < ActiveType::Record[User]
  change_association :credentials, class_name: 'SignUpCredential'
end

Now, if you load `credentials...

How to recognize CVE-2019-5418

If you get requests with values for formats like this:

{:locale=>[:de], :formats=>["../../../../../../../../../../etc/services{{"], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}

or fails like this:

Invalid query parameters: invalid %-encoding (../../../../../../../../../etc/passwd%%0000.html)

Someone tries to exploit CVE-2019-5418.
If you use the latest Rails (or latest Rails LTS) you're...

Heads up: Capybara 3's text matchers no longer squish whitespace by default

Until Capybara 2, node finders that accept a text option were able to find nodes based on rendered text, even if it spans over multiple elements in the HTML. Imagine a page that includes this HTML:

<div class='haystack'>
  Hi!
  <br>
  Try to match me.
</div>

Even though the text is separated by a <br> tag in the HTML, it is matched until Capybara 2 which used to "squish" text prior to the comparison.

# Capyabara 1 or 2
page.find(...

Webpack: Automatically generating an icon font from .svg files

Over the years we have tried several solution to have vector icons in our applications. There are many ways to achieve this, from SVGs inlined into the HTML, SVGs inlined in CSS, JavaScript-based solutions, to icon fonts.

Out of all these options, the tried and true icon font seems to have the most advantages, since

  • icon fonts are supported everywhere
  • they perform well and require no JavaScript at all
  • their icons align nicely with text
  • their icons automatically inherit color and size of the surrounding text

The big issue used to b...