Stabilize integrations tests with flakyness introduced by Turbo / Stimulus / Hotwire

If you run a Rails app that is using Turbo, you might observe that your integration tests are unstable depending on the load of your machine. We have a card "Fixing flaky E2E tests" that explains various reasons for that in detail.

Turbo currently ships with three modules:

  • Turbo Drive accelerates links and form submissions by negating the need for full page reloads.
  • Turbo Frames decompose pages into independent contexts, which scope navigation and can be lazily loaded.
  • T...

What does 100% mean in CSS?

The attached article examines what the percent unit (%) is relative to in CSS

The article does a great job of visualizing the dependencies. The TLDR is:

Own property % of
height parent height
width parent width
top parent height
left parent width
margin-top parent width
margin-left parent width
padding-top parent width
padding-left parent width

Webpack: How to avoid multiple versions of jQuery

To avoid multiple versions of a package, you can manually maintain a resolutions section in your package.json. We recommend you to do this for packages like jQuery. Otherwise the jQuery library attached to window might not include the functions of your packages that depend on jQuery.

Note: This is only an issue in case you want to use a package functionality from window e.g. $(...).datepicker() from your dev console or any other javascript within the application.

Background

By default yarn will create a folder node_modules ...

Processing GitLab Merge Requests within RubyMine

GitLab has a RubyMine plugin that enables you to review and process merge requests within RubyMine!

Setup

  1. Open RubyMine settings (Ctrl + Alt + S) > Plugins > Search for "GitLab" > Install
    • (You might need to re-open settings afterwards.)
  2. In the RubyMine settings > Version Control > GitLab > Connect your GitLab account with "+"

Working with merge requests

  1. From the Actions menu (Ctrl + Shift + A), choose "View merge requests" (with GitLab icon)
  2. From the subtle dropdown, select the correct origin. Confirm with "View Me...

Rails: Redirect the Logger output temporary aka show Rails logs in the console

Most of the time, when you are interested in any log output,

  • you see the logs directly on your console
  • or you tail / grep some logfile in a separater terminal window

In rare cases it's helpful, to redirect the Logger output temporary to e.g. STDOUT.

Rails.logger = Logger.new(STDOUT)
ActiveRecord::Base.logger = Logger.new(STDOUT)

User.save!
#=> D, [2025-09-08T11:12:26.683106 #1094157] DEBUG -- :   User Load (1.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]

Many frameworks in Rail...

Colorful output for several linux command line tools: grc

Because colors improve readability so much.
On Ubuntu 18.04 you can install it with sudo apt install grc

From github:

For the impatient - try following commands:

grc netstat
grc ping hostname
grc tail /var/log/syslog
grc ps aux

How to evaluate CSS media queries in JavaScript

To make CSS rules dependent on the screen size, we use media queries:

@media (max-width: 500px) {
  // rules for screen widths of 500px or smaller
}

Browsers will automatically enable and disable the conditional rules as the screen width changes.

To detect responsive breakpoints from JavaScript, you may use the global matchMedia() function. It is supported in all brow...

Rails: Fixing the memory leak / performance issues in prepend_view_path

Recently we detected a memory leak in one of our applications. Hunting it down, we found that the memory leak was located in Rails' #prepend_view_path. It occurs when the instance method prepend_view_path is called in each request, which is a common thing in a multi-tenant application.

On top of leaking memory, it also causes a performance hit, since templates rendered using the prepended view path will not be cached and compiled anew on each request.

