pretty_face 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +5 -0
  4. data/ChangeLog +2 -0
  5. data/Gemfile +12 -0
  6. data/Guardfile +17 -0
  7. data/README.md +21 -0
  8. data/Rakefile +18 -0
  9. data/cucumber.yml +3 -0
  10. data/features/pretty_face_report.feature +63 -0
  11. data/features/support/env.rb +9 -0
  12. data/features/support/hooks.rb +6 -0
  13. data/fixtures/advanced.feature +14 -0
  14. data/fixtures/basic.feature +17 -0
  15. data/fixtures/step_definitions/advanced_steps.rb +12 -0
  16. data/fixtures/step_definitions/basic_steps.rb +19 -0
  17. data/fixtures/support/env.rb +3 -0
  18. data/lib/pretty_face.rb +6 -0
  19. data/lib/pretty_face/formatter/html.rb +140 -0
  20. data/lib/pretty_face/formatter/report.rb +68 -0
  21. data/lib/pretty_face/formatter/view_helper.rb +60 -0
  22. data/lib/pretty_face/templates/face.jpg +0 -0
  23. data/lib/pretty_face/templates/failed.jpg +0 -0
  24. data/lib/pretty_face/templates/main.erb +194 -0
  25. data/lib/pretty_face/templates/passed.jpg +0 -0
  26. data/lib/pretty_face/templates/pending.jpg +0 -0
  27. data/lib/pretty_face/templates/skipped.jpg +0 -0
  28. data/lib/pretty_face/templates/undefined.jpg +0 -0
  29. data/lib/pretty_face/version.rb +3 -0
  30. data/pretty_face.gemspec +26 -0
  31. data/sample_report/LisaCrispin1.png +0 -0
  32. data/sample_report/LisaCrispin2.png +0 -0
  33. data/sample_report/blue_s.jpeg +0 -0
  34. data/sample_report/green_bar.jpeg +0 -0
  35. data/sample_report/green_check.jpg +0 -0
  36. data/sample_report/red_bar.gif +0 -0
  37. data/sample_report/red_x.jpg +0 -0
  38. data/sample_report/sample_report.html +167 -0
  39. data/sample_report/some_code/gherkin_formatter_adapter.rb +87 -0
  40. data/sample_report/some_code/html.rb +655 -0
  41. data/sample_report/some_code/ordered_xml_markup.rb +24 -0
  42. data/sample_report/some_code/summary.rb +35 -0
  43. data/sample_report/yellow_o.jpg +0 -0
  44. data/spec/lib/html_formatter_spec.rb +111 -0
  45. data/spec/spec_helper.rb +5 -0
  46. metadata +168 -0
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ *.swp
7
+ fixture.html
8
+ images
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format doc
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 1.8.7
data/ChangeLog ADDED
@@ -0,0 +1,2 @@
1
+ === Release 0.1 / 2012-11-17
2
+ Initial release with single page basic report
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake'
4
+ gem 'fuubar'
5
+ gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
6
+ gem 'growl'
7
+ gem 'guard-rspec'
8
+ gem 'guard-cucumber'
9
+
10
+
11
+ # Specify your gem's dependencies in pretty_face.gemspec
12
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,17 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :cli => '--color --format Fuubar' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
10
+ guard 'cucumber', :notification => true, :all_after_pass => false, :cli => '--profile focus' do
11
+ watch(%r{^features/.+\.feature$})
12
+ watch(%r{^features/support/.+$}) { 'features' }
13
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
14
+ watch(%r{^lib/.+\.rb$}) { "features" }
15
+ watch(%r{^lib/.+\.erb$}) { "features" }
16
+ end
17
+
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # pretty_face
2
+
3
+ HTML report for cucumber and rspec. You can customzie the report by editing an erb file.
4
+
5
+ ## Known Issues
6
+
7
+ See [http://github.com/cheezy/pretty_face/issues](http://github.com/cheezy/pretty_face/issues)
8
+
9
+ ## Contribute
10
+
11
+ * Fork the project.
12
+ * Test drive your feature addition or bug fix. Adding specs is important and I will not accept a pull request that does not have tests.
13
+ * Make sure you describe your new feature with a cucumber scenario.
14
+ * Make sure you provide RDoc comments for any new public method you add. Remember, others will be using this gem.
15
+ * Commit, do not mess with Rakefile, version, or ChangeLog.
16
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
17
+ * Send me a pull request. Bonus points for topic branches.
18
+
19
+ ## Copyright
20
+
21
+ Copyright (c) 2012 Jeffrey S. Morgan. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require 'cucumber'
3
+ require 'cucumber/rake/task'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Cucumber::Rake::Task.new(:features, "Run all features") do |t|
7
+ t.profile = 'default'
8
+ end
9
+ RSpec::Core::RakeTask.new(:spec) do |spec|
10
+ spec.ruby_opts = "-I lib:spec"
11
+ spec.pattern = 'spec/**/*_spec.rb'
12
+ end
13
+ task :spec
14
+
15
+ desc 'Run all specs and features'
16
+ task :test => %w[spec features]
17
+
18
+ task :default => :test
data/cucumber.yml ADDED
@@ -0,0 +1,3 @@
1
+ default: --color --no-source --format pretty
2
+ fixture: --color --no-source --require fixtures/step_definitions --format PrettyFace::Formatter::Html --out fixture.html
3
+ focus: --color --no-source --format pretty --tags @focus
@@ -0,0 +1,63 @@
1
+ Feature: pretty face report
2
+
3
+ Background:
4
+ When I run `cucumber fixtures --profile fixture`
5
+
6
+ Scenario: Cucumber crefates an html report
7
+ Then the following files should exist:
8
+ | fixture.html |
9
+
10
+ Scenario: Generating the basic html page from the erb
11
+ Then the file "fixture.html" should contain "DOCTYPE html PUBLIC"
12
+ And the file "fixture.html" should contain "<html xmlns='http://www.w3.org/1999/xhtml'>"
13
+ And the file "fixture.html" should contain "<head>"
14
+ And the file "fixture.html" should contain "<body"
15
+ And the file "fixture.html" should contain "<title>Test Results</title>"
16
+
17
+ Scenario: Generating some basic stats from the erb
18
+ Then the file "fixture.html" should contain "<th>Executed<"
19
+ And the file "fixture.html" should contain "<th>Average<br/>Duration"
20
+ And the file "fixture.html" should contain "Scenarios"
21
+ And the file "fixture.html" should contain "Steps"
22
+
23
+ Scenario: Including the styles for the main page
24
+ Then the file "fixture.html" should contain "<style type='text/css'>"
25
+ And the file "fixture.html" should contain "</style>"
26
+
27
+ Scenario: Including an image / logo
28
+ Then the file "fixture.html" should contain "<img src="
29
+ And the file "fixture.html" should contain "images/face.jpg"
30
+
31
+ Scenario: It should copy the logo image to the images directory
32
+ Then the following files should exist:
33
+ | images/face.jpg |
34
+
35
+ Scenario: It should show start time and duration in the header
36
+ Then the file "fixture.html" should contain "Tests started:"
37
+ And the file "fixture.html" should contain "Duration:"
38
+
39
+ Scenario: It should capture scenario and step statuses
40
+ Then the file "fixture.html" should contain "Passed"
41
+ And the file "fixture.html" should contain "Failed"
42
+ And the file "fixture.html" should contain "Pending"
43
+ And the file "fixture.html" should contain "Undefined"
44
+ And the file "fixture.html" should contain "Skipped"
45
+
46
+ Scenario: It should display all of the tests with failures
47
+ Then the file "fixture.html" should contain "Tests With Failures:"
48
+
49
+ Scenario: It should display a list of all features / scenarios
50
+ Then the file "fixture.html" should contain "Scenario Overview:"
51
+
52
+ Scenario: It should display useful information about each scenario
53
+ Then the file "fixture.html" should contain "Result"
54
+ And the file "fixture.html" should contain "Name"
55
+ And the file "fixture.html" should contain "# Steps"
56
+ And the file "fixture.html" should contain "Duration"
57
+
58
+ Scenario: It should display the data from scenario outlines
59
+ Then the file "fixture.html" should contain "| aaa | bbb |"
60
+ And the file "fixture.html" should contain "| ccc | ddd |"
61
+
62
+ Scenario: It should display the scenario name for scenario outlines
63
+ Then the file "fixture.html" should contain "A scenario outline"
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+
3
+ require 'aruba/cucumber'
4
+
5
+ require 'pretty_face'
6
+
7
+ Before do
8
+ @dirs = [File.join(File.dirname(__FILE__), '..', '..')]
9
+ end
@@ -0,0 +1,6 @@
1
+ require 'fileutils'
2
+
3
+ After do
4
+ file = File.join(File.dirname(__FILE__), '..', '..', 'fixture.html')
5
+ # FileUtils.rm file
6
+ end
@@ -0,0 +1,14 @@
1
+ Feature: Advanced scenarios
2
+
3
+ Scenario Outline: A scenario outline
4
+ Given I am using a scenario outline
5
+ When I use <first>
6
+ And I use <second>
7
+ Then the examples should work
8
+
9
+ Examples:
10
+ | first | second |
11
+ | aaa | bbb |
12
+ | ccc | ddd |
13
+ | eee | fff |
14
+
@@ -0,0 +1,17 @@
1
+ Feature: Basic scenarios
2
+
3
+ Scenario: A passing scenario
4
+ When Cucumber puts "hello"
5
+ Then it should say hello
6
+
7
+ Scenario: A failing scenario
8
+ When the first step fails
9
+ Then the second step should not execute
10
+
11
+ Scenario: A pending scenario
12
+ When the first step is pending
13
+ Then the second step is undefined
14
+
15
+ Scenario: A undefined scenario
16
+ When all steps are undefined
17
+ Then the scenario is undefined
@@ -0,0 +1,12 @@
1
+ Given /^I am using a scenario outline$/ do
2
+
3
+ end
4
+
5
+ When /^I use (.*?)$/ do |value|
6
+
7
+ end
8
+
9
+ Then /^the examples should work$/ do
10
+
11
+ end
12
+
@@ -0,0 +1,19 @@
1
+ When /^Cucumber puts "(.*?)"$/ do |some_string|
2
+ puts some_string
3
+ end
4
+
5
+ Then /^it should say hello$/ do
6
+ puts "It said hello"
7
+ end
8
+
9
+ When /^the first step fails$/ do
10
+ true.should == false
11
+ end
12
+
13
+ Then /^the second step should not execute$/ do
14
+ puts "Should not execute"
15
+ end
16
+
17
+ When /^the first step is pending$/ do
18
+ pending
19
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+
3
+ require 'pretty_face'
@@ -0,0 +1,6 @@
1
+ require "pretty_face/version"
2
+ require "pretty_face/formatter/html"
3
+
4
+ module PrettyFace
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,140 @@
1
+ require 'erb'
2
+ require 'fileutils'
3
+ require 'cucumber/formatter/io'
4
+ require 'cucumber/formatter/duration'
5
+ require 'cucumber/ast/scenario'
6
+ require 'cucumber/ast/table'
7
+ require 'cucumber/ast/outline_table'
8
+ require File.join(File.dirname(__FILE__), 'view_helper')
9
+ require File.join(File.dirname(__FILE__), 'report')
10
+
11
+ module PrettyFace
12
+ module Formatter
13
+
14
+ class Html
15
+ include Cucumber::Formatter::Io
16
+ include Cucumber::Formatter::Duration
17
+ include ViewHelper
18
+
19
+ def initialize(step_mother, path_or_io, options)
20
+ @path = path_or_io
21
+ @io = ensure_io(path_or_io, 'html')
22
+ @step_mother = step_mother
23
+ @options = options
24
+ @report = Report.new
25
+ @step_times = []
26
+ @scenario_times = []
27
+ @outline_steps = []
28
+ end
29
+
30
+ def before_features(features)
31
+ @tests_started = Time.now
32
+ end
33
+
34
+ def before_feature(feature)
35
+ @report.add_feature ReportFeature.new(feature)
36
+ end
37
+
38
+ def after_feature(feature)
39
+ @report.current_feature.title = feature.title
40
+ end
41
+
42
+ def before_feature_element(feature_element)
43
+ @scenario_timer = Time.now
44
+ unless scenario_outline? feature_element
45
+ @report.add_scenario ReportScenario.new(feature_element)
46
+ end
47
+ end
48
+
49
+ def after_feature_element(feature_element)
50
+ unless scenario_outline?(feature_element)
51
+ process_scenario(feature_element)
52
+ end
53
+ end
54
+
55
+ def after_outline_table(outline_table)
56
+ process_scenario_outline(outline_table)
57
+ end
58
+
59
+ def after_table_row(example_row)
60
+ @scenario_times.push Time.now - @scenario_timer
61
+ end
62
+
63
+ def before_step(step)
64
+ @step_timer = Time.now
65
+ end
66
+
67
+ def after_step(step)
68
+ process_step(step)
69
+ end
70
+
71
+ def after_features(features)
72
+ @features = features
73
+ @duration = format_duration(Time.now - @tests_started)
74
+ generate_report
75
+ copy_images_directory
76
+ end
77
+
78
+ def features
79
+ @report.features
80
+ end
81
+
82
+ private
83
+
84
+ def generate_report
85
+ filename = File.join(File.dirname(__FILE__), '..', 'templates', 'main.erb')
86
+ text = File.new(filename).read
87
+ @io.puts ERB.new(text, nil, "%").result(binding)
88
+ end
89
+
90
+ def copy_images_directory
91
+ path = "#{File.dirname(@path)}/images"
92
+ FileUtils.mkdir path unless File.directory? path
93
+ %w(face failed passed pending undefined skipped).each do |file|
94
+ FileUtils.cp File.join(File.dirname(__FILE__), '..', 'templates', "#{file}.jpg"), path
95
+ end
96
+ end
97
+
98
+ def process_scenario(scenario)
99
+ @scenario_times.push Time.now - @scenario_timer
100
+ @report.current_scenario.populate(scenario)
101
+ end
102
+
103
+ def process_example_row(example_row)
104
+ @report.add_scenario build_scenario_outline_with example_row
105
+ end
106
+
107
+ def process_scenario_outline(scenario_outline)
108
+ scenario_outline.example_rows.each do |example_row|
109
+ process_example_row(example_row)
110
+ end
111
+ @outline_steps = []
112
+ end
113
+
114
+ def process_step(step)
115
+ @step_times.push Time.now - @step_timer
116
+ if step_belongs_to_outline? step
117
+ @outline_steps << ReportStep.new(step)
118
+ else
119
+ @report.add_step ReportStep.new(step)
120
+ end
121
+ end
122
+
123
+ def scenario_outline?(feature_element)
124
+ feature_element.is_a? Cucumber::Ast::ScenarioOutline
125
+ end
126
+
127
+ def step_belongs_to_outline?(step)
128
+ scenario = step.instance_variable_get "@feature_element"
129
+ not scenario.nil?
130
+ end
131
+
132
+ def build_scenario_outline_with(example_row)
133
+ scenario = ReportScenario.new(example_row)
134
+ scenario.steps = @outline_steps
135
+ scenario.populate example_row
136
+ scenario
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,68 @@
1
+ module PrettyFace
2
+ module Formatter
3
+
4
+ class Report
5
+ attr_reader :features
6
+
7
+ def initialize
8
+ @features = []
9
+ end
10
+
11
+ def current_feature
12
+ @features.last
13
+ end
14
+
15
+ def current_scenario
16
+ current_feature.scenarios.last
17
+ end
18
+
19
+ def add_feature(feature)
20
+ @features << feature
21
+ end
22
+
23
+ def add_scenario(scenario)
24
+ current_feature.scenarios << scenario
25
+ end
26
+
27
+ def add_step(step)
28
+ current_scenario.steps << step
29
+ end
30
+ end
31
+
32
+ class ReportFeature
33
+ attr_accessor :title, :scenarios
34
+
35
+ def initialize(feature)
36
+ self.scenarios = []
37
+ end
38
+ end
39
+
40
+ class ReportScenario
41
+ attr_accessor :name, :file_colon_line, :status, :steps
42
+
43
+ def initialize(scenario)
44
+ self.steps = []
45
+ end
46
+
47
+ def populate(scenario)
48
+ if scenario.instance_of? Cucumber::Ast::Scenario
49
+ self.name = scenario.name
50
+ self.file_colon_line = scenario.file_colon_line
51
+ elsif scenario.instance_of? Cucumber::Ast::OutlineTable::ExampleRow
52
+ self.name = scenario.scenario_outline.name
53
+ self.file_colon_line = scenario.backtrace_line
54
+ end
55
+ self.status = scenario.status
56
+ end
57
+ end
58
+
59
+ class ReportStep
60
+ attr_accessor :name, :file_colon_line, :status
61
+ def initialize(step)
62
+ self.name = step.name
63
+ self.file_colon_line = step.file_colon_line
64
+ self.status = step.status
65
+ end
66
+ end
67
+ end
68
+ end