effective_test_bot 0.4.9 → 0.4.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6cf4d62267c1a02ff2a0bd22303f3ee9910e16ba
4
- data.tar.gz: 9c971d7950781d4195c2e13b0dd2af2dd4ebe7eb
3
+ metadata.gz: fce8a949abc11a081049b6bf71e9212533cd060a
4
+ data.tar.gz: 7c7ceda55bd5db3edb0fd1325a07d0ab27aeb475
5
5
  SHA512:
6
- metadata.gz: e78e8b4eca28808362fd52db931bb236d26571a814d7dabf372a6c268899b853d9c2c2cc405c5b53013250854f692717e1d7cf1c9b822e13649fcbd19f3aeb65
7
- data.tar.gz: 9ac142dffbfc8288e6ebe00d9335f4d7c5b8a69d470be8dd32503232e42859bebaa945688715ebc8d9083f0998a30f020e4a920217e6926c865b66e8331df27b
6
+ metadata.gz: ac832e73e5c7fe59e84d0c4a3dccb180d68432d962bb65b21c9527a14c56bda7b5ee8efbe60215d51b2e4f34418314d683a3d04e50337fbdd7f3424257ca502a
7
+ data.tar.gz: 9be90c3a4f5efba42943460588c9219468fc3b3f3d0c789695f96f64da9c9da44de7cdda6ce5ce65bfe2ca988d519ecb7e484de96163895c1e3349c15999b69e
@@ -0,0 +1,39 @@
1
+ # bundle exec derailed exec perf:heap
2
+ # http://samsaffron.com/archive/2015/03/31/debugging-memory-leaks-in-ruby
3
+ # HeapAnalyzer.new(ARGV[0]).analyze
4
+
5
+ require 'json'
6
+
7
+ module EffectiveProfileBot
8
+ class HeapAnalyzer
9
+ attr_accessor :data, :filename
10
+
11
+ def initialize(filename)
12
+ puts "Initialized with #{filename}"
13
+
14
+ @filename = filename
15
+ @data = []
16
+ end
17
+
18
+ def analyze
19
+ File.open(filename) do |f|
20
+ f.each_line do |line|
21
+ parsed = JSON.parse(line)
22
+ data << parsed
23
+ end
24
+
25
+ end
26
+
27
+ data.group_by { |row| row['generation'] }.sort{ |a, b| a[0].to_i <=> b[0].to_i }.each do |k, v|
28
+ puts "generation #{k} objects #{v.count}"
29
+ end
30
+
31
+ data.select { |row| row['generation'] == 95 }
32
+ .group_by { |row| "#{row["file"]}:#{row["line"]}" }
33
+ .sort { |a, b| b[1].count <=> a[1].count }.each do |k, v|
34
+ puts "#{k} * #{v.count}"
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module EffectiveTestBot
2
- VERSION = '0.4.9'.freeze
2
+ VERSION = '0.4.10'.freeze
3
3
  end
@@ -0,0 +1,14 @@
1
+ namespace :profile do
2
+ namespace :bot do
3
+ desc 'Runs the HeapAnalyzer on a dump file'
4
+ task :heap, [:filename] do |t, args|
5
+ if args[:filename].blank?
6
+ puts "Expected usage: rake profile:bot:heap[my_heap.dump]"
7
+ exit
8
+ end
9
+
10
+ require 'effective_profile_bot/heap_analyzer'
11
+ EffectiveProfileBot::HeapAnalyzer.new(args[:filename]).analyze
12
+ end
13
+ end
14
+ end
@@ -5,7 +5,8 @@ require 'rails/test_unit/sub_test_task'
5
5
  # rake test:bot TEST=documents#new
6
6
  # rake test:bot TEST=documents#new,documents#show
7
7
  # rake test:bot TOUR=true
8
- # rake test:bot TOUR=verbose
8
+ # rake test:bot TOUR=verbose # Prints out the animated gif patch after test is run
9
+ # rake test:bot TOUR=extreme # Makes a whole bunch of extra screenshots
9
10
 
10
11
  # rake test:bot:tour
11
12
  # rake test:bot:tour TEST=documents#new
@@ -16,9 +17,11 @@ require 'rails/test_unit/sub_test_task'
16
17
  # rake test:bot:tours
17
18
  # rake test:bot:tours TEST=documents
18
19
 
20
+ # rake test:tour # Not the bot, just regular minitest 'rake test'
21
+ # rake test:tourv
19
22
 
20
23
  namespace :test do
