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.
About the Author