Thursday, August 6, 2009

Work around Selenium IDE's iteration deficiency with Prototype JavaScript evals

Selenium IDE, the FireFox testing plugin, is a nice tool. One of its limitations is the lack of straightforward methods for iterating or doing other control flow during tests. This is one reason to switch to writing tests in Selenium RC. However, it is sometimes possible to work around the limitations from within Selenium IDE by evaluating arbitrary JavaScript. In particular, Rails applications using the standard Prototype JavaScript library have available some nice ways to iterate over elements.

For example, I recently wanted to write a Selenium IDE test to clear the shopping cart for a web app. To do this, I needed to iterate over all the elements in the cart, set their quantity to 0, and then update the cart. To accomplish the iterative set quantity to 0, we can use the getEval method to run arbitrary JavaScript: selenium.browserbot.getUserWindow().document.body.select('input[id^="line_item_"][id$="_quantity"]').each(function(elem){elem.value = 0}).

Going through this piece by piece:

  // This gets us the user window.  
  // Older versions might use getCurrentWindow() instead.
  selenium.browserbot.getUserWindow()
  
  // Gets us down to the document body
  // Because this is a standard Rails app, 
  // body has already been extended with Prototype.
  // select() invokes Prototype's $$() CSS selector.
  document.body.select
  
  // These are CSS3 attribute selectors
  // Basically we want to match id="line_item_*_quantity".
  // May require FireFox >= 3
  input[id^="line_item_"][id$="_quantity"]
  
  // Prototype's Enumerable.each() does the iteration,
  // with an anonymous function setting the values.
  each(function(elem){elem.value = 0})

No comments:

Post a Comment