Monday, January 23, 2012

Cucumber, Capybara, and Webkit testing for Ajaxified actions

I recently upgraded my testing stack and now use Capybara and Webkit with Cucumber (and RSpec, too). I ran into a number of problems and found this post by Mathew O'Riordan incredibly helpful. He tracks the history of his research and testing through a github project and at various points on the blog entry shows the commit for the changes he just discussed: kudos on that approach!

A couple of gotchas that I ran into along the way:

First, you may need to add the following line to your features/support/env.rb file:
require 'capybara-webkit'
O'Riordan doesn't do this in his project, but I got an error:
"no driver called :webkit was found, available drivers: :rack_test, :selenium (Capybara::DriverNotFoundError)"
and found this discussion which gave me the solution.

Second, although it may be obvious, I missed the fact that you MUST put
@javascript
before each scenario that requires in-browser javascript. I had thought this was just a way of grouping scenarios together, but it actually triggers the use of the webkit driver to run the step.

Thursday, January 27, 2011

Solving one IE rendering problem...

I know this has been posted elsewhere, but since I recently ran into the issue and had to do some digging and coding to work around it, I thought I'd post it for others to find.

While working with a drop-down select box in a form, I wanted to be able to show/hide different sections of the form depending on the value of the selection (I'm currently using the Prototype javascript library for this project). It all worked fine in every browser except IE (surprise... NOT!). IE was not setting the "value" property of the select box.

After some testing, I found that IE DID properly set the selectedIndex attribute, so I could use that to get IE to work like I wanted it to; here's the code:

MHC.select_display = function(select_id, select_value, select_number, toggle_id) {
/***
* NOTICE IE6 properly sets the selectedIndex value but does NOT set the value property; therefore, we have to give both values to this routine
* to handle both browsers.
* alert("Hi - I've been changed! / " + select_id + " / " + select_value + " / " + toggle_id + " / " + $(select_id).selectedIndex + " / " +  $(select_id).options[$(select_id).selectedIndex].value + " / " + $(select_id).value) + " / " + $(select_id).options.value;
**/     
if(Prototype.Browser.IE) {
  if($(select_id).selectedIndex == select_number) {
    $(toggle_id).appear();
    }
  else {
    $(toggle_id).hide();
    }
  }
else {
  if($(select_id).options[$(select_id).selectedIndex].value == select_value) {
    $(toggle_id).appear();
    }
  else {
    $(toggle_id).hide();
    }
  }
};
While I don't know this for a fact, I'm guessing that other problems with IE form fields (such as checkboxes and the "checked" attribute) may be due to the timing of updates to the attributes; you may be able to find alternative attributes that you can interrogate to get things done.