Sometimes you need to access a dev server running on localhost from another machine that is not part of the same network. Maybe you want to use your phone to test a web page, but are only in a guest WiFi. In the past, we often used some port forwarding or other techniques to expose the service to the internet.
Enter ngrok, a command line tool that gives you an on-the-fly internet...
RSpec Rails can automatically mix in different behaviors to your tests based on their type
tag, for example enabling you to call get
and
post
in specs with the tag type: :request
.
Alternatively you can skip these tags by setting the config config.infer_spec_type_from_file_location!
in the spec_helper.rb
. This will automatically choose the right type context based on the file location of the test.
For instan...
You can use RSpec::Matchers.define_negated_matcher
to define a negated version of an existing matcher.
This is particularly useful in composed matcher expressions or to create more expressive and meaningful matchers.
RSpec::Matchers.define_negated_matcher :not_change, :change
describe 'A negated matcher' do
it 'can be used to chain negated changes' do
expect { subject.maybe_change(object) }
.to not_change(object, :attr_1)
.and not_change(contract, :attr_2)
end
end
RSpec::...
Proxy caching is a good feature to serve your publicly visible application content faster and reduce load on your servers. It is e.g. available in nginx, but also affects proxies delivered by ISPs.
Unfortunately, there is a little problem in Rails < 6.1 when delivering responses for different MIME-types. Say you have an arbitrary route in your Rails application that is able to respond with regular HTML and JSON. By sending the specific MIME type in the Accept
header, you tell the application to either return HTML (text/html
) or JSON (`t...
ImageMagick can convert SVGs to raster image formats.
Example for PNG:
convert input.svg output.png
If the SVG has a size of 24x24 (viewBox="0 0 24 24
"), the resulting PNG will also have a size of 24x24.
An SVG's viewBox
specifies the intended size, but vector image formats can be scaled freely.
If you want your raster image to be larger, the naive approach would be to use the resize
flag.
convert -resize 96x96 input.svg output.png
However, this resu...
The Interactive Advertising Bureau (IAB) is a European marketing association which has introduced a standard how advertising can be served to users in line with the General Data Protection Regulation (GDPR). This standard is called the TCF 2.0 (Transparency and Consent Framework). If you want to integrate any kind of advertising into a website, chances are the advertising network will require your website to implement that standard. This is a very brief overview of what this means:
The basic idea in the TCF 2.0 ...
Some users might use Adblock Plus or similar browser plugins to reduce the number of ads displayed. If you run into an issue that your application or part of an application is blocked, this card will give you some guidance on how to debug it.
In general ad blocking is not an issue for most of our web apps. But if your application uses iframes or is embedded in another site it's more prone to it.
Blocked elements most of the time appear to the user as empty frames in the page. The indicator icon of the ad blocker also gives ...
From Exploring ES6:
Module imports are hoisted (internally moved to the beginning of the current scope). Therefore, it doesn’t matter where you mention them in a module and the following code works without any problems:
foo(); import { foo } from 'my_module';
When you're not aware of import hoisting you may be surprised that your code runs in a different order than you see in the source file.
The example below is taken from the [...
Modern versions of Capybara include a finder method #ancestor
which allows you to find a parental element using CSS or XPath.
If you previously did something like this:
field.find(:xpath, './ancestor::div[contains(@class, "form-group")]')
..and prefer CSS, you may rewrite it:
field.ancestor('div.form-group')
Both versions will return the outermost matching element. Use the #order
option find the closest parent:
field.ancestor('div.form-group', order: :reverse)
Jasmine is a great way to unit test your JavaScript components without writing an expensive end-to-end test for every small requirement.
After we integrated Jasmine into a Rails app we often add an E2E test that opens that Jasmine runner and expects all specs to pass. This way we see Jasmine failures in our regular test runs.
In a [feature spec](https://relishapp.com/rspec/rspec-rails/docs/feature-spec...
A flaky test is a test that is often green, but sometimes red. It may only fail on some PCs, or only when the entire test suite is run.
There are many causes for flaky tests. This card focuses on a specific class of feature with heavy side effects, mostly on on the UI. Features like the following can amplify your flakiness issues by unexpectedly changing elements, causing excessive requests or other timing issues:
If you want Sidekiq to be able to talk to Redis on staging and production servers, you need to add the following to your configuration:
# config/initializers/sidekiq.rb
require 'sidekiq'
Sidekiq.configure_client do |config|
config.redis = { url: REDIS_URL }
end
Sidekiq.configure_server do |config|
config.redis = { url: REDIS_URL }
end
The following step may be skipped for new Sidekiq 6+, since it isn't recommended anymore to use a global redis client.
# config/initializers/redis.rb
require 'redis'
require_relativ...
Within development and test environments, Rails is usually configured to show a detailed debug page instead of 404s. However, there might be some cases where you expect a 404 and want to test for it.
An example would be request-specs that check authorization rules. (If you use a gem like consul for managing authorization rules, you should always check these rules via power-specs. However, request-specs can be used as a light-weight version of integration tests here.)
In this case, Rails will replace the 404 page that you want to test ...
This RailsCast demonstrated a very convenient method to activate VCR for a spec by simply tagging it with :vcr
.
For RSpec3 the code looks almost the same with a few minor changes. If you have the vcr
and webmock
gems installed, simply include:
# spec/support/vcr.rb
VCR.configure do |c|
c.cassette_library_dir = Rails.root.join("spec", "vcr")
c.hook_into :webmock
end
RSpec.configure do |c|
c.around(:each, :vcr) do |example|
name = example.metadata[:full_descripti...
RSpec is smart when using the include
-matcher in combination with .not_to
. One could assume that
.not_to include(3, 4, 5)
evaluates to:
NOT( .to include(3, 4, 5) )
However, it behaves like:
.to (NOT include(3) && NOT include(4) && NOT include(5) )
Warning
Using
.not_to
in combination with theinclude
-matcher doesn't logically negate the final truth value. It instead negates the individual include-expectations for each argument.
describe 'RSpec' do
it "doesn't use logical nega...
Inspired by recent "git shortcut" cards I figured it would be nice to have one of these for rebasing a few commits onto another branch. The usual notation is prone to of-by-one errors as you have to either specify the commit before the ones you want to move or count the number of commits.
You may add this rebase-onto
function to your ~/.bashrc
:
function rebase-onto {
commit=$(git log --oneline | fzf --prompt 'Select the first commit y...
Event delegation is a pattern where a container element has a single event listener that handles events for all descendants that match a CSS selector.
This pattern was popularized by jQuery that lets you do this:
$('.container').on('click', '.message', function(event) {
console.log("A message element was clicked!")
})
This technique has some advantages:
Sometimes a link or input field has no visible label. E.g. a text field with a magnifying glass icon 🔎 and a "Search" button does not really need a visible label "Query".
For accessibility reasons it is good practice to give such a field an [aria-label]
attribute:
<input type="search" aria-label="Search contacts">
This way, when a visually impaired user focuses the field, the screen reader will speak the label text ("Search contacts").
Info
Without an `[aria-...
Besides their default styling properties, HTML elements have a semantic meaning. For example, an h1
tag is usually styled with a larger font and bold, while it denotes "the single most important headline in its context".
While CSS enables us to style almost any HTML element like anything that is needed, choosing HTML elements corresponding to the meaning of their content has a few advantages:
Ruby lets you re-use existing RegExp
objects by interpolating it into new patterns:
locales_pattern = /de|en|fr|es/i
html_tag_pattern = /<html lang="#{locales_pattern}">/
Any modifiers like /i
or /x
will be preserved within the interpolated region, which is pretty cool. So in the example above only the interpolated locales are case-insensitive, while the pattern around it (/<html .../
) remains case-sensitive.
The RSpec matcher tests if two HTML fragments are equivalent. Equivalency means:
You use it like this:
html = ...
expect(html).to match_html(<<~HTML)
<p>
Expected content
</p>
HTML
You may override options from CompareXML by passing keyword arguments after the HTML string:
html = ...
expect(html).to match_html(<<~HTML, ignore_text_nodes: true)
...
We are using Spring in our tests for sequential test execution but not for parallel test execution. And Rails requires you to set the config.cache_classes = false
if you are using Spring in tests.
With our setup, this would raise the following error in cucumber-rails for parallel test executions due to some legacy database cleaner issue.
WARNING: You have set Rails' config.cache_classes to false
(Spring needs cache_classes set to false). This is known to cause probl...
Bookmarks for directories will be most helpful if you are forced to work in deeply nested projects. Then it's really helpful!
This makes use of the CDPATH
variable. Similar to the PATH
variable, which holds the list of directories which are searched for executables, CDPATH
contains the list of directories that are available for cd
. Besides the current directory (.
), you can add others to that.
The trick is to add a directory for bookmarks to CDPATH
.
First, create the directory with: mkdir ~/.bookmarks
.
Then add the followin...
With cd ..
you can navigate one directory up from the one you are at now. If you use that a lot, consider some handy aliases.
Add the following lines to your ~/.bashrc
:
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
alias ......="cd ../../../../.."
you can add even more aliases, but I usually loose track after too many levels and just jump to the directly directly, e.g. using its absolute path or its bookmark (see [this card](https://makandracards.com/makandra/504947-working-on-the-li...