21
- desc 'Runs the effective_test_bot'
24
+ desc 'Runs the effective_test_bot automated test suite'
22
25
  task :bot do
23
26
  if ENV['TEST'].present?
24
27
  ENV['TEST_BOT_TEST'] = ENV['TEST']
@@ -28,6 +31,18 @@ namespace :test do
28
31
  Rake::Task['test:effective_test_bot'].invoke
29
32
  end
30
33
 
34
+ desc "Runs 'rake test' with effective_test_bot tour mode enabled"
35
+ task :tour do
36
+ ENV['TOUR'] ||= 'true'
37
+ Rake::Task['test'].invoke
38
+ end
39
+
40
+ desc "Runs 'rake test' with effective_test_bot verbose tour mode enabled"
41
+ task :tourv do
42
+ ENV['TOUR'] ||= 'verbose'
43
+ Rake::Task['test'].invoke
44
+ end
45
+
31
46
  namespace :bot do
32
47
  desc 'Runs effective_test_bot environment test'
33
48
  task :environment do
@@ -55,6 +70,7 @@ namespace :test do
55
70
 
56
71
  desc 'Prints all effective_test_bot animated gif tour file paths'
57
72
  task :tours do
73
+ present = false
58
74
  Dir['test/tours/*.gif'].each do |file|
59
75
  file = file.to_s
60
76
 
@@ -62,8 +78,11 @@ namespace :test do
62
78
  next unless file.include?(ENV['TEST'])
63
79
  end
64
80
 
81
+ present = true
65
82
  puts "\e[32m#{Rails.root + file}\e[0m" # 32 is green
66
83
  end
84
+
85
+ puts 'No effective_test_bot tours present.' unless present
67
86
  end
68
87
  end # /namespace bot
69
88
 
@@ -33,7 +33,6 @@ module EffectiveTestBotFormFiller
33
33
  tab.click()
34
34
  synchronize!
35
35
  save_test_bot_screenshot
36
- @shared_max_fields = nil # Reset value_for_input_numeric_field() history
37
36
 
38
37
  within('div' + tab['href']) { fill_form_fields(fills) }
39
38
  end
@@ -67,19 +66,15 @@ module EffectiveTestBotFormFiller
67
66
  when 'input_text', 'input_email', 'input_password', 'input_tel', 'input_number', 'input_checkbox', 'input_radio', 'textarea'
68
67
  field.set(value_for_field(field, fills))
69
68
  when 'select'
70
- if field['class'].to_s.include?('select2') # effective_select
71
- if EffectiveTestBot.tour_mode_extreme?
72
- page.execute_script("try { $('select##{field['id']}').select2('open'); } catch(e) {};")
73
- save_test_bot_screenshot
74
- end
69
+ if EffectiveTestBot.tour_mode_extreme? && field['class'].to_s.include?('select2') # select2
70
+ page.execute_script("try { $('select##{field['id']}').select2('open'); } catch(e) {};")
71
+ save_test_bot_screenshot
75
72
  end
76
73
 
77
74
  field.select(value_for_field(field, fills), match: :first)
78
75
 
79
- if field['class'].to_s.include?('select2') # effective_select
80
- if EffectiveTestBot.tour_mode_extreme?
81
- page.execute_script("try { $('select##{field['id']}').select2('close'); } catch(e) {};")
82
- end
76
+ if EffectiveTestBot.tour_mode_extreme? && field['class'].to_s.include?('select2')
77
+ page.execute_script("try { $('select##{field['id']}').select2('close'); } catch(e) {};")
83
78
  end
84
79
  when 'input_file'
85
80
  if field['class'].to_s.include?('asset-box-uploader-fileinput')
@@ -99,8 +94,12 @@ module EffectiveTestBotFormFiller
99
94
  end
100
95
  end
101
96
 
102
- save_test_bot_screenshot
97
+ # Clear any value_for_field momoized values
98
+ @filled_numeric_fields = nil
99
+ @filled_password_fields = nil
100
+ @filled_radio_fields = nil
103
101
 
102
+ save_test_bot_screenshot
104
103
  end
105
104
 
106
105
  # Generates an appropriately pseudo-random value for the given field
@@ -115,10 +114,9 @@ module EffectiveTestBotFormFiller
115
114
 
116
115
  fill_value = fill_value_for_field(fills, attributes)
117
116
 
