Red Squirrel Reflections
Dave Hoover explores the psychology of software development

Dave Hoover

All [Atom]
Craftsmanship [Atom]
Dynamic [Atom]
Intersection [Atom]
Learning [Atom]
Links [Atom]
Polyglot [Atom]
Projects [Atom]
XP [Atom]
Old Blog

Obtivian Blogs

Andy Maleh
Colin Harris
Fred Polgardy
Jim Breen
Kevin Taylor
Todd Webb
Turner King
Tyler Jennings


March 2009 (1)
January 2009 (1)
December 2008 (1)
October 2008 (3)
September 2008 (1)
June 2008 (4)
April 2008 (3)
March 2008 (1)
February 2008 (1)
August 2007 (1)
July 2007 (1)
June 2007 (1)
May 2007 (4)
April 2007 (3)
March 2007 (5)
February 2007 (6)
January 2007 (6)
December 2006 (10)
November 2006 (5)
October 2006 (8)
September 2006 (8)
August 2006 (5)
July 2006 (12)
June 2006 (7)
May 2006 (5)
April 2006 (5)
March 2006 (4)
February 2006 (2)
January 2006 (5)
December 2005 (5)
November 2005 (3)
October 2005 (3)
September 2005 (6)
August 2005 (4)
July 2005 (7)
June 2005 (14)
May 2005 (6)
April 2005 (8)
March 2005 (9)
February 2005 (11)
January 2005 (16)
Old Archives


Thu, 23 Oct 2008

Rails Rumble 2008: Developing Run.Track.Run.

Leah Welty-Rieger joined Obtiva a couple months ago. She is an apprentice in our Software Studio. (She also recently earned her PhD in Particle Physics from Indiana University.) About a month or so ago, Leah and I were walking back from lunch and started talking about our shared interest in running. Then she told me about an idea she had for making simpler, easier, more informative running software for planning and tracking your training. A couple weeks later I found a link to Rails Rumble 2008. I'd wanted to rumble in the past, because I'm a fairly speedy programmer, and I love competition. But having very little CSS-fu and lacking any inspired 48-hour-sized ideas, I'd never rumbled. Until this year. I immediately thought of Leah's idea and realized that with the addition of CSS-ninja Dan Nawara to our Studio team, we had sufficient skills to rumble. And just because I had the luxury of doing so, I asked Fred Polgardy to join us as well, because, well, Fred's a genius, particularly with JavaScript.

We got together 3 times before the competition to formulate our plan of attack. This helped us start on the same page. We understood the domain model (Users have Runs have Splits), and we knew we were going to integrate with the Garmin Forerunner, and we knew we were going to use Flotr to build the HTML-canvas-based graphs that Leah had specified. We decided to use HAML and SASS, which I had never used, but found perfectly intuitive and productive (and now prefer it). I decided to stick with good old test/unit for TDD. I'm still much more productive in test/unit than any other Ruby testing framework and I needed something dead simple since I was going to be running low on energy. I also planned to use TDD strategically. Basically, I used it to test my models, but developed my controllers without tests. Ironically, this helped keep my controllers really skinny, since I ended up extracting logic into models (such as the Garmin XML file processing and matching scheduled runs to actual runs) and wrapping them in tests. We also decided on the name for the app: Run.Track.Run. We were both excited and disappointed to find out a day later that Relevance had created Run Code Run and would be offering free continuous integration for rumblers, and thereby leading everyone to assume that we copied their name.

The competition started on Friday at 7pm Chicago time. My wife, kids, and I with friends in their house. I rudely, and suddenly grabbed my laptop and bluetooth-enabled modem/mobile-phone and started the process of setting up our github repository with Bort, installed Debian on Linode (with Apache+Passenger, MySQL, Postfix), hooked our build into Run Code Run, and pushed our first Capistrano deployment up to the server. The next morning the 4 of us met at the office and started rumbling as a team. The rest of the story is actually pretty mundane. I got really pissed off, swearing loudly at the Garmin JavaScript libraries for a while until Fred came over and solved the problem. We did a lot of pair programming. And mostly just kicked ass consistently for 48 hours. I got to pair with Leah, Dan and Fred (sorted in order of amount of pairing time). I think everyone paired with everyone. And everyone got enough sleep. And with an hour to go, we were kicking back with beer and making final tweaks. In the end, we launched Run.Track.Run., which I'm particularly excited about, since I'm one of the (currently) 75 runners who are already using the application.

