launcuke 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzI2M2UzMjhjNWFmZWY4ZGZjOTAyZmNmY2ZmODUyZDUxNDRjMjI3Zg==
4
+ ODgyNmIwNzBhOWJlNjk3NjYzN2E4NDlmOGNmZDczMDE4ZTM0ODY5OA==
5
5
  data.tar.gz: !binary |-
6
- NDVhOGY2YzQyODQ0NjNlN2JmNDgwYzM5MjJiZDUwOWZlNmFlZjUxZg==
6
+ YzdkOTBhNjFiZDliZDA4NzFlMmE5ODU2Y2Q0MmI3NTE2YzFmYzNlOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTA0Y2RiZWE1ODRhOGU4ZGMzNGFlNzEyODllNWQ1MGQ2YzA2OTEzYjYxZmE0
10
- Y2ZjOTQwYzAwOWJkYzRiMjRhZWJiMWIyODc5NTAzOTI4NDlmNzdkMzZkNWM0
11
- M2E5NGQ0ZGRiYjNlOWQ4ZWMzMjYxYzE2MjE4MGViZjUyMzAzZDY=
9
+ MjVjNWU2ZWFiM2I4MWIzYWE2MzdmZDc0NjQxOTQwODBlMDBlMWM3MjFlNTlh
10
+ Y2IwNTM1NTAyZDkzYWZmYTk0NTdhNDQxMDUyY2FkNzU3NmIwMThjM2M1MWFj
11
+ MWQ1NDlkOWQwZWQxMzM0MTliNzQzN2Q1Y2ZlN2FlN2UzYjRiNmI=
12
12
  data.tar.gz: !binary |-