118
- # If there is a predefined fill value for this field, return it here
119
- # except for select fields which are treated differently, so we can match fill values on both the html text or value
120
- # this edge case is implemented below
121
- if fill_value.present? && !['select'].include?(field_name)
117
+ # If there is a predefined fill value for this field return it now
118
+ # except for select, checkbox and radio fields which we want to match by value or label
119
+ if fill_value.present? && !['select', 'input_checkbox', 'input_radio'].include?(field_name)
122
120
  return fill_value
123
121
  end
124
122
 
@@ -171,6 +169,25 @@ module EffectiveTestBotFormFiller
171
169
  Faker::Lorem.words(3).join(' ').capitalize
172
170
  end
173
171
 
172
+ when 'input_checkbox'
173
+ value_for_input_checkbox_field(field, fill_value)
174
+
175
+ when 'input_email'
176
+ Faker::Internet.email
177
+
178
+ when 'input_file'
179
+ "#{File.dirname(__FILE__)}/important_documents._test"
180
+
181
+ when 'input_number'
182
+ value_for_input_numeric_field(field, "input[type='number'][name$='[#{attribute}]']")
183
+
184
+ when 'input_password'
185
+ # Use the same password throughout a single test. Allows passwords and password_confirmations to match.
186
+ @filled_password_fields ||= Faker::Internet.password
187
+
188
+ when 'input_radio'
189
+ value_for_input_radio_field(field, fill_value)
190
+
174
191
  when 'select'
175
192
  if fill_value.present? # accept a value or text
176
193
  field.all('option:enabled').each do |option|
@@ -179,30 +196,55 @@ module EffectiveTestBotFormFiller
179
196
  end
180
197
 
181
198
  field.all('option:enabled').select { |option| option.value.present? }.sample.try(:text) || '' # Don't select an empty option
182
- when 'input_number'
183
- value_for_input_numeric_field(field, "input[type='number'][name$='[#{attribute}]']")
184
- when 'input_email'
185
- Faker::Internet.email
186
- when 'input_password'
187
- # Use the same password throughout a single test. Allows passwords and password_confirmations to match.
188
- @test_bot_current_password ||= Faker::Internet.password
199
+
189
200
  when 'input_tel'
190
201
  d = 10.times.map { DIGITS.sample }
191
202
  d[0] + d[1] + d[2] + '-' + d[3] + d[4] + d[5] + '-' + d[6] + d[7] + d[8] + d[9]
203
+
192
204
  when 'textarea'
193
205
  Faker::Lorem.paragraph
194
- when 'input_checkbox', 'input_radio'
195
- if field['value'] == 'true'
196
- true
197
- elsif field['value'] == 'false'
198
- false
199
- else
206
+
207
+ else
208
+ raise "fill_value unsupported field type: #{field['type']}"
209
+ end
210
+ end
211
+
212
+ def value_for_input_checkbox_field(field, fill_value)
213
+ if fill_value.present?
214
+ fill_values = Array(fill_value) # Allow an array of fill values to be passed
215
+ (fill_values.include?(field['value']) || fill_values.include?(field.find(:xpath, '..').text))
216
+ elsif field['value'] == 'true'
217
+ true
218
+ elsif field['value'] == 'false'
219
+ false
220
+ else
221
+ [true, false].sample
222
+ end
223
+ end
224
+
225
+ # The first time we run into a radio button, we definitely want to set it to TRUE so it's definitely selected
226
+ # Subsequent ones, we can randomly true/false
227
+ # Then if we run into something that has a fill_value, we definitely want to set that one to TRUE, and false the rest
228
+ def value_for_input_radio_field(field, fill_value)
229
+ @filled_radio_fields ||= {}
230
+
231
+ previous = @filled_radio_fields[field['name']]
232
+
233
+ retval =
234
+ if previous == true # We've selected one of the options before
200
235
  [true, false].sample
236
+ elsif previous.kind_of?(String) # We selected a previous option with a specific fill_value
237
+ false
238
+ else # We've never seen this radio field before
239
+ true
201
240
  end
202
- when 'input_file'
203
- "#{File.dirname(__FILE__)}/important_documents._test"
241
+
242
+ if fill_value.present? && (fill_value == field['value'] || fill_value == field.find(:xpath, '..').text)
243
+ @filled_radio_fields[field['name']] = fill_value
244
+ true
204
245
  else
205
- raise "fill_value unsupported field type: #{field['type']}"
246
+ @filled_radio_fields[field['name']] ||= true
247
+ retval
206
248
  end
207
249
  end
208
250
 
@@ -219,10 +261,10 @@ module EffectiveTestBotFormFiller
219
261
 
220
262
  # So there's definitely 2+ fields that share the same max, named the same
