lang/unicode_utils · GitHub

UnicodeUtils implements Unicode algorithms for case conversion, normalization, text segmentation and more in pure Ruby code.

If you don't need the ton of features that UnicodeUtils offers, try stringex.

Useful methods to process tables in Cucumber step definitions

When you accept a table in your Cucumber step definition, that table object will have the cryptic type Cucumber::Ast::Table. Don't immediately call table.raw to convert it into an array of arrays! Cucumber::Ast::Table has a lot of useful methods for tasks such as:

table.raw

Turn the table into an array of arrays

table.hashes

Convert the table to an array of hashes, where the keys are the table headers from the first row

`table.header...

Test that a form field is visible with Cucumber/Capybara

Spreewald now comes with a step that tests if a form field is visible:

Then the "Due date" field should be visible
But the "Author" field should not be visible

The step works by looking up the field for the given label, then checks if that field is hidden via CSS (or Javascript).

It is not currently tested if the label is visible or hidden. For this see: [Check that an element is visible or hidden via CSS with Cucumber/Capybara](https://makandracards.com/makandra/1049-check-that-an-elem...

Memcache: Your cache node may degenerate over time, check your settings

We recently had a problem on a Memcache cluster, where one of the servers showed a significantly worse cache hit rate and a lot more evictions.

It turned out that the only reason was that the server was running for a few months longer than the others. Some investigation showed this to be a known problem with Memcache: Once your cache gets full, it might be "hardwired" for your specific usage patterns. If those change (and you for example start to store larger values), memory is no longer allocated optimally, in extreme cases Memcache might ...

Behave.js

Behave.js is a lightweight library for adding IDE style behaviors to plain text areas, making it much more enjoyable to write code in. Features include:

  • Custom Code/Behavior Fencing
  • Hard and Soft Tabs
  • Auto Open/Close Parenthesis, Brackets, Braces, Double and Single Quotes
  • Auto delete a paired character
  • Overwrite a paired character
  • Multi-line Indentation/Unindentation
  • Automatic Indentation

How to update a single gem conservatively

The problem

Calling bundle update GEMNAME will update a lot more gems than you think. E.g. when you do this:

bundle update cucumber-rails

... you might think this will only update cucumber-rails. But it actually updates cucumber-rails and all of its dependencies. This will explode in your face when one of these dependencies release a new version with breaking API changes. Which is all the time.

In the example above updating cucumber-rails will give you Capybara 2.0 (because capybara is a dependency of `cucumber-rail...

Running "bundle update" without arguments might break your application

Calling bundle update (without arguments) updates all your gems at once. Given that many gems don't care about stable APIs, this might break your application in a million ways.

To stay sane, update your gems using the applicable way below:

Projects in active development

Update the entire bundle regularily (e.g. once a week). This ensures that your libraries are up-to-date while it's easy to spot major version bumps which may break the app.