13
- ODU1ZjMzZTc3OTEwYTUzZTI2YTQ3YzVhMWFmN2VkYWRiZTk2NWE0OGVjYjA3
14
- NTk4ZTk0NDg3YjY2NGYzYWI1NWJiNDNiYjJhYzhkNjY2NWZhOTc5MTUwZjdi
15
- NGEzZDIwOWFmY2MwYzRmMWU3YzNkYzE4MTZmZTY4YTM0NzljZDI=
13
+ MzkwZDBjYjI0OTEwNGI4OTYzNWE5MGM3NDY5YmY5ZTU4ZjIzODBmYjVjODJl
14
+ ZWY1Njc1Yzk3NTMxYTBhODgwNzg2NDI3ODk4ZWQ5NmE5ZTkzMzJiZmMwNTIx
15
+ NTRmNTY1MmQ0MzdkMGVhZmYyZmY0YzQ0Mjc4NzQ5MmQ0MTc5YTk=
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'cucumber'
4
+ gem 'rspec'
5
+ gem 'nokogiri'
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Launcuke
2
+
3
+ Run your cucumber test and generate a index html page to show all reports by feature.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'launcuke'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install launcuke
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/launcuke/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/launcuke.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/launcuke/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'launcuke'
6
+ s.date = '2014-11-24'
7
+ s.summary = "Launch cuke!"
8
+ s.description = "A simple cucumber runner gem"
9
+ s.authors = ["Yi MIN"]
10
+ s.email = 'tebat804@gmail.com'
11
+ s.files = ["lib/launcuke.rb"]
12
+ s.homepage =
13
+ 'http://rubygems.org/gems/launcuke'
14
+ s.files = `git ls-files`.split($\)
15
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ s.license = 'MIT'
17
+ s.require_paths = ["lib"]
18
+ s.version = Launcuke::VERSION
19
+ s.add_dependency 'cucumber'
20
+ s.add_dependency 'rspec'
21
+ s.add_dependency 'nokogiri'
22
+ end
@@ -0,0 +1,59 @@
1
+ module Launcuke
2
+
3
+ # Generate the index page reporting on the features and their status.
4
+ # Provides the links to the actual full Cucumber html reports.
5
+ class ReportsIndex
6
+
7
+ # Collection of ran features directories results used for reporting
8
+ attr_reader :features_dirs
9
+
10
+ # Full path for the index html file
11
+ attr_reader :index_path
12
+
13
+ def initialize(reports_path, features_dirs)
14
+ @features_dirs = features_dirs
15
+ @index_path = File.join(reports_path, "index.html")
16
+ end
17
+
18
+ def generate
19
+ index_file = File.new(index_path, "w")
20
+
21
+ b = Builder::XmlMarkup.new :target => index_file, :indent => 2
22
+ b.html {
23
+ b.head {
24
+ b.title("Cucumber Reports")
25
+ b.style(css_content)
26
+ }
27
+ b.body {
28
+ b.h2("Features")
29
+ b.ul {
30
+ features_dirs.each { |features_dir|
31
+ b.li(:class => (features_dir.failed? ? "failed" : "success")) {
32
+ b.a(features_dir.human_name, :href => "#{features_dir.dir_name}.html")
33
+ b.span("[#{features_dir.duration}]", :class => "duration")
34
+ b.span("Scenarios: #{features_dir.scenarios_results}, Steps: #{features_dir.steps_results}", :class => "result")
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ index_file.close
42
+ end
43
+
44
+ private
45
+
46
+ def css_content
47
+ <<-CSS
48
+ body {font-family: "Lucida Grande", Helvetica, sans-serif; margin: 2em 8em 2em 8em;}
49
+ ul {list-style-type: square;}
50
+ li {margin: 1em 0 1em 0;}
51
+ li span {float: right; margin-left: 1em; padding: 0 0.3em;}
52
+ li.failed span.result{background: #DC6E6E;}
53
+ li.success span.result{background: #C1E799;}
54
+ span.duration {color: #999999;}
55
+ CSS
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,197 @@
1
+ require 'launcuke/index'
2
+
3
+ module Launcuke
4
+
5
+ # Wrapper of {Kernel#system} method for test/mock
6
+ class SystemCommand
7
+
8
+ def run(full_command_as_array)
9
+ system *full_command_as_array
10
+ end
11
+
12
+ def exit(status = 0)
13
+ Kernel.exit(status == 0)
14
+ end
15
+
16
+ end
17
+
18
+ # Set of features under one specific directory
19
+ class FeaturesDir
20
+
21
+ # Directory name fo the features
22
+ attr_reader :dir_name
23
+
24
+ # Result string for passed/failed scenarios
25
+ attr_accessor :scenarios_results
26
+
27
+ # Result string for passed/failed steps
28
+ attr_accessor :steps_results
29
+
30
+ # Running time in ms for all features in this feature directory
31
+ attr_accessor :duration
32
+
33
+ # True if a scenario or step has failed for this set of features
34
+ attr_writer :failed
35
+
36
+ def initialize(directory_name)
37
+ @dir_name = directory_name
38
+ @failed = false
39
+ @scenarios_results = ""
40
+ @steps_results = ""
41
+ end
42
+
43
+ # True if one feature has failed
44
+ def failed?
45
+ (scenarios_results.include?"failed") || (steps_results.include?"failed")
46
+ end
47
+
48
+ # Human readable name used for index page (ex: user_logout --> User logout)
49
+ def human_name
50
+ dir_name.gsub(/[_-]/, " ").capitalize
51
+ end
52
+
53
+ end
54
+
55
+ # Actual clas that will spawn one command process per directory of features collected
56
+ # according to configuration
57
+ class Runner
58
+
59
+ # Root path to your features directory. Ex: your_project/features
60
+ attr_accessor :features_root_path
61
+
62
+ # Optional name for directory containing the reports. Default to 'cucumber_reports'
63
+ attr_accessor :output_dir_name
64
+
65
+ # Optional full path for generated reports. Default to ../{features_root_path}.
66
+ attr_accessor :output_path
67
+
68
+ # Optional regexp for name of features directories to exclude.
69
+ attr_accessor :excluded_dirs
70
+
71
+ # Optional only the features directories to be included
72
+ attr_accessor :included_only_dirs
73
+
74
+ # Array of extra options to pass to the command. Ex: ["-p", "my_profile", "--backtrace"]
75
+ attr_accessor :extra_options
76
+
77
+ # Define the size for the pool of forks. Default is 5
78
+ attr_accessor :forks_pool_size
79
+
80
+ # Full final path where html reports will be generated
81
+ attr_reader :reports_path
82
+
83
+ # Optional. If true will generate index file but not launch processes. Used for testing.
84
+ attr_accessor :dry_run
85
+
86
+ # Add cucumber --require option load *.rb files under features root path by default unless specified to false.
87
+ attr_accessor :require_features_root_option
88
+
89
+ # Delegate to a wrapper of system call in order mock/test
90
+ attr_accessor :system_command
91
+
92
+ def initialize(features_root)
93
+ @features_root_path = features_root
94
+ @extra_options ||= []
95
+ yield self if block_given?
96
+
97
+ @dry_run = false if dry_run.nil?
98
+ @forks_pool_size ||= 5
99
+ @require_features_root_option = true if require_features_root_option.nil?
100
+ @output_dir_name = "#{@extra_options[1]}" unless output_dir_name
101
+ @output_path = File.expand_path("../reports", output_dir_name) unless output_path
102
+ @excluded_dirs ||= []
103
+ @included_only_dirs ||= []
104
+
105
+ @reports_path = File.join(output_path, output_dir_name)
106
+ @system_command ||= SystemCommand.new
107
+ end
108
+
109
+ def start
110
+ FileUtils.mkdir_p reports_path
111
+ exit_status = launch_process_per_dir
112
+ collect_results
113
+ reports = ReportsIndex.new(reports_path, features_dirs).generate
114
+ puts "See reports index at #{reports.index_path}" if reports
115
+ system_command.exit(exit_status)
116
+ end
117
+
118
+ private
119
+
120
+ def launch_process_per_dir
121
+ if dry_run
122
+ 0
123
+ else
124
+
125
+ results = features_dirs.each { |features_dir|
126
+ report_file_path = File.join(reports_path, "#{features_dir.dir_name}.html")
127
+ feature_full_path = File.join(features_root_path, "#{features_dir.dir_name}")
128
+ main_command = %W[bundle exec cucumber #{feature_full_path}]
129
+ options = %W[--format html --out #{report_file_path}]
130
+ options.concat %W[--require #{features_root_path}] if require_features_root_option
131
+ full_command = main_command + options + extra_options
132
+ result = system_command.run full_command
133
+ puts "Features '#{features_dir.dir_name.upcase}' finished. #{result ? 'SUCCESS' : 'FAILURE'} (pid: #{Process.pid})"
134
+ result
135
+ }
136
+
137
+
138
+ global_exit_status = results.inject(0) { |acc, result|
139
+ result ? acc : acc +1
140
+ }
141
+ puts "Global exit status = #{global_exit_status}"
142
+ global_exit_status
143
+ end
144
+ end
145
+
146
+ def collect_results
147
+ features_dirs.each { |features_dir|
148
+ feature_file = File.join(reports_path, "#{features_dir.dir_name}.html")
149
+ File.open(feature_file) { |file|
150
+ content = file.read
151
+ duration_match = content.match(/Finished in\s+<\w+>(.*?)</)
152
+ duration = duration_match ? duration_match.captures.first : ""
153
+ scenarios_match = content.match(/\d+ scenarios? \((.*?)\)/)
154
+ scenarios = scenarios_match ? scenarios_match.captures.first : ""
155
+ steps_match = content.match(/\d+ steps? \((.*?)\)/)
156
+ steps = steps_match ? steps_match.captures.first : ""
157
+
158
+ features_dir.scenarios_results = scenarios
159
+ features_dir.steps_results = steps
160
+ features_dir.duration = duration
161
+ } if File.exists?(feature_file)
162
+ }
163
+ end
164
+
165
+ def features_dirs
166
+ @features_dirs ||= resolve_features_dirs_name
167
+ end
168
+
169
+ def resolve_features_dirs_name
170
+ Dir.glob(File.join(features_root_path, "*", "*.feature")).select{ |path|
171
+ configured_dir?(path)
172
+ }.map { |feature_path|
173
+ dir_name = File.basename(File.dirname(feature_path))
174
+ FeaturesDir.new(dir_name)
175
+ }.uniq { |feature_dir|
176
+ feature_dir.dir_name
177
+ }
178
+ end
179
+
180
+ def configured_dir?(path)
181
+ if included_only_dirs.empty?
182
+ included_dir?(path)
183
+ else
184
+ exact_word_match_expressions = included_only_dirs.map { |dir_name|
185
+ "\\b#{dir_name}\\b"
186
+ }
187
+ path.match(Regexp.new(exact_word_match_expressions.join("|")))
188
+ end
189
+ end
190
+
191
+ def included_dir?(path)
192
+ excluded_dirs.empty? || (not path.match(Regexp.new(excluded_dirs.join("|"))))
193
+ end
194
+
195
+ end
196
+
197
+ end
@@ -0,0 +1,3 @@
1
+ module Launcuke
2
+ VERSION = '0.0.2'
3
+ end
data/lib/launcuke.rb CHANGED
@@ -1,5 +1,6 @@
1
- class Launcuke
2
- def self.hi
3
- puts "Hello world!"
4
- end
5
- end
1
+ require "launcuke/version"
2
+ require "launcuke/runner"
3
+
4
+ require 'fileutils'
5
+ require 'builder'
6
+ require 'nokogiri'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: launcuke
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yi MIN
@@ -9,14 +9,62 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-11-24 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cucumber
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  description: A simple cucumber runner gem
14
56
  email: tebat804@gmail.com
15
57
  executables: []
16
58
  extensions: []
17
59
  extra_rdoc_files: []
18
60
  files:
61
+ - Gemfile
62
+ - README.md
63
+ - launcuke.gemspec
19
64
  - lib/launcuke.rb
65
+ - lib/launcuke/index.rb
66
+ - lib/launcuke/runner.rb
67
+ - lib/launcuke/version.rb
20
68
  homepage: http://rubygems.org/gems/launcuke
21
69
  licenses:
22
70
  - MIT