whoa selenium running works

This commit is contained in:
John Bintz 2012-02-23 16:12:00 -05:00
parent 45b1c44e5b
commit af77c8f1b3
11 changed files with 222 additions and 59 deletions

View File

@ -5,7 +5,7 @@ require 'flowerbox-delivery'
require 'thor' require 'thor'
class Flowerbox::CLI < Thor class Flowerbox::CLI < Thor
desc "test DIR SPEC_PATTERN", "Run the specs found in spec dir" desc "test DIR", "Run the specs found in spec dir, loading spec_helper.rb for configuration details"
method_options :pwd => :string method_options :pwd => :string
def test(dir) def test(dir)
Dir.chdir(pwd) do Dir.chdir(pwd) do
@ -15,18 +15,17 @@ class Flowerbox::CLI < Thor
Tilt::CoffeeScriptTemplate.default_bare = Flowerbox.bare_coffeescript Tilt::CoffeeScriptTemplate.default_bare = Flowerbox.bare_coffeescript
sprockets = Flowerbox::Delivery::SprocketsHandler.new(:asset_paths => [ dir, Flowerbox.asset_paths ].flatten) sprockets = Flowerbox::Delivery::SprocketsHandler.new(:asset_paths => [ Flowerbox.path.join("lib/assets/javascripts"), dir, Flowerbox.asset_paths ].flatten)
Flowerbox.load_test_environment(sprockets) Flowerbox.test_environment.inject_into(sprockets)
Flowerbox.spec_patterns.each do |pattern| Flowerbox.spec_patterns.each do |pattern|
Dir[File.join(dir, pattern)].each do |file| Dir[File.join(dir, pattern)].each do |file|
sprockets.add(file.gsub(dir + '/', '')) sprockets.add(file.gsub(dir + '/', ''))
end end
end end
exit Flowerbox::Runner::Node.run(sprockets.files) exit Flowerbox.runner_environment.run(sprockets)
end end
end end

View File

@ -1,14 +1,5 @@
Feature: Basic Run Feature: Basic Run
Scenario: Use the Node runner using Jasmine Background:
Given I have the file "spec/javascripts/spec_helper.rb" with the content:
"""
Flowerbox.configure do |c|
c.test_with :jasmine
c.spec_patterns << "**/*_spec.*"
c.asset_paths << "lib"
c.bare_coffeescript = true
end
"""
Given I have the file "spec/javascripts/cat_spec.js.coffee" with the content: Given I have the file "spec/javascripts/cat_spec.js.coffee" with the content:
""" """
#= require cat #= require cat
@ -25,6 +16,39 @@ Feature: Basic Run
class Cat class Cat
meow: -> "meow" meow: -> "meow"
""" """
Scenario: Use the Node runner using Jasmine
Given I have the file "spec/javascripts/spec_helper.rb" with the content:
"""
Flowerbox.configure do |c|
c.test_with :jasmine
c.run_with :node
c.spec_patterns << "**/*_spec.*"
c.asset_paths << "lib"
c.bare_coffeescript = true
c.test_environment.reporters << "SimpleNodeReporter"
end
"""
When I run Flowerbox with "spec/javascripts"
Then I should have 1 test and 0 failures
Scenario: Use the Selenium runner using Jasmine
Given I have the file "spec/javascripts/spec_helper.rb" with the content:
"""
Flowerbox.configure do |c|
c.test_with :jasmine
c.run_with :selenium
c.runner_environment.browser = :firefox
c.spec_patterns << "**/*_spec.*"
c.asset_paths << "lib"
c.bare_coffeescript = true
c.test_environment.reporters << "SimpleSeleniumReporter"
end
"""
When I run Flowerbox with "spec/javascripts" When I run Flowerbox with "spec/javascripts"
Then I should have 1 test and 0 failures Then I should have 1 test and 0 failures

View File

@ -21,4 +21,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'flowerbox-delivery' gem.add_dependency 'flowerbox-delivery'
gem.add_dependency 'thor' gem.add_dependency 'thor'
gem.add_dependency 'capybara'
gem.add_dependency 'sinatra'
end end

View File

@ -0,0 +1,9 @@
class jasmine.SimpleNodeReporter
reportRunnerResults: (runner) ->
console.log(runner.results().totalCount + '/' + runner.results().failedCount)
if runner.results().failedCount == 0
process.exit(0)
else
process.exit(1)

View File

@ -0,0 +1,6 @@
class jasmine.SimpleSeleniumReporter
reportRunnerResults: (runner) ->
xhr = new XMLHttpRequest()
xhr.open("POST", "/results")
xhr.send(runner.results().totalCount + '/' + runner.results().failedCount)

View File

@ -3,6 +3,8 @@ require "flowerbox/version"
module Flowerbox module Flowerbox
module Runner module Runner
autoload :Node, 'flowerbox/runner/node' autoload :Node, 'flowerbox/runner/node'
autoload :Selenium, 'flowerbox/runner/selenium'
autoload :Base, 'flowerbox/runner/base'
end end
class << self class << self
@ -15,16 +17,18 @@ module Flowerbox
end end
def test_with(what) def test_with(what)
@test_with = what require "flowerbox/test_environment/#{what}"
end end
def load_test_environment(sprockets) def run_with(what)
require "flowerbox/test_environment/#{@test_with}" require "flowerbox/runner/#{what}"
Flowerbox.test_environment.inject_into(sprockets)
end end
attr_accessor :test_environment, :bare_coffeescript def path
Pathname(File.expand_path('../..', __FILE__))
end
attr_accessor :test_environment, :runner_environment, :bare_coffeescript
def configure def configure
yield self yield self