[/projects/runtrackrun] permanent link

Fri, 25 Apr 2008

Tweet Nodes

I ripped the WordNet server-side integration out of The Lightweight Visual Thesaurus and shoved in the Twitter API to create Tweet Nodes. It's still at total hack and only works on Firefox, but it's a fun little Twitter conversation browser.

Here's how olabini's Tweet Nodes look today...

[/projects/tweet_nodes] permanent link

Wed, 10 Jan 2007

SafariWatir on iPhone?

I'm not sure why anyone would want to run Watir scripts on a handheld device ... but since the iPhone runs on OS X and ships with Safari, I'm wondering how difficult it would be to get SafariWatir setup ... just because we can.

[/projects/watir] permanent link

Wed, 03 Jan 2007

assert_select for Watir

Inspired by Jamis' post on assert_select I've just committed an update to my Watir on Rails plugin that adds support for both assert_select and assert_tag. Give it a try!
require File.dirname(__FILE__) + '/../test_helper'

class GettingStartedTest < Test::Unit::TestCase
  include WatirOnRails
  def test_getting_started
    browser = open_browser("/")
    assert_select "div#getting-started h1", "Getting started"
    assert_tag :tag => "h1", :content => "Getting started",
               :parent => { :tag => "div", :attributes => { :id => "getting-started"} }
Rather than asserting against the body of the response from the controller, I'm grabbing the HTML from the most recently opened browser.

[/projects/watir] permanent link

Reviving the Lightweight Visual Thesaurus

I've brought my Lightweight Visual Thesaurus back to life. I'm hoping to make some improvements to it this year, like supporting more browsers than just Firefox.

[/projects/lvt] permanent link

Wed, 06 Dec 2006

SafariWatir Screencast

Watch the screencast of SafariWatir running its test suite.

[/projects/watir] permanent link

Wed, 22 Nov 2006

SafariWatir 0.2.0

Hamish released the first rb-appscript gem, paving the way for the new and improved SafariWatir. Now with non-sluggish performance! Seriously, my regression test script runs ridiculously fast on my MacBook Pro compared to previous versions of SafariWatir.

This performance boost comes as no surprise. Up until now I was doing the simplest most naive (and slowest) thing that could possible work by using backticks to invoke AppleScript from the command line...

