effective_test_bot 0.4.9 → 0.4.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|