Blake Mizerany of Heroku talks about building lightweight RESTful web services with his Ruby framework Sinatra.
Monthly Archives: March 2009
Standup 03/05/2009
Interesting Things
Giving your fake acts_as_fu model the same name as an actual model you have can lead to very obscure test failures. For those not in the know, acts_as_fu gives you the ability to test your model extensions directly by creating a fake model in your tests and mixing your extensions into it.
A few people have been using Paperclip to manage their attachments and have found it easier to integrate than Attachment_fu.
New York Standup 3/4/2009
Interesting
While this has been mentioned before, naming an ActiveRecord association :target will cause infinite recursion. Especially lame if you are building an app for assassins or mobsters.
The tracker team upgraded to 2.2 and saw a big increase in the size of their mongrels, and much longer start-up times.
In an erector widget it appears that respond_to? checks arity. For example:
self.respond_to?("some_method") # => false
self.respond_to?("some_method", some_value) # => true
Run JavaScript in Selenium tests. Easily.
Here’s the gist of this post: gist.github.com/58876
Ever since I’ve started using Webrat, a lot of the pain of Selenium has gone away
for me. There’s still a little bit of pain though. Part of it is caused by the fact
that it’s harder than it should be to just execute arbitrary bits of JavaScript in
in your current window under test. Well no more. Here’s a helper:
module SeleniumHelpers
# Execute JavaScript in the context of your Selenium window
def run_javascript(javascript)
driver.get_eval <<-JS
(function() {
with(this) {
#{javascript}
}
}).call(selenium.browserbot.getCurrentWindow());
JS
end
private
# If running in regular Selenium context, get_eval is defined on self.
def driver
respond_to?(:selenium) ? send(:selenium) : self
end
end
To use it with Cucumber, do like so:
World do |world|
world.extend(SeleniumHelpers)
world
end
To use it with POS, do like so:
class JavaScriptHelperTest < SeleniumTestCase
include SeleniumHelpers
# your tests go here...
end
Now what?
Now to run JavaScript in your Selenium window, just call run_javascript. Note
that it’s always going to return a String, so you may have to massage the output
a tad:
checked_boxes_count = run_javascript <<-JS
jQuery('input[type=checkbox]:checked').size();
JS
checked_boxes_count # => "3"
checked_boxes_count.to_i # => 3
Cooler stuff
While Webrat’s DSL for traversing web apps is awesome, I’ve always found the
alternatives (Polonium for example) to not jive well with how I think. They’re
way better than talking directly to Selenium, you’re still locked in to a certain
style. The run_javascript helper makes it easier to write your own helpers that
fit your own style.
module ElementHelpers
class Element
def initialize(context, selector)
@context, @selector = context, selector
end
def hide!
call(:hide)
end
def show!
call(:show)
end
def visible?
call(:is, ':visible') == 'true'
end
private
def call(fn, *args)
@context.run_javascript <<-JS
return jQuery(#{@selector.inspect})[#{fn.to_s.inspect}](#{args.map(&:inspect).join(', ')});
JS
end
end
def locate(selector)
Element.new(self, selector)
end
end
Now you can write your tests like so:
class JavaScriptHelperTest < ActiveSupport::TestCase
include SeleniumHelpers
include ElementHelpers
def setup
@element = locate('#all')
end
def test_visible_by_default
assert @element.visible?
end
def test_hide_element
@element.hide!
assert ! @element.visible?
end
def test_show_element
@element.hide! # setup
@element.show!
assert @element.visible?
end
end
Credit should go to Brian Takita, since he did most of the hard work and I just wrote a method. Let me
know if you have any issues or ideas with the helper, and may all your tests be green.
Parselets and SelectorGadget
Andrew Cantino and Kyle Maxwell talk about Parselets.com, a cross-language toolset for developer-generated APIs, and SelectorGadget, their bookmarklet that finds the minimal CSS selector for elements on the page.
Hoptoad: Ride the Toad
Tammer Saleh of thoughtbot demonstrates Hoptoad, their Rails exception notification service. By aggregating repeat error notifications Hoptoad stops the email onslaught from a production bug while still providing appropriate notification and escalation.
Engine Yard Solo
Ezra Zygmuntowicz of Engine Yard demonstrates Solo, their new cloud offering for the deployment and management of lightweight Rails, Merb, or Rack apps.
Standup 03/04/2009
Interesting Things
Integer("008") != "008".to_i
The
to_imethod is what you want, unless you want exceptions or octal numbers.Somebody needed help constructing a
named_scopewhere they could reference the count of an associatedhas_manyassociation. There was some grumbling about using:joinsand:group(and if you do this, be sure not to callcounton the scope itself without also doing a:select => 'DISTINCT primary_key'). The winning solution was to just put a counter_cache on the association and use the denormalized column instead.
Standup 03/03/2009
Interesting Things
Somebody was seeing mongrels hang when using an older copy of the S3 gem. It turned out the older version had the option for persistent connections defaulting to true. Setting
:persistent => falseor using a newer version that hasfalseas the default fixed their problemOne of our sites was seeing a unbalanced distribution of requests despite the fact that the load balancer was evenly distributing connections. One host typically had 2x the traffic of the others, and it would switch every few hours to be a different host. It turned out to be the Google crawler, which uses a keepalive, getting stuck on a single host and making a lot of requests. The load balancer is only able to balance TCP connections, which Google is only using a single one of. The likely solution will be haproxy or something similar in front of the hosts to better distribute traffic.
Standup 03/02/2009
Interesting Things
Tired of refreshing your page to view changes in your CSS? Erik Hanson has a bookmarklet you can use without refreshing your page. See it on his blog.
There is a beta version of the Selenium 1.1.15 gem that includes the latest selenium-server.jar (1.0 beta-2). This fixes some problems with using Firefox 3. You can get the gem here, and you can read the details here.