makandra/capybara-lockstep
capybara-lockstep can help you with flaky end-to-end tests:
This Ruby gem synchronizes Capybara commands with client-side JavaScript and AJAX requests. This greatly improves the stability of a full-stack integration test suite, even if that suite has timing issues.
Webmock < 3.12.1 cannot handle IPv6 addresses correctly
We had the issue, that a VCR spec failed, after updating CarrierWave
from version 0.11.0
to 1.3.2
.
In this version, CarrierWave
uses the gem SsrfFilter
, which retrieves the IP addresses for the given hostname and replaces the hostname in the requested url with one of them.
It works with IPv4 addresses, but not with IPv6 addresses, because WebMock cannot handle those correctly:
uri = "#{protocol}://...
Making ZSH the default shell on Ubuntu 20.04
ZSH is an alternative command line shell that includes some features like spelling correction, cd automation, better theme, and plugin support. You can replace Bash with ZSH like following:
sudo apt-get install zsh
Setting ZSH as default login shell
sudo usermod -s /usr/bin/zsh $(whoami)
Opening a new terminal window will show you a dialog where you can configure your initial ZSH config (Option 2 recommended).
Afterwards you can install the plugin manager Oh-My-ZSH and select a prop...
CarrierWave: Default Configuration and Suggested Changes
CarrierWave comes with a set of default configuration options which make sense in most cases. However, you should review these defaults and adjust for your project wherever necessary.
You will also find suggestions on what to change below.
Understanding the default configuration
Here is the current default config for version 2:
config.permissions = 0644
config.directory_permissions = 0755
config.storage_engines = {
:f...
Best practices for REST API design
A rough guide how to implement a REST API.
The discussion here includes some interesting points as well:
- Timestamps: ISO8601 format ("2021-02-22T20:34:53.686Z")
- Google API guideline: https://google.aip.dev/
- Numbers: String vs. Number
The JSON number type is not a double. It's just a number of arbitrary size and precision in integer/decimal/E format that can be parsed as whatever the parser finds fitting.
- Pagination: Limit + Offset vs. Object ID / Pointer vs. System-Version...
Running old ImageMagick versions in a Docker container
If your project depends on an old version of ImageMagick that you can no longer install in your system, you can choose the run an old ImageMagick in a Docker container.
Dockerized ImageMagick commands will only work with absolute path arguments. You need to boot a corresponding docker container once before using it.
Setting up Docker
If you haven't installed Docker yet, use our guide or the [official instructions](https://docs.docker.com/get-started/...
Parallelize Development Using Git Worktrees
You can use git worktree
to manage multiple working trees attached to the same repository. But why should I use git worktree
?
You can use more than one working tree to ...
... run tests while working on another branch
... compare multiple versions
... work on a different branch without disturbing your current branch
Creating a new working tree is as simple as creating a new branch. You only need to execute git worktree add <path> <branch>
. When you are done, you can remove the working tree with git worktree remove <Worktree>
...
Regular Expressions: Quantifier modes
When you repeat a subpattern with a *
, +
or {...}
operator, you may choose between greedy, lazy and possessive modes.
Switching modes may affect the result and performance of your regular expressions. In the worst case, an ill-suited mode may make your regular expression so slow that it can DoS your application (Examples are the ActiveRecord's PostgreSQL CVE-2021-22880 or the [Cloudflare outage 2019](https://makandracards.com/makandra/77515-regular-expressions-excessive-backtracking...
Linux: How to make a terminal window title reflect the current path
By default, your terminal emulator (Gnome Terminal, Terminator, etc.) sets some kind of window title to reflect the shell type you are running (e.g. /bin/bash
).
This is most often not too helpful, but you can change that from your shell.
To set a specific title, print an escape sequence like this:
echo -en "\033]0;Hello\a"
You can easily include the current path:
echo -en "\033]0;$(pwd)\a"
Or, to replace your home directory's part with a tilde:
echo -en "\033]0;$(pwd | sed -e "s;^$HOME;~;")\a"
Or,...
DNS debug tools
There are several tools for DNS debugging which offer you more or less information. Most of the time the more simple ones, like host
oder nslookup
will be sufficient.
host
simple DNS lookup utility.
>host heise.de
heise.de has address 193.99.144.80
heise.de has IPv6 address 2a02:2e0:3fe:1001:302::
heise.de mail is handled by 10 relay.heise.de.
nslookup
query Internet domain name servers. Nslookup has two modes: interactive and non-interactive.
>nslookup heise.de
Server: 146.254.160.30
Address: 146.254.160.3...
Git: Parsing large diffs as a human
I just finished migrating a project from the Asset Pipeline to Webpacker, this is what my diff to master looks like:
5.825 files changed, 44.805 insertions(+), 529.948 deletions(-)
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 5134 and retry the command.
There is no way me or my peer reviewer is able to parse 500k+ lines of code. Fortunately, git has ...
Using the Truemail gem to validate e-mail addresses
The Truemail gem (not to be confused with truemail.io) allows validating email addresses, e.g. when users enter them into a sign-up form. It runs inside your application and does not depend on an external SaaS service.
Truemail supports different validation "layers":
- Regex validation: if the given address is syntactically valid
- DNS validation (called MX validation): if the given domain exists and can receive email
- SMTP validation: connects to the host received from DNS and starts a test d...
Transporting blank values in URL queries
URLs can transport key/value pairs ("parameters") using this syntax:
/path?foo=bar
If the value is blank, mind these subtle differences:
URL | Meaning |
---|---|
/path?foo= |
Parameters have a key foo . Its value is an empty string. |
/path?foo |
Parameters have a key foo . Its value is null . |
/path |
Parameters have no key foo . |
How to build a fully custom TinyMCE 5 dialog
TinyMCE is a WYSIWYG editor which is quite customizable.
- Add a custom button to the tinyMCE toolbar and tell tinyMCE to open a dialog with the route to your dialog's view.
tinymce.init({
// ...
toolbar: 'myCustomButton',
setup: function(editor) {
editor.ui.registry.addButton('myCustom Button', {
...
Missing certificates for rubygems and bundler in Ruby 1.8.7
Using Ruby 1.8.7 you will not be able to use the maximum versions Rubygems 1.8.30 and Bundler 1.17.3 with https://rubygems.org/
anymore. This is a result of a server certificate on December 5th, 2020. The resulting errors will look like following:
TypeError: can't modify frozen object
Could not verify the SSL certificate for https://rubygems.org/*
Bundler::Fetcher::CertificateFailureError: Could not verify the SSL certificate for https://index.rubygems.org/versions.
- `Error fetching data: hostname was not m...
Configuring Webpacker deployments with Capistrano
When deploying a Rails application that is using Webpacker and Capistrano, there are a few configuration tweaks that optimize the experience.
Using capistrano-rails
capistrano-rails is a Gem that adds Rails specifics to Capistrano, i.e. support for Bundler, assets, and migrations. While it is designed for Asset Pipeline (Sprockets) assets, it can easily be configured for Webpacker. This brings these features to the Webpacker world:
- Automatic removal of expired assets
- Manifest backups
How to have a target=_blank link open with DevTools open
In the tab where you need it, open Chrome DevTools with F12, open settings with F1, scroll down to the "Global" section and check "Auto-open DevTools for popups".
When you follow a link with target=_blank within that tab, DevTools will be open and you can inspect e.g. request headers.
Variable fonts for web developers
This card is mainly an explanation how variable fonts work in CSS, not necessarily a recommendation to actually use them.
What is a variable font?
Designing and rendering fonts are two highly complex topics. For an arbitrary text to appear properly on your screen, its font must be created multiple times for different "settings" like stroke width (boldness) and style (e.g. italic).
Now as web developers, we usually ship these variants of the same font via multiple @font-face
s of the same font-family:
@font-face
font-family...
How to configure file watchers in RubyMine
Installation
You need to install the official plugin, it is not bundled with RubyMine by default.
Example: Setup a watcher to verify rubocop integrity
First, open Settings -> Tools -> File Watchers. Then, configure rubocop to check every change to the VCS:
Note that the "program" argument must be part of your $PATH
. I worked around this constraint by using b
as a shim for bundle exec
.
Resources
- [File watchers documen...
Convert curl commands to ruby code
curl-to-ruby is a handy tool that converts your curl
command to ruby code that uses the Net::HTTP library.
Example
curl -X POST -d
"grant_type=password&email=email&password=password"
localhost:3000/oauth/token
will output to:
require 'net/http'
require 'uri'
uri = URI.parse("http://localhost:3000/oauth/token")
request = Net::HTTP::Post.new(uri)
request.set_form_data(
"email" => "email",
"grant_type" => "password",
"password" => "password",
)
req_options =...
VCR and the webdrivers gem
If you're using the webdrivers gem and VCR together, depending on your configuration, VCR will yell at you regulary.
The webdrivers gem tries to update your webdrivers on your local machine. To do so, it checks the internet for newer versions, firing an HTTP-request to e.g. https://chromedriver.storage.googleapis.com
You can "fix" this in multiple ways:
-
Update your drivers on your machine with
RAILS_ENV=test rake webdrivers:chromedriver:update
-
Ignore the driver update-URL in your ...
How to include Sidekiq job IDs in Rails logs
When logging in Rails, you can use the log_tags
configuration option to add extra information to each line, like :request_id
or :subdomain
. However, those are only valid inside a request context and have no effect when your application is logging from inside a Sidekiq process.
This includes custom as well as any framework logs, like query logging from ActiveRecord.
Since Sidekiq Workers run inside threads of a single process, running multiple jobs in...
Ruby: How to determine the absolute path relative to a file
If you want to get the path of a file relative to another, you can use the expand_path
method with either the constant __FILE__
or the method __dir__
. Read this card for more information about __FILE__
and __dir__
.
Example
Structure:
.
├── bin
│ ├── format_changelog
├── CHANGELOG.md
bin/format_changelog
:
#!/usr/bin/env ruby
changelog_path = ? # How to get the path to ../CHANGELOG.md independent of the working dir of the caller
changelog = File.read(changelog_path)
# ... further actions...
CSS variables aka CSS Custom Properties
CSS variables are very different from preprocessor variables. While preprocessors use variables to compile a static piece of CSS, CSS custom properties are a reactive (i.e. live) part of the styles. Think of them like usual CSS properties that cascade, but have:
- a special syntax: CSS variables always start with a double-dash (
--color
) - no inherent meaning: Defining a CSS variable will not change any styles in itself
- a special functionality: CSS variables can be used within the values of other properties, including CSS variables...