From c0f10818e0c58dbf7af1404247709356046bd96e Mon Sep 17 00:00:00 2001 From: Rada Bogdan Raul Date: Fri, 12 Aug 2016 15:21:58 +0300 Subject: [PATCH] jasmine 2.0 support and junit formatter for legacy version , also updated reporters to add more info and also the console output to ressemble more with Rspec --- Gemfile | 6 + README.md | 88 ++++++++- Rakefile | 53 +++++- .../jasminerice_legacy_reporter.js.coffee | 62 +++++++ .../jasminerice_reporter.js.coffee | 69 +++++++ .../jasminerice_runner_base.js.coffee | 90 +++++++++ jasminerice-runner.gemspec | 59 ++++-- .../jasminerice_reporter.js.coffee | 25 --- lib/jasminerice-runner.rb | 39 +++- lib/jasminerice-runner/configuration.rb | 25 +++ lib/jasminerice-runner/engine.rb | 14 ++ .../formatters/legacy_junit_xml.rb | 77 ++++++++ lib/jasminerice-runner/runner.rb | 85 --------- .../tasks/jasminerice-runner.rake | 10 + lib/jasminerice-runner/version.rb | 31 +++- lib/jasminerice-runner/worker.rb | 171 ++++++++++++++++++ lib/tasks/jasminerice-runner.rake | 10 - 17 files changed, 758 insertions(+), 156 deletions(-) create mode 100644 app/assets/javascripts/jasminerice_legacy_reporter.js.coffee create mode 100644 app/assets/javascripts/jasminerice_reporter.js.coffee create mode 100644 app/assets/javascripts/jasminerice_runner_base.js.coffee delete mode 100644 lib/assets/javascripts/jasminerice_reporter.js.coffee create mode 100644 lib/jasminerice-runner/configuration.rb create mode 100644 lib/jasminerice-runner/engine.rb create mode 100644 lib/jasminerice-runner/formatters/legacy_junit_xml.rb delete mode 100644 lib/jasminerice-runner/runner.rb create mode 100644 lib/jasminerice-runner/tasks/jasminerice-runner.rake create mode 100644 lib/jasminerice-runner/worker.rb delete mode 100644 lib/tasks/jasminerice-runner.rake diff --git a/Gemfile b/Gemfile index d6fc253..e4f58bd 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,9 @@ source "http://rubygems.org" # Specify your gem's dependencies in jasminerice-runner.gemspec gemspec + +if RUBY_VERSION >= '2.2.0' + gem 'rack', '>= 1.0', '>= 1.0' +else + gem 'rack', '>= 1.0', '< 2.0' +end diff --git a/README.md b/README.md index 51df852..5808d03 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,98 @@ jasminerice-runner ================== +**The original repo hasn't been updated in 4 years , this fork though tries to keep up-to-date with latest updates.** + Uses capybara to run jasmine specs with jasminerice and rails asset pipeline -Usage ------ +Requirements +------------ + +1. [capybara >= 2.0](https://github.com/celluloid/celluloid) +2. [jasminerice >= 0.0.10](https://github.com/jwo/celluloid-pmap) +3. [jasmine >= 1.1](https://github.com/bogdanRada/celluloid_pubsub) +4. [nokogiri >= 1.6](https://github.com/swoop-inc/composable_state_machine) +5. [colorize >= 0.8](https://github.com/tj/terminal-table) +6. [coffee-script >= 2.0](https://github.com/fazibear/colorize) + +Compatibility +------------- + +Rails 4.0 or greater ( currently this was tested only with Rails), but i can accept pull requests for other rack-based applications +[MRI >= 2.0](http://www.ruby-lang.org) + +Rubinius, Jruby, MRI 1.8, MRI 1.9 are not officially supported. + +Installation Instructions +------------------------- Add it to your Gemfile gem "jasminerice-runner" - -Add this to your spec.js: +Usage +----- + +For Jasmine <2.0 add this to your spec.js: + +```coffee + #= require jasminerice_runner_base + #= require jasminerice_legacy_reporter +``` + +For Jasmine > 2.0 add this to your spec.js: + +```coffee + #= require jasminerice_runner_base #= require jasminerice_reporter - +``` + + Then, run the rake task +```sh rake jasminerice:run - +``` To switch drivers, in a config/initializer - Jasminerice::Runner.capybara_driver = :webkit - -Default driver is :selenium +```ruby + Jasminerice::Runner.configure do |config| + # you can use any other driver (phantomjs, or other drivers) + config.capybara_driver = :webkit + + # For Jasmine < 2.0, this gem also provides a Junit XML formatter ( for Jasmine > 2.0 this will have no effect ) + # If you want to enable the JUNIT XML Formatter you need to specify `:junit_xml` + # By Default this is set to nil, however if the environment variable CI is present and has as value 'true', + # and you are using Jasmine < 2.0, this will be automatically set to :junit_xml + # unless of course this is not overidden in a initializer + config.formatters = nil + + # For Jasmine < 2.0, this gem also provides a Junit XML formatter ( for Jasmine > 2.0 this will have no effect ) + config.junit_xml_path = File.join(Dir.pwd, 'spec', 'reports') + end +``` + + +**Default driver is :selenium*** + + +Using other formatters for Jasmine > 2.0 +----------------------------------- + + Starting with version 2.0 , Jasmine supports custom formatters by using this configuration: + + +```ruby + + Jasmine.configure do |config| + config.formatters << Jasmine::Formatters::JunitXml + end +``` + +Put this configuration in a file located in **config/initializers**. + +But in order for this to work , you will have to add the gem **jasmine_junitxml_formatter** to your Gemfile + Using Multiple Jasmine Environments ----------------------------------- diff --git a/Rakefile b/Rakefile index 2995527..d7b4583 100644 --- a/Rakefile +++ b/Rakefile @@ -1 +1,52 @@ -require "bundler/gem_tasks" +require 'bundler/setup' +require 'bundler/gem_tasks' +require 'appraisal' +require 'rspec/core/rake_task' +require 'coveralls/rake/task' +require 'yard' +Coveralls::RakeTask.new + +RSpec::Core::RakeTask.new(:spec) do |spec| + default_options = ['--colour'] + default_options.concat(['--backtrace', '--fail-fast']) if ENV['DEBUG'] + spec.rspec_opts = default_options + spec.verbose = true +end + +YARD::Config.options[:load_plugins] = true +YARD::Config.load_plugins + +# dirty hack for YardocTask +::Rake.application.class.class_eval do + alias_method :last_comment, :last_description +end + +YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb', 'spec/**/*_spec.rb'] # optional + t.options = ['--any', '--extra', '--opts', '--markup-provider=redcarpet', '--markup=markdown', '--debug'] # optional + t.stats_options = ['--list-undoc'] # optional +end + +desc 'Default: run the unit tests.' +task default: [:all] + +desc 'Test the plugin under all supported Rails versions.' +task :all do |_t| + if ENV['TRAVIS'] + # require 'json' + # puts JSON.pretty_generate(ENV.to_hash) + if ENV['BUNDLE_GEMFILE'] =~ /gemfiles/ + appraisal_name = ENV['BUNDLE_GEMFILE'].scan(/rails\_(.*)\.gemfile/).flatten.first + command_prefix = "appraisal rails-#{appraisal_name}" + exec("#{command_prefix} bundle install && #{command_prefix} bundle exec rspec && bundle exec rake coveralls:push ") + else + exec(' bundle exec appraisal install && bundle exec rake appraisal spec && bundle exec rake coveralls:push') + end + else + exec('bundle exec appraisal install && bundle exec rake appraisal spec') + end +end + +task :docs do + exec('bundle exec inch --pedantic && bundle exec yard --list-undoc') +end diff --git a/app/assets/javascripts/jasminerice_legacy_reporter.js.coffee b/app/assets/javascripts/jasminerice_legacy_reporter.js.coffee new file mode 100644 index 0000000..70e63d1 --- /dev/null +++ b/app/assets/javascripts/jasminerice_legacy_reporter.js.coffee @@ -0,0 +1,62 @@ +#= require ./jasminerice_runner_base +class JasminericeLegacyReporter extends window.JasminericeRunnerBase + constructor : -> + super + + reportRunnerStarting: (runner) -> + super(runner) + + reportRunnerResults: (runner) -> + @finished = true + + reportSpecResults: (spec) -> + spec_result = if spec.results().failedCount > 0 then "failed" else "passed" + spec_id = spec.id + @totalCount++ + @results_[spec_id] = { + 'status': spec_result + 'messages': spec.results().getItems(), + 'id': spec_id, + 'description': spec.description, + 'suite': spec.suite, + 'full_name': spec.getFullName() + } + @final_results_[spec_id] = @.summarizeResult_(spec, @results_[spec_id]) + if spec_result == 'failed' + @failedCount++ + @failedSpecs.push(@final_results_[spec_id]) + + resultsForSpecs : (specIds) -> + results = {} + for i in [0...specIds.length] + specId = specIds[i] + results[specId] = @.summarizeResult_(specIds[i], @results_[specId]) + results + + summarizeResult_ : (spec, result) -> + summaryMessages = [] + for messageIndex in [0...result.messages.length] + resultMessage = result.messages[messageIndex] + summaryMessages.push({ + 'status': if resultMessage.passed then resultMessage.passed() else true, + 'message': resultMessage.message, + 'matcherName': resultMessage.matcherName, + 'expected': ''+resultMessage.expected, + 'actual': ''+resultMessage.actual, + 'trace': { + 'stack': if resultMessage.passed && !resultMessage.passed() then resultMessage.trace.stack else jasmine.undefined + } + }) + { + 'id': result.id, + 'status': result.status + 'name': result.full_name, + 'description': result.description + 'messages': summaryMessages, + 'suite_name': @.getFullDescOfSuite(result.suite), + } + +# make sure this exists so we don't have timing issue +# when capybara hits us before the onload function has run +window.jasmineRiceReporter = new JasminericeLegacyReporter() +window.jasmineRiceReporter.register() diff --git a/app/assets/javascripts/jasminerice_reporter.js.coffee b/app/assets/javascripts/jasminerice_reporter.js.coffee new file mode 100644 index 0000000..b0fdfbc --- /dev/null +++ b/app/assets/javascripts/jasminerice_reporter.js.coffee @@ -0,0 +1,69 @@ +#= require ./jasminerice_runner_base +class JasminericeReporter extends window.JasminericeRunnerBase + constructor : -> + super + @runner_results = [] + + jasmineStarted: (suiteInfo) -> + @started = true + @failedSpecs = [] + @totalCount = 0 + @failedCount = 0 + #@.log('Running suite with ' + suiteInfo.totalSpecsDefined) + + suiteStarted: (result) -> + @suites_[suite.id] = @.summarize_(result) + #@.log('Suite started: ' + result.description + ' whose full description is: ' + result.fullName) + + specStarted: (result) -> + #@.log('Spec started: ' + result.description + ' whose full description is: ' + result.fullName) + + specDone: (spec) -> + spec_result = if spec.failedExpectations.length > 0 then "failed" else "passed" + spec_id = spec.id + @totalCount++ + @results_[spec_id] = { + 'status': spec_result + 'messages': spec.failedExpectations, + 'id': spec_id, + 'description': spec.description, + 'full_name': spec.fullName + } + @final_results_[spec_id] = @.summarizeResult_(spec, @results_[spec_id]) + if spec_result == 'failed' + @failedCount++ + @failedSpecs.push(@final_results_[spec_id]) + + summarizeResult_ : (spec, result) -> + summaryMessages = [] + for messageIndex in [0...result.messages.length] + resultMessage = result.messages[messageIndex] + summaryMessages.push({ + 'status': result.status, + 'message': resultMessage.message, + 'matcherName': resultMessage.matcherName, + 'expected': ''+resultMessage.expected, + 'actual': ''+resultMessage.actual, + 'trace': { + 'stack': if !resultMessage.passed then resultMessage.stack else jasmine.undefined + } + }) + { + 'id': result.id, + 'status': result.status + 'name': result.full_name, + 'description': result.description + 'messages': summaryMessages, + } + + suiteDone: (result) -> + #The result here is the same object as in suiteStarted but with the addition of a status and a list of failedExpectations. + @.log('Suite: ' + result.description + ' was ' + result.status); + + jasmineDone: -> + @finished = true + +# make sure this exists so we don't have timing issue +# when capybara hits us before the onload function has run +window.jasmineRiceReporter = new JasminericeReporter() +window.jasmineRiceReporter.register() diff --git a/app/assets/javascripts/jasminerice_runner_base.js.coffee b/app/assets/javascripts/jasminerice_runner_base.js.coffee new file mode 100644 index 0000000..b98c4b0 --- /dev/null +++ b/app/assets/javascripts/jasminerice_runner_base.js.coffee @@ -0,0 +1,90 @@ +class JasminericeRunnerBase + constructor: -> + @started = false + @finished = false + @failedSpecs = [] + @totalCount = 0 + @failedCount = 0 + @failure_message = 'Failure/Error: ' + # additional data ( optional ) + @suites_ = {} + @results_ = {} + @final_results_ = {} + + results: -> + @results_ + + all_summarized_results: -> + summarized_results = [] + for key, value of @final_results_ + summarized_results.push(value) + summarized_results + + suites: -> + @suites_ + + extend_object: (object, properties) -> + for key, val of properties + object[key] = val + object + + resultsForSpec: (specId) -> + @results_[specId] + + getFullDescOfSuite: (suite) -> + desc = "" + while(suite.parentSuite) + desc = suite.description + " " + desc + suite = suite.parentSuite + desc = suite.description + " " + desc + desc + + reportRunnerStarting: (runner) -> + @started = true + suites = runner.topLevelSuites() + for i in [0...suites.length] + suite = suites[i] + @suites_[suite.id] = @.summarize_(suite) + + summarize_ : (suiteOrSpec) -> + isSuite = suiteOrSpec instanceof jasmine.Suite + summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: if isSuite then 'suite' else 'spec', + children: [] + } + if (isSuite && suiteOrSpec.hasOwnProperty('children')) + children = suiteOrSpec.children() + for i in [0...children.length] + summary.children.push(@.summarize_(children[i])) + summary + + inspect: -> + { + 'started': @started, + 'finished': @finished, + 'totalCount': @totalCount, + 'failedCount': @failedCount + 'failedSpecs': @failedSpecs + } + + log: (str) -> + console.log(str) + + bindEvent: (eventHandler) -> + eventName = 'DOMContentLoaded' + if (document.addEventListener) + document.addEventListener(eventName, eventHandler, false) + else if (document.attachEvent) + document.attachEvent('on'+eventName, eventHandler) + + register: -> + @.bindEvent( => + @.registerIntoJasmine() + ) + + registerIntoJasmine: -> + jasmine.getEnv().addReporter(window.jasmineRiceReporter) + +window.JasminericeRunnerBase = JasminericeRunnerBase diff --git a/jasminerice-runner.gemspec b/jasminerice-runner.gemspec index c181f45..cb6c759 100644 --- a/jasminerice-runner.gemspec +++ b/jasminerice-runner.gemspec @@ -1,24 +1,45 @@ # -*- encoding: utf-8 -*- -$:.push File.expand_path("../lib", __FILE__) -require "jasminerice-runner/version" +require File.expand_path('../lib/jasminerice-runner/version', __FILE__) -Gem::Specification.new do |s| - s.name = "jasminerice-runner" - s.version = Jasminerice::Runner::VERSION - s.authors = ["Chris Nelson"] - s.email = ["chris@gaslightsoftware.com"] - s.homepage = "" - s.summary = %q{runs jasmine specs using capybara} - s.description = %q{Adds a rake task to run jasmine specs using capybara} - - s.rubyforge_project = "jasminerice-runner" - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.require_paths = ["lib"] +Gem::Specification.new do |spec| + spec.name = "jasminerice-runner" + spec.version = Jasminerice::Runner.gem_version + spec.platform = Gem::Platform::RUBY + spec.authors = ['Chris Nelson', 'Rada Bogdan Raul'] + spec.email = ["chris@gaslightsoftware.com", 'raoul_ice@yahoo.com'] + spec.homepage = '' + spec.summary = %q{runs jasmine specs using capybara} + spec.description = %q{Adds a rake task to run jasmine specs using capybara} + spec.date = Date.today + spec.licenses = ['MIT'] + spec.rubyforge_project = 'jasminerice-runner' + spec.files = `git ls-files`.split("\n") + spec.test_files = spec.files.grep(/^(spec)/) + spec.require_paths = ['lib'] + spec.required_ruby_version = '>= 2.0' + spec.required_rubygems_version = '>= 2.5' + spec.metadata = { + 'source_code' => spec.homepage, + 'bug_tracker' => "#{spec.homepage}/issues" + } # specify any dependencies here; for example: - # s.add_development_dependency "rspec" - s.add_runtime_dependency "capybara" + # spec.add_development_dependency "rspec" + spec.add_runtime_dependency 'capybara', '~> 2.0', '>= 2.0' + spec.add_runtime_dependency 'jasminerice', '>= 0.0', '>= 0.0.10' + spec.add_runtime_dependency 'jasmine', '>= 1.1', '>= 1.1' + spec.add_runtime_dependency 'nokogiri', '~> 1.6', '>= 1.6' + spec.add_runtime_dependency 'colorize', '~> 0.8', '>= 0.8' + spec.add_runtime_dependency 'coffee-script', '>= 2.0', '>= 2.0' + + spec.add_development_dependency 'appraisal', '~> 2.1', '>= 2.1' + spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4' + spec.add_development_dependency 'simplecov', '~> 0.11', '>= 0.10' + spec.add_development_dependency 'simplecov-summary', '~> 0.0.4', '>= 0.0.4' + spec.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7' + spec.add_development_dependency 'rake', '~> 11.0', '>= 11.0' + spec.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7' + spec.add_development_dependency 'redcarpet', '~> 3.3', '>= 3.3' + spec.add_development_dependency 'github-markup', '~> 1.3', '>= 1.3.3' + spec.add_development_dependency 'inch', '~> 0.6', '>= 0.6' end diff --git a/lib/assets/javascripts/jasminerice_reporter.js.coffee b/lib/assets/javascripts/jasminerice_reporter.js.coffee deleted file mode 100644 index b90fd77..0000000 --- a/lib/assets/javascripts/jasminerice_reporter.js.coffee +++ /dev/null @@ -1,25 +0,0 @@ -class JasminericeReporter - @failedSpecs = {} - reportRunnerResults: (runner)-> - @finished = true - @results = runner.results() - - reportSpecResults: (spec) -> - #return if @failed - @failedSpecs or= {} - if spec.results().failedCount > 0 - failure = '' - for expectation in spec.results().getItems() - if !expectation.passed() - failure = expectation.message - @failedSpecs[spec.suite.description] or= {} - @failedSpecs[spec.suite.description][spec.description] or= [] - @failedSpecs[spec.suite.description][spec.description].push(failure) -#@failed = true - -# make sure this exists so we don't have timing issue -# when capybara hits us before the onload function has run -window.jasmineRiceReporter = new JasminericeReporter() - -document.addEventListener 'DOMContentLoaded', -> - jasmine.getEnv().addReporter window.jasmineRiceReporter diff --git a/lib/jasminerice-runner.rb b/lib/jasminerice-runner.rb index fbcf13a..73ec959 100644 --- a/lib/jasminerice-runner.rb +++ b/lib/jasminerice-runner.rb @@ -1,7 +1,38 @@ +# frozen_string_literal: true +require 'rubygems' +require 'bundler' +require 'bundler/setup' + +require 'colorize' +require 'capybara' +require 'capybara/dsl' +require 'jasmine' +require 'nokogiri' +require 'jasminerice' +require 'coffee-script' + +require 'thread' +require 'fileutils' +require 'pathname' + +%w(formatters).each do |folder_name| + Gem.find_files("jasminerice-runner/#{folder_name}/**/*.rb").each { |path| require path } +end + + module Jasminerice - class Runner - cattr_accessor :capybara_driver - end - class JasmineRiceRunnerEngine < Rails::Engine + module Runner + require 'jasminerice-runner/configuration' + require 'jasminerice-runner/worker' + require 'jasminerice-runner/version' + require 'jasminerice-runner/engine' if defined?(Rails) + + def self.configure + yield config + end + + def self.config + @config ||= Jasminerice::Runner::Configuration.new + end end end diff --git a/lib/jasminerice-runner/configuration.rb b/lib/jasminerice-runner/configuration.rb new file mode 100644 index 0000000..c5fd28a --- /dev/null +++ b/lib/jasminerice-runner/configuration.rb @@ -0,0 +1,25 @@ +module Jasminerice + module Runner + class Configuration + SETTINGS = [:capybara_driver, :formatters, :junit_xml_path] + + SETTINGS.each do |setting| + attr_accessor setting + end + + def initialize + @capybara_driver = nil + @formatters = ENV['CI'].to_s == 'true' && !Jasmine.respond_to?(:configure) ? [:junit_xml] : [] + @junit_xml_path = nil + end + + def gem_root + File.expand_path(File.dirname(__dir__)) + end + + def formatters + (@formatters.is_a?(Array) ? @formatters : [@formatters]).compact + end + end + end + end diff --git a/lib/jasminerice-runner/engine.rb b/lib/jasminerice-runner/engine.rb new file mode 100644 index 0000000..23cc4ec --- /dev/null +++ b/lib/jasminerice-runner/engine.rb @@ -0,0 +1,14 @@ +if defined?(Rails) + class Jasminerice::Runner::Engine < Rails::Engine + + config.assets.precompile += %w( + jasminerice_runner_base.js.coffee + jasminerice_legacy_reporter.js.coffee + jasminerice_reporter.js.coffee + ) + + rake_tasks do + load 'jasminerice-runner/tasks/jasminerice-runner.rake' + end + end +end diff --git a/lib/jasminerice-runner/formatters/legacy_junit_xml.rb b/lib/jasminerice-runner/formatters/legacy_junit_xml.rb new file mode 100644 index 0000000..352a19a --- /dev/null +++ b/lib/jasminerice-runner/formatters/legacy_junit_xml.rb @@ -0,0 +1,77 @@ +module Jasminerice + module Runner + module Formatters + class LegacyJunitXml + def initialize + @doc = Nokogiri::XML '', nil, 'UTF-8' + @spec_count = 0 + @failure_count = 0 + end + + def format(results) + testsuite = doc.at_css('testsuites testsuite') + + @spec_count += results.size + + results.each do |result| + testcase = Nokogiri::XML::Node.new 'testcase', doc + testcase['classname'] = result['suite_name'].strip + testcase['name'] = result['description'].strip + + if result['status'] == 'failed' + @failure_count += 1 + result['messages'].each do |failed_exp| + failure = Nokogiri::XML::Node.new 'failure', doc + failure['message'] = failed_exp['message'].strip + failure['type'] = 'Failure' + failure.content = failed_exp['trace']['stack'].strip + failure.parent = testcase + end + end + + testcase.parent = testsuite + end + end + + def done(run_details) + testsuite = doc.at_css('testsuites testsuite') + properties = Nokogiri::XML::Node.new 'properties', doc + properties.parent = testsuite + + if run_details['order'] + random = Nokogiri::XML::Node.new 'property', doc + random['name'] = 'random' + random['value'] = run_details['order']['random'] + + random.parent = properties + + if run_details['order']['random'] + seed = Nokogiri::XML::Node.new 'property', doc + seed['name'] = 'seed' + seed['value'] = run_details['order']['seed'] + + seed.parent = properties + end + end + + testsuite['tests'] = @spec_count + testsuite['failures'] = @failure_count + testsuite['errors'] = 0 + + FileUtils.mkdir_p(output_dir) unless File.directory?(output_dir) + File.open(File.join(output_dir, 'junit_results.xml'), 'w') do |file| + file.puts doc.to_xml(indent: 2) + end + end + + private + attr_reader :doc, :config + + def output_dir + Jasminerice::Runner.config.junit_xml_path || File.join(Dir.pwd, 'spec', 'reports') + end + + end + end + end +end diff --git a/lib/jasminerice-runner/runner.rb b/lib/jasminerice-runner/runner.rb deleted file mode 100644 index 2ff153c..0000000 --- a/lib/jasminerice-runner/runner.rb +++ /dev/null @@ -1,85 +0,0 @@ -module Jasminerice - class Runner - include Capybara::DSL - - def initialize(environment) - @environment = environment - end - - def capybara_driver - self.class.capybara_driver || :selenium - end - - def run - Capybara.default_driver = capybara_driver - visit jasmine_url - print "Running jasmine specs" - - wait_for_finished - results = get_results - puts "Jasmine results - Passed: #{results[:passed]} Failed: #{results[:failed]} Total: #{results[:total]}" - failures = results[:failures] - - if failures.size == 0 - puts "Jasmine specs passed, yay!" - else - report_failures(failures) - raise "Jasmine specs failed" - end - end - - def jasmine_url - url = "/jasmine" - if @environment.present? - url += "?environment=#{@environment}" - end - - url - end - - def get_results - { - passed: page.evaluate_script("window.jasmineRiceReporter.results.passedCount"), - failed: page.evaluate_script("window.jasmineRiceReporter.results.failedCount"), - total: page.evaluate_script("window.jasmineRiceReporter.results.totalCount"), - failures: page.evaluate_script("window.jasmineRiceReporter.failedSpecs") - } - end - - def report_failures(failures) - puts 'Jasmine failures: ' - for suiteName,suiteFailures in failures - puts " " + suiteName + "\n" - for specName,specFailures in suiteFailures - puts " " + specName + "\n" - for specFailure in specFailures - puts " " + specFailure + "\n" - end - end - puts "\n" - end - end - - def wait_for_finished - reporter = page.evaluate_script("window.jasmineRiceReporter") - if reporter.nil? - if @environment.present? - filename = "#{@environment}_spec.js" - else - filename = "spec.js" - end - puts "\njasmineRiceReporter not defined! Check your configuration to make\n" + - "sure that #{filename} exists and that jasminerice_reporter is included." - raise "Reporter not found" - end - - start = Time.now - while true - break if page.evaluate_script("window.jasmineRiceReporter.finished") - sleep 1 - print "." - end - print "\n" - end - end -end diff --git a/lib/jasminerice-runner/tasks/jasminerice-runner.rake b/lib/jasminerice-runner/tasks/jasminerice-runner.rake new file mode 100644 index 0000000..c2ec370 --- /dev/null +++ b/lib/jasminerice-runner/tasks/jasminerice-runner.rake @@ -0,0 +1,10 @@ +namespace :jasminerice do + + desc "run jasmine specs in jasmine rice" + task :run, [:jasmine_environment] => :environment do |t, args| + require "capybara/rails" if defined?(Rails) + require "jasminerice-runner/worker" + runner = Jasminerice::Runner::Worker.new(args[:jasmine_environment]) + runner.run + end +end diff --git a/lib/jasminerice-runner/version.rb b/lib/jasminerice-runner/version.rb index 811f448..4c0975a 100644 --- a/lib/jasminerice-runner/version.rb +++ b/lib/jasminerice-runner/version.rb @@ -1,5 +1,30 @@ +# frozen_string_literal: true module Jasminerice - class Runner - VERSION = "0.0.4" + # Returns the version of the gem as a Gem::Version + module Runner + # it prints the gem version as a string + # + # @return [String] + # + # @api public + def self.gem_version + Gem::Version.new VERSION::STRING + end + + # module used to generate the version string + # provides a easy way of getting the major, minor and tiny + module VERSION + # major release version + MAJOR = 0 + # minor release version + MINOR = 5 + # tiny release version + TINY = 0 + # prelease version ( set this only if it is a prelease) + PRE = nil + + # generates the version string + STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') + end end -end \ No newline at end of file +end diff --git a/lib/jasminerice-runner/worker.rb b/lib/jasminerice-runner/worker.rb new file mode 100644 index 0000000..8138842 --- /dev/null +++ b/lib/jasminerice-runner/worker.rb @@ -0,0 +1,171 @@ +module Jasminerice + module Runner + class Worker + include Capybara::DSL + + FOMATTERS_MAPPER = { + junit_xml: { + legacy: Jasminerice::Runner::Formatters::LegacyJunitXml, + } + }.freeze + + def initialize(environment) + @environment = environment + @finished = false + @total_runned_tests = 0 + @test_statuses = {} + end + + def formatter_name(formatter, type = :legacy) + type = type.is_a?(Symbol) ? type : type.to_sym + formatter_name = formatter.is_a?(Symbol) ? formatter : formatter.to_sym + Jasminerice::Runner::Worker::FOMATTERS_MAPPER[formatter_name][type] + end + + def runner_formatters + Jasminerice::Runner.config.formatters + end + + def junit_enabled? + runner_formatters.include?(:junit_xml) + end + + def capybara_driver + Jasminerice::Runner.config.capybara_driver || :selenium + end + + def filter_failures_allowed_keys(failures) + failures.map do |hash| + hash['messages'] = hash['messages'].map {|message| message.slice('message', 'trace') } + hash.select do |key, value| + ['name', 'messages'].include?(key.to_s) + end + end + end + + def run + Capybara.default_driver = capybara_driver + visit jasmine_url + print "Running jasmine specs" + wait_for_finished + results = get_results + #puts JSON.pretty_generate(results) + puts "Jasmine results - Failed: #{results[:failed]} Total: #{results[:total]}" + failures = results[:failures] + failures = (failures.is_a?(Array) ? failures : [failures]).compact + + if failures.size == 0 + puts "Jasmine specs passed, yay!" + else + puts 'Jasmine failures: ' + puts "\n" + filtered_failures = filter_failures_allowed_keys(failures) + formatted_results = report_failures(filtered_failures) + print_formatted_failures(formatted_results) + puts "Jasmine specs failed" + end + if !Jasmine.respond_to?(:configure) && !value_blank?(runner_formatters) + runner_formatters.each do |formatter| + formatter_instance = formatter_name(formatter, :legacy).new + formatter_instance.format(results[:all_results]) + formatter_instance.done({}) + end + end + exit + end + + def jasmine_url + url = "/jasmine" + if @environment.present? + url += "/#{@environment}" + else + url +='#/index' + end + url + end + + def get_results + { + failed: page.evaluate_script("window.jasmineRiceReporter.failedCount"), + total: page.evaluate_script("window.jasmineRiceReporter.totalCount"), + failures: page.evaluate_script("window.jasmineRiceReporter.failedSpecs"), + all_results: page.evaluate_script("window.jasmineRiceReporter.all_summarized_results()") + } + end + + def print_formatted_failures(formatted_results) + formatted_results.each_with_index do |failure_hash, index| + print "#{(index + 1)}) " + failure_hash.each do |key, value| + print print_color(key, value.to_s) + "\n" + end + puts "\n" + end + end + + def report_failures(failures, array = []) + return unless failures.is_a?(Array) + failures.each_with_index do |failure, index| + collect_failure(failure, index, array) + end + array.compact + end + + def value_blank?(value) + value.nil? || value_empty?(value) || (value.is_a?(String) && /\A[[:space:]]*\z/.match(value)) + end + + def value_empty?(value) + value.respond_to?(:empty?) ? value.empty? : !value + end + + def collect_failure(failure, index, array) + failure.each do |key, value| + if value.is_a?(Hash) + collect_failure(value, index, array) + elsif value.is_a?(Array) + value.each { |array_value| collect_failure(array_value, index, array) } + elsif !value.nil? && !value_blank?(value) + array[index] ||= {} + array[index][key] = print_color(key, value.to_s).uncolorize + end + end + end + + def print_color(key, value) + case key.to_s + when 'message' + "Failure/Error: #{value}" + when 'stack' + "Backtrace: #{value.red}" + else + value + end + end + + def wait_for_finished + start_time = Time.now + reporter = page.evaluate_script("typeof(window.jasmineRiceReporter)") + if reporter.nil? || reporter !='object' + if @environment.present? + filename = "#{@environment}_spec.js" + else + filename = "spec.js" + end + puts "\njasmineRiceReporter not defined! Check your configuration to make\n" + + "sure that #{filename} exists and that jasminerice_reporter is included." + raise "Reporter not found" + end + loop do + @finished = page.evaluate_script("window.jasmineRiceReporter.finished") + break if @finished + sleep(0.1) + print "." + end + print "\n" + duration = Time.now - start_time + puts "Jasmine test Duration was #{duration.inspect}" + end + end + end +end diff --git a/lib/tasks/jasminerice-runner.rake b/lib/tasks/jasminerice-runner.rake deleted file mode 100644 index 6af90ca..0000000 --- a/lib/tasks/jasminerice-runner.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :jasminerice do - - desc "run jasmine specs in jasmine rice" - task :run, [:jasmine_environment] => :environment do |t, args| - require "capybara/rails" - require "jasminerice-runner/runner" - runner = Jasminerice::Runner.new(args[:jasmine_environment]) - runner.run - end -end