Ruby: Removing leading whitespace from HEREDOCs
If you're on Ruby 2.3+ there's a <<~
operator to automatically unindent HEREDOCs:
str = <<~MESSAGE
Hello Universe!
This is me.
Bye!
MESSAGE
If you have an older Ruby, you can use the String#strip_heredoc
method from ActiveSupport. See Summarizing heredoc in ruby and rails for an example.
Technically...
Detecting when fonts are loaded via JavaScript
Webfonts are not always available when your JavaScript runs on first page load. Since fonts may affect element sizes, you may want to know when fonts have been loaded to trigger some kind of recalculation.
Vanilla JavaScript / Modern DOM API
In modern browsers (all but IE and legacy Edge) you can use document.fonts
. Use load
to request a font and receive a Promise that will be resolved once the font is available. Example:
document.fonts.load('1rem "Open S...
Sharing cookies across subdomains with Rails 3
To achieve this goal you have to setup the session store like the following example:
MyApp::Application.config.session_store(
:cookie_store,
{
:key => '_myapp_session',
:domain => :all, # :all defaults to da tld length of 1, '.web' has length of 1
:tld_length => 2 # Top Level Domain (tld) length -> '*.myapp.web' has a length of 2
}
)
The invconvenient side effect for local development
… or: Why do I get "Can't verify CSRF token authenticity" even if csrf token is present?
As `:domain => :all...
How to create giant memory leaks in AngularJS (and other client-side JavaScript)
This guide shows how to create an AngularJS application that consumes more and more memory until, eventually, the browser process crashes on your users.
Although this guide has been written for Angular 1 originally, most of the advice is relevant for all client-side JavaScript code.
How to observe memory consumption
To inspect the amount of memory consumed by your Javascripts in Chrome:
- Open an incognito window
- Open the page you want to inspect
- Press
Shift + ESC
to see a list of Chrome processes...
An auto-mapper for BEM classes in Cucumber selectors
When you are using the #selector_for
helper in Cucumber steps, as e.g. Spreewald does, the following snippet will save you typing. It recognizes a prose BEM-style selector and maps it to the corresponding BEM class.
For a variation on this idea, see An auto-mapper for ARIA labels and BEM classes in Cucumber selectors.
Examples
"the main menu" -> '.main-menu'
"the item box's header" -> '.item-box--header'
Here are some examples of steps (using Spreewald, too):
T...
grosser/rspec-instafail
Gem to show failing specs instantly.
Unlike the --fail-fast
option it doesn't abort abort on the first failure, but keeps running other examples after print out the failure.
I haven't tried it with parallel_tests
.
Block formatting contexts
TL;DR Block formatting contexts establish an isolating container. float
and clear
only apply to elements within such a container.
About
Block formatting contexts (BFCs) are important for the positioning and clearing
of floats. The rules for positioning and clearing of floats apply only to
things within the same block formatting context.
Floats do not affect the layout of things in other block formatting contexts,
and clear
only clears past floats in the same block formatting context.
How to create a new block form...
Understanding z-index: it's about stacking contexts
The CSS property z-index
is not as global as you might think. Actually, it is scoped to a so-called "stacking context". z-indexes only have meaning within their stacking context, while stacking contexts are treated as a single unit in their parent stacking context. This means indices like 99999
should never actually be needed.
Creating a new stacking context
In order to create a stacking context with the least possible side effects, use the isolation
property on an...
Git: How to get a useful diff when renaming files
tldr; Use git diff -M
or git diff --find-renames
when you've moved a few files around.
Usage
$ git diff --help
Options:
-M[<n>], --find-renames[=<n>]
Detect renames. If n is specified, it is a threshold on the similarity index
(i.e. amount of addition/deletions compared to the file’s size). For example,
-M90% means Git should consider a delete/add pair to be a rename if more than
90% of the file hasn’t changed. Without a % sign, the number is to be read as
a fraction, with a decimal point...
How to load an SQL dump from a migration
If you want to load an SQL dump from an ActiveRecord migration, you might find this to be harder than you thought. While you can call ActiveRecord::Base.connection.execute(sql)
to execute arbitrary SQL commands, the MySQL connection is configured to only accept a single statement per query. If you try to feed it multiple statements, it will die with You have an error in your SQL syntax.
You can work around this by opening a second MySQL connection that does accept multiple statements per call.
Below is an example for a migration that l...
RSpec: Only stub a method when a particular argument is passed
To only stub a method call if a given argument is used, but use the default implementation for other arguments:
object.should_receive(:some_method).and_call_original
object.should_receive(:some_method).with('my argument').and_return('other value')
Requires rspec-mocks
2.13+.
Geordi 1.0 released
Geordi 1.0 features a command line application geordi
, that holds most of Geordi's previous commands.
New features
-
command help and usage examples right within
geordi
(geordi help
andgeordi help <command>
) -
quick command access: type just the first few letters of a command, e.g.
geordi rs
orgeordi dev[server]
-
command dependencies, e.g.
geordi rspec
invokesgeordi bundle-install
(which bundles only if needed) -
no cluttered
/usr/bin
, but all commands in one handy tool -
template for easily adding new...
How to set up database_cleaner for Rails with Cucumber and RSpec
Add gem 'database_cleaner'
to your Gemfile. Then:
Cucumber & Rails 3+
# features/support/database_cleaner.rb
DatabaseCleaner.clean_with(:deletion) # clean once, now
DatabaseCleaner.strategy = :transaction
Cucumber::Rails::Database.javascript_strategy = :deletion
Cucumber & Rails 2
The latest available cucumber-rails
for Rails 2 automatically uses database_cleaner
when cucumber/rails/active_record
is required -- but only if transactional fixtures are off. To have database_cleaner
work correctly:
- Add the ...
How to circumvent Firefox's "Document expired" page in Selenium tests
When navigating back to a page that was received from a POST request, undesired side effects may happen. Therefore, modern browsers try to keep users from doing so, i.e. Firefox 24 displays an error page explaining what's wrong. If the user presses "Try Again", it shows an additional alert asking whether the user is certain.
Solution
If you need to circumvent this protection, e.g. to test that your application behaves correctly despite being misused, do this:
page.execute_script 'history.back()'
page.execute_script 'retryThis(this)...
How to view a file from another branch
Just run git show branch:file
. Examples:
git show HEAD~:bin/command
git show origin/master:../lib/version.rb
ImageMagick: Cropping images
ImageMagick takes a string with several options when cropping an image. See the command line options for how to provide the expected image geometry for details.
Note that ImageMagick tends to preserve the original aspect ratio of the source image automatically.
Examples:
-
crop 200x200
means Maximum values of height and width given, aspect ratio preserved. -
crop 200x200!
means Width and height emphatically given, original aspect ratio ignored.
Jasmine 2 cheat sheet for RSpec lamers
In the tradition of our PostgreSQL cheat sheet for MySQL lamers, here is a cheat sheet for Jasmine when you're used to RSpec.
Note that Jasmine syntax has changed with Jasmine 2, so if you're using Jasmine 1.x you might instead want to use an older cheat sheet.
Expectations
# RSpec
expect(foo).to.eq("value")
expect(foo).to_not eq("value")
# Jasmine
expect(foo).toBe("value")
expect(...
Jasmine: Testing AJAX calls that manipulate the DOM
Here is a Javascript function reloadUsers()
that fetches a HTML snippet from the server using AJAX and replaces the current .users
container in the DOM:
window.reloadUsers = ->
$.get('/users').then (html) ->
$('.users').html(html)
Testing this simple function poses a number of challenges:
- It only works if there is a
<div class="users">...</div>
container in the current DOM. Obviously the Jasmine spec runner has no such container. - The code requests
/users
and we want to prevent network interaction in our uni...
Jasmine: Reset the location when testing code that uses pushState / replaceState
When testing code that uses pushState / replaceState, your browser will appear to navigate away from http://localhost:3000/specs
(or wherever you run your Jasmine tests). This is inconvenient, since reloading the document will no longer re-run the test suite.
To remedy this, copy the attached file to a place like spec/javascripts/helpers
and #= require
it from your tests. It will store the current location before every test and reset if afterwards (using location.replaceState
).
How to upgrade Cucumber on Rails 3+
-
Run
bundle update cucumber capybara cucumber-rails
to update to the newest versions. -
Backup your
features/support/path.rb
to be able to add your own paths again after the cucumber installation script in step 4. -
Backup your
features/support/env.rb
file to be able to reintegrate parts like your blueprints setup:ENV["RAILS_ENV"] ||= "cucumber" require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') require 'spec/support/blueprints'
-
Run `$ rails generate cucumber:install --capyba...
AngularJS: Binding to Perl-style getter/setters functions
Angular 1.3+ has an alternative getter/setter pattern: You can bind ng-model
to an accessor function. This is a function that is either a getter (when it gets no arguments) or a setter (when it gets the new value as an argument):
$scope.name = function(newName) {
return angular.isDefined(newName) ? (_name = newName) : _name;
}
You need to bind this function with ng-model
and `ng-model-options="{ getterSette...
Getter and setter functions for JavaScript properties
JavaScript objects can have getter and setter functions that are called when a property is read from or written to.
For example, if you'd like an object that has a virtual person.fullName
attribute that dynamically composes person.firstName
and person.lastName
:
var person = {
firstName: 'Guybrush',
lastName: 'Threepwood',
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(name) {
var parts = name.split(" ");
this.firstName = parts[0];
this.lastName = parts[1];
}
};
`...
Testing focus/blur events with Cucumber
This is a problem when using Selenium with Firefox. We recommend using ChromeDriver for your Selenium tests.
This setup allows to test focus/blur events in Cucumber tests (using Selenium). For background information, see How to solve Selenium focus issues.
Cucumber step definition:
# This step is needed because in Selenium tests, blur events are not triggered
# when the browser has no focus.
When /^I unfocus the "(.*?)" field to trigger ja...