221
263
  # We want the total value of all these fields to add upto the max single max value
222
- @shared_max_fields ||= {}
223
- @shared_max_fields[selector] ||= max
264
+ @filled_numeric_fields ||= {}
265
+ @filled_numeric_fields[selector] ||= max
224
266
 
225
- available = @shared_max_fields[selector]
267
+ available = @filled_numeric_fields[selector]
226
268
 
227
269
  amount = if max.kind_of?(Float)
228
270
  (((max * 1000.0) / shared_max_fields.length.to_f).ceil() / 1000.0).round(2)
@@ -231,7 +273,7 @@ module EffectiveTestBotFormFiller
231
273
  end
232
274
  amount = [[amount, min].max, available].min
233
275
 
234
- @shared_max_fields[selector] = (available - amount)
276
+ @filled_numeric_fields[selector] = (available - amount)
235
277
  amount
236
278
  end
237
279
 
@@ -5,22 +5,18 @@ module EffectiveTestBotScreenshotsHelper
5
5
 
6
6
  # Creates a screenshot based on the current test and the order in this test.
7
7
  def save_test_bot_screenshot
8
- return unless EffectiveTestBot.screenshots? && defined?(current_test)
9
-
10
- full_path = current_test_temp_path + "/#{current_test_screenshot_id}.png"
11
- page.save_screenshot(full_path)
8
+ return unless EffectiveTestBot.screenshots?
9
+ page.save_screenshot("#{current_test_temp_path}/#{current_test_screenshot_id}.png")
12
10
  end
13
11
 
14
12
  # This is run before every test
15
13
  # def before_setup
16
- # super
17
- # return unless (EffectiveTestBot.screenshots? && defined?(current_test))
18
14
  # end
19
15
 
20
16
  # This gets called after every test. Minitest hook for plugin developers
21
17
  def after_teardown
22
18
  super
23
- return unless EffectiveTestBot.screenshots? && defined?(current_test) && (@test_bot_screenshot_id || 0) > 0
19
+ return unless EffectiveTestBot.screenshots? && (@test_bot_screenshot_id || 0) > 0
24
20
 
25
21
  if !passed? && EffectiveTestBot.autosave_animated_gif_on_failure?
26
22
  save_test_bot_failure_gif
@@ -101,7 +97,7 @@ module EffectiveTestBotScreenshotsHelper
101
97
  # current_test_failure_path: destination for .gifs of failing tests
102
98
 
103
99
  def current_test_temp_path
104
- @_current_test_temp_path ||= "#{Rails.root}/tmp/test_bot/#{current_test || 'none'}"
100
+ @_current_test_temp_path ||= "#{Rails.root}/tmp/test_bot/#{current_test_name}"
105
101
  end
106
102
 
107
103
  def current_test_failure_path
@@ -110,7 +106,7 @@ module EffectiveTestBotScreenshotsHelper
110
106
 
111
107
  def current_test_failure_filename
112
108
  # Match Capybara-screenshots format-ish
113
- "#{current_test}_failure_#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}.gif"
109
+ "#{current_test_name}_failure_#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}.gif"
114
110
  end
115
111
 
116
112
  # Where the tour animated gif ends up
@@ -119,7 +115,11 @@ module EffectiveTestBotScreenshotsHelper
119
115
  end
120
116
 
121
117
  def current_test_tour_filename
122
- "#{current_test}.gif"
118
+ "#{current_test_name}.gif"
119
+ end
120
+
121
+ def current_test_name
122
+ defined?(curent_test) ? current_test : (@NAME.to_s.presence || 'none')
123
123
  end
124
124
 
125
125
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_test_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-14 00:00:00.000000000 Z
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -215,12 +215,14 @@ extensions: []
215
215
  extra_rdoc_files: []
216
216
  files:
217
217
  - app/helpers/effective_test_bot_controller_helper.rb
218
+ - lib/effective_profile_bot/heap_analyzer.rb
218
219
  - lib/effective_test_bot/engine.rb
219
220
  - lib/effective_test_bot/version.rb
220
221
  - lib/effective_test_bot.rb
221
222
  - lib/generators/effective_test_bot/install_generator.rb
222
223
  - lib/generators/templates/effective_test_bot.rb
223
224
  - lib/generators/templates/test_helper.rb
225
+ - lib/tasks/effecitve_profile_bot_tasks.rake
224
226
  - lib/tasks/effective_test_bot_tasks.rake
225
227
  - test/concerns/test_botable/base_dsl.rb
226
228
  - test/concerns/test_botable/crud_dsl.rb