SeleniumRC spec

Selenium on Railsもいいけど、やっぱり、Rspecに全部統合したいわけですよ。あと、全部Rakeから自動でやりたい。で、SeleniumRCの呼び出しをRSpecに統合してみた。

2007-03-05追記。@selenium.stopを忘れてました。

2007-11-20追記。RSpecの新記法/新実装に対応した 新しいバージョン を作りました。

script/selenium/にselenium-server.jarを置いておいて、

def selenium_context(*args, &block)
  context(*args) do  
    context_setup do 
      @selenium_pid = Process.fork do
        $stdin.reopen(File.open('/dev/null'))
        $stdout.reopen(File.open(File.join(RAILS_ROOT, 'log', 'seleniumrc'), 'a'))
        $stderr.reopen(File.open(File.join(RAILS_ROOT, 'log', 'seleniumrc.err'), 'a'))
        exec 'java', '-jar', File.join(RAILS_ROOT, 'script', 'selenium', 'selenium-server.jar')
      end
      @server_pid = Process.fork do
        exec File.join(RAILS_ROOT, 'script', 'server'), *%w[-p 4545 -e test]
      end
      sleep 0.5 # サーバーが起動するまで適当に待機
      @verification_errors = []
      @selenium = Selenium::SeleneseInterpreter.new("localhost", 4444, "*firefox", "http://localhost:4545", 10000)
      @selenium.start
      @selenium.set_context("test_new", "info")
      @selenium.instance_eval do
        def method_missing(msg, *args)
          if self.respond_to?("get_#{msg}")
            self.__send__("get_#{msg}", *args)
          else
            super
          end
        end
      end 
    end
    context_teardown do
      @selenium.stop if @selenium rescue nil
      Process.kill :INT, @selenium_pid  if @selenium_pid rescue nil
      Process.kill :INT, @server_pid if @server_pid rescue nil
      Process.waitall
      @verification_errors.should_be == []
    end
    instance_eval(&block)
  end
end

spec_helper.rbにこんな風に書いておいて、specのほうは、

require File.dirname(__FILE__) + '/../spec_helper'
require "selenium"
selenium_context 'Hogeのとき' do
  setup do
    @selenium.open('/hoge/')
  end 
  specify '表題' do
    @selenium.title.should_be == 'huga'
  end
end

ついでに Rakefile

namespace 'spec' do
  Spec::Rake::SpecTask.new(:selenium => "db:test:prepare") do |t|
    t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
    t.spec_files = FileList['spec/selenium/**/*_spec.rb']
  end
end
task :spec => 'spec:selenium'