GitHub Actions: Manually running a workflow
To start a workflow manually it must have a trigger called workflow_dispatch
:
---
name: Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
branches:
- master
In the Actions tab of your repo you can now select a workflow and press "Run Workflow".
PostgreSQL's OVERLAPS operator is not fully inclusive
PostgreSQL supports the SQL OVERLAPS
operator. You can use it to test if two date ranges overlap:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-20'::date, '2002-10-30'::date);
overlaps
--------
true
An important caveat is that the date ranges are defined as start <= time < end
. As such the later date is not included in the range:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-21'::date, '2002-10-30'::date);
overlaps
--------
false
Also compar...
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...
Usage of RSpec's raise_error
Never use raise_error
without specifying the Error you expect.
expect { do_a_lot_of_complicated_stuff }.to raise_error
will be green if you make any error in programming. E.g. a simple typo would make the test above green. The block will catch the Spec::
exception and the test will be happy.
Be sure to always have custom errors in your models and raise them in a manner that lets you know what went wrong.
expect { execute_payment! }.to raise_error(PayPal...
Testing for XSS in Markdown Fields
If you render markdown from user input, an attacker might be able to use this to inject javascript code into the source code of your page.
The linked github page is a collection of common markdown XSS payloads which is handy for writing tests.
Producing arbitrary links:
[Basic](javascript:alert('Basic'))
[Local Storage](javascript:alert(JSON.stringify(localStorage)))
[CaseInsensitive](JaVaScRiPt:alert('CaseInsensitive'))
[URL](javascript://www.google.com%0Aalert('URL'))
[In Quotes]('javascript:alert("InQuotes")')
Using onload...
Minify Font Awesome fonts with webpack
Font Awesome 5 is a comprehensive solution for vector icons on your website.
Originally, Font Awesome came as an icon font (plus stylesheets), but recently it can also be used as a pure JavaScript solution (which will render icons as inline <svg>
tags), or even as SVG sprites.
All solutions have their pros and cons:
Icon font:
- little CPU load (no JavaScript)
- fonts are relatively large
- 1 extra HTTP request
Javascript + inline SVG:
- higher CPU load (needs to watch the DOM via mutation observers to ad...
Katapult 0.3.0 released
Katapult 0.3.0 brings Rails 5 and Ruby 2.5 support with a new design, plus a ton of smaller features, fixes and improvements.
Features
- Generating a Rails 5.1.4 app on Ruby 2.5.0
- Dropped asset pipeline in favor of Webpacker
- The generated application now has a sleek, simple design based on Bootstrap
- Employing Unpoly
- New application model DSL shortcut
crud
for "create a model and a web UI with crud actions" - The generated application model is now a transformable e...
How to: Validate dynamic attributes / JSON in ActiveRecord
PostgreSQL and ActiveRecord have a good support for storing dynamic attributes (hashes) in columns of type JSONB
. But sometimes you are missing some kind of validation or lookup possibility (with plain attributes you can use Active Record's built-in validations and have your schema.rb
).
One approach about being more strict with dynamic attributes is to use JSON Schema validations. Here is an example, where a project has the dynamic attributes analytic_stats
, that we can use to store analytics from an external measurement tool.
- A g...
Rspec: How to write better specs
betterspecs.org is a documentation on how to write better RSpec tests.
Note that there are also other approaches like The Self-Contained Test, which is complementary to the dry-approches in betterspecs. Like usual you need to weight the different recommendation and there is no rule of thumb for all specs.
Setup your terminal to not scroll when there is new output
When you are scrolling up to investigate a test failure it is super annoying when the terminal scrolls back down whenever the running test outputs another line. Luckily you can disable this behavior:
- Gnome terminal: *Edit -> Profile preferences -> Scrolling", uncheck Scroll on output
- Terminator: Right click on terminal screen, Preferences -> Profile -> (for each profile) -> Scrolling, uncheck Scroll on output
Rails 3/4: How to add routes for specs only
If you want to have routes that are only available in tests (e.g. for testing obscure redirects), you can use the with_routing
helper -- but that one destroys existing routes which may break a specs that require them to work.
To keep both "regular" and test routes, do this:
class MyApplicationController < ActionController::Base
def show
render text: 'Welcome to my application'
end
end
test_routes = Proc.new do
get '/my_application' => 'my_application#show'
end
Rails.application.routes.ev...
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 ...
Online tool to convert tables between different formats
https://tableconvert.com/ is an online tool to convert tables between different formats (e.g. json, markdown, csv).
It also has a button to transpose a table ("rotate" it by 90 degree).
The tool can be handy if you have tests with large markdown tables for testing contents of a flat json structure or csv.
Please note that you should not use it with sensitive data (like all online tools in general).
The Bark Blog » Testing Rails Model Plugins
Unfortunately, by default plugin tests are pretty bland. They use the plain unit test suite supplied by Ruby, and not any of the extended Rails test framework. This will leave our plugin’s test classes with no access to fixtures, database.yml configuration, or any of those nice class auto-loading features.
Traversing the DOM tree with jQuery
jQuery offers many different methods to move a selection through the DOM tree. These are the most important:
$element.find(selector)
Get the descendants of each element in the current set of matched elements, filtered by a selector. Does not find the current element, even it matches. If you wanted to do that, you need to write $element.find(selector).addBack(selector)
.
$element.closest(selector)
Get the first ancestor el...
dbconsole in Rails 3 requires the environment as the first argument
There is a bug in Rails 3's dbconsole
script, which makes the following command open a database console for the development
environment:
rails dbconsole -p test
You need to write this instead:
rails dbconsole test -p
How to set up SMTP email delivery with a Gmail account
If you want to make your Rails application be capable of sending SMTP emails, check out the action mailer configuration section in the Ruby on Rails guide.
TL;DR you will end up having an smtp_settings
hash that looks something like this:
smtp_settings = {
address: ...,
domain: ...,
port: ...,
user_name: ...,
password: ...,
authentication: ...,
tls: ...,
enable_starttls_auto: ...,
}
This hash can be set as the `delivery_me...
How to avoid ActiveRecord::EnvironmentMismatchError on "rails db:drop"
After loading a staging dump into development, you might get an ActiveRecord::EnvironmentMismatchError
when trying to replace the database (like rails db:drop
, rails db:schema:load
).
$ rails db:drop
rails aborted!
ActiveRecord::EnvironmentMismatchError: You are attempting to modify a database that was last run in `staging` environment.
You are running in `development` environment. If you are sure you want to continue, first set the environment using:
bin/rails db:environment:set RAILS_ENV=development
Starting with R...
How to run a small web server (one-liner)
Sometimes you just want to have a small web server that serves files to test something.
Serve the current directory
On Ruby 1.9.2+ you can do the following (".
" for current directory).
ruby -run -ehttpd . -p8000
Python 2.x offers a similar way.
python -m SimpleHTTPServer 8000 .
This is the same way with Python 3.x
python -m http.server
In both cases your web server is single-threaded and will block when large files are being downloaded from you.
WEBrick also offers [a simple way](https://stackoverflow.com/quest...
Silencing Deprecation Warnings in Rspec
If you’re testing the behavior of deprecated code in your Ruby project, the warning messages littered throughout your spec output is incredibly noisy.
You could silence all warnings with ::ActiveSupport::Deprecation.silenced = true, but you might miss out on an important warning in one of your dependencies. It’s tempting to remove the tests altogether (the code will be burned soon too, right?), but I figured out something a little nicer a little while back in Formtastic’s test suite.
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:
- It does not freeze your server like when you're using a debugger. (Compared to the
Then console
step) - It enables interacting with the server. (Compared to taking screenshots in Capybara)
- It is a faster alternat...
Capybara 'fill_in': Ambiguous match for different input names
When you have two inputs, where one contains the name of the other (eg. Name
and Name with special treatment
), Capybara's fill_in
method will fail with the following message:
Ambiguous match, found 2 elements matching visible field "Name" that is not disabled (Capybara::Ambiguous)
You can force Capybara to match exactly what you are typing (which makes your tests better anyways) with match: :prefer_exact
:
name = 'Name'
value = 'Bettertest Cucumberbatch'
fill_in(field, with: value, match: :prefer_exact)
Furthermore...
How to install packages from newer Ubuntu releases
We're usually running Ubuntu LTS versions. Sometimes newer hardware requires packages from more recent Ubuntu releases that only come with 6 months of support. If there is really no other way, it's possible to install packages from later Ubuntu releases
Caution: Pay really close attention to what you're doing. Depending on the package, this process may require upgrading a lot of dependencies, possibly breaking the system! You really should not do this unless you've carefully calculated the impact on your system
Preparation
First,...
How to change will_paginate's "per_page" in Cucumber features
The will_paginate
gem will show a default of 30 records per page.
If you want to test pagination in a Cucumber feature, you don't want to create 31 records just for that.
Instead, you probably want to modify the number of items shown, by saying something like this:
Given we paginate after 2 users
Using the following step definition, you now can! :)
require 'cucumber/rspec/doubles'
Given /^paginate after (\d+) (.*)$/ do |per_page, model_name|
model = model_name.singularize.gsub(/...