rbenv: How to update list of available Ruby versions on Linux
When you tell rbenv to install a Ruby it does not know about, you will get an error message.
$ rbenv install 2.1.2
ruby-build: definition not found: 2.1.2
You can list all available versions with `rbenv install --list'.
If the version you're looking for is not present, first try upgrading
ruby-build. If it's still missing, open a request on the ruby-build
issue tracker: https://github.com/sstephenson/ruby-build/issues
(Fun fact: Recent versions of ruby-build will give you a more helpful error message which...
About "unexpected '#' after 'DESCENDANT_SELECTOR' (Nokogiri::CSS::SyntaxError)"
The error unexpected 'x' after 'DESCENDANT_SELECTOR' (Nokogiri::CSS::SyntaxError)
(where x
may be basically any character) occurs when the Nokogiri parser receives an invalid selector like .field_with_errors #
or td <strong>
.
In Cucumber, the culprit will be an invalid step definition that builds an invalid selector:
# inside some step definition:
field = find_field(label)
page.send(expectation, have_css(".field_with_errors ##{field[:id]}"))
The above raises the mentioned error if field[:id]
is nil, i.e. the foun...
No more file type confusion in TextMate2
When using TextMate2 with the cucumber bundle, it does not recognize step definitions (e.g. custom_steps.rb
) as such but believes they are plain Ruby files. But there is help!
Solution
Add these lines to the bottom of your .tm_properties
file (in ~/
for global settings, in any directory for per-project settings):
[ "*_steps.rb" ]
fileType = "source.ruby.rspec.cucumber.steps"
Apparently, this works for any files. Define a regex and specify custom settings. The attached article lists all available configuration options (whic...
Ruby on Rails 4 and Batman.js
Batman is an alternative Javascript MVC with a similar flavor as AngularJS, but a lot less features and geared towards Ruby on Rails.
The attached link leads to a tutorial for a small blog written with Rails / Batman.js.
I'm collecting other Batman.js resources in my bookmarks.
How Ruby method lookup works
When you call a method on an object, Ruby looks for the implementation of that method. It looks in the following places and uses the first implementation it finds:
- Methods from the object's singleton class (an unnamed class that only exists for that object)
- Methods from prepended modules (Ruby 2.0+ feature)
- Methods from the object's class
- Methods from included modules
- Methods from the class hierarchy (superclass and its an...
Collection of Rails development boosting frameworks
Development environment setup
- Rails Composer
-
Basically a comprehensive Rails Template. Prepares your development environment and lets you select web server, template engine, unit and integration testing frameworks and more.
Generate an app in minutes using an application template. With all the options you want!
Code generators
- Rails Bricks
-
A command line wizard. Once you get it running, it creates sleek applications.
RailsBricks enables you to cre...
Your Rails sandbox console
Just found out about a great feature in Rails that seems to be around since Rails 2. Start a console with the --sandbox
(or -s
) parameter:
rails console --sandbox
All changes you make to the database will be rolled back on exit.
Warning
Changes beyond the database (deleting files, sending emails, etc) cannot be rolled back!
String#indent: Know your definitions!
String#indent
is not a standard Ruby method. When you use it, be sure to know where this method comes from. Many Gems shamelessly define this method for internal usage, and you'll never know when it may be removed (since it's usually not part of the Gem's API).
Unless you're using Rails 4 (which brings String#indent
in ActiveSupport), you'll be best of defining it yourself. This card has it for you.
Gems that define String#indent
(incomplete)
----------------------------...
Spreewald version 0.9.4 released
- "I click on ..." step fixed
- Errors added to
ToleranceForSeleniumSyncIssues::RETRY_ERRORS
Capybara::ElementNotFound
Selenium::WebDriver::Error::ElementNotVisibleError
Selenium::WebDriver::Error::NoSuchFrameError
Fix when assigning nested attributes raises "undefined method `to_sym' for nil:NilClass"
You might have a table without a primary key set in MySQL.
You can fix this by adding a primary key index to the guilty MySQL table, or by setting self.primary_key = "id"
in your class definition.
Related, but different issue: Rails 2 does not find an association when it is named with a string instead of a symbol
Debugging in Cucumber
Spreewald includes a few useful steps for debugging a Capybara session.
Then show me the page # => Opens the page in the browser
Then debugger # => Open a debugging session
Cucumber does not find neither env.rb nor step definitions when running features in nested directories
Usually, Cucumber feature files live in features/
. When you group them in sub directories, make sure to add -r features
to the standard Cucumber options.
In Rails apps, Cucumber options are likely to be stored in config/cucumber.yml
.
Cucumber: Wait until CKEditor is loaded
I had to deal with JavaScript Undefined Error
while accessing a specific CKEditor instance to fill in text.
Ensure everything is loaded with
patiently do
page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
end
Example
The fill in text
snippet for Cucumber:
When /^I fill in the "([^\"]+)" WYSIWYG editor with:$/ do |selector, html|
patiently do
page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
end
html.gsub!(/\n+/, "") # otherwise: unterminated string lit...
Custom error messages in RSpec or Cucumber steps
Sometimes you have a test expectation but actually want a better error message in case of a failure. Here is how to do that.
Background
Consider this test:
expect(User.last).to be_present
In case of an error, it will fail with a not-so-helpful error message:
expected present? to return true, got false (Spec::Expectations::ExpectationNotMetError)
Solution
That can be fixed easily. RSpec expectations allow you to pass an error message like this:
expect(User.last).to be_present, 'Could not find a user!'
...
How to doubleclick in Selenium
Put the attached file into features/support/
.
Example usage:
When /^I open the task named "(.+?)"$/ do |task_name|
task = page.all('.task').detect do |t|
t.find('.label').text.downcase == task_name.downcase
end
task.double_click
end
Note: only Selenium understands doubleclicks.\
Credits: the attached Capybara issue discussion.
Checking the character length of a text containing markup (e.g. WSYIWYG)
If you have a text that is edited by WSYIWYG-Editor but want some length checking nevertheless, you need to strip all tags and then the special characters:
def hard_sanitize(text)
ActionController::Base.helpers.strip_tags(text).gsub(/[^[:word:]]+/, " ")
end
:001 > hard_sanitize("This is <strong>beautiful</strong> <h1>markup<h1>")
=> "This is beautiful markup"
If you allready have nokogiri on board, you can use that as well, though it has no extra benefit:
:001 > Nokogiri::HTML("This is <strong>beau...
Resolving Element cannot be scrolled into view (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError) on Mavericks
After I upgraded to Mac OS X Mavericks, I regularly got this error message when running Cucumber features with Selenium:
Element cannot be scrolled into view:[object XrayWrapper [object HTMLInputElement]] (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)
I had the Terminal window running the test on my secondary screen, whereas the Selenium-webdriven Firefox always started on my primary one. Now if I had focused the secondary screen when running the tests, Selenium could not start Firefox and switch to it (probably because t...
Trailer, a faster and easier way to deal with pull requests
Introducing Trailer from HouseTrip, a simple menu bar app that helps you manage your GitHub pull requests. It’s one feature we felt was lacking from our workflow!
Bash: Setting the title of your terminal tab
If your terminal has many tabs, you'll want to keep them organized. To change their title from the prompt, run this function:
function tab_title {
if [ -z "$1" ]
then
title=${PWD##*/} # current directory
else
title=$1 # first param
fi
echo -n -e "\033]0;$title\007"
}
Put it into your ~/.bashrc
to have it always available. Adjust to your needs.
Usage
$> tab_title
# title set to the current directory's name
$> tab_title new_title
# title set to "new_title"
Auto-setting the title
=================...
MySQL 5.6 slightly changes DECIMAL data type
About
A MySQL DECIMAL
column is used when it is important to preserve exact precision. It takes two parameters, where precision is the total number of digits and scale the number of digits to the right of the decimal point. A DECIMAL(6,2)
column may store numbers up to 9,999.99.
In Rails, a decimal column definition looks like this: t.decimal :amount, :precision => 6, :scale => 2
.
Issue
MySQL prior to 5.6 stored leading zeros (0003.1) and +/- characters (+2.1) within the column. However, **it would permit storing ...
Cucumber / Selenium: Access and test document title
If you want to test that a certain text is contained within the document title of your page, you can do so using Selenium and a step such as
Then /^"(.*?)" should be shown in the document title$/ do |expectation|
title = page.driver.browser.title
title.should include(expectation)
end
Threads and processes in a Capybara/Selenium session
TLDR: This card explains which threads and processes interact with each other when you run a Selenium test with Capybara. This will help you understand "impossible" behavior of your tests.
When you run a Rack::Test (non-Javascript) test with Capybara, there is a single process in play. It runs both your test script and the server responding to the user interactions scripted by your test.
A Selenium (Javascript) test has a lot more moving parts:
- One process runs your test script. This is the process you...
Auto-coerced virtual attributes with Virtus
We've since created ActiveType which has a restricted subset of Virtus' features. It might be enough for your needs.
We sometimes give our ActiveRecord models virtual attributes for values that don't need to be stored permanently.
When such a virtual attribute should contain integer values you might get unexpected behavior with forms, because every param is a string and you don't get the magic type casting that Rails would give you if it ...