Cucumber: Removing uploaded files after test runs
Cucumber will clean up files you've uploaded in your Cucumber features automatically with the attached code. Put the file in features/support/.
RSpec matcher "be_sorted"
RSpec::Matchers.define :be_naturally_sorted do
match do |array|
array == array.natural_sort
end
end
See RSpec: Where to put custom matchers and other support code. To use natural_sort, see this card.
This matcher is now part of Spreewald.
Cucumber step to test whether a select field is sorted
This step will pass if the specified select is sorted.
Then /^the "(.*?)" select should be sorted$/ do |label, negate|
select = find_field(label)
options = select.all('option').reject { |o| o.value.nil? }
options.collect(&:text).each_cons(2) do |a,b|
(a.text.downcase <=> b.text.downcase).should <= 0
end
end
In conjunction with this custom matcher, the each_cons block can be replaced with:
options.should be_naturally_sorted
Usage
Then the "Organizations" select should be sorted...
Fixing the warning Time#succ is obsolete; use time + 1
Chances are you're seeing the warning repeated a lot of times, maybe thousands of times. Here's how to reproduce the issue:
Example 1
# bad code
(Time.current .. Time.current + 1.hour).include?(Time.current)
# Use Range#cover? instead of Range#include? since the former does no typecasting into integers.
(Time.current .. Time.current + 1.hour).cover?(Time.current)
Example 2
# bad code
Post.where(:created_at => min_date.beginning_of_day .. max_date.end_of_day)
# Use 'BETWEEN x AND y'
Post.where(['posts.created_at BETWEEN...
How to emulate simple classes with plain JavaScript
If you want a class-like construct in JavaScript, you can use the module pattern below. The module pattern gives you basic class concepts like a constructor, private state, public methods.
Since the module pattern only uses basic JavaScript, your code will run in any browser. You don't need CoffeeScript or an ES6 transpiler like Babel.
A cosmetic benefit is that the module pattern works without the use of this or prototypes.
Example
Here is an example for a Ruby class that we want to translate into Javascript using the module patter...
AngularJS: How to remove a watch
Sometimes you want Angular to watch an object only until a certain state is reached (e.g. an object appears in the scope).
Angular's $watch returns a method that you can call to remove that watch. For example:
unwatch = $scope.$watch 'user', (user) ->
if user?
... # do something
unwatch()
That's it.
Heads up: LibreOffice Calc adds quotation marks when copying data from multi-line cells
Copy data from LibreOffice Calc
When you copy data from multi-line cells in LibreOffice Calc, quotation marks are automatically added, which you may not want.
For example with license keys:
09:46:24 [✔] pascal:~> icdiff license license_copy
license license_copy
===== LICENSE BEGIN ===== "===== LICENSE BEGIN =====
00000yIeXfhGSbt"yULWQR9n 00000yIeXfhGSbt""yULWQR9n
olysFAv105bHmKOiqbxRX"Yr ...
Asset Pipeline Basics
The Rails asset pipeline improves delivery of application assets (javascripts, stylesheets, images, fonts). Here are some basic facts about its inner workings.
No magic
Manifests are the handle on your assets:
app/assets/stylesheets/application.css # use via: stylesheet_link_tag 'application'
The asset pipeline only considers files you explicitly require within your manifest files. The most common directives used in manifests are require some/file and require_tree some/directory. Paths may be **relative to the current director...
AngularJS: How to hook to the end of a digest cycle (before the browser redraws)
When you run code inside a $watch expression that forces a repaint (e.g. by computing an element's width, or running something like element.is(':visible')) you may end up with "page flickering" or scroll offset changes.
You can hook to the end of a digest cycle to avoid that.
The following is basically straight from the docs, but pretty awkward to use. Do it...
Install or update Chromedriver on Linux
Option 0: Download from the official page (preferred)
- Open https://googlechromelabs.github.io/chrome-for-testing/
- In Section "Stable" > chromedriver / linux64 > Download ZIP from URL
- Take the
chromedriverbinary from the ZIP file and put it e.g. into~/bin.
Chromedriver must be available in your path. You can add ~/bin to your path like this:
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bash_profile
If you're also using Geordi, disable automatic updating of chromedriver in ~/.config/geordi/global.yml:
a...
The Easiest Way to Parse URLs with JavaScript
A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.
You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:
var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'
if (pathname[0] != '/')
pathname = '/' + pathname // Fix IE11
One advantag...
vague puppet error messages with broken yaml files
If you get one of this errors:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: (<unknown>): found character that cannot start any token while scanning for the next token at line 1297 column 3
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: undefined method `empty?' for nil:NilClass at /etc/puppet/environments/production/manifests/nodes.pp:1 on node example.makandra.de
Warning: ...
tel_to Rails helper for linking phone numbers
When putting phone numbers into web pages, you should use tel: links so smartphone users can click those numbers to call someone.
Here is a small helper method that you can use to simplify this:
def tel_to(text)
groups = text.to_s.scan(/(?:^\+)?\d+/)
link_to text, "tel:#{groups.join '-'}"
end
This will allow you to use human-readable numbers and get clean links:
>> tel_to '(01234) 555 6789'
=> <a href="tel:01234-555-6789">(01234) 555 6789</a>
>> tel_to '+1 555 123-456'
=> <a href="tel:+1-555-123-456...
RaphaelJS: A Javascript vector graphics library
Raphaël is a small JavaScript library that should simplify your work with vector graphics on the web. If you want to create your own specific chart or image crop and rotate widget, for example, you can achieve it simply and easily with this library.
Upgrading a Rails 3.2 application to Ruby 2.1 is really easy
Upgrading from Ruby 1.8.7 to 2.1.2 took me an hour for a medium-sized application. It involved hardly any changes except
- removing the occasional monkey patch where I had backported functionality from modern Rubies
- Migrating from
requiretorequire_relativewhere I loaded RSpec factories in Cucumber'senv.rb(the Rails application root is no longer in the load path by default) - replacing the old debugger with
byebug - removing
sytem_timerfrom Gemfile (see [this SO thread](http://stackoverflow.com/questions/7850216/how-to-inst...
Cucumber features as documentation
Cucumber allows for prose in features and scenarios. Example:
Feature: Cancel account
There are several ways to cancel a user account. Admins need to
do it in complex cases, but normally, users can do it themselves.
Scenario: User cancels his own account
Users should be able to cancel an account themselves, so the
admins do not need to do it.
Given a user account for "willy@astor.de"
When I sign in as "willy@astor.de"
And I follow "Cancel account"
Then I should see "Account canceled"...
PSA: Dont allow private gems to be pushed to rubygems.org
If you make a gem with Bundler, you will get a rake release task that will instantly publish your gem to rubygems.org for all the world to admire. For private gems this is very bad.
To make sure this cannot happen, rubygems 2.2+ allows you to restrict eligible push hosts:
Gem::Specification.new 'my_gem', '1.0' do |s|
# ...
s.metadata['allowed_push_host'] = 'https://gems.my-company.example'
end
In case you already messed up, [follow these instructions to get your gem removed](http://help.rubygems.org/kb/rubygems/removing-an-a...
Firefox: Focus-sensitive Selenium tests do not work reliably in parallel test execution
This is a problem when using Selenium with Firefox. We recommend using ChromeDriver for your Selenium tests.
Firefox will not trigger focus/blur events when its window is not focused. While this makes sense in standard usage, it breaks in parallel test execution.
Please do not rely on focus events in your tests. The linked card has an example of how to build passing tests that deal with focus/blur events.
Speed up JSON generation with oj
Using this gem I could get JSON generation from a large, nested Ruby hash down from 200ms to 2ms.
Its behavior differs from the default JSON.dump or to_json behavior in that it serializes Ruby symbols as ":symbol", and that it doesn't like an ActiveSupport::HasWithIndifferentAccess.
There are also some issues if you are on Rails < 4.1 and want it to replace #to_json (but you can always just call Oj.dump explicitely).
Security warning: Oj does not escape HTML entities in JSON
---------...
New Firefox and gem versions for our Selenium testing environment (Ubuntu 14.04+)
Firefox 5.0.1, which we were using for most Rails 2.3 projects, does not run on Ubuntu 14.04 any more. Here is how to update affected projects.
-
Update (or create)
.firefox-versionwith the content:24.0
If you haven't installed Firefox 24 yet, the next time you run tests with Geordi, it will tell you how to install it. -
On a Rails 2 project:
-
Update your Cucumber-related gems as described in Upgrading Cucumber and Capybara, including
cucumber_spinnerandlaunchy. -
If you...
-
How to install the `xelatex` binary on Ubuntu 14.04
Just install the texlive-xetex package:
sudo apt-get install texlive-xetex
Running integration tests without texlive-xetex will produce an error during xelatex execution:
RTeX::Document::ExecutableNotFoundError
JavaScript: How to check if an object is NaN
JavaScript's NaN ("Not a Number") is hard to compare against. It never equals anything, not even itself:
NaN === NaN; // false
Number.NaN === NaN; // false
There is the isNaN method, but it is not really what you are looking for:
isNaN(NaN) // true
isNaN('hello') // true
Option 1: ES6
The Object.is() method determines whether two values are the same value. It even works for NaN:
Object.is(NaN, NaN) // true
Option 2: ES5
The example above shows that simply using isNaN would match other ...
Remember: LoDash syntax is a bit different from UnderscoreJS
Since we are using LoDash instead of UnderscoreJS in recent/current projects, you should keep in mind that their syntax is a bit different.
UnderscoreJS
In UnderscoreJS, methods always return a value:
x = [1, 2, 2]
_.uniq(x) // => [1, 2]
_(x).uniq() // => [1, 2]
If you want to chain multiple calls, you need to start off with a _.chain, and call value() to terminate the chain.
_.chain(x).uniq().map(function(i) { return i + 10 }).reverse().value() // => [12, 11]
##...
Managing vendor assets in Rails with Bower
bower-rails is a great solution for managing vendored assets in your Rails app. It feels especially much more convenient and easier to update assets when going this way.
bower-rails generates a Bowerfile that works much like the Gemfile you're used to. Just specify your dependencies and run rake bower:install. You can find available packages here.
An example Bowerfile:
# ./Bowerfile
asset 'angular'
asset 'angular-i18n'
asset 'angular-ui-router'
asset 'angu...