captureful_formatter 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30f3679548cc23945e25fe8752233c60bd2af5fe
4
- data.tar.gz: 9a7369666c42c652ca0311d87bbf10d5430af47c
3
+ metadata.gz: ad0d60a1d2e31c32f13ef5818453e0b1f6132339
4
+ data.tar.gz: 7101c556ec29a301315d734f2386a2416eb71129
5
5
  SHA512:
6
- metadata.gz: e4cf41d025eacb2900a37fd594f70448195d77ad672234307f69b24cc7094d6f2f90f927b77490f8eca32db7f76b1cb3c8faa5389b889c733c60828bb498ec38
7
- data.tar.gz: 5e2d0bf8c276f76f634c8c31f6e53bd262559203f968856141f44a82bbea4023c94fcd4854e775fc1437d361f2dfadba4e2f8f160868350c15c664f3db5742ef
6
+ metadata.gz: 825b0041593dce90b6a20eea8da9a9471dadd904a658ea0c8183e3a3faf11b2f8301355ba290f3c1aaa94165c7b343ec226c0517f26f798e526290c0b92c27fd
7
+ data.tar.gz: 49f2d534da1914cd3ef48e1798d5a63ca6d296548a834798e0436379799b23acd64d58383fc2ba54a6f15051ee2e3c119897592d3d938bdd7fbff4c6421c69de
data/README.md CHANGED
@@ -29,10 +29,15 @@ Run this command.
29
29
 
30
30
  $ rspec
31
31
 