View File

@ -0,0 +1,20 @@
module Flowerbox
module Runner
class Base
attr_reader :sprockets
def run(sprockets)
@sprockets = sprockets
end
def type
self.class.name.to_s.split('::').last.downcase.to_sym
end
def start_test_environment
Flowerbox.test_environment.start_for(type)
end
end
end
end

View File

@ -2,16 +2,10 @@ require 'tempfile'
module Flowerbox module Flowerbox
module Runner module Runner
class Node class Node < Base
def self.run(files) def run(sprockets)
new(files).run super
end
def initialize(files)
@files = files
end
def run
file = Tempfile.new("node") file = Tempfile.new("node")
file.print template file.print template
file.close file.close
@ -22,23 +16,28 @@ module Flowerbox
end end
def template def template
env = start_test_environment
<<-JS <<-JS
var fs = require('fs'); var fs = require('fs'),
var window = this; vm = require('vm');
// expand the sandbox a bit
var context = function() {};
context.window = true;
for (method in global) { context[method] = global[method]; }
#{template_files.join("\n")} #{template_files.join("\n")}
#{start_test_environment} #{env}
JS JS
end end
def template_files def template_files
@files.collect { |file| %{eval(fs.readFileSync('#{file}', 'utf-8'));} } sprockets.files.collect { |file| %{vm.runInNewContext(fs.readFileSync('#{file}', 'utf-8'), context, '#{file}');} }
end
def start_test_environment
Flowerbox.test_environment.start_for(:node)
end end
end end
end end
end end
Flowerbox.runner_environment = Flowerbox::Runner::Node.new

View File

@ -0,0 +1,92 @@
require 'capybara'
require 'capybara/dsl'
require 'sinatra'
require 'thread'
module Flowerbox
module Runner
class Selenium < Base
include Capybara::DSL
class Rack < Sinatra::Base
class << self
attr_accessor :runner
end
def runner
self.class.runner
end
post '/results' do
runner.results = request.env['rack.input'].read
end
get %r{^/__F__(/.*)$} do |file|
File.read(file)
end
get '/' do
runner.template
end
end
attr_accessor :browser, :results
def run(sprockets)
super
Capybara.register_driver :firefox do |app|
Capybara::Selenium::Driver.new(app, :browser => :firefox)
end
Capybara.default_driver = :firefox
Rack.runner = self
Capybara.app = Rack
visit '/'
1.upto(30) do
if results
break
else
sleep 1
end
end
if results
puts results
exit (results.split('/').last.to_i == 0) ? 0 : 1
else
exit 1
end
end
def template
env = start_test_environment
<<-HTML
<html>
<head>
<title>Flowerbox - Selenium Runner</title>
#{template_files.join("\n")}
</head>
<body>
<h1>Flowerbox - Selenium Runner</h1>
<script type="text/javascript">
#{env}
</script>
</body>
</html>
HTML
end
def template_files
sprockets.files.collect { |file| %{<script type="text/javascript" src="/__F__#{file}"></script>} }
end
end
end
end
Flowerbox.runner_environment = Flowerbox::Runner::Selenium.new

View File

@ -3,37 +3,45 @@ require 'jasmine-core'
module Flowerbox module Flowerbox
module TestEnvironment module TestEnvironment
class Jasmine class Jasmine
def self.inject_into(sprockets) def inject_into(sprockets)
sprockets.append_path(::Jasmine::Core.path) @sprockets = sprockets
sprockets.add('jasmine.js') @sprockets.append_path(::Jasmine::Core.path)
sprockets.add('jasmine-html.js')
@sprockets.add('jasmine.js')
@sprockets.add('jasmine-html.js')
end end
def self.start_for(runner) def start_for(runner)
@sprockets.add("flowerbox/jasmine/#{runner}")
case runner
when :node
<<-JS <<-JS
jasmine.NodeReporter = function() {} var jasmine = context.jasmine;
jasmine.NodeReporter.prototype.reportSpecResults = function(spec) { #{jasmine_reporters.join("\n")}
console.log(spec.results().totalCount + '/' + spec.results().failedCount); jasmine.getEnv().execute();
JS
if (spec.results().failedCount == 0) { when :selenium
process.exit(0); <<-JS
} else { jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
process.exit(1); jasmine.getEnv().addReporter(new jasmine.SimpleSeleniumReporter());
}
}
jasmine.NodeReporter.prototype.reportRunnerResults = function(runner) {
}
jasmine.getEnv().addReporter(new jasmine.NodeReporter());
jasmine.getEnv().execute(); jasmine.getEnv().execute();
JS JS
end end
end end
def jasmine_reporters
reporters.collect { |reporter| %{jasmine.getEnv().addReporter(new jasmine.#{reporter}());} }
end
def reporters
@reporters ||= []
end
end
end end
end end
Flowerbox.test_environment = Flowerbox::TestEnvironment::Jasmine Flowerbox.test_environment = Flowerbox::TestEnvironment::Jasmine.new