Integration Testing AJAXy sites
A friend of mine was trying to write some integration tests against a site that makes a lot of use of AJAX requests for navigation. She started out using her standard tool, Watir, but was having trouble getting selectors th would work. Part of the issue was that she needed to explicitly wait for parts of the page to finish loading before looking for things in the DOM. She could fix that with some ‘wait until loaded’ stanzas. But the site she was testing didn’t have a lot of unique ids or classes. For one link she was trying to click, the only unique attribute on the link she wanted was in a data attribute - which watir wasn’t finding. I suspect there is a way to do it - but I can’t find where I can read about what watir uses to parse the DOM so I couldn’t help her figure out the correct syntax. So we decided to give capybara a try.
The capybara documentation says:
It goes on to say we just ‘gem install capybara-webkit’. That gave me an error which the internet says can be fixed by installing Qt via ‘brew install qt’:
Fetching: capybara-webkit-1.0.0.gem (100%) Building native extensions. This could take a while... ERROR: Error installing capybara-webkit: ERROR: Failed to build gem native extension. /Users/cnk/.rvm/rubies/ruby-2.0.0-p247/bin/ruby extconf.rb Command 'qmake -spec macx-g++' not available
Poking around Minitest and Capybara docs, I cobbled together the following:
require 'minitest/autorun' require 'capybara' Capybara.default_driver = :selenium class RequestTest < MiniTest::Spec include Capybara::DSL def test_google visit('http://google.com/') page.has_selector?('div#searchform') end end
Which gives the followign error:
1) Error: test_google(RequestTest): LoadError: Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler.
Installing that gem makes the tests run - but it launches a full on browser. Not sure that is what I wanted. I thought I could use capybara-webkit to do headless JS testing.
ALSO, did I want to be inheriting from MiniTest::Spec given that I am trying not to use ‘describe’ syntax but instead use the ‘define a method who’s name starts with test’ style.