Test that a select option is selected with Cucumber

This step tests whether a given select option comes preselected in the HTML. There is another step to test that an option is available at all.

Capybara

Then /^"([^"]*)" should be selected for "([^"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
  with_scope(selector) do
    field_labeled(field).find(:xpath, ".//option[@selected = 'selected'][text() = '#{value}']").should be_present
  end
end

Webrat
...

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)...

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...

How to test your website for different versions of Internet Explorer or Edge

Virtualization

Microsoft provides virtual machines for different Internet Explorer versions.

The images are available for various virtualization solutions, including VirtualBox.

BrowserStack

For a monthly fee browserstack.com provides access to various versions of Windows and Internet Explorer through your web browser. It's pretty convenient.

By installing a Chrome addon you can ...

Capybara: Disable sound during Selenium tests

If the application under test makes sound, you probably want to disable this during integration testing.

You can use the args option to pass parameters to the browser. For Chrome:

Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome, args: ["--mute-audio"])
end

I haven't found a corresponding command line option for Firefox.

Hat tip to kratob.

Test a gem in multiple versions of Rails

Plugins (and gems) are typically tested using a complete sample rails application that lives in the spec folder of the plugin. If your gem is supposed to work with multiple versions of Rails, you might want to use to separate apps - one for each rails version.

