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 +4 -4
- data/lib/effective_profile_bot/heap_analyzer.rb +39 -0
- data/lib/effective_test_bot/version.rb +1 -1
- data/lib/tasks/effecitve_profile_bot_tasks.rake +14 -0
- data/lib/tasks/effective_test_bot_tasks.rake +21 -2
- data/test/support/effective_test_bot_form_filler.rb +77 -35
- data/test/support/effective_test_bot_screenshots_helper.rb +10 -10
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fce8a949abc11a081049b6bf71e9212533cd060a
|
4
|
+
data.tar.gz: 7c7ceda55bd5db3edb0fd1325a07d0ab27aeb475
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -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') #
|
71
|
-
|
72
|
-
|
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')
|
80
|
-
|
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
|
-
|
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
|
119
|
-
# except for select
|
120
|
-
|
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
|
-
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
203
|
-
|
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
|
-
|
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
|
-
@
|
223
|
-
@
|
264
|
+
@filled_numeric_fields ||= {}
|
265
|
+
@filled_numeric_fields[selector] ||= max
|
224
266
|
|
225
|
-
available = @
|
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
|
-
@
|
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?
|
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? &&
|
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/#{
|
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
|
-
"#{
|
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
|
-
"#{
|
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.
|
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-
|
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
|