This is not a new memory leak. It was [first reported in in 2014](https://github.com/...

Disable SimpleCov if you only run a fraction of your tests

Coverage reports are rarely useful if you run only small parts of your test suite.

Just do not load SimpleCov in this case, and you will see less noise in your test output:

if RSpec.configuration.files_to_run.count > 5
  require "simplecov"
  SimpleCov.start 'rails'
end

See also

Javascript: How to match text by Unicode properties

The linked MDN article is quite informative of a neat feature supported by all major browsers: Unicode character class escape.

You can use it to write regular expressions that work on the full UTF-8 space, not just Latin/ASCII. For example, a password policy matcher might include regular expressions like [A-z] or [0-9], but those do not match e.g. German umlauts or [Eastern Arabic Numerals](https:/...

ActiveRecord: Named bindings in conditions

In Active Record you can use named bindings in where-conditions. This helps you to make your code more readable and reduces repetitions in the binding list.

Example without named bindings

User.where(
  'name = ? OR email = ?',
  params[:query],
  params[:query]
)

Example with named bindings

User.where(
  'name = :query OR email = :query',
  query: params[:query]
)

Capybara will not find links without an href attribute

Capybara and most assistive technology will fail to find <a> tags that are missing an href attribute. This will probably happen to you every now and then on JavaScript-heavy applications.

An example would be an AngularJS application where the following HTML actually works. [1]

<a ng-click="hello()">Hello</a>

Capybara will fail to find that link, even though looking it up via the DOM shows it:

>> find_link("Hello")
Capybara::...

Don't define a controller action called #process

Remember that your controller actions share the same method space with private methods defined in ActionController::Base. If your controller behaves in super-weird ways, check that you don't overwrite some internal method with a controller action.

Examples for internal methods:

  • #process
  • #process_action
  • #cookies
  • #params
  • #request
  • #response

Debugging

If you accidentally did overwrite some internal method, you may come across an ArgumentError with the message `wrong number of arguments (given 1, expe...

Updated: Integrating ESLint

Updated the instructions for ESLint to work with version 5.x.

Improve accessibility with [aria-required] in SimpleForm

SimpleForm comes with an option browser_validations which could be used to give fields that have a presence validation the HTML required attribute. We usually turn it off due to difficulties controlling its behavior and appearance. Instead we only mark required fields with an asterisk (*) next to its label. Blind users probably only discover the validation issue after submitting the form due to the now displayed error messages.

A compromise with better acce...

RSpec: Marking sections in long examples

RSpec examples can get quite long, especially in feature specs. This makes them hard to read & understand. Also, when executing them, it may take seconds to see any progress.

To improve this, I have successfully been using a little "step" helper in my tests. It marks semantic sections, structuring an example while improving documentation. When the test runs, each step prints its message (or a dot, depending on your formatter).

# spec/support/step_helper.rb
module StepHelper

  # Use this helper to label groups of related actions in l...

Updated: A simpler default controller implementation

Added:

  • etag { flash.to_h }
  • etag { I18n.locale } (could be left out if all URLs contain a locale fragment, but also doesn't hurt and is a good default)

How to silence Puma for your feature tests

When RSpecs runs the first feature spec, you may see log output like this:

Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:39949

You can disable this behavior by tweaking Capybara's Puma server in your spec/support/capybara.rb:

Capybara.server = :puma, { Silent: true }

Note

You don't need to configure this if you're using system tests with modern versions of Rails. They do [exactly the same](https://github.com/rails/rails/blob/ma...

How to use Ubuntu in English, but still show German formats

If you want to have an English Ubuntu UI, but still see dates, money amounts, paper formats, etc. in German formats, you can fine-tune your /etc/default/locale like this:

LANG="en_US.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"

Make sure you have both en...

Git: rebase dependent feature branch after squash

This card will show you how to use git rebase --onto without confusion.

Use case:

You've got two feature branches (one and two), where two depends on one. Now commits of branch one have changed after you branched two from it (i.e. after code review the commits of branch one are squashed). Thus the commit history of branch one has changed. Branch two's history however didn't change.

Solution:

To make the branches share the same commit history again you will have to rebase and replay (attach) the a...

RSpec: Defining helper methods for an example group

You can define methods in any example group using Ruby's def keyword or define_method method:

describe "example" do
  def sum(a, b)
    a + b
  end

  it "has access to methods defined in its group" do
    expect(sum(3, 4)).to be(7)
  end
end

The helper method is also available to groups nested within that group. The helper method is not available to parent or sibling groups.

Global helpers

To define helpers for all specs (or all specs of a type), [define it in a module](https://rspec.info/features/3-12/rspec-core/help...

How to define a table name prefix for all Rails models in a given namespace

ActiveRecord computes table names of model classes, and results are usually just like you'd expect.
Adding a prefix for all classes in a namespace can feel a odd or broken, but does not have to be. It's actually very easy when done right.

Summary (tl;dr)

Here's the short version: Define a table_name_prefix method in the namespace module, and do not define any table_name_prefix in ActiveRecord classes inside of it. If this sounds familiar, we have [a card about using it already](https://makandracards.com/makandra/47198-rails-namespac...

How to find out what is running on a port on a remote machine

By convention, common protocols use a defined port, like 80 for HTTP or 443 for HTTPS.

You can use nmap to find out what service is running behind a given port, and most often see some details about it. This can be helpful if servers don't offer the services you expect for some ports. If you'd like to see what ports are listing on your local machine, you might want to use ss instead of nmap.

Note that nmap's service discovery may trigger several requests.

Example

When using nmap, adding the -A switch will ...

RSpec Argument Matchers: Expecting non-primitive objects as method invocation arguments

Expecting a primitive value as an argument to a method invocation is easy:

expect(object).to receive(:foo).with('arg1', 'arg2')

This expectation would be met with this call:

object.foo('arg1', 'arg2')

But what if the argument is expected to be an object with a given set of methods? E.g. this class with #first_name and #last_name methods:

class Person

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end
  
  attr_reader :first_name, :last_name
  
end
``...