One of my favorite changes in Capybara 2.1 is ignoring all hidden elements by default. This could be viewed as a limiting of Capybara’s feature set, since you can no longer (easily) test certain elements on a page. I will argue that it steers you into writing tests that are more realistic, causing this limitation to actually enhance the quality of your acceptance tests.
iFrame you frame…
Helps
undefined method `fields' for nil
We keep getting this error across multiple projects & machines, with different versions of the pg gem and the PostgreSQL server, with varying consistency. Switching the tests to sqlite seems to fix it.
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::StatementInvalid:
NoMethodError: undefined method `fields' for nil:NilClass: SELECT "locations".* FROM "locations" WHERE "locations"."id" IN (11, 10, 5, 4, 1, 3, 2)
It appears that PG::Connection#async_exec is returning nil for some queries.
It was suggested to add a "fields" method for the nil class.
Interestings
Homebrew is Kickstarting an automated test bot
http://www.kickstarter.com/projects/homebrew/brew-test-bot £50 to get a pair of pint glasses…
Resizing the window to test media queries
If you want to test your media query css as part of your acceptance suite, you can just ask Capybara to resize the firefox window.
Don't use the iframe to do this, because it will be buggy. Note you will need to use min/max-width not min/max-device-width when defining your media queries. Otherwise resizing the browser window will not trigger the media query.
Capybara.current_session.driver.browser.manage.window.resize_to(width, height)
Capybara.current_session.driver.browser.manage.window.position = Struct.new(:x, :y).new(session_name == :default ? 0 : width, 0)
Thanks to Ryan for the tip.
without_page_refresh capybara helper
I recently had to write a small capybara helper:
def without_page_refresh
page.execute_script("window._withoutPageRefresh = 'BAM'")
yield
page.evaluate_script("window._withoutPageRefresh").should == "BAM", "Page was navigated away"
end
Use case:
You are building a form that gracefully degrades
when javascript is not enabled. It goes something like this:
# uses rack-test so no javascript
scenario "User can lose money in an accessible way" do
visit "/your_account"
page.should have_content "You have $100"
click_button "Charge me"
page.should have_content "You have $50"
end
Next step is to make that form do the ajax thingy.
You copy test above and switch it to use javascript driver:
# uses selenium for javascript
scenario "User can lose money with style", :js => true do
visit "/your_account"
page.should have_content "You have $100"
click_button "Charge me"
page.should have_content "You have $50"
end
Newly written test is pretty good except that it passes without
writing a single line of javascript. So here’s when that helper
comes into play. Our javascript test becomes:
# uses selenium for javascript
scenario "User can lose money with style", :js => true do
visit "/your_account"
without_page_refresh do
page.should have_content "You have $100"
click_button "Charge me"
page.should have_content "You have $50"
end
end
Now javascript test fails with “Page was navigated away”
since nothing is preventing that form from submiting to another page.
Waiting for jQuery Ajax calls to finish in Cucumber
You may be asking yourself why you’d want to do this in the first place. Well here’s why I would want to do it.
We had some Webdriver based Cucumber tests that passed fine locally but kept failing on our CI box. Our CI box is a bit underpowered at the moment so I thought what might be happening is that our tests weren’t waiting long enough for the Ajaxy stuff to happen because the Ajax responses were taking a long time.
After some poking around in the source code of jQuery, I found the $.active property. This property keeps track of the number of active Ajax requests that are going on and I thought this might help us out.
What I came up with was this gist:
I added this step right after my Cucumber step that caused the Ajax call so that Cucumber would wait to move on until I knew that everything was done.
This step solved our CI failures and all was good in our test suite again.
Using Firebug with WebDriver in Capybara/Cucumber – New and Improved
Forget the steps I published earlier…just install the capybara-firebug gem and away you go.
Thanks jfirebaugh!
Using Cucumber/Capybara with SauceLabs SauceOnDemand
SauceLabs is a cloud based way to test your site against different browsers.
Up until now, they only supported the older Selenium RC based tests.
For those of us using Capybara, we were out of luck because Capybara uses Webdriver.
Well that just changed, they now support Webdriver. Check out the instructions on how to get is set up here.
The one thing that I disagree with in that post is setting the default Capybara driver to :sauce (Capybara.default_driver = :sauce). This seems a little heavy handed to me since I may not want to run all of my scenarios through the Sauce driver.
Upon further review of the source code, it looks like after installing the sauce gem, they redirect any scenarios tagged with @selenium to the Sauce driver. I like this better so if you don’t want to switch over all of your scenarios over to Sauce, you can just ignore the line mentioned above and simply tag the scenarios you want to run on Sauce with @selenium.
I haven’t had a lot of time to play with this but at least it is a start in getting Capybara based Cucumber scenarios to run against Sauce Labs.
My next step is to figure out how to run one Cucumber scenario to run against multiple browsers on Sauce.
Another thing I’d like to figure out how to do is only run Selenium based tests on demand so they don’t run on Sauce every time I run my Cucumber suite. That could run up a decent Sauce bill, especially if you had multiple developers running Cucumber scenarios multiple times a day.
Rails3, Caypbara, Cucumber, FakeWeb…oh my….
While helping client upgrade a Rails 2.3.10 site to Rails 3.0.1, I came across a very perplexing problem with our WebDriver based Cucumber tests that all worked fine under 2.3.10.
We were “randomly” getting some very strange errors from Cucumber having to do with timeout problems and other strangeness like Cucumber not being able to find form fields to fill in.
The solution:
1) require => false for the FakeWeb line in the Gemfile
2) add require ‘fakeweb’ to the top of the test_helper.rb file
or optionally scrap FakeWeb for either Artifice or WebMock
It has something to do with FakeWeb inserting it into the HTTP stack strangely even if you tell it to allow non-local HTTP requests. We weren’t seeing it in 2.3.10 because we were using a cucumber environment to run the cucumber tests. Now under 3.0.1 we run the cucumber tests in the test environment.
I wish I had some more details but I was just happy to move past this strangeness so I didn’t really look back.
Using Firebug with WebDriver in Capybara/Cucumber
Ever wanted to be able to debug an HTML page using the power of Firebug while running Cucumber/Capybara features/steps?
Follow these simple steps and you can get it to work:
1) Create a new “WebDriver” Firefox profile using the instructions found here
2) Fire up Firefox using the newly created profile and install/configure Firebug the way you want it. See instructions above.
3) Run your Cucumber/Capybara steps and pause the feature using a sleep() statement long enough for you to poke around in the page with Firebug.
**Note this has been proven to work on OS X, your mileage on other OS’s may be limited.
Capybara/Cucumber and waiting for Javascripty stuff to happen
A little ditty that makes it really easy to wait for something Javascripty to happen…like a Javascript dialog to appear that gets populated from an AJAX call.
The has_css? method call will wait until the element shows up and if it doesn’t show up before the Capybara timeout expires then it will return false.
Standup 7/20/2010: The Daily Rubymine
Interesting Things
RubyMine 2.0.2, refactor => extract partial == FAIL. If you select multiple divs and perform
extract partial, the selected region is removed, but only the first complete div is included in
the new partial.Rspec/Rubymine focused tests. Rubymine attempts to run focused tests using the
--example 'text'option. Rspec apparently finds the example group, and runs the examples that are
directly a part of that example group, but does not include descendent example groups — *which can
lead you to think examples are passing that were not actually run*. Apparently this is
fixed in rspec 2.
Ask for Help
“Display of time is off by an hour, presumably due to Daylight Saving Time”
The team is displaying time stored as utc in the database, using strftime, and the time is off by an hour.
“Binding Click to Checkbox with Jquery”
A team was trying to check the value of a checkbox during the click event, but getting the opposite
value. They worked through it but was hoping to find a better solution.
“Why is there a new default for include_root_in_json for rails 3?”
Just curious.
“Fakeweb, Capybara w/Selenium Webdriver == end of file?”
Getting “end of file” failure on CI. There were a few suggestions:
- There is a fork of fakeweb that allows it to ignore localhost.
- Consider using Webmock instead of fakeweb.