`osascript <<SCRIPT
tell application "Safari"
  do JavaScript "#{script}" in document 1
end tell

This got me started, but it turns out that using an Apple Event bridge like rb-appscript is more natural, and so much faster...

app ="Safari")
document = app.documents[1]
app.do_JavaScript(script, :in => document)
In unrelated news, my fellow Obtivian Tyler Jennings has submitted his first Rails patch.

[/projects/watir] permanent link

Mon, 16 Oct 2006

Bye-Bye AppleScript, Hello Apple Events, Thanks Hamish

So I lied. In my last post I said that I would be taking a break from Open Source in the short-term. How wrong I was. When I released SafariWatir 0.1.2 I whined about the lack stable Ruby/AppleScript support, which has been my excuse for SafariWater's sluggish performance. On Saturday, Hamish Sanderson, the author of appscript (Python + Apple Events) and rb-appscript (Ruby + Apple Events), contacted me to point me toward his recent port of appscript to rb-appscript on RubyForge. I just committed to the svn repository after spending about 3 hours tonight refactoring SafariWatir to use rb-appscript. Wow! Now I have a different performace problem. The pages actually go by too quickly!

A release should be out soon, right after Hamish and I sort out some annoying warnings being spewed out somewhere in the depths of his magical modules.

[/projects/watir] permanent link

Fri, 13 Oct 2006

SafariWatir 0.1.2

On the plane to San Jose last week I polished off another SafariWatir release. This will likely be the last release for a while. Due to the flooding that we experienced last week, I have become very focused on revenue-generating activities in the short-term. There's nothing like losing 1/3 of your living space and slow-to-respond insurance companies and a family of 5 to support to keep you focused on the bottom line!

This release adds table and frame support, along with improving the click events. Here are some examples of what you can do with SafariWatir at this point...

require 'rubygems'
require 'safariwatir'
require 'test/unit/assertions'
include Test::Unit::Assertions

browser =
browser.frame("menu").link(:text, "Books").click
browser.frame("menu").link(:text, /psychology/i).click
assert_match /Silver Anniversary/, browser.frame("content").text

assert_match /What is Basecamp\?/, browser.table(:index, 1)[1][2].text
                                                # First table
browser.close                                   #          First row
                                                #             Second cell
                                                # Yes, Watir uses 1-based indexes.

[/projects/watir] permanent link

Wed, 04 Oct 2006

Rails Seminar Watir on Rails talk cancelled due to Flood

I arrived in San Jose late yesterday because of a thunderstorm delay in Chicago. When I landed I called my wife to let her know I had arrived. I was looking forward to presenting Watir on Rails at AjaxWorld's Ruby on Rails Seminar. Unfortunately, the thunderstorms that delayed my flight also flooded our home. Thankfully my wife and children are OK, but there's some serious damage to our house and I'm catching the next flight back. My talk won't be happening today.

Update: We've received an amazing amount of help and support over the last 24 hours. When I arrived at home today, it was depressing to see a mudpit and a dumpster where our front yard used to be, but it was inspirational to see so many friends and family hard at work getting things cleaned up and dried out. This experience has certainly given Staci and me an opportunity to see things, particularly material things, from a new perspective. At times like this I'm frequently reminded of Jerry's Sage Advice: "It may look like a crisis, but it's only the end of an illusion."

[/projects/watir] permanent link

Thu, 21 Sep 2006

Watir on Rails Update: It's all Relative

I made a backward compatible update to the Watir on Rails plugin to allow you to get rid of those nasty fully-qualified URLs in your Watir on Rails tests. To allow for this, I added some config-like class methods to specify the server and port (defaults to http://localhost:3000) in your TestCases. Here's a simple example, relying on the defaults:
class WelcomeTest < Test::Unit::TestCase
  include WatirOnRails

  def test_salutation
    browser = open_browser
    assert_match /Welcome Guest/, browser.div(:id, "banner").text
A slightly more complex example, testing against a non-standard test server configuration:
class MyAccountTest < Test::Unit::TestCase
  include WatirOnRails
  server ""
  port 3001

  def test_update_preference
    browser = open_browser("/squirrels/"), /preferences/i).click
    browser.text_field(:name, "user").set("dave")
    browser.text_field(:name, "pass").set("test")
    browser.button(:name, "commit").click

    assert_match /<h2>Welcome Dave<\/h2>/, browser.html

    browser.checkbox(:id, "largeFont").set
    browser.button(:name, "commit").click
    assert_match /<h1>Welcome Dave<\/h1>/, browser.html
If you're serious about building up a good Watir acceptance test suite, consider developing a site-specific lanaguage (example here).

[/projects/watir] permanent link

Thu, 07 Sep 2006

Watir on Rails Plugin

After showing some hacked up examples of Watir and Rails integration at RailsConf and last Friday's Ajax on Rails addon, I decided that I was way overdue to venture into the exciting world of Rails Plugins. And just a few hours later, Watir on Rails was born.

Here's a quickstart...

  gem install [safari]watir
  ./script/plugin install svn://
  ./script/generator watir SuccessfulLogin
  ./script/server -e test
  rake test:watir

One of my goals for this first release was to make Watir on Rails have a similar feel to Rails Integration Tests, which provide a handy open_session method you can use to decorate your session object with a site-specific language. Well, if you know anything about Watir, it should not come as a surprise that Watir on Rails provides an open_browser method that does something similar. You can use open_browser to simply open a browser and use the excellent Watir API, or you can provide an optional block and write Watir on Rails tests methods like this...

  def test_login	
    browser = open_browser
    browser.login_with :username => "dave", :password => "test"
    assert_match /Welcome Dave/, browser.div(:id, "banner").text

  def open_browser
    super do |browser|
      def browser.login_with(args)
        text_field(:name, "user[name]").set(args[:username])
        password(:name, "user[password]").set(args[:password])
        button(:name, "login").click

[/projects/watir] permanent link

Mon, 24 Jul 2006

SafariWatir 0.1.1

SafariWatir now offers feedback when you try to access an element that doesn't exist...
browser = Watir::Safari.start("")
browser.button(:name, "foo").click
Watir::Exception::UnknownObjectException: Unable to locate Button element with name of foo.
        from /usr/local/lib/ruby/gems/1.8/gems/safariwatir-0.1.1/./safariwatir/scripter.rb:243:in `execute'
        from /usr/local/lib/ruby/gems/1.8/gems/safariwatir-0.1.1/./safariwatir/scripter.rb:68:in `highlight'
        from /usr/local/lib/ruby/gems/1.8/gems/safariwatir-0.1.1/./safariwatir.rb:10:in `click'
        from (irb):4
