Puppet: Could not evaluate: Field 'device' is required

If you get an error like this for a puppet mount:

$ > puppet agent --test 
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for example.makandra.de
Info: Applying configuration version '1483001792'
Info: Computing checksum on file /etc/fstab
Info: FileBucket got a duplicate file {md5}34b9adc036cf1dbd2392df84f921547d
Notice: /Stage[main]/Foobar/Swap_file::Files[default]/Mount[/var/swapfile]/ensure: defined 'ensure' as 'defined'
Error: /Stage[main]/Foobar/Swap_file::Files[default]/Mount[/var/s...

How to remove RSpec "old syntax" deprecation warnings

RSpec 3.0 deprecates the :should way of writing specs for expecting things to happen.

However, if you have tests you cannot change (e.g. because they are inside a gem, spanning multiple versions of Rails and RSpec), you can explicitly allow the deprecated syntax.

Fix

Inside spec/spec_helpber.rb, set rspec-expectations’ and/or rspec-mocks’ syntax as following:

RSpec.configure do |config|
  # ...
  config.mock_with :rspec do |c|
    c.syntax = [:should, :expect]
 ...

How to upgrade Cucumber on Rails 3+

  1. Run bundle update cucumber capybara cucumber-rails to update to the newest versions.

  2. Backup your features/support/path.rb to be able to add your own paths again after the cucumber installation script in step 4.

  3. 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'
    
  4. Run `$ rails generate cucumber:install --capyba...

Removing MiniTest warnings from Rails 4 projects

Warnings like those below may originate from rspec or shoulda-matchers or other gems that have not updated yet to the new MiniTest API.

One

Warning: you should require 'minitest/autorun' instead.
Warning: or add 'gem "minitest"' before 'require "minitest/autorun"'
# (backtrace)

Solution: Add gem 'minitest' to your Gemfile, before any rspec gem.

Another

MiniTest::Unit::TestCase is now Minitest::Test. From /Users/makandra/.rvm/rubies/ruby-1.9.3-p484/lib/ruby/1.9.1/tes...

MySQL: How to dump single tables instead of a complete database

Sometimes you want to test migrations with production or staging data. Dumping single tables makes sense if a complete dump would be to big.

mysqldump -u deploy_user -p application_production table1 table2 table2 > table1_table2_table2.sql.dump

Hint: If a table has to many constraints, a complete dump could be more handy.


Further reading:

Perform HTTP basic authentication in Cucumber (with or without Selenium)

This card describes a Cucumber step that lets you say:

When I perform basic authentication as "username/password" and I visit the admin area

The path component ("... the admin area") is parsed through your path_to helper in features/support/paths.rb.

Capybara

The step definition is part of Spreewald. The step has been tested with multiple versions of Capybara, Rack::Test and Selenium.

Webrat (legacy)

This is a simpler version of the step above:

When /...

How to pair a Bose Quiet Comfort 35 with your Ubuntu computer

You need to disable "Bluetooth low energy", then follow these core steps:

  1. Make sure the headphones are in pairing mode.
  2. Pair with System Settings > Bluetooth. On 16.04 I had to choose "proceed without pairing" and enter the PIN "0000"
  3. Select & test the headphones in System Settings > Sound. Choose High Fidelity Playback (A2DP Sink).

I also had to install a package with sudo apt-get install pulseaudio-module-bluetooth and load it with pactl load-module module-bluetooth-discover. Put the latter command into ~/.bashrc or you'll...

Linux: How to add a task bar to VNC displays

If you are using VNC to run Selenium tests, it may be hard to see what's going on since by default there is no list of open windows and Alt+Tab won't work.

Solving that is easy:

  1. Install a panel of your choice (like lxpanel) which offers task switching:

    sudo apt-get install lxpanel
    

    (You can't use gnome-panel because it won't start twice -- but lxpanel does a good job)

  2. To have that panel appear on VNC screens by default, edit ~/.vnc/xstartup...

Capybara: Trigger requests with custom request method

Preface: Normally, you would not need this in integrations tests (probably that's why it is so hard to achieve), because it is no actual "integration testing". If you use this step, know what you are doing.


Destroying a record with Capybara is not as easy as calling visit user_path(user, method: :delete), because RackTest's visit can only perform GET requests.

With this step you can destroy a records using either Selenium or RackTest. Ex...

Colcade is a lightweight Masonry alternative

Masonry is a famous library to dynamically arrange a grid of items that have different aspect ratio, like horizontal and vertical images.
Colcade is an alternative masonry-layouting library, developed by the same developer, but with a more modern approach.

It is said to have better performance while being smaller and having no dependencies. It automagically detects jQuery and defines a jQuery initializer, if present.
However, it offers [a few less features](https:...

Airbrake notification in Rake tasks

Put

def task_with_hoptoad_notification(options)
  task(options) do
    begin
      yield
    rescue Exception => e
      Airbrake.notify(e)
      raise e
    end
  end
end

at the top of the Rakefile, and replace all relevant

task :my_task => :environment do
    do_something
end

with

task_with_hoptoad_notification :my_task => :environment do
    do_something
end

This will use the usual notification rules, i.e. you won't get anything in the development or test environments.
...

Reload the page in your Cucumber features

Both these approaches will keep your GET parameters -- and will only work for GET requests.

  • Capybara:

    When /^I reload the page$/ do
      visit [ current_path, page.driver.request.env['QUERY_STRING'] ].reject(&:blank?).join('?')
    end
    
  • Webrat:

    When /^I reload the page$/ do
      visit url_for(request.params)
    end
    

For a step that distinguishes between drivers (Selenium, Rack::Test, Culerity), check [n4k3d.com](http://n4k3d.com/blog/2011/02/02/reloading-the-page-in-cucumber-with-capybara-and-seleniu...

A solid and unobtrusive plugin for form field placeholders

jquery-placeholder is a simple jQuery plugin that enables form placeholders in browsers that do not support them natively, i.e. IE < 10.

Properties

  • Works in IE6.
  • Automatically checks whether the browser natively supports the HTML5 placeholder attribute for input and textarea elements. If this is the case, the plugin won’t do anything. If @placeholder is only supported for input elements, the plugin will leave those alone and apply to textareas exclusively. (This is the case for Safari 4, Opera 11.00, and possibly other browsers.)
    ...

VCR: Inspecting a request

Using VCR to record communication with remote APIs is a great way to stub requests in tests. However, you may still want to look at the request data like the payload your application sent.

Using WebMock, this is simple: Make your request (which will record/play a VCR cassette), then ask WebMock about it:

expect(WebMock).to have_requested(:post, 'http://example.com').with(body: 'yolo')

Easy peasy.

Related cards

Fix: Capybara is very slow when filling out fields in large forms

In large forms (30+ controls) new Capybara version become [extremely slow] when filling out fields. It takes several seconds per input. The reason for this is that Capybara generates a huge slow XPath expression to find the field.

The attached code patches fill_in with a much faster implementation. It's a dirty fix and probably does a lot less than Capybara's own fill_in so don't use it unless you are having problems with test suites that are unusable because of this...

Force Google Chrome to run in English on Linux

If you need Google Chrome to run in English, and your system locale is a non-English one, you have two options:

  • Switch your system to an English locale
  • Head over to /opt/google/chrome/locales/ and remove any .pak files except those starting with “en”. They reappear when Chrome gets updated.

This may help you running your Selenium tests using the Chrome driver on applications that choose the language from what the browser sends as preferred language (which Chrome guesses from your system locale).

Capybara steps to match stuff within any selector

These steps are now part of Spreewald.

Since Capybara 0.4.1 a within scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.

In order to perform a test or action in all matching elements, do not use within but prefer the attached "inside any" Cucumber steps like these:

When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"

Match strings in a given order with Cucumber and Capybara

Sometimes the order in which strings appear on a page matters to you.

Spreewald gives you steps like these:

Then I should see in this order:
  | Alpha Group |
  | Augsburg    |
  | Berlin      |
  | Beta Group  |

Or, if you prefer multiline strings:

Then I should see in this order:
  """
  Alpha Group
  Augsburg
  Berlin
  Beta Group
  """

The step ignores all HTML tags and only tests on plain text.

Capybara: A step for finding images with filename and extension

This cucumber step is useful for testing an image (looking at the src of the image).

Then(/^I should see the image "([^"]*)"$/) do |filename_with_extension|
  expect(page).to have_css("img[src*='#{filename_with_extension}']")
end
Then I should see the image "placeholder.png"

Outline: Read more about how to test a uploaded file here, e.g. file downloads.

Webrat doesn't follow redirect because it considers the url external

Rails doesn't know which host it is running on. For generating links, it strips the hostname off the request URL, which can lead to errors when you have absolute URLs in your Cucumber tests.

If you really need to use absolute URLs somewhere, say in an email you send, either throw away the host when parsing it (e.g. body.scan(/http:\/\/[^\/]+\/([^\s"<]+)/)) or tell Webrat you're back on your site.

Rails: Disable options of a select field

Simply give the select helper an option :disabled, passing either a single value or an array. You need to specify the option's value, not its text.

= form.select :country, Address.countries_for_select, :include_blank => true, :disabled => ['disabled-value1', 'disabled-value-2']

Also see Cucumber: Check if a select field contains a disabled option on how to test this.

Geordi: Choose your firefox version for cuc

Geordi 0.16+ supports running selenium tests with project-specific firefox versions.

Just update the gem. It will still default to using the old 5.0.1 firefox. If you want another one, add a file .firefox-version to your project, containing your preferred version.

geordi cucumber will prompt (and guide) you to install the given version. You can delete any old installation sitting in /opt/firefox-for-selenium if you have one.

Better output for Cucumber

We built cucumber_spinner to have a progress bar for Cucumber features, which also outputs failing scenarios as soon as they fail.

Installation

gem install cucumber_spinner

Usage

cucumber --format CucumberSpinner::ProgressBarFormatter

If you use CucumberSpinner::CuriousProgressBarFormatter and a feature fails, the according page will show up in your browser.


Note that if you run your Cucumber tests using the [cuc](https://makandracards.com/makandra/1277-a-nicer-way-to-...

Check that a Range covers an element in both Ruby 1.9 and 1.8.7

In order to cover some edge cases you rarely care about, Range#include? will become very slow in Ruby 1.9:

Range#include? behaviour has changed in ruby 1.9 for non-numeric ranges. Rather than a greater-than/less-than check against the min and max values, the range is iterated over from min until the test value is found (or max) [...] Ruby 1.9 introduces a new method Range#cover? that implements the old include? behaviour, however this method isn’t available in 1.8.7.

The attached ...