pretty_face 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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