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
- Open RubyMine settings (Ctrl + Alt + S) > Plugins > Search for "GitLab" > Install
- (You might need to re-open settings afterwards.)
- In the RubyMine settings > Version Control > GitLab > Connect your GitLab account with "+"
Working with merge requests
- From the Actions menu (Ctrl + Shift + A), choose "View merge requests" (with GitLab icon)
- 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
``...