For best practice examples that give you full coverage with minimal repitition of code, check out our gems has_defaults and assignable_values. In particular, take a look at:

  • Multiple `sp...

Pattern: Disabling a certain feature in tests

There is a kind of features in web applications that hinder automated integration tests. Examples include cookie consent banners or form captchas. Clearly, these should be disabled so you do not have to explicitly deal with them in each and every test (like, every test starting with accepting the cookies notice). On the other hand, they must be tested as well.

A good feature disabling solution should therefore meet these requirements:

  • The feature is generally disabled in tests. A test does not need to do anything manually.

  • It is *...

Fix randomly failing PDF cucumber tests

Sometimes PDF cucumber tests fail at the first test run and succeed at the second run. You can fix this with this step:

When PDF generation is ready
And I follow "Save as PDF"
# Checks for PDF contents go here

Here is the step definition:

When /^PDF generation is ready$/ do
  Then 'I should see ""'
end

state_machine: Test whether an object can take a transition

When using state_machine you sometimes need to know whether an object may execute a certain transition. Let's take an arbitrary object such as a blog article as an example that has those states:

A -> B -> C -> D

Additionally, you have transitions between the states as shown above. Let's call the transition between 'A' and 'B' transition_ab for simplicity. \
Given an object in state 'A'. You can call object.transition_ab but calling object.transition_bc! will obviously fail because ...

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...

Using QEMU to quickly test an ISO or bootable USB drive

When you want to quickly boot from a drive or image in a virtual machine you do not need to setup up a VirtualBox machine. Often QEMU does the job well enough.

Install it:

sudo apt-get install qemu

To boot an ISO:

qemu-system-x86_64 -cdrom filename.iso

If you prepared a USB pen drive and want to test it, run it like this (/dev/sdx being your device name; you may need to sudo to access it):

qemu-system-x86_64 -hda /dev/sdx

Be aware that not everything runs smoothly in QEMU -- you might need to set up a _VirtualBox...

How to test resource_controller hooks

When using the resource_controller gem you often hook onto events like this:
update.before do
do_something
end

For testing such things in your controller you should -- as always -- not trigger something that eventually calls the thing you want.\
Instead, in your specs, have resource_controller run those hooks like it does itself. Like that:

describe 'before update' do
 ...

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

Cucumber steps to test input fields for equality (with wildcard support)

Our collection of the most useful Cucumber steps, Spreewald, now supports exact matching of form fields and lets you use wildcards.

Examples:

And the "Money" field should contain "134"
# -> Only is green if that field contains the exact string "134", neither "134,50" nor "1000134"

And the "Name" field should contain "*Peter*"
# -> Accepts if the field contains "Peter" or "Anton Peter" or "Peter Schödl" etc.

And the "Comment" field should contain "Dear*bye"
# -> Accepts if the field contains "De...

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...

thoughtbot/fake_stripe: A Stripe fake so that you can avoid hitting Stripe servers in tests.

fake_stripe spins up a local server that acts like Stripe’s and also serves a fake version of Stripe.js, Stripe’s JavaScript library that allows you to collect your customers’ payment information without ever having it touch your servers. It spins up when you run your feature specs, so that you can test your purchase flow without hitting Stripe’s servers or making any external HTTP requests.

We've also had tests actually hitting the testing sandbox of Stripe, which worked OK most of the time (can be flakey).

Test that a hash contains a partial hash with RSpec

To test whether a hash includes an expected sub-hash:

expect(user.attributes).to match(hash_including('name' => 'Bruce Wayne'))
expect(User).to receive(:create!).with(hash_including('name' => 'Bruce Wayne'))

Test whether a form field exists with Cucumber and Capybara

The step definition below lets you say:

 Then I should see a field "Password"
 But I should not see a field "Role"

Here is the step definition:

Then /^I should( not)? see a field "([^"]*)"$/ do |negate, name|
  expectation = negate ? :should_not : :should
  begin
    field = find_field(name)
  rescue Capybara::ElementNotFound
    # In Capybara 0.4+ #find_field raises an error instead of returning nil
  end
  field.send(expectation, be_present)
end

Note that you might have to adapt the step defi...

Cucumber step to test that a tooltip text exists in the HTML

Tooltips that are delivered through HTML attributes are encoded. Decode entities before checking for their presence.

Capybara:

Then /^there should( not)? be a(n encoded)? tooltip "([^"]*)"$/ do |negate, encoded, tooltip|
  tooltip = HTMLEntities.new.encode(tooltip) if encoded
  Then "I should#{negate} see \"#{tooltip}\" in the HTML"
end

Note

This step uses the htmlentities gem described in another card.

Ma...

Capybara: Test that a string is visible as static text

This is surprisingly difficult when there is a <textarea> with the same text on the page, but you really want to see the letters as static text in a <p> or similiar.

The step definition below lets you say:

Then I should see the text "foo"

You should not look too closely at the step definition because when you see the light, it will blind you.

Then /^I should see the text "(.*?)"$/ do |text|
  elements = page.all('*', :text => text).reject { |element| element.tag_name == 'textarea' || element.all('*', :text => text...

Test that a string of text is (not) linked in Webrat or Capybara

The step definition below allows you to write:

Then I should see a link labeled "Foo"
But I should not see a link labeled "Bar"

Webrat

Then /^I should( not)? see a link labeled "([^"]*)"$/ do |negate, label|
  expectation = negate ? :should_not : :should
  response.send(expectation, have_selector("a", :content => label))
end

Capybara

Then /^I should( not)? see a link labeled "([^"]*)"$/ do |negate, label|
  expectation = negate ? :should_not : :should
  page.send(expectat...

Test the content-type of a response in Cucumber

The step definitions below allow you to write this in both Webrat and Capybara:

When I follow "Download as PDF"
Then I should get a response with content-type "application/pdf"

Capybara

Then /^I should get a response with content-type "([^"]*)"$/ do |content_type|
  page.response_headers['Content-Type'].should == content_type
end

Webrat

Then /^I should get a response with content-type "([^"]*)"$/ do |content_type|
  response.content_type.should == content_type
end

Unfortunatly this do...

Test e-mail dispatch in Cucumber

Spreewald has steps that let you test that e-mails have been sent, using arbitrary conditions in any combination.

The attached file is for legacy purposes only.

Test meta-refresh redirects with Cucumber

The step definition below allows you to write:

Then I should see an HTML redirect to "http://www.makandracards.com" in the page head

Capybara

Then /^I should see an HTML redirect to "([^\"]*)" in the page head$/ do |redirect_url|
  page.should have_xpath("//meta[@http-equiv=\"refresh\" and contains(@content, \"#{redirect_url}\")]")
end

To find meta tags with Capybara, you can also use page.find('meta', visible: false).