That's an important step forward, but I added something else this weekend just for fun.

Tell me, Mr. Anderson, what good is a phone call if you're unable to speak?

You can now interrogate any SafariWatir element ... and it will speak. After you gem install safariwatir, turn up your speakers and try this...

browser = Watir::Safari.start("")
browser.span(:id, "matrix_quote").speak
I'm not sure what a feature like this is good for, but I couldn't resist.

[/projects/watir] permanent link

Sun, 23 Jul 2006

Rails Acceptance Testing eBook

I am writing an eBook for Addison-Wesley (they call them shortcuts) on using Selenium and Watir to test Rails apps. Look for it in the October-November timeframe. If you have experience reports that you would be willing to share, let me know.

[/projects/watir] permanent link

Fri, 21 Jul 2006

SafariWatir 0.1.0

If you're a Mac-user who has been coveting the power and simplicity of (Windows/IE-only) Watir, your wait is over! It's your turn now! A pre-pre-pre-alpha of SafariWatir has been released. Go ahead and gem install safariwatir, fire up irb and go nuts...
require 'rubygems'
require 'safariwatir'
browser =
browser.text_field(:name, "q").set("safariwatir")
browser.button(:name, "btnI").click
puts "FAILURE" unless browser.contains_text("Watir on Safari")
There are tons of things missing from this release, but many of the basic Watir actions are in place. The critical missing piece is error messages: If you try to access elements that don't exist on the page, SafariWatir won't complain (yet).

[/projects/watir] permanent link

Thu, 20 Jul 2006

Watir at Rails Seminar

I will be showing how to use Watir to test Rails+Ajax apps at the Real-World Ruby on Rails Seminar in Silicon Valley on October 3. This time I shouldn't need to use Windows on Parallels to show off Watir on my MacBook Pro thanks to SafariWatir. :-)

[/projects/watir] permanent link

Thu, 13 Jul 2006

SafariWatir in development

If you haven't noticed, I'm a big fan of web testing tools like Selenium and Watir. As I prepared for my RailsConf talk (at RailsConf), surrounded by herds of Macs, I realized that Watir adoption in the Rails community was seriously not going to happen anytime soon without some cross-browser and cross-platform support. Without that support, I continue to recommend Selenium RC or Selenium on Rails to most Rails developers.

And yet I still find myself infatuated with Watir's dead-simple setup (gem install watir and you're done) and intuitive API. So ... <deep-breath/> ... inspired by the Mac-centric tendencies of most of the Rails frontrunners, I have launched the SafariWatir project on RubyForge. There's not very much there yet. You can open and close Safari, fill out text fields, click buttons and links, ask whether the page contains text ... oh, and you can click alert boxes.

I just discovered Apple's GUI Scripting integration with AppleScript, which makes it wonderfully easy to handle things that Windows makes incredibly difficult. (Apple provides GUI Scripting to facilitate universal access.) Watir (for IE) developers, you may want to look away, the following code could hurt...

tell application "System Events" to tell process "Safari"
	tell window 1
		if button named "OK" exists then
			click button named "OK"
		end if
	end tell
end tell
That's all it takes to click an alert button in AppleScript. I wrap that in Ruby-goodness and stick it behind the Watir API, and man, I think this project is going to just about write itself.

[/projects/watir] permanent link

Sat, 08 Jul 2006

Selenium 0.7 RubyGem Update

As I mentioned in my talk at RailsConf, I needed to update the Selenium RubyGem to get it up-to-date. The gem is now available: gem install selenium. This will give you the latest release (0.7) of Selenium Core. In previous Selenium gems there were a few crufty Ruby files in there, but these have now been extracted to Selenium Remote Control.

