nanonano87-cucumber_statistics 0.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 (34) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +20 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +46 -0
  8. data/README.md +44 -0
  9. data/Rakefile +7 -0
  10. data/cucumber_statistics.gemspec +38 -0
  11. data/lib/cucumber_statistics.rb +8 -0
  12. data/lib/cucumber_statistics/autoload.rb +5 -0
  13. data/lib/cucumber_statistics/configuration.rb +56 -0
  14. data/lib/cucumber_statistics/feature_statistics.rb +28 -0
  15. data/lib/cucumber_statistics/formatter.rb +101 -0
  16. data/lib/cucumber_statistics/overall_statistics.rb +29 -0
  17. data/lib/cucumber_statistics/renderer.rb +30 -0
  18. data/lib/cucumber_statistics/renderer_helper.rb +102 -0
  19. data/lib/cucumber_statistics/scenario_statistics.rb +28 -0
  20. data/lib/cucumber_statistics/step_statistics.rb +91 -0
  21. data/lib/cucumber_statistics/unused_steps.rb +18 -0
  22. data/lib/cucumber_statistics/version.rb +3 -0
  23. data/lib/cucumber_statistics/view/combined_statistics.html +299 -0
  24. data/lib/cucumber_statistics/view/combined_statistics.html.haml +169 -0
  25. data/notes.txt +9 -0
  26. data/spec/cucumber_statistics/configuration_spec.rb +20 -0
  27. data/spec/cucumber_statistics/feature_statistics_spec.rb +78 -0
  28. data/spec/cucumber_statistics/renderer_helper_spec.rb +27 -0
  29. data/spec/cucumber_statistics/renderer_spec.rb +71 -0
  30. data/spec/cucumber_statistics/scenario_statistics_spec.rb +86 -0
  31. data/spec/cucumber_statistics/step_statistics_spec.rb +199 -0
  32. data/spec/cucumber_statistics/unused_steps_spec.rb +39 -0
  33. data/spec/spec_helper.rb +9 -0
  34. metadata +184 -0
@@ -0,0 +1,169 @@
1
+ !!!
2
+ %html{:lang => "en"}
3
+ %head
4
+ %meta{:charset => "utf-8"}/
5
+ %meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
6
+ %meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
7
+ %meta{:content => "Cucumber Scenario Statistics", :name => "description"}/
8
+ %meta{:content => "AlienFast", :name => "author"}/
9
+ %title Cucumber Scenario Statistics
10
+ / Bootstrap core CSS
11
+ %link{:href => "http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css", :rel => "stylesheet"}/
12
+ / Custom styles for this layout
13
+ :css
14
+ body {
15
+ min-height: 2000px;
16
+ padding-top: 70px;
17
+ }
18
+
19
+ td {
20
+ white-space: nowrap;
21
+ /*max-width: 100px;*/
22
+ }
23
+ tr td:first-child {
24
+ overflow: hidden;
25
+ text-overflow: ellipsis;
26
+ max-width: 300px;
27
+ }
28
+ %link{:href => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Contents/bootstrap-sortable.css", :rel => "stylesheet"}/
29
+ / HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
30
+ /[if lt IE 9]
31
+ <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
32
+ <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
33
+ %body
34
+ / Fixed navbar
35
+ .navbar.navbar-default.navbar-fixed-top{:role => "navigation"}
36
+ .container
37
+ .navbar-header
38
+ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", :type => "button"}
39
+ %span.sr-only Toggle navigation
40
+ %span.icon-bar
41
+ %span.icon-bar
42
+ %span.icon-bar
43
+ %a.navbar-brand{:href => "#"} cucumber_statistics
44
+ .navbar-collapse.collapse
45
+ %ul.nav.navbar-nav.navbar-right
46
+ %li
47
+ %a{:href => "https://github.com/alienfast/cucumber_statistics", :target => 'other'} Github
48
+ / /.nav-collapse
49
+
50
+ .container
51
+ .navbar
52
+ .tabbable
53
+ %ul.nav.nav-tabs
54
+ %li.active
55
+ %a.content_tab{:href => "#steps_tab",:toggle=>"tab"}
56
+ Steps
57
+ %li
58
+ %a.content_tab{:href => "#scenarios_tab", :toggle=>"tab"}
59
+ Scenarios
60
+ %li
61
+ %a.content_tab{:href => "#features_tab", :toggle=>"tab"}
62
+ Features
63
+
64
+ .container
65
+ .tab-content
66
+ #steps_tab.tab-pane.active
67
+ / Main component for a primary marketing message or call to action
68
+ .jumbotron
69
+ %h1 Cucumber step statistics
70
+ %p ... allows you to easily identify long running steps.
71
+
72
+ .alert.alert-info
73
+ #{alert_info_text(overall_statistics)}
74
+
75
+ %table.table.table-bordered.table-striped.sortable
76
+ %thead
77
+ %tr
78
+ %th Step
79
+ %th Fastest
80
+ %th Slowest
81
+ %th Variation
82
+ %th Variance
83
+ %th Std Deviation
84
+ %th Count
85
+ %th Average
86
+ %th{"data-defaultsort" => "desc"} Total
87
+ %tbody
88
+
89
+ - highest_average = step_statistics.highest_average
90
+ - highest_total = step_statistics.highest_total
91
+ - highest_variation = step_statistics.highest_variation
92
+
93
+ - step_statistics.all.each do |step_results|
94
+
95
+ %tr
96
+ = name_td step_results
97
+ = time_td step_results, :fastest
98
+ = time_td step_results, :slowest
99
+ = time_td step_results, :variation, highest_variation
100
+ = time_td step_results, :variance
101
+ = time_td step_results, :standard_deviation
102
+ = count_td step_results, :count
103
+ = time_td step_results, :average, highest_average
104
+ = time_td step_results, :total, highest_total
105
+ / /container
106
+
107
+
108
+ #scenarios_tab.tab-pane
109
+ / Main component for a primary marketing message or call to action
110
+ .jumbotron
111
+ %h1 Cucumber scenario statistics
112
+ %p ... find those slow scenarios.
113
+
114
+ .alert.alert-info
115
+ #{alert_info_text(overall_statistics)}
116
+
117
+ %table.table.table-bordered.table-striped.sortable
118
+ %thead
119
+ %tr
120
+ %th Scenario File
121
+ %th{"data-defaultsort" => "desc"} Time
122
+ %tbody
123
+ - scenario_statistics.all.each do |file_name, scenario_result|
124
+ %tr
125
+ = std_file_td file_name, scenario_result[:scenario_name]
126
+ = std_time_td scenario_result[:duration]
127
+ / /container
128
+
129
+
130
+ #features_tab.tab-pane
131
+ / Main component for a primary marketing message or call to action
132
+ .jumbotron
133
+ %h1 Cucumber feature statistics
134
+ %p ... find those slow features.
135
+
136
+ .alert.alert-info
137
+ #{alert_info_text(overall_statistics)}
138
+
139
+ %table.table.table-bordered.table-striped.sortable
140
+ %thead
141
+ %tr
142
+ %th Feature File
143
+ %th{"data-defaultsort" => "desc"} Time
144
+ %tbody
145
+ - feature_statistics.all.each do |file_name, feature_result|
146
+
147
+ %tr
148
+ = std_file_td file_name, feature_result[:feature_name]
149
+ = std_time_td feature_result[:duration]
150
+ / /container
151
+
152
+
153
+
154
+ / Bootstrap core JavaScript
155
+ / \==================================================
156
+ / Placed at the end of the document so the pages load faster
157
+ %script{:src => "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"}
158
+ %script{:src => "http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"}
159
+ %script{:src => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/moment.min.js"}
160
+ %script{:src => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/bootstrap-sortable.js"}
161
+ :javascript
162
+ // Initialise on DOM ready
163
+ $(function() {
164
+ $.bootstrapSortable(true, 'reversed');
165
+ });
166
+ $('a.content_tab').click(function (e) {
167
+ e.preventDefault();
168
+ $(e.target).tab('show');
169
+ });
@@ -0,0 +1,9 @@
1
+ http://www.oesmith.co.uk/morris.js/lines.html
2
+ http://drvic10k.github.io/bootstrap-sortable/
3
+
4
+ http://stackoverflow.com/questions/6125265/using-layouts-in-haml-files-independently-of-rails
5
+ http://getbootstrap.com/examples/navbar-fixed-top/
6
+
7
+
8
+ Total time of run
9
+ file path/name/line number of step
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe Configuration do
5
+
6
+ before do
7
+ Configuration.clean_tmp_dir
8
+ end
9
+
10
+ it 'should auto create tmp_dir' do
11
+
12
+ tmp_dir = Configuration.tmp_dir
13
+ expect(Dir.exists?(tmp_dir)).to be_truthy
14
+
15
+ Dir.delete tmp_dir
16
+ tmp_dir = Configuration.tmp_dir
17
+ expect(Dir.exists?(tmp_dir)).to be_truthy
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe FeatureStatistics do
5
+
6
+ subject(:feature_statistics) { FeatureStatistics.new }
7
+ subject(:overall_statistics) { OverallStatistics.new } #not sure if really need
8
+
9
+ describe 'record' do
10
+ it 'should create a record' do
11
+ record 'my feature', 50, 'features/admin_cancel_account.feature'
12
+
13
+ expect(feature_statistics.all.count).to eq 1
14
+ expect(feature_statistics.all['features/admin_cancel_account.feature'][:duration]).to eq 50
15
+ end
16
+
17
+ it 'should support multiple scenarios with the same name' do
18
+ record 'my feature', 50, 'admin_cancel_account.feature'
19
+ record 'my feature', 75, 'noise/features/super_admin/admin_cancel_account.feature'
20
+
21
+ expect(feature_statistics.all.count).to eq 2
22
+ expect(feature_statistics.all['admin_cancel_account.feature'][:duration]).to eq 50
23
+ expect(feature_statistics.all['features/super_admin/admin_cancel_account.feature'][:duration]).to eq 75
24
+ end
25
+
26
+ it 'chops off file path up to features/' do
27
+ record 'my feature', 50, '/User/some/file/path/that/doesnt/matter really/features/admin_cancel_account.feature'
28
+ expect(feature_statistics.all.keys.first).to eq 'features/admin_cancel_account.feature'
29
+ end
30
+
31
+ it 'uses the whole string if the filepath doesnt include the features folder' do
32
+ record 'my feature', 50, 'admin_cancel_account.feature'
33
+ expect(feature_statistics.all.keys.first).to eq 'admin_cancel_account.feature'
34
+ end
35
+ end
36
+
37
+ describe 'all' do
38
+ before(:each) do
39
+ record 'my feature', 24, 'admin_cancel_account.feature'
40
+ record 'my feature', 50, 'admin_edit_account.feature'
41
+ end
42
+
43
+ it 'should return all records' do
44
+ expect(feature_statistics.all.count).to eq 2
45
+ feature_statistics.all.each_with_index do |file_colon_line, data, index|
46
+ case index
47
+ when 1
48
+ expect(file_colon_line).to eq 'admin_cancel_account.feature'
49
+ when 2
50
+ expect(file_colon_line).to eq 'admin_edit_account.feature'
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'set operations' do
57
+ before(:each) do
58
+ record 'a', 25, 'admin_cancel_account.feature'
59
+ record 'c', 51, 'view_account.feature'
60
+ record 'b', 75, 'edit_account.feature'
61
+ end
62
+
63
+ describe 'sort_by_property' do
64
+ context 'should sort all records by any property' do
65
+ it { expect(feature_statistics.sort_by_property(:feature_name).first[0]).to eq 'admin_cancel_account.feature' }
66
+ it { expect(feature_statistics.sort_by_property(:feature_name).last[0]).to eq 'view_account.feature' }
67
+
68
+ it { expect(feature_statistics.sort_by_property(:duration).first[0]).to eq 'admin_cancel_account.feature' }
69
+ it { expect(feature_statistics.sort_by_property(:duration).last[0]).to eq 'edit_account.feature' }
70
+ end
71
+ end
72
+ end
73
+
74
+ def record(feature_name, duration, file)
75
+ feature_statistics.record feature_name, duration, file
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe RendererHelper do
5
+
6
+ describe '#format' do
7
+ it 'formats milliseconds' do
8
+ assert_format(0.000123, '< 0.000s')
9
+ end
10
+ it 'formats seconds' do
11
+ assert_format(3.123456, '3.123s')
12
+ end
13
+ it 'formats minutes' do
14
+ assert_format(60, '1m 0.000s')
15
+ assert_format(60.12345, '1m 0.123s')
16
+ end
17
+ it 'formats hours' do
18
+ assert_format(3600, '1h 0m 0.000s')
19
+ assert_format(3600.12345, '1h 0m 0.123s')
20
+ end
21
+ end
22
+
23
+ def assert_format(duration, expectation)
24
+ expect(RendererHelper.new.format duration).to eq(expectation)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe Renderer do
5
+
6
+ subject(:step_statistics) { StepStatistics.new }
7
+ subject(:scenario_statistics) { ScenarioStatistics.new }
8
+ subject(:feature_statistics) { FeatureStatistics.new }
9
+ subject(:overall_statistics) { OverallStatistics.new }
10
+
11
+ before(:each) do
12
+ # clean up before start, leave after in case we want to inspect it.
13
+ Configuration.clean_tmp_dir
14
+
15
+ overall_statistics.start_time = Time.now - 35
16
+ overall_statistics.feature_count_inc
17
+ overall_statistics.scenario_count_inc
18
+
19
+ record 'my step 1', 1.100116
20
+ record 'my step 1', 9.213553
21
+ record 'my step 2', 3.100117
22
+ record 'my step 2', 14.204407
23
+ record 'my step 3', 1.500131
24
+ record 'my step 3', 3.48993
25
+ record 'my step 4', 4.21
26
+ record 'my step 4', 4.21
27
+
28
+ record_scenario 'my scenario 1', 10.2, '/Users/kross/alienfast/acme/features/account management/admin_cancel_account.feature:8'
29
+ record_scenario 'my scenario 2', 30.2, '/Users/kross/alienfast/acme/features/account management/admin_cancel_account.feature:13'
30
+ record_scenario 'my scenario 3', 17.342, '/Users/kross/alienfast/acme/features/user experience/view.feature:2'
31
+ record_scenario 'my scenario 3', 3.2, '/Users/kross/alienfast/acme/features/user experience/view.feature:23'
32
+
33
+ record_feature 'my admin feature', 50, '/Users/kross/alienfast/acme/features/account management/admin_cancel_account.feature'
34
+ record_feature 'my user feature', 50, '/Users/kross/alienfast/acme/features/user experience/view.feature'
35
+
36
+ overall_statistics.end_time = Time.now
37
+ step_statistics.calculate
38
+ end
39
+
40
+
41
+ describe 'render statistics' do
42
+ context 'should render content' do
43
+
44
+ it 'renders combined results file' do
45
+ expect(File.exists?(Configuration.result_combined_statistics)).to eql false
46
+ absolute_file_name = Renderer.render_combined_statistics step_statistics, scenario_statistics, feature_statistics, overall_statistics
47
+ expect(File.exists?(absolute_file_name)).to eql true
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+ def record(step_name, duration)
54
+ # fake a source for convenience
55
+ step_statistics.record step_name, duration, '/Users/kross/alienfast/acme/features/account management/admin_cancel_account.feature:8'
56
+ overall_statistics.step_count_inc
57
+ end
58
+
59
+ def record_scenario(scenario_name, duration, file_colon_line)
60
+ # fake a source for convenience
61
+ scenario_statistics.record scenario_name, duration, file_colon_line
62
+ overall_statistics.scenario_count_inc
63
+ end
64
+
65
+ def record_feature(feature_name, duration, file_colon_line)
66
+ # fake a source for convenience
67
+ feature_statistics.record feature_name, duration, file_colon_line
68
+ overall_statistics.feature_count_inc
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe ScenarioStatistics do
5
+
6
+ subject(:scenario_statistics) { ScenarioStatistics.new }
7
+ subject(:overall_statistics) { OverallStatistics.new } #not sure if really need
8
+
9
+ describe 'record' do
10
+ it 'should create a record' do
11
+ record 'my scenario', 50, 'features/admin_cancel_account.feature:8'
12
+
13
+ expect(scenario_statistics.all.count).to eq 1
14
+ expect(scenario_statistics.all['features/admin_cancel_account.feature:8'][:duration]).to eq 50
15
+ end
16
+
17
+ it 'should support multiple scenarios with the same name' do
18
+ record 'my scenario', 50, 'admin_cancel_account.feature:8'
19
+ record 'my scenario', 75, 'noise/features/super_admin/admin_cancel_account.feature:8'
20
+
21
+ expect(scenario_statistics.all.count).to eq 2
22
+ expect(scenario_statistics.all['admin_cancel_account.feature:8'][:duration]).to eq 50
23
+ expect(scenario_statistics.all['features/super_admin/admin_cancel_account.feature:8'][:duration]).to eq 75
24
+ end
25
+
26
+ it 'chops off file path up to features/' do
27
+ record 'my scenario', 50, '/User/some/file/path/that/doesnt/matter really/features/admin_cancel_account.feature:8'
28
+ expect(scenario_statistics.all.keys.first).to eq 'features/admin_cancel_account.feature:8'
29
+ end
30
+
31
+ it 'uses the whole string if the filepath doesnt include the features folder' do
32
+ record 'my scenario', 50, 'admin_cancel_account.feature:8'
33
+ expect(scenario_statistics.all.keys.first).to eq 'admin_cancel_account.feature:8'
34
+ end
35
+ end
36
+
37
+ describe 'all' do
38
+ before(:each) do
39
+ record 'my scenario 1', 24, 'admin_cancel_account.feature:8'
40
+ record 'my scenario 1', 50, 'admin_cancel_account.feature:18'
41
+ record 'my scenario 2', 75, 'admin_cancel_account.feature:38'
42
+ end
43
+
44
+ it 'should return all records' do
45
+ expect(scenario_statistics.all.count).to eq 3
46
+ scenario_statistics.all.each_with_index do |file_colon_line, data, index|
47
+ case index
48
+ when 1
49
+ expect(file_colon_line).to eq 'admin_cancel_account.feature:8'
50
+ when 2
51
+ expect(file_colon_line).to eq 'admin_cancel_account.feature:18'
52
+ when 3
53
+ expect(file_colon_line).to eq 'admin_cancel_account.feature:38'
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'set operations' do
60
+ before(:each) do
61
+ record 'my scenario 1', 25, 'admin_cancel_account.feature:8'
62
+ record 'my scenario 2', 50, 'admin_cancel_account.feature:13'
63
+ record 'my scenario 3', 49, 'admin_cancel_account.feature:15'
64
+ record 'my scenario 1', 51, 'view_account.feature:3'
65
+ record 'my scenario 2', 75, 'view_account.feature:6'
66
+ record 'my scenario 3', 10, 'view_account.feature:22'
67
+ end
68
+
69
+ describe 'sort_by_property' do
70
+ context 'should sort all records by any property' do
71
+ it { expect(scenario_statistics.sort_by_property(:scenario_name).first[0]).to eq 'admin_cancel_account.feature:8' }
72
+ it { expect(scenario_statistics.sort_by_property(:scenario_name).last[0]).to eq 'view_account.feature:22' }
73
+
74
+ it { expect(scenario_statistics.sort_by_property(:duration).first[0]).to eq 'view_account.feature:22' }
75
+ it { expect(scenario_statistics.sort_by_property(:duration).last[0]).to eq 'view_account.feature:6' }
76
+ end
77
+ end
78
+ end
79
+
80
+ def record(scenario_name, duration, file_colon_line)
81
+ # fake a source for convenience
82
+ scenario_statistics.record scenario_name, duration, file_colon_line
83
+ #overall_statistics.step_count_inc
84
+ end
85
+ end
86
+ end