32
+ ## Sample
33
+
34
+ ![output sample](https://github.com/crowdworks/captureful_formatter/blob/master/sample.png)
35
+
32
36
  ## Configuration
33
37
 
34
38
  ```ruby
35
39
  CapturefulFormatter.configure do |config|
40
+ c.project_name = "Your Project" # Title of test report
36
41
  c.output_directory = "./.captureful_formatter" # The path to where the test report is saved.
37
42
  c.template_path = "path/to/template" # your custom template file path.
38
43
  end
@@ -1,6 +1,7 @@
1
1
  require 'captureful_formatter/formatter'
2
2
  require 'captureful_formatter/notifications'
3
3
  require 'captureful_formatter/printer'
4
+ require 'captureful_formatter/structures'
4
5
  require 'captureful_formatter/version'
5
6
  require 'logger'
6
7
 
@@ -20,6 +21,8 @@ module CapturefulFormatter
20
21
  end
21
22
 
22
23
  class Configuration
24
+ attr_accessor :project_name
25
+
23
26
  attr_accessor :output_directory
24
27
 
25
28
  # what types to take screenshot
@@ -45,6 +48,7 @@ module CapturefulFormatter
45
48
  end
46
49
 
47
50
  CapturefulFormatter.configure do |c|
51
+ c.project_name = "Your Project"
48
52
  c.output_directory = "./.captureful_formatter"
49
53
  c.target_type = [:feature]
50
54
  c.template_path = File.join(File.dirname(__FILE__), "/../templates/test_report.html.erb")
@@ -1,5 +1,4 @@
1
1
  require 'capybara'
2
- require 'digest/md5'
3
2
  require 'fileutils'
4
3
  require 'rspec/core'
5
4
  require "rspec/core/formatters/base_formatter"
@@ -9,52 +8,54 @@ module CapturefulFormatter
9
8
  ::RSpec::Core::Formatters.register self, :start, :example_group_started, :example_group_finished,
10
9
  :example_started, :step_started, :example_passed, :example_pending, :example_failed, :stop
11
10
 
12
- Example = Struct.new("Example", :groups, :steps, :status, :fail_info)
13
- FailInfo = Struct.new("FailInfo", :exception, :backtraces)
14
-
15
11
  def start notification
16
12
  @should_capture = false
17
- @examples = {}
18
- @group_level = 0
19
- @group_examples = []
13
+ @features = []
20
14
  end
21
15
 
22
16
  def example_group_started notification
23
- @should_capture = CapturefulFormatter.configuration.target_type.include? notification.group.metadata[:type]
24
- @group_level += 1
25
- @group_examples.push notification.group.description
17
+ if notification.group.metadata[:parent_example_group].nil?
18
+ @should_capture = CapturefulFormatter.configuration.target_type.include? notification.group.metadata[:type]
19
+ @current_feature = CapturefulFormatter::Structures::Feature.new(notification)
20
+ else
21
+ @current_scenario = CapturefulFormatter::Structures::Scenario.new(notification)
22
+ end
26
23
  end
27
24
 
28
25
  def example_group_finished(notification)
29
- @should_capture = false
30
- @group_level -= 1
31
- @group_examples.pop
26
+ if notification.group.metadata[:parent_example_group].nil?
27
+ @features.push @current_feature
28
+ @should_capture = false
29
+ else
30
+ @current_feature.scenarios.push @current_scenario
31
+ end
32
32
  end
33
33
 
34
34
  def example_started notification
35
35
  return unless @should_capture
36
- @current_example_hash = Digest::MD5.hexdigest(@group_examples.join())
37
- @examples[@current_example_hash] = Example.new(@group_examples.dup, [] , nil, nil)
38
36
  end
39
37
 
40
38
  def step_started notification
41
- save_step_sessions notification.description
39
+ return unless @should_capture
40
+ @current_scenario.steps.push CapturefulFormatter::Structures::Step.new(notification)
41
+ save_step_sessions
42
42
  end
43
43
 
44
44
  def example_passed notification
45
45
  return unless @should_capture
46
- @examples[@current_example_hash].status = :passed
46
+
47
+ @current_scenario.status = :passed
47
48
  end
48
49
 
49
50
  def example_pending notification
50
51
  return unless @should_capture
51
- @examples[@current_example_hash].status = :pending
52
+ @current_scenario.status = :pending
52
53
  end
53
54
 
54
55
  def example_failed notification
55
56
  return unless @should_capture
56
- @examples[@current_example_hash].status = :failed
57
- @examples[@current_example_hash].fail_info = FailInfo.new(notification.exception.to_s, notification.formatted_backtrace.dup)
57
+ @current_scenario.status = :failed
58
+ @current_scenario.exception = notification.exception
58
59
  end
59
60
 
60
61
  def stop notification
@@ -71,18 +72,16 @@ module CapturefulFormatter
71
72
  @dir ||= Pathname.new(Dir.mktmpdir ["d", self.object_id.to_s ])
72
73
  end
73
74
 
74
- def save_step_sessions step_description
75
+ def save_step_sessions
75
76
  return unless @should_capture
76
- current_count = @examples[@current_example_hash].steps.size
77
- @examples[@current_example_hash].steps << step_description
78
- filename_base = report_save_dir.join("#{@current_example_hash}-#{current_count.to_s}")
77
+ filename_base = report_save_dir.join("#{@current_scenario.hash}-#{@current_scenario.step_count.to_s}")
79
78
  Capybara.current_session.save_page filename_base.sub_ext(".html")
80
79
  Capybara.current_session.save_screenshot filename_base.sub_ext(".png")
81
80
  end
82
81
 
83
82
  def publish_reports
84
83
  FileUtils.copy_entry report_save_dir, CapturefulFormatter.configuration.output_directory
85
- CapturefulFormatter::Printer.print @examples
84
+ CapturefulFormatter::Printer.print @features
86
85
  end
87
86
 
88
87
  def cleanup_reports
@@ -23,11 +23,11 @@ module CapturefulFormatter
23
23
  class << self
24
24
  attr_accessor :title
25
25
 
26
- def print examples
26
+ def print(features)
27
27
  path = template_path
28
28
  params = {
29
- title: "test report",
30
- examples: examples
29
+ title: CapturefulFormatter.configuration.project_name,
30
+ features: features
31
31
  }
32
32
  template = Template.new(params)
33
33
  filename = File.join(CapturefulFormatter.configuration.output_directory, "/index.html")
@@ -0,0 +1,71 @@
1
+ require 'digest/md5'
2
+
3
+ module CapturefulFormatter
4
+
5
+ # Data Structures for template files.
6
+ module Structures
7
+ class Feature
8
+ attr_accessor :scenarios
9
+ attr_accessor :description
10
+
11
+ # [notification]
12
+ # GroupNotification
13
+ def initialize(notification)
14
+ @description = notification.group.description
15
+ @scenarios = []
16
+ end
17
+
18
+ def all_passed
19
+ @scenarios.count == num_passed
20
+ end
21
+
22
+ def num_passed
23
+ @scenarios.count {|scenario| scenario.status == :passed }
24
+ end
25
+
26
+ def num_pending
27
+ @scenarios.count {|scenario| scenario.status == :pending }
28
+ end
29
+
30
+ def num_failed
31
+ @scenarios.count {|scenario| scenario.status == :failed }
32
+ end
33
+ end
34
+
35
+ class Scenario
36
+ attr_accessor :steps
37
+ attr_accessor :description
38
+ attr_accessor :status
39
+ attr_accessor :exception
40
+
41
+ # [notification]
42
+ # ExampleNotification
43
+ def initialize(notification)
44
+ @steps = []
45
+ @status = nil
46
+ @description = notification.group.description
47
+ @exception = nil
48
+ feature_description = notification.group.metadata[:parent_example_group][:description]
49
+ @hash = Digest::MD5.hexdigest("#{feature_description}#{notification.group.description}")
50
+ end
51
+
52
+ def hash
53
+ @hash
54
+ end
55
+
56
+ def step_count
57
+ @steps.size
58
+ end
59
+ end
60
+
61
+ class Step
62
+ attr_accessor :description
63
+
64
+ # [notification]
65
+ # StepNotification
66
+ def initialize(notification)
67
+ @description = notification.description
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,3 +1,3 @@
1
1
  module CapturefulFormatter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
Binary file
@@ -44,6 +44,8 @@ describe CapturefulFormatter::Formatter do
44
44
  before do
45
45
  allow(RSpec::Core::ExampleGroup).to receive(:metadata).and_return({type: :feature})
46
46
  formatter.example_group_started group_notification
47
+ allow(RSpec::Core::ExampleGroup).to receive(:metadata).and_return({type: :feature, parent_example_group: {description: "test feature"}})
48
+ formatter.example_group_started group_notification
47
49
  end
48
50
 
49
51
  describe "at step by steps" do
@@ -3,7 +3,10 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <title><%= title %></title>
6
- <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
6
+ <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" media="screen">
7
+ <style type="text/css">
8
+ body { background-color: #ececec; }
9
+ </style>
7
10
  </head>
8
11
  <body>
9
12
  <nav class="navbar navbar-inverse navbar-static-top">
@@ -16,48 +19,77 @@
16
19
 
17
20
  <div class="container">
18
21
  <div class="row">
19
- <h2 id="index">index</h2>
20
- <ul>
21
- <% examples.each do |example_hash, example| %>
22
- <li class="<%= background_by_status example.status %>"><a href="#<%= example_hash %>"><%= example.groups.join(" - ") %></a></li>
23
- <% end %>
24
- </ul>
25
- </div>
26
- </div>
27
-
28
- <div class="container">
29
- <div class="row">
30
- <h2>examples</h2>
31
- <% examples.each do |example_hash, example| %>
32
- <h3 id=<%= example_hash %>><%= example.groups.join(" - ") %></h3>
33
- <% example.steps.each_with_index do |step, index| %>
34
- <div class="row <%= (example.steps.size - 1 == index)? background_by_status(example.status) : "" %>">
35
- <div class="col-md-5">
36
- <a href="./<%= example_hash %>-<%= index %>.png">
37
- <img class="img-rounded" height="256" wedth="320" src="./<%= example_hash %>-<%= index %>.png">
38
- </a>
39
- </div>
40
- <div class="col-md-6">
41
- <p><%= step %><p>
42
- <% if example.steps.size - 1 == index %>
43
- <% unless example.fail_info.nil? %>
44
- <p><%= example.fail_info.exception %></p>
45
- <ul>
46
- <% example.fail_info.backtraces.each do |backtrace| %>
47
- <li><%= backtrace %></li>
48
- <% end %>
49
- </ul>
50
- <% end %>
22
+ <div class="col-md-3">
23
+ <ul class="nav nav-list affix">
24
+ <% features.each do |feature| %>
25
+ <li>
26
+ <a href="#<%= feature.description %>">
27
+ <%= feature.description %>
28
+ <% if feature.all_passed %>
29
+ <span class="label label-success">all passed</span>
51
30
  <% end %>
52
- </div>
53
- </div><!-- row -->
31
+ <% if feature.num_failed > 0 %>
32
+ <span class="badge alert-danger"><%= feature.num_failed %></span>
33
+ <% end %>
34
+ <% if feature.num_pending > 0 %>
35
+ <span class="badge alert-warning"><%= feature.num_pending %></span>
36
+ <% end %>
37
+ </a>
38
+ </li>
39
+ <% end %>
40
+ </ul>
41
+ </div>
42
+ <div class="col-md-9">
43
+ <!-- Test Report -->
44
+ <div class="page-header">
45
+ <h1><%= title %> <small>test report</small></h1>
46
+ </div>
47
+ <% features.each do |feature| %>
48
+ <section id="<%= feature.description %>">
49
+ <h2><%= feature.description %></h2>
50
+ <ol>
51
+ <% feature.scenarios.each do |scenario| %>
52
+ <li>
53
+ <a href="#<%= scenario.hash %>">
54
+ <%= scenario.description %>
55
+ <% if scenario.status == :passed %>
56
+ <span class="label label-success">passed</span>
57
+ <% elsif scenario.status == :pending %>
58
+ <span class="label label-warning">pending</span>
59
+ <% else %>
60
+ <span class="label label-danger">failed</span>
61
+ <% end %>
62
+ </a>
63
+ </li>
64
+ <% end %>
65
+ </ol>
66
+ <% feature.scenarios.each do |scenario| %>
67
+ <section id="<%= scenario.hash %>">
68
+ <h3><%= scenario.description %></h3>
69
+ <% scenario.steps.each_with_index do |step, index| %>
70
+ <div class="row <%= (scenario.step_count - 1 == index)? background_by_status(scenario.status) : "" %>">
71
+ <div class="col-md-6">
72
+ <a href="./<%= scenario.hash %>-<%= index + 1 %>.png">
73
+ <img class="img-thumbnail" height="256" wedth="320" src="./<%= scenario.hash %>-<%= index + 1 %>.png">
74
+ </a>
75
+ </div>
76
+ <div class="col-md-6">
77
+ <p><%= step.description %><p>
78
+ <% if ((scenario.step_count - 1) == index) && scenario.status == :failed && !scenario.exception.nil? %>
79
+ <p><%= scenario.exception.to_s %></p>
80
+ <% end %>
81
+ </div>
82
+ </div><!-- row -->
83
+ <hr />
84
+ <% end %>
85
+ </section>
86
+ <% end %>
87
+ </section>
54
88
  <% end %>
55
- <hr />
56
- <% end %>
89
+ <!-- Test Report -->
90
+ </div>
57
91
  </div>
58
92
  </div>
59
-
60
-
61
93
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
62
94
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
63
95
  </body>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: captureful_formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Atsushi Yasuda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-21 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -100,8 +100,10 @@ files:
100
100
  - lib/captureful_formatter/notifications.rb
101
101
  - lib/captureful_formatter/printer.rb
102
102
  - lib/captureful_formatter/rspec_ext/rspec_core_reporter.rb
103
+ - lib/captureful_formatter/structures.rb
103
104
  - lib/captureful_formatter/turnip_ext/turnip_rspec_execute.rb
104
105
  - lib/captureful_formatter/version.rb
106
+ - sample.png
105
107
  - spec/captureful_formatter/formatter_spec.rb
106
108
  - spec/captureful_formatter/printer_spec.rb
107
109
  - spec/captureful_formatter_spec.rb