This update is mostly for Jonas and Bret.

[/projects/selenium] permanent link

Thu, 15 Jun 2006

My Canvas/Ajax articles in Russian

It appears that my articles on Canvas and Ajax (originals here and here) have been translated into Russian: the Supertrain article and the Interactive Canvas on IE article. Although they probably don't have permission from O'Reilly to reprint them, it's an exciting moment to realize someone else has taken the time to make my work available to a new population.

[/projects] permanent link

Thu, 11 May 2006

The Interactive Canvas on has published my Interactive Canvas and Internet Explorer article.

[/projects/interactivecanvas] permanent link

Tue, 02 May 2006

Selenium 0.6 RubyGem Update

The Selenium RubyGem on RubyForge was woefully out of date. Until today. It now contains the current Selenium release (0.6). Thanks to Jon for holding my hand as I created my first gemspec and to Jonas for his excellent Selenium on Rails plugin, which was the impetus for this update.

[/projects/selenium] permanent link

Tue, 25 Apr 2006

Watir, the Lazy Programmer's Friend

My current client was in need of a functional test suite for their web site to raise our confidence that we wouldn't break anything when we upgraded to Hibernate 3. Despite being a Selenium fan, I wanted to give Watir a try (for various reasons, it felt like a good fit). People were hesitant about the introduction of a new language (Watir is a web testing DSL in Ruby), but after I spent a day getting a bunch of test scenarios scripted, Watir proved its worth. Every developer I paired with said the same thing: "I'm never going to type into a browser again."

There were things I could do with Watir that I would be hard pressed to do with Selenium, like outsmarting CAPTCHA, abstracting common code by opening Watir::IE, and switching between dev, test, and staging by changing a single variable. That last point is one of the big wins of Watir over Selenium, you never touch the server, it's dead simple to setup. That said, the achilles heel of Watir is that it currently only runs on Windows and IE, while Selenium runs virtually anywhere on any browser. So I'll stick with Selenium for my Rails project on my MacBook, while Watir seems to be a good fit for our Windows workstations at my client site.

Abstracting common code into Watir::IE has worked beautifully so far. We created a WatirHelper module that includes code like this:

module Watir
  class IE
    def login_admin
      text_field(:name, "name").set("jerryQ")
      text_field(:name, "pass").set("bletch")
      button(:name, "Sumbit").click

    def fill_out_problem_form(last_name, email)
      select_list(:name , "dateMonth").select("December")
      select_list(:name , "dateDay").select("25")
      select_list(:name , "dateYear").select("2008")
      text_field(:name, "firstName").set("F")
      text_field(:name, "lastName").set(last_name)
      text_field(:name, "email").set(email)
      text_field(:name, "confirmEmail").set(email)
Which allows our Watir scripts to look like this.
require 'watir'
require 'watir_helper'
include Watir

# update this to point to any server you want
server_name = "localhost" 

ie =
ie.login_admin, "Tell us your problem").click
ie.fill_out_problem_form("Foo", "")
assert ...
Over time, we had become so lazy (thanks to Watir) that we couldn't tolerate filling out the lengthy forms on the site when we needed to try something out but didn't want to run the tests. So we developed some smaller scripts that didn't test anything, but would fill out forms and click through a series of pages so we could get on with the more interesting stuff. This worked beautifully, mostly because we had already removed enough duplication to give us coarse-grained operations with which we could construct short, powerful scripts to do our bidding.

But then I got tired of running scripts. I wanted a Watir dashboard. Ruby/Tk to the rescue! Here's my quick spike of how to drive Watir from a GUI.

require 'tk'
require 'watir_helper'

root = { title "Dashboard" }
button = do
  text "Start Google"
  command proc do
    ie =

It took me a couple more minutes to get a real dashboard up and running and now I can drive around my client's webapp with a push of a button!

[/projects/watir] permanent link

Mon, 17 Apr 2006

The Interactive Canvas and Internet Explorer

I wrote up a simple example of how to create interactive canvas applications. I used ExplorerCanvas to ensure compatibility on all major browsers.

[/projects/interactivecanvas] permanent link

