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