Projects that have not been updated in a while

  1. [Update a single gem conservatively](htt...

Phusion Passenger 4 Technology Preview: Out-Of-Band Work – Phusion Corporate BlogPhusion Corporate Blog

The Out-of-Band Work feature allows one to perform arbitrary long-running work outside the request/response cycle without blocking HTTP clients. The primary use case is to run the garbage collector in between cycles so that your requests will finish faster because they will not be interrupted by the garbage collector.

randym/axlsx · GitHub

Axlsx is an incredible gem to generate "Office Open XML" spreadsheet files (XLSX). Does not break on large spreadsheets and supports a ton of features like graphs.

API looks mature and existing code is easy to migrate when coming from the spreadsheet gem.
The documentation of some methods is a bit out of date, but you'll find your way around the gem's code.

No support for reading files, however. :( If you want to open XLSX spreadsheets (for example to confirm your output in tests), you can use [roo](h...

Understanding database cleaning strategies in tests

TLDR: In tests you need to clean out the database before each example. Use :transaction where possible. Use :deletion for Selenium features or when you have a lot of MyISAM tables.

Understanding database cleaning

You want to clean out your test database after each test, so the next test can start from a blank database. To do so you have three options:

  • Wrap each test in a transaction which is rolled back when you're done (through DatabaseCleaner.strategy = :transaction or `config.use_transactional_fi...

How to provoke Selenium focus issues in parallel test processes

As attachments to this card you will find a Cucumber feature and supplementing step definition that you can use to provoke Selenium focus issues that only occur when two focus-sensitive Selenium scenarios run at the same time (probably with parallel_tests). This can help you to detect and fix flickering integration tests.

The attached feature works by going to your root_path and focusing a random form element every 5...

How to test if an element has scrollbars with JavaScript (Cucumber step inside)

The basic idea is pretty simple: an element's height is accessible via the offsetHeight property, its drawn height via scrollHeight -- if they are not the same, the browser shows scrollbars.

var hasScrollbars = element.scrollHeight != element.offsetHeight;

So, in order to say something like...

Then the element "#dialog_content" should not have scrollbars

... you can use this step (only for Selenium scenarios):

Then /^the element "([^\"]+)" should( not)? have scrollbars$/ do |selector, no_scrollbars|
  scroll_heig...

How to find out the currently focused DOM element with JavaScript

This works in all relevant browsers:

document.activeElement

You can use this in your Selenium steps, for example, to assert that a form field is or is not focused.

Custom error pages in Rails

Static error pages

To add a few basic styles to the default error pages in Rails, just edit the default templates in public, e.g. public/404.html.

A limitation to these default templates is that they're just static files. You cannot use Haml, Rails helpers or your application layout here. If you need Rails to render your error pages, you need the approach below.

Dynamic error pages

  1. Register your own app as the applicatio...

How to change the hostname in Cucumber features

Capybara uses www.example.com as the default hostname when making requests.
If your application does something specific on certain hostnames and you want to test this in a feature, you need to tell Capybara to assume a different host.

Given /^our host is "([^\"]+)"$/ do |host|
  page.config.stub app_host: "http://#{host}"
  
  # In older Capybaras (< 2.15) you needed to do this instead:
  Capybara.stub app_host: "http://#{host}"
end

You can now say:

When I go to the start page
Then I should not see "Home ...

Don't name columns like counter_cache columns in Rails pre v4.2.4

< Rails v4.2.4

ActiveRecord has a feature called counter caching where the containing record in a has_many relationship caches the number of its children. E.g. when you have House has_many :rooms, Rails can cache the number of rooms in House#rooms_count.

Mind that when a model has a column that looks to Rails like a counter-cache column, Rails will apply counter-cache logic to your model, even if you're not using counter caches.

E.g. you have a house with 12...

New makandra cards feature: Repeating cards

Cards can now be flagged as "Repeating".

Every Wednesday, some of these cards will be moved back to the top of the deck.

This is intended for important cards that you want your team to occasionally repeat, so they aren't lost in the depths of your deck.

For your own deck, you can set the number of cards to repeat in your Deck Admin.

How to solve Selenium focus issues

Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.

This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.

Preventing accidental interaction with the Selenium window
--------------------...

imgAreaSelect - image selection/cropping jQuery plugin

imgAreaSelect is a jQuery plugin for selecting a rectangular area of an image. It allows web developers to easily implement image cropping functionality, as well as other user interface features, such as photo notes (like those on Flickr).

Capybara 2.0 has been released

The gem author Jonas Nicklas highlights in a Google Groups post that the release

  • is not backwards compatible to 1.x versions of Capybara
  • does not support Ruby 1.8.x anymore
  • removes confusion with Rails' built in integration tests (you put capybara rspec integration tests into the spec/feature/... folder) and the :type metadata has been changed from :request to :feature
  • throws exceptions when trying to interact with an element whose identifier is...

Capybara: evaluate_script might freeze your browser

Capybara gives you two different methods for executing Javascript:

page.evaluate_script("$('input').focus()")
page.execute_script("$('input').focus()")

While you can use both, the first line (with evaluate_script) might freeze your browser window for 10 seconds.

The reason is that evaluate_script will always return a result. The return value will be converted back to Ruby objects, which in case of complex objects (e.g. a jQuery collection) is very expensive.

Because of this we recommend to only use evaluate_script whe...

Keyboard Navigation Plugin for Safari, Chrome and Firefox with a rich feature set

gleeBox is an experimental project that takes a keyboard-centric approach to navigating the web. It provides alternatives to actions that are traditionally performed via the mouse. Some of these are radically more efficient than using a mouse, some not so much. In all cases, they are mostly meant for keyboard and command line lovers.

Gleebox is a terrific plugin that makes navigating through webpages a wink. It even allows for selecting by jQuery selector.

Cucumber: Wait for any requests to finish before moving on to the next scenario

Background

Generally, Selenium tests use the browser to interact with the page. If it's unavailable, a timeout error is thrown.

Now, consider a scenario like this:

@javascript
Scenario: Receive an e-mail after clicking the fancy link
  When I follow "fancy link"
  Then I should have an e-mail with the subject "Hello"

When the last step in the scenario passes, you are done. Right? Wrong.

Why it's not enough

What if clicking our "fancy link" above sends the e-mail that we expect, but it also does stuff on the server...

Waiting for page loads and AJAX requests to finish with Capybara

If you're using the Capybara webdriver, steps sometimes fail because the browser hasn't finished loading the next page yet, or it still has a pending AJAX request. You'll often see workarounds like

When I wait for the page to load
Then ...

Workarounds like this do not work reliably, will result in flickering tests and should be avoided. There is no known reliable way to detect if the browser has finished loading the page.

Solution

Instead you should wait until you can observe the result of a page load. E.g. if y...