Thu, 30 Mar 2006

Google puts Canvas on IE: The Game Changer

Update: ExplorerCanvas is the official project name.

Master Canvas hacker Benjamin Joffe announced something on the canvas developers group yesterday that, in my humble opinion, is a game changer. Google is putting canvas on Internet Explorer. Benjamin received a pre-release version of a Javascript library (soon to be officially released on that, when included on a page with canvas, allows the downtrodden Internet Explorer users of the world to step into the wonderful world of canvas. Emil started this work and it looks like Google is finishing it.

It doesn't take a genius to figure out the implications of Google's work on this ... look out world!

Here are a few examples that are using Google's canvas library:

[/projects/ajaxtrains] permanent link

Fri, 24 Mar 2006

Using Rails as Javascript Scaffolding

I'm working on something that I'm not talking about yet, but I can say it's a Rails app. I'm likely a bit behind the times, but I thought I'd mention a habit emerging in my Rails/Ajax development that I haven't read about in any of the blogs I follow.

After I started playing with Behaviour, I grew to appreciate keeping my markup free of Javascript. At the same time, I enjoy using Rails JavaScriptHelper methods to do the dirty work for me. So what I end up doing is writing the Rails code and get everything working the way I want it. Then I view source in my browser, copy the Rails-generated HTML and Javascript and paste over the Rails code in my template. Then I'm free to separate everything into the appropriate places. Styles can get pulled up into a CSS file, onFoo methods can get extracted into Behaviours, and HTML elements can be formatted and identified the way I want. I just went through this routine with the marvelous autocomplete and it worked like a charm.

It feels so right, I wonder if it's wrong. I suppose I'm making my code more susceptible to breaking with future Rails/Scriptaculous upgrades. But it also feels like a smaller incarnation of the Rails scaffolding philosophy. So I'm wondering if I'm just doing something many others have silently practiced before me or if I'm violating an unspoken rule of Rails development.

[/projects/beratings] permanent link

Fri, 17 Mar 2006

Selenium at RailsConf

My Selenium on Rails proposal was accepted for RailsConf 2006. Attendees can look forward to practical examples of all types of Selenium tests extracted from Real Life Project(s). You can also look forward to no slides, just code. See you in June!

[/projects/selenium] permanent link

Mon, 13 Feb 2006

Canvas Directed Graph Library: webdep

Update: Aslak's sites are temporarily unavailable. In the meantime, visit this working example if you want to play with webdep.

I mentioned in my previous post that Aslak and I were collaborating on a new DamageControl feature that uses canvas to setup build dependencies. We're beginning to extract our code into it's own project. We're calling it webdep and it is currently hosted at buildpatterns.

Browse the source or use subversion and svn co

Currently we have the just extracted the layout behavior without any user interaction or Ajax. These will be coming soon, along with (hopefully) IE support (thanks to Emil).

[/projects/webdep] permanent link

Thu, 19 Jan 2006

Canvas, Ajax, and the Supertrain: Reloaded

After I wrote my Supertrains article last month, O'Reilly's decided to publish it. I reworked the Javascript into a more object-oriented style, replaced the homegrown wire protocol with JSON, and added a "hotspots" feature. I can't resist quoting Brooks...
To only a fraction of the human race does God give the privilege of earning one's bread doing what one would have gladly pursued free, for passion. I am very thankful. --The Mythical Man Month, p. 291

[/projects/ajaxtrains] permanent link

Sat, 14 Jan 2006

Lightweight Visual Thesaurus v0.2

I joined the canvas-developers Yahoo! group a couple weeks ago. On Thursday, Benjamin Joffe posted an example of writing text to the canvas element. This had been my biggest frustration with canvas up to now, but Benjamin blew that problem away. I plugged his CanvasRenderingContext2D.prototype.drawString function into The Lightweight Visual Thesaurus this morning, and bam! v0.2 was born.

[/projects/lvt] permanent link

Fri, 23 Dec 2005

Canvas, Ajax, and the Supertrain

I've written a tutorial on how to combine canvas and Ajax. In this article I use canvas to graphically represent the real-time state of a fictional railway system (live example). Send me feedback if you have suggestions for improvements.

Merry Christmas!

[/projects/ajaxtrains] permanent link

powered by blosxom