Spreewald 1.2.0 released: new "select field should be sorted" step
Usage:
Then the "sorted" select should be sorted
But the "unsorted" select should not be sorted
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)...
Cucumber: More patience for Selenium features
When running Selenium features with parallel_tests, some browser-server interaction might take longer than usual and the impatient Capybara will not wait enough to see results.
Put the attached file into features/support/
to make Capybara more patient in scenarios tagged @javascript
.
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...
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...
Taking screenshots in Capybara
Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest.
Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. Screenshots are saved into $APPLICATION_ROOT/tmp/capybara
.
Manually saving a page
Additionally you can trigger the same behavior manually from the test using Capybara::Session#save_and_open_page and [...
Reading an element's attributes with Capybara
capybara_element['attribute_name']
allows accessing an element's attributes in Capybara.
A few examples:
find('#my_element')['class']
# => "first-class second-class"
find('#my_input')['placeholder']
# => "My placeholder value"
find('a#example-link')['href']
# => "http://example.com"
find('#my_element')['missing_attribute']
# => nil
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/
.
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...
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...
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: ...
How to: Context-dependent word expansion in RubyMine
One of the many useful features of TextMate is autocompletion of words. If I were in TextMate right now, I could write "au[tab]", and it would complete it to "autocompletion". RubyMine can do this, too. When you write a word (e.g. a variable name), just hit ALT + / repeatedly and it will offer all completions for the letters you typed. This action is called Cyclic Expand Word in RubyMine / IntelliJ IDEA.
This feature keeps you from mistyping variable names, saves you keystrokes and speeds up development. ~10 keystrokes to the price ...
How to combine "change", "up", and "down" in a Rails migration
Rails migrations allow you to use a change
method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE
statements) you can not define up
and down
methods at the same time.
If you were to define define all 3 of them, Rails would only run change
and ignore up
and down
. However, Rails 4+ features a helper method called reversible
:
class MyMigration < ActiveRecord::Migration
def cha...
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
require
torequire_relative
where 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_timer
from 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"...
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.
MetricsGraphics.js
MetricsGraphics.js is a library built on top of D3 that is optimized for visualizing and laying out time-series data. It provides a simple way to produce common types of graphics in a principled, consistent and responsive way. The library currently supports line charts, scatterplots and histograms as well as features like rug plots and basic linear regression.
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-version
with 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_spinner
andlaunchy
. -
If you...
-
Heads up: JavaScript does not like big numbers
In a JavaScript console, type this:
> 9112347935156469760
9112347935156470000
Ooops. And that's not a float!
This occurs because JavaScript uses double precision floats to store numbers.
So according to IEEE floating point definition only numbers between -(2^53 - 1)
(-9007199254740991) and 2^53 - 1
(9007199254740991) can safely be represented in JavaScript.
Note that ECMAScript 6 will probably also offer [Number.MAX_SAFE_INTEGER
](https://developer.mozilla.org/en-US/docs/W...
HTML5: Allow to choose multiple files with a vanilla file picker
Modern browsers natively suppport file pickers that allow the user to choose multiple files at once. To activate this feature, set the multiple
attribute:
<input type="file" name="images[]" multiple />
Or in a Rails view:
<%= file_field_tag "images[]", multiple: true %>
This works in IE10+.
Make sure that the field name ends in []
so your server-side code will parse the incoming files into an array. Obviously this naming convention is not compatible with default Rails nested attribute setters, so you'll need to write a form ...
How to fix: Font too small when reading e-mails in Thunderbird
In Thunderbird, you can set custom font faces and sizes for reading plain-text e-mails. However, Thunderbird sometimes "randomly" does not respect your choices.
This is actually not a bug, but a rather weird feature: Fonts are defined per encoding of e-mails.
Some e-mails will be considered Unicode, some Western (ISO 8859-1), and some maybe yet another encoding.
The advanced font settings dialog by default just opens on "Western". Choose a different encoding from the "Fonts for" dropdown menu and you'll see that your custom font sett...
Capybara will not find links without an href attribute
Capybara will fail to find <a>
tags that are missing an href
attribute. This will probably happen to you every now and then on JavaScript-heavy applications.
An example would be an AngularJS application where the following HTML actually works. [1]
<a ng-click="hello()">Hello</a>
Capybara will fail to find that link, even though looking it up via the DOM shows it:
>> find_link("Hello")
Capybara::ElementNotFound: Unable to find link "Hello"
>> find("a").text
=> "Hello"
To make find_link
and click_link
work, ...
The Curious Case of the Flip-Flop
The flip-flop operator is a hotly contested feature of Ruby. It's still struggling to find an idiomatic use case, except for a few very rarely needed things. It's not something you'll likely reach for on a daily, weekly or even monthly basis. The only thing you really need to know about it is what it does, and that's only in case you encounter it in someone else's code. Many even go as far to say not to use the flip-flop operator, that it only adds confusion.
My brain just melted.