chemistrykit 3.9.0.rc2 → 3.9.0.rc3

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 (35) hide show
  1. data/CHANGELOG.md +8 -1
  2. data/Gemfile +2 -1
  3. data/README.md +3 -3
  4. data/TODO.md +2 -0
  5. data/chemistrykit.gemspec +2 -3
  6. data/features/basic_auth.feature +0 -1
  7. data/features/chemists.feature +13 -5
  8. data/features/exit_status.feature +0 -1
  9. data/features/reporting.feature +0 -3
  10. data/features/split_testing.feature +29 -0
  11. data/features/step_definitions/steps.rb +1 -1
  12. data/features/tags.feature +0 -1
  13. data/lib/chemistrykit/cli/cli.rb +10 -15
  14. data/lib/chemistrykit/config/basic_auth.rb +37 -0
  15. data/lib/chemistrykit/config/split_testing.rb +26 -0
  16. data/lib/chemistrykit/configuration.rb +15 -4
  17. data/lib/chemistrykit/reporting/html_report_assembler.rb +40 -2
  18. data/lib/chemistrykit/rspec/html_formatter.rb +5 -0
  19. data/lib/chemistrykit/split_testing/optimizely_provider.rb +21 -0
  20. data/lib/chemistrykit/split_testing/provider_factory.rb +18 -0
  21. data/report/index.html +81 -1
  22. data/report/sass/app.scss +54 -2
  23. data/report/stylesheets/app.css +820 -116
  24. data/spec/integration/lib/chemistrykit/split_testing/provider_factory_spec.rb +15 -0
  25. data/spec/spec_helper.rb +0 -6
  26. data/spec/support/config.yaml +8 -0
  27. data/spec/unit/lib/chemistrykit/catalyst_spec.rb +1 -0
  28. data/spec/unit/lib/chemistrykit/cli/helpers/formula_loader_spec.rb +1 -0
  29. data/spec/unit/lib/chemistrykit/config/basic_auth_spec.rb +76 -0
  30. data/spec/unit/lib/chemistrykit/config/split_testing_spec.rb +31 -0
  31. data/spec/unit/lib/chemistrykit/configuration_spec.rb +30 -0
  32. data/spec/unit/lib/chemistrykit/formula/base_spec.rb +1 -0
  33. data/spec/unit/lib/chemistrykit/split_testing/optimizely_provider_spec.rb +42 -0
  34. data/spec/unit/lib/chemistrykit/split_testing/provider_factory_spec.rb +22 -0
  35. metadata +21 -5
@@ -1,5 +1,12 @@
1
+ #3.9.0-rc.3 (2013-08-19)
2
+ - added toggle for parts of html reports
3
+ - added a fix to allow jenkins ci server to show the html report images
4
+ - integrated new selenium connect
5
+ - updates to configurations
6
+ - integrated optimizely opt out
7
+
1
8
  #3.9.0-rc.2 (2013-08-14)
2
- Added Basic Auth Support. Preserving release candidate numbering since there are improvements to be made to HTTP reporting
9
+ - Added Basic Auth Support. Preserving release candidate numbering since there are improvements to be made to HTTP reporting
3
10
 
4
11
  #3.9.0-rc.1 (2013-08-12)
5
12
  Release candidate with new features including
data/Gemfile CHANGED
@@ -15,7 +15,8 @@ gem 'ruby2ruby'
15
15
  gem 'reek', '1.3.1'
16
16
  gem 'guard-reek'
17
17
  gem 'guard-rubocop'
18
-
19
18
  gem "selenium-client", "~> 1.2.18"
20
19
  gem 'compass'
21
20
  gem 'zurb-foundation'
21
+
22
+
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #ChemistryKit 3.9.0-rc.2 (2013-08-14)
1
+ #ChemistryKit 3.9.0.rc3 (2013-08-19)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/chemistrykit.png)](http://badge.fury.io/rb/chemistrykit) [![Build Status](https://travis-ci.org/arrgyle/chemistrykit.png?branch=develop)](https://travis-ci.org/jrobertfox/chef-broiler-platter) [![Code Climate](https://codeclimate.com/github/arrgyle/chemistrykit.png)](https://codeclimate.com/github/arrgyle/chemistrykit) [![Coverage Status](https://coveralls.io/repos/arrgyle/chemistrykit/badge.png?branch=develop)](https://coveralls.io/r/arrgyle/chemistrykit?branch=develop)
4
4
 
@@ -138,11 +138,11 @@ Here is a summary of the other methods available:
138
138
  Using `.and_with` lets you mix up various sets of user data. For example:
139
139
 
140
140
  @formula_lab.using('my_formula').with('admin1').and_with('sub_account1').mix
141
-
141
+
142
142
  Would get you (assuming `sub_account1` has a type of `sub_account`, and a field `my_sub_field`) the ability to do something like this:
143
143
 
144
144
  chemist.sub_account.my_sub_field
145
-
145
+
146
146
  Inside your formula. COOL!
147
147
 
148
148
 
data/TODO.md CHANGED
@@ -14,3 +14,5 @@
14
14
  - opera
15
15
  - chrome
16
16
  - flex pilot (for flex/flash support)
17
+
18
+ - add documentation about basic auth and a/b testing for final 3.9 release
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'chemistrykit'
5
- s.version = '3.9.0.rc2'
5
+ s.version = '3.9.0.rc3'
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ['Dave Haeffner', 'Jason Fox']
8
8
  s.email = ['dave@arrgyle.com', 'jason@arrgyle.com']
@@ -24,12 +24,11 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency 'builder', '~> 3.2.2'
25
25
  s.add_dependency 'selenium-webdriver', '~> 2.29.0'
26
26
  s.add_dependency 'rest-client', '~> 1.6.7'
27
- s.add_dependency 'selenium-connect', '~> 3.5.0'
27
+ s.add_dependency 'selenium-connect', '~> 3.6.0'
28
28
  s.add_dependency 'parallel_tests', '~> 0.15.0'
29
29
  s.add_dependency 'parallel', '~> 0.7.0'
30
30
  s.add_dependency 'rspec-retry', '~> 0.2.1'
31
31
  s.add_dependency 'nokogiri', '~> 1.6.0'
32
-
33
32
  s.add_dependency 'syntax'
34
33
  s.add_dependency 'pygments.rb', '~> 0.5.2'
35
34
  end
@@ -16,7 +16,6 @@ Background:
16
16
  end
17
17
  end
18
18
  """
19
-
20
19
  Scenario: Pre-load HTTP before each test
21
20
  And a file named "config.yaml" with:
22
21
  """
@@ -11,6 +11,13 @@ Feature: Brewing a ChemistryKit project
11
11
  ran1,random,normal@email.com,Ms. Normal,test123%
12
12
  ran2,random,normal@email.com,Ms. Normal,test123%
13
13
  """
14
+ And I overwrite config.yaml with:
15
+ """
16
+ screenshot_on_fail: true
17
+ selenium_connect:
18
+ log: 'evidence'
19
+ browser: 'firefox'
20
+ """
14
21
  And a file named "formulas/basic_formula.rb" with:
15
22
  """
16
23
  module Formulas
@@ -76,13 +83,13 @@ Feature: Brewing a ChemistryKit project
76
83
  @driver.get url
77
84
  end
78
85
 
79
- def find(locator)
80
- @driver.find_element locator
86
+ def find(locater)
87
+ @driver.find_element locater
81
88
  end
82
89
 
83
- def displayed?(locator)
90
+ def displayed?(locater)
84
91
  begin
85
- find(locator).displayed?
92
+ find(locater).displayed?
86
93
  rescue
87
94
  false
88
95
  end
@@ -154,6 +161,7 @@ Feature: Brewing a ChemistryKit project
154
161
  When I run `ckit brew`
155
162
  Then the stdout should contain "2 examples, 0 failures"
156
163
 
164
+ @announce
157
165
  Scenario: Composing a chemist from multiple files
158
166
  Given a file named "beakers/chemist_beaker.rb" with:
159
167
  """
@@ -170,7 +178,7 @@ Feature: Brewing a ChemistryKit project
170
178
  And a file named "chemists/others.csv" with:
171
179
  """
172
180
  Key,Type,Item
173
- other1,some_sub_account,some_item
181
+ other1,some_sub_account,some
174
182
  """
175
183
  When I run `ckit brew`
176
184
  Then the stdout should contain "1 example, 0 failures"
@@ -23,7 +23,6 @@ Feature: Exit Status
23
23
  When I run `ckit brew`
24
24
  Then the exit code should be 0
25
25
 
26
- @announce
27
26
  Scenario: Failing
28
27
  And a file named "beakers/test_beaker.rb" with:
29
28
  """
@@ -48,14 +48,12 @@ Feature: Advanced HTML Reports
48
48
  browser: 'firefox'
49
49
  """
50
50
 
51
- @announce
52
51
  Scenario: I can run the tests
53
52
  When I run `ckit brew`
54
53
  Then the stdout should contain "5 examples, 3 failures, 1 pending"
55
54
  And the following files should exist:
56
55
  | evidence/final_results.html |
57
56
 
58
- @announce
59
57
  Scenario: I can run the tests local with concurrency
60
58
  Given I overwrite config.yaml with:
61
59
  """
@@ -70,7 +68,6 @@ Feature: Advanced HTML Reports
70
68
  And the following files should exist:
71
69
  | evidence/final_results.html |
72
70
 
73
- @announce
74
71
  Scenario: I can run the tests with concurrency
75
72
  Given I overwrite config.yaml with:
76
73
  """
@@ -0,0 +1,29 @@
1
+ Feature: opting out of ab tests based on configuration
2
+
3
+ Background:
4
+ Given I run `ckit new split-test`
5
+ And I cd to "split-test"
6
+ And a file named "beakers/first_beaker.rb" with:
7
+ """
8
+ describe "Split test beaker", :depth => 'shallow' do
9
+ it "would not hit the ab testing end point" do
10
+ @driver.get 'http://the-internet.herokuapp.com/abtest'
11
+ @driver.find_element(css: 'h3').text.should == 'No A/B Test'
12
+ end
13
+ end
14
+ """
15
+ And I overwrite config.yaml with:
16
+ """
17
+ screenshot_on_fail: true
18
+ base_url: 'http://the-internet.herokuapp.com/abtest'
19
+ selenium_connect:
20
+ log: 'evidence'
21
+ browser: 'firefox'
22
+ split_testing:
23
+ provider: 'optimizely'
24
+ opt_out: true
25
+ """
26
+
27
+ Scenario: opt out is on
28
+ When I run `ckit brew`
29
+ Then the stdout should contain "1 example, 0 failures"
@@ -30,7 +30,7 @@ Then(/^there should be "(.*?)" "(.*?)" log files in "(.*?)"$/) do |number, type,
30
30
  when 'report'
31
31
  count += 1 if file =~ /sauce_job\.log/
32
32
  when 'sauce log'
33
- count += 1 if file =~ /server\.log/
33
+ count += 1 if file =~ /server\.log/
34
34
  end
35
35
  end
36
36
  count.should == number.to_i
@@ -7,7 +7,6 @@ Feature: Listing all the tags
7
7
  Given I run `ckit new tags-test`
8
8
  And I cd to "tags-test"
9
9
 
10
- @announce
11
10
  Scenario: Get the tag for a single beaker
12
11
  Given a file named "beakers/bookie_beaker.rb" with:
13
12
  """
@@ -21,6 +21,8 @@ require 'rspec/core/formatters/html_formatter'
21
21
  require 'chemistrykit/rspec/html_formatter'
22
22
 
23
23
  require 'chemistrykit/reporting/html_report_assembler'
24
+ require 'chemistrykit/split_testing/provider_factory'
25
+
24
26
  module ChemistryKit
25
27
  module CLI
26
28
 
@@ -124,7 +126,6 @@ module ChemistryKit
124
126
  protected
125
127
 
126
128
  def process_html
127
- puts 'PROCESS HTML CALLED'
128
129
  File.join(Dir.getwd, 'evidence')
129
130
  results_folder = File.join(Dir.getwd, 'evidence')
130
131
  output_file = File.join(Dir.getwd, 'evidence', 'final_results.html')
@@ -211,23 +212,17 @@ module ChemistryKit
211
212
  example.run
212
213
  end
213
214
  c.before(:each) do
214
- # basic auth caching
215
- if config.basic_auth[:username]
216
- if config.basic_auth[:http_path]
217
- basic_auth_http_url = config.base_url.gsub(%r{http://}, "http:\/\/#{config.basic_auth[:username]}:#{config.basic_auth[:password]}@") + config.basic_auth[:http_path]
218
- @driver.get basic_auth_http_url
219
- else
220
- basic_auth_http_url = config.base_url.gsub(%r{http://}, "http:\/\/#{config.basic_auth[:username]}:#{config.basic_auth[:password]}@")
221
- @driver.get basic_auth_http_url
222
- end
223
- if config.basic_auth[:https_path]
224
- basic_auth_https_url = config.base_url.gsub(%r{http://}, "https:\/\/#{config.basic_auth[:username]}:#{config.basic_auth[:password]}@") + config.basic_auth[:https_path]
225
- @driver.get basic_auth_https_url
226
- end
215
+ if config.basic_auth
216
+ @driver.get(config.basic_auth.http_url)
217
+ @driver.get(config.basic_auth.https_url) if config.basic_auth.https?
218
+ end
219
+
220
+ if config.split_testing
221
+ ChemistryKit::SplitTesting::ProviderFactory.build(config.split_testing).split(@driver)
227
222
  end
228
223
  end
229
224
  c.after(:each) do
230
- if example.exception != nil
225
+ if example.exception.nil? == false
231
226
  @job.finish failed: true, failshot: @config.screenshot_on_fail
232
227
  else
233
228
  @job.finish passed: true
@@ -0,0 +1,37 @@
1
+ # Encoding: utf-8
2
+
3
+ module ChemistryKit
4
+ module Config
5
+ class BasicAuth
6
+
7
+ attr_accessor :username, :password, :base_url, :http_path, :https_path
8
+
9
+ def initialize(opts)
10
+ opts.each do |key, value|
11
+ begin
12
+ send("#{key}=", value)
13
+ rescue NoMethodError
14
+ raise ArgumentError.new "The config key: \"#{key}\" is unknown!"
15
+ end
16
+ end
17
+ end
18
+
19
+ def http?
20
+ !!http_path
21
+ end
22
+
23
+ def https?
24
+ !!https_path
25
+ end
26
+
27
+ def http_url
28
+ base_url.gsub(%r{http://}, "http:\/\/#{username}:#{password}@") + (http_path || '')
29
+ end
30
+
31
+ def https_url
32
+ base_url.gsub(%r{http://}, "https:\/\/#{username}:#{password}@") + (https_path || '')
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ # Encoding: utf-8
2
+
3
+ module ChemistryKit
4
+ module Config
5
+ class SplitTesting
6
+
7
+ attr_accessor :provider, :base_url
8
+
9
+ attr_writer :opt_out
10
+
11
+ def initialize(opts)
12
+ opts.each do |key, value|
13
+ begin
14
+ send("#{key}=", value)
15
+ rescue NoMethodError
16
+ raise ArgumentError.new "The config key: \"#{key}\" is unknown!"
17
+ end
18
+ end
19
+ end
20
+
21
+ def opt_out?
22
+ !!@opt_out
23
+ end
24
+ end
25
+ end
26
+ end
@@ -3,6 +3,9 @@
3
3
  require 'yaml'
4
4
  require 'ostruct'
5
5
 
6
+ require 'chemistrykit/config/basic_auth'
7
+ require 'chemistrykit/config/split_testing'
8
+
6
9
  module ChemistryKit
7
10
  # Default configuration class
8
11
  class Configuration
@@ -10,10 +13,9 @@ module ChemistryKit
10
13
  attr_accessor :base_url,
11
14
  :concurrency,
12
15
  :screenshot_on_fail,
13
- :retries_on_failure,
14
- :basic_auth
16
+ :retries_on_failure
15
17
 
16
- attr_reader :log
18
+ attr_reader :log, :basic_auth, :split_testing
17
19
 
18
20
  attr_writer :selenium_connect
19
21
 
@@ -27,7 +29,8 @@ module ChemistryKit
27
29
  @log.path = 'evidence'
28
30
  @log.results_file = 'results_junit.xml'
29
31
  @log.format = 'ChemistryKit::RSpec::JUnitFormatter'
30
- @basic_auth = {}
32
+ @basic_auth = nil
33
+ @split_testing = nil
31
34
 
32
35
  # overide with argument
33
36
  populate_with_hash hash
@@ -40,6 +43,14 @@ module ChemistryKit
40
43
  end
41
44
  end
42
45
 
46
+ def basic_auth=(basic_auth_hash)
47
+ @basic_auth = ChemistryKit::Config::BasicAuth.new(basic_auth_hash.merge(base_url: base_url))
48
+ end
49
+
50
+ def split_testing=(split_testing_hash)
51
+ @split_testing = ChemistryKit::Config::SplitTesting.new(split_testing_hash.merge(base_url: base_url))
52
+ end
53
+
43
54
  def selenium_connect
44
55
  # return the default log unless the sc log is set
45
56
  if @selenium_connect[:log].nil?
@@ -43,7 +43,7 @@ module ChemistryKit
43
43
  file.write '<!--[if IE 8]> <html class="no-js lt-ie9" lang="en" > <![endif]-->'
44
44
  file.write '<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->'
45
45
 
46
- file.write get_report_head 'passing'
46
+ file.write get_report_head status
47
47
  file.write '<body>'
48
48
  file.write get_report_header
49
49
  file.write '<div class="report">'
@@ -101,12 +101,30 @@ module ChemistryKit
101
101
  build_fragment do |doc|
102
102
  doc.div(class: 'summary') do
103
103
  doc.div(class: "row status #{status}") do
104
- doc.div(class: 'large-12 columns') do
104
+ doc.div(class: 'large-9 columns') do
105
105
  doc.h1 do
106
106
  doc.i(class: icon)
107
107
  doc.text message
108
108
  end
109
109
  end
110
+ doc.div(class: 'large-3 columns top-row') do
111
+ %w[passing failing pending].each do | type |
112
+ doc.div(class: 'row switch-row') do
113
+ doc.div(class: 'large-6 columns switch-label') do
114
+ doc.text type.capitalize
115
+ end
116
+ doc.div(class: 'large-6 columns') do
117
+ doc.div(class: "#{type}-switch") do
118
+ doc.input(id: "show-#{type}", onclick: "toggle#{type.capitalize}();", name: "switch-show-#{type}", type: 'radio', checked: 'checked')
119
+ doc.label(for: "show-#{type}") { doc.text 'Hide' }
120
+ doc.input(id: "show-#{type}1", onclick: "toggle#{type.capitalize}();", name: "switch-show-#{type}", type: 'radio')
121
+ doc.label(for: "show-#{type}1") { doc.text 'Show' }
122
+ doc.span
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
110
128
  end
111
129
  doc.div(class: 'row details') do
112
130
  doc.div(class: 'large-12 columns') do
@@ -150,6 +168,26 @@ module ChemistryKit
150
168
  doc.text load_from_file(File.join(File.dirname(File.expand_path(__FILE__)), '../../../report/', 'javascripts', 'foundation', 'foundation.section.js'))
151
169
  end
152
170
  doc.script { doc.text '$(document).foundation();' }
171
+ doc.script do
172
+ doc.text "
173
+ function togglePassing() {
174
+ console.log('passing')
175
+ $('.example.passing').toggle();
176
+ $('.example-group.passing').toggle();
177
+ }
178
+
179
+ function toggleFailing() {
180
+ console.log('failing')
181
+ $('.example.failing').toggle();
182
+ $('.example-group.failing').toggle();
183
+ }
184
+
185
+ function togglePending() {
186
+ console.log('pending')
187
+ $('.example.pending').toggle();
188
+ $('.example-group.pending').toggle();
189
+ }"
190
+ end
153
191
  end
154
192
  end
155
193
 
@@ -128,9 +128,14 @@ module ChemistryKit
128
128
  def render_failshot_if_found(example)
129
129
  beaker_folder = slugify(@example_group.description)
130
130
  example_folder = slugify(@example_group.description + '_' + example.description)
131
+
131
132
  path = File.join(Dir.getwd, 'evidence', beaker_folder, example_folder, 'failshot.png')
132
133
  if File.exist?(path)
133
134
  render_section('Failure Screenshot') do |doc|
135
+ # if this is a jenkins job this variable is set and we can use it to get the right path to the images
136
+ if ENV['JOB_NAME']
137
+ path = File.join("/job/#{ENV['JOB_NAME']}/ws", 'evidence', beaker_folder, example_folder, 'failshot.png')
138
+ end
134
139
  doc.img(src: path)
135
140
  end
136
141
  end