whoa more stuff and it works in production projects
This commit is contained in:
parent
0529359352
commit
e6bdbf6313
@ -5,10 +5,18 @@ require 'thor'
|
|||||||
|
|
||||||
class Flowerbox::CLI < Thor
|
class Flowerbox::CLI < Thor
|
||||||
desc "test DIR", "Run the specs found in spec dir, loading spec_helper.rb for configuration details"
|
desc "test DIR", "Run the specs found in spec dir, loading spec_helper.rb for configuration details"
|
||||||
method_options :pwd => :string, :runners => :string, :verbose_server => false
|
method_options :pwd => :string, :runners => :string, :runner => :string, :verbose_server => false
|
||||||
def test(dir = "spec/javascripts")
|
def test(dir = "spec/javascripts")
|
||||||
Dir.chdir(pwd) do
|
Dir.chdir(pwd) do
|
||||||
exit Flowerbox.run(dir, options)
|
exit Flowerbox.run(dir, options.dup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "debug DIR", "Start the Flowerbox server to help debug loading issues."
|
||||||
|
method_options :pwd => :string, :runners => :string, :runner => :string, :verbose_server => false
|
||||||
|
def debug(dir = "spec/javascripts")
|
||||||
|
Dir.chdir(pwd) do
|
||||||
|
Flowerbox.debug(dir, options.dup)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,32 +4,28 @@
|
|||||||
#
|
#
|
||||||
Flowerbox =
|
Flowerbox =
|
||||||
baseUrl: '/'
|
baseUrl: '/'
|
||||||
|
debug: false
|
||||||
ping: ->
|
ping: ->
|
||||||
Flowerbox.contact('ping')
|
Flowerbox.contact('ping')
|
||||||
|
|
||||||
pause: (time) ->
|
|
||||||
t = (new Date()).getTime()
|
|
||||||
|
|
||||||
while (t + time) > (new Date().getTime())
|
|
||||||
Flowerbox.ping()
|
|
||||||
|
|
||||||
contact: (url, data...) ->
|
contact: (url, data...) ->
|
||||||
attempts = 3
|
if !Flowerbox.debug
|
||||||
|
attempts = 3
|
||||||
|
|
||||||
doContact = ->
|
doContact = ->
|
||||||
attempts -= 1
|
attempts -= 1
|
||||||
|
|
||||||
try
|
try
|
||||||
xhr = new XMLHttpRequest()
|
xhr = new XMLHttpRequest()
|
||||||
xhr.open("POST", Flowerbox.baseUrl + url, false)
|
xhr.open("POST", Flowerbox.baseUrl + url, false)
|
||||||
xhr.setRequestHeader("Accept", "application/json")
|
xhr.setRequestHeader("Accept", "application/json")
|
||||||
xhr.send(JSON.stringify(data))
|
xhr.send(JSON.stringify(data))
|
||||||
catch e
|
catch e
|
||||||
if attempts == 0
|
if attempts == 0
|
||||||
throw e
|
throw e
|
||||||
else
|
else
|
||||||
doContact()
|
doContact()
|
||||||
|
|
||||||
doContact()
|
doContact()
|
||||||
fail: ->
|
fail: ->
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class Flowerbox.Exception
|
class Flowerbox.Exception
|
||||||
constructor: (@stack) ->
|
constructor: (@source, @name, @stack) ->
|
||||||
|
|
||||||
toJSON: ->
|
toJSON: ->
|
||||||
{ trace: { stack: @stack } }
|
{ status: Flowerbox.Result.FAILURE, source: @source, name: @name, trace: { stack: @stack } }
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#= require flowerbox/jasmine/reporter
|
#= require flowerbox/jasmine/reporter
|
||||||
|
|
||||||
|
# because why not?
|
||||||
|
@context = @describe
|
||||||
|
|
||||||
getSplitName = (parts) ->
|
getSplitName = (parts) ->
|
||||||
parts.push(String(@description).replace(/[\n\r]/g, ' '))
|
parts.push(String(@description).replace(/[\n\r]/g, ' '))
|
||||||
parts
|
parts
|
||||||
|
@ -1,4 +1,16 @@
|
|||||||
class jasmine.FlowerboxReporter
|
class jasmine.FlowerboxReporter
|
||||||
|
buildResult: (spec, overrides = {}) ->
|
||||||
|
data =
|
||||||
|
status: Flowerbox.Result.SUCCESS
|
||||||
|
source: 'jasmine'
|
||||||
|
name: spec.getSpecSplitName()
|
||||||
|
file: 'unknown:0'
|
||||||
|
|
||||||
|
for key, value of overrides
|
||||||
|
data[key] = value
|
||||||
|
|
||||||
|
new Flowerbox.Result(data)
|
||||||
|
|
||||||
reportRunnerStarting: (runner) ->
|
reportRunnerStarting: (runner) ->
|
||||||
@time = (new Date()).getTime()
|
@time = (new Date()).getTime()
|
||||||
|
|
||||||
@ -7,17 +19,15 @@ class jasmine.FlowerboxReporter
|
|||||||
Flowerbox.contact("start_test", spec.description)
|
Flowerbox.contact("start_test", spec.description)
|
||||||
|
|
||||||
if spec.description == 'encountered a declaration exception'
|
if spec.description == 'encountered a declaration exception'
|
||||||
Flowerbox.contact("finish_test", new Flowerbox.Exception([ spec.description ]))
|
Flowerbox.contact("finish_test", this.buildResult(spec, status: Flowerbox.Result.FAILURE))
|
||||||
Flowerbox.contact("results", 0)
|
|
||||||
Flowerbox.fail() if Flowerbox.fail?
|
|
||||||
|
|
||||||
reportSpecResults: (spec) ->
|
reportSpecResults: (spec) ->
|
||||||
result = new Flowerbox.Result(status: Flowerbox.Result.SUCCESS, source: 'jasmine', name: spec.getSpecSplitName(), file: 'unknown:0')
|
result = this.buildResult(spec)
|
||||||
|
|
||||||
for item in spec.results().items_
|
for item in spec.results().items_
|
||||||
if !item.passed_
|
if !item.passed_
|
||||||
result.status = Flowerbox.Result.FAILURE
|
result.status = Flowerbox.Result.FAILURE
|
||||||
failure = { runner: Flowerbox.environment, message: item.message, stack: item.trace.stack }
|
failure = { runner: Flowerbox.environment, message: item.message, stack: (item.trace.stack || '').split("\n") }
|
||||||
|
|
||||||
result.failures.push(failure)
|
result.failures.push(failure)
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ require "flowerbox/version"
|
|||||||
require 'flowerbox-delivery'
|
require 'flowerbox-delivery'
|
||||||
require 'rainbow'
|
require 'rainbow'
|
||||||
|
|
||||||
|
module Guard
|
||||||
|
autoload :Flowerbox, 'guard/flowerbox'
|
||||||
|
end
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module CoreExt
|
module CoreExt
|
||||||
autoload :Module, 'flowerbox/core_ext/module'
|
autoload :Module, 'flowerbox/core_ext/module'
|
||||||
@ -35,12 +39,14 @@ module Flowerbox
|
|||||||
|
|
||||||
class << self
|
class << self
|
||||||
attr_writer :reporters
|
attr_writer :reporters
|
||||||
|
attr_accessor :port
|
||||||
|
|
||||||
def reset!
|
def reset!
|
||||||
@spec_patterns = nil
|
@spec_patterns = nil
|
||||||
@spec_files = nil
|
@spec_files = nil
|
||||||
@asset_paths = nil
|
@asset_paths = nil
|
||||||
@reporters = nil
|
@reporters = nil
|
||||||
|
@port = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def spec_patterns
|
def spec_patterns
|
||||||
@ -55,6 +61,10 @@ module Flowerbox
|
|||||||
@reporters ||= []
|
@reporters ||= []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def additional_files
|
||||||
|
@additional_files ||= []
|
||||||
|
end
|
||||||
|
|
||||||
def test_with(what)
|
def test_with(what)
|
||||||
self.test_environment = Flowerbox::TestEnvironment.for(what)
|
self.test_environment = Flowerbox::TestEnvironment.for(what)
|
||||||
end
|
end
|
||||||
@ -90,34 +100,80 @@ module Flowerbox
|
|||||||
@bare_coffeescript ||= true
|
@bare_coffeescript ||= true
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(dir, options = {})
|
def prep(dir, options = {})
|
||||||
reset!
|
reset!
|
||||||
|
|
||||||
load File.join(dir, 'spec_helper.rb')
|
load File.join(dir, 'spec_helper.rb')
|
||||||
|
|
||||||
if options[:runners]
|
|
||||||
Flowerbox.run_with(options[:runners].split(','))
|
|
||||||
end
|
|
||||||
|
|
||||||
require 'coffee_script'
|
require 'coffee_script'
|
||||||
require 'tilt/coffee'
|
require 'tilt/coffee'
|
||||||
|
|
||||||
Tilt::CoffeeScriptTemplate.default_bare = Flowerbox.bare_coffeescript
|
Tilt::CoffeeScriptTemplate.default_bare = Flowerbox.bare_coffeescript
|
||||||
|
|
||||||
|
if runners = options[:runners] || options[:runner]
|
||||||
|
Flowerbox.run_with(runners.split(','))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def debug(dir, options = {})
|
||||||
|
options[:debug] = true
|
||||||
|
|
||||||
|
prep(dir, options)
|
||||||
|
|
||||||
|
env = Flowerbox.runner_environment.first
|
||||||
|
env.setup(build_sprockets_for(dir), spec_files_for(dir), options)
|
||||||
|
|
||||||
|
Flowerbox.reporters.replace([])
|
||||||
|
|
||||||
|
puts "Flowerbox debug server running test prepared for #{env.console_name} on #{env.server.address}"
|
||||||
|
|
||||||
|
env.server.start
|
||||||
|
|
||||||
|
trap('INT') do
|
||||||
|
env.server.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
@restart = false
|
||||||
|
|
||||||
|
trap('QUIT') do
|
||||||
|
puts "Restarting Flowerbox server..."
|
||||||
|
@restart = true
|
||||||
|
env.server.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
while env.server.alive?
|
||||||
|
sleep 0.25
|
||||||
|
end
|
||||||
|
|
||||||
|
if @restart
|
||||||
|
debug(dir, options)
|
||||||
|
else
|
||||||
|
puts "Flowerbox finished."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(dir, options = {})
|
||||||
|
prep(dir, options)
|
||||||
|
|
||||||
result_set = ResultSet.new
|
result_set = ResultSet.new
|
||||||
|
|
||||||
time = 0
|
time = 0
|
||||||
realtime = Time.now.to_i
|
realtime = Time.now.to_i
|
||||||
|
|
||||||
Flowerbox.runner_environment.each do |env|
|
runner_envs = Flowerbox.runner_environment.collect do |env|
|
||||||
env.ensure_configured!
|
env.ensure_configured!
|
||||||
|
|
||||||
result_set << env.run(build_sprockets_for(dir), spec_files_for(dir), options)
|
result_set << env.run(build_sprockets_for(dir), spec_files_for(dir), options)
|
||||||
|
|
||||||
time += env.time
|
time += env.time
|
||||||
|
|
||||||
|
env
|
||||||
end
|
end
|
||||||
|
|
||||||
result_set.print(:time => time, :realtime => Time.now.to_i - realtime)
|
result_set.print(:time => time, :realtime => Time.now.to_i - realtime)
|
||||||
|
|
||||||
|
runner_envs.each(&:cleanup)
|
||||||
|
|
||||||
result_set.exitstatus
|
result_set.exitstatus
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -136,6 +192,8 @@ module Flowerbox
|
|||||||
|
|
||||||
Flowerbox.test_environment.inject_into(sprockets)
|
Flowerbox.test_environment.inject_into(sprockets)
|
||||||
|
|
||||||
|
Flowerbox.additional_files.each { |file| sprockets.add(file) }
|
||||||
|
|
||||||
sprockets
|
sprockets
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,13 +5,17 @@ require 'cgi'
|
|||||||
module Flowerbox
|
module Flowerbox
|
||||||
class Rack < Sinatra::Base
|
class Rack < Sinatra::Base
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :runner
|
attr_accessor :runner, :sprockets
|
||||||
end
|
end
|
||||||
|
|
||||||
def runner
|
def runner
|
||||||
self.class.runner
|
self.class.runner
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sprockets
|
||||||
|
self.class.sprockets
|
||||||
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
JSON.parse(request.body.string)
|
JSON.parse(request.body.string)
|
||||||
end
|
end
|
||||||
@ -44,11 +48,16 @@ module Flowerbox
|
|||||||
runner.ping
|
runner.ping
|
||||||
end
|
end
|
||||||
|
|
||||||
get %r{^/__F__(/.*)$} do |file|
|
get %r{^/__F__/(.*)$} do |file|
|
||||||
File.read(file)
|
asset = sprockets.asset_for(file, :bundle => false)
|
||||||
|
|
||||||
|
content_type asset.content_type
|
||||||
|
asset.body
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
|
sprockets.expire_index!
|
||||||
|
|
||||||
runner.template
|
runner.template
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,22 +9,26 @@ module Flowerbox::Reporter
|
|||||||
end
|
end
|
||||||
|
|
||||||
def report_progress(result)
|
def report_progress(result)
|
||||||
result.name.each_with_index do |name, index|
|
if result.name
|
||||||
if @name_stack[index] != name
|
result.name.each_with_index do |name, index|
|
||||||
if name != result.name.last
|
if @name_stack[index] != name
|
||||||
message = name
|
if name != result.name.last
|
||||||
else
|
message = name
|
||||||
message = self.send("progress_#{result.type}", result)
|
else
|
||||||
if !(file_display = path_for(result)).empty?
|
message = self.send("progress_#{result.type}", result)
|
||||||
message << " # #{file_display}"
|
if !(file_display = path_for(result)).empty?
|
||||||
|
message << " # #{file_display}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
puts indent(message, index)
|
||||||
end
|
end
|
||||||
|
|
||||||
puts indent(message, index)
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
@name_stack = result.name.dup
|
@name_stack = result.name.dup
|
||||||
|
else
|
||||||
|
puts result.data
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def progress_skipped(result)
|
def progress_skipped(result)
|
||||||
|
@ -11,6 +11,7 @@ module Flowerbox
|
|||||||
end
|
end
|
||||||
|
|
||||||
autoload :Base, 'flowerbox/result/base'
|
autoload :Base, 'flowerbox/result/base'
|
||||||
|
autoload :Exception, 'flowerbox/result/exception'
|
||||||
autoload :Failure, 'flowerbox/result/failure'
|
autoload :Failure, 'flowerbox/result/failure'
|
||||||
autoload :Pending, 'flowerbox/result/pending'
|
autoload :Pending, 'flowerbox/result/pending'
|
||||||
autoload :FailureMessage, 'flowerbox/result/failure_message'
|
autoload :FailureMessage, 'flowerbox/result/failure_message'
|
||||||
|
@ -18,8 +18,12 @@ module Flowerbox
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(sprockets, spec_files, options)
|
def setup(sprockets, spec_files, options)
|
||||||
@sprockets, @spec_files, @options = sprockets, spec_files, options
|
@sprockets, @spec_files, @options = sprockets, spec_files, options
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(*args)
|
||||||
|
setup(*args)
|
||||||
|
|
||||||
@count = 0
|
@count = 0
|
||||||
|
|
||||||
@ -41,6 +45,10 @@ module Flowerbox
|
|||||||
def configure
|
def configure
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def debug?
|
||||||
|
options[:debug] == true
|
||||||
|
end
|
||||||
|
|
||||||
def ensure_configured!
|
def ensure_configured!
|
||||||
if !configured?
|
if !configured?
|
||||||
puts "#{console_name} is not configured for this project, configuring now..."
|
puts "#{console_name} is not configured for this project, configuring now..."
|
||||||
@ -65,9 +73,11 @@ module Flowerbox
|
|||||||
|
|
||||||
server_options = { :app => Flowerbox::Rack }
|
server_options = { :app => Flowerbox::Rack }
|
||||||
server_options[:logging] = true if options[:verbose_server]
|
server_options[:logging] = true if options[:verbose_server]
|
||||||
|
server_options[:port] = Flowerbox.port
|
||||||
|
|
||||||
@server = Flowerbox::Delivery::Server.new(server_options)
|
@server = Flowerbox::Delivery::Server.new(server_options)
|
||||||
Flowerbox::Rack.runner = self
|
Flowerbox::Rack.runner = self
|
||||||
|
Flowerbox::Rack.sprockets = @sprockets
|
||||||
|
|
||||||
@server
|
@server
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ class Flowerbox::Runner::Chrome < Flowerbox::Runner::Selenium
|
|||||||
end
|
end
|
||||||
|
|
||||||
def browser
|
def browser
|
||||||
:chrome
|
@browser ||= ::Selenium::WebDriver.for(:chrome)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class Flowerbox::Runner::Firefox < Flowerbox::Runner::Selenium
|
|||||||
end
|
end
|
||||||
|
|
||||||
def browser
|
def browser
|
||||||
:firefox
|
@browser ||= ::Selenium::WebDriver.for(:firefox)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ module Flowerbox
|
|||||||
File.directory?(File.join(Dir.pwd, 'node_modules/cucumber'))
|
File.directory?(File.join(Dir.pwd, 'node_modules/cucumber'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cleanup ; end
|
||||||
|
|
||||||
def configure
|
def configure
|
||||||
system %{bash -c "mkdir -p node_modules && npm link jsdom && npm link xmlhttprequest && npm link cucumber"}
|
system %{bash -c "mkdir -p node_modules && npm link jsdom && npm link xmlhttprequest && npm link cucumber"}
|
||||||
end
|
end
|
||||||
@ -73,7 +75,7 @@ jsdom.env(
|
|||||||
var options = {
|
var options = {
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
port: #{server.port},
|
port: #{server.port},
|
||||||
path: "/__F__" + file,
|
path: "/__F__/" + file,
|
||||||
method: "GET"
|
method: "GET"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ require 'selenium-webdriver'
|
|||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Runner
|
module Runner
|
||||||
class Selenium < Base
|
class Selenium < Base
|
||||||
|
|
||||||
def name
|
def name
|
||||||
raise StandardError.new("Override me")
|
raise StandardError.new("Override me")
|
||||||
end
|
end
|
||||||
@ -12,17 +11,19 @@ module Flowerbox
|
|||||||
:selenium
|
:selenium
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cleanup
|
||||||
|
@browser.close if @browser
|
||||||
|
end
|
||||||
|
|
||||||
|
def browser
|
||||||
|
raise StandardError.new("Define a browser")
|
||||||
|
end
|
||||||
|
|
||||||
def run(sprockets, spec_files, options)
|
def run(sprockets, spec_files, options)
|
||||||
super do
|
super do
|
||||||
begin
|
browser.navigate.to "http://localhost:#{server.port}/"
|
||||||
selenium = ::Selenium::WebDriver.for(browser)
|
|
||||||
|
|
||||||
selenium.navigate.to "http://localhost:#{server.port}/"
|
ensure_alive
|
||||||
|
|
||||||
ensure_alive
|
|
||||||
ensure
|
|
||||||
selenium.quit if selenium
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -50,13 +51,13 @@ console.log = function(msg) {
|
|||||||
<body>
|
<body>
|
||||||
<h1>Flowerbox - #{Flowerbox.test_environment.name} Runner</h1>
|
<h1>Flowerbox - #{Flowerbox.test_environment.name} Runner</h1>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Flowerbox.environment = '#{browser}';
|
Flowerbox.environment = '#{name}';
|
||||||
|
|
||||||
var context = this;
|
var context = this;
|
||||||
|
|
||||||
window.onload = function() {
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
#{env}
|
#{env}
|
||||||
};
|
}, false);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -64,7 +65,7 @@ HTML
|
|||||||
end
|
end
|
||||||
|
|
||||||
def template_files
|
def template_files
|
||||||
sprockets.files.collect { |file| %{<script type="text/javascript" src="/__F__#{file}"></script>} }
|
sprockets.files.collect { |file| %{<script type="text/javascript" src="/__F__/#{file.logical_path}"></script>} }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
23
lib/guard/flowerbox.rb
Normal file
23
lib/guard/flowerbox.rb
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
require 'guard'
|
||||||
|
require 'guard/guard'
|
||||||
|
|
||||||
|
module Guard
|
||||||
|
class Flowerbox < ::Guard::Guard
|
||||||
|
def initialize(watchers = [], options = {})
|
||||||
|
@options = options
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
puts "Starting Guard::Flowerbox..."
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_all
|
||||||
|
::Flowerbox.run(@options[:dir], @options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_on_change(files = [])
|
||||||
|
::Flowerbox.run(@options[:dir], @options.merge(:files => files))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user