effective_test_bot 1.1.2 → 1.1.3

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
  SHA256:
3
- metadata.gz: 2a36dd85a7f66b33cf3fdc0508b65b1770a1422e3a13d894b514adedaec140aa
4
- data.tar.gz: 8a0c3fbad9e4e215daeeb8c9dd3e0218a645b4cc279b8ebaf198d3c5f6ac8c3b
3
+ metadata.gz: eb70d79c59a6971cd71b7473836a0c8d32bddc718b88f1643c8859be73393c01
4
+ data.tar.gz: 2758973ff90e358433c44a528691425863ccadcdd58840737ea5c78a0d27923d
5
5
  SHA512:
6
- metadata.gz: b650ba5b81172e4a22fc8cc41d195fa909abe04cdf2ccb2488956563f797d16dee3a935e88375302af9d8794867f023bde921672f590b915978dd8b50d68122d
7
- data.tar.gz: 77a754437f4d2d614bcf1219eb8de8602b90e695d702a22c58ffe11305304e7581bae115257637876c5fb53e44a1cc36a93ef3acf3d9f39f9294f80568c28618
6
+ metadata.gz: f11567a699e875251431ca2d96232aed6e1c35c910f8d54fc4e732f7fe9f5b53c9312077f054cead0951f591d161c20cc6f3a02b76f0e07bf2918e54dd65831a
7
+ data.tar.gz: 528f4cd925c04064df27a94bc80180ad92c99bfd6d466cf09cab8966afc3d068d96c49ac4152915524eb30ca6fa50426d14f932bacbdba54afe9e1dd12c5cfbe
data/README.md CHANGED
@@ -531,8 +531,8 @@ rails test:bot:fails
531
531
  # Only runs failed tests and stops after first failure
532
532
  rails test:bot:fails
533
533
 
534
- # Purges all screenshots and fails
535
- rails test:bot:purge
534
+ # Clobber (delete) all screenshots and fails
535
+ rails test:bot:clobber
536
536
  ```
537
537
 
538
538
  ## Animated gifs and screenshots
@@ -584,7 +584,7 @@ To delete all tour and autosave on failure animated .gifs, run the following:
584
584
 
585
585
  ```
586
586
  # Deletes all tour and failure animated .gifs
587
- rails test:bot:purge
587
+ rails test:bot:clobber
588
588
  ```
589
589
 
590
590
  As well, to enable tour mode when running the standard `rails test`:
@@ -47,9 +47,9 @@ if Rails.env.test?
47
47
  # Also enabled the crud_test #tour type tests
48
48
  #
49
49
  # You can override this default by setting an ENV or calling
50
- # `rake test:bot TOUR=true` or `rake test:bot TEST=posts TOUR=verbose`
50
+ # `rake test:bot TOUR=true` or `rake test:bot TEST=posts TOUR=extreme`
51
51
  #
52
- # Valid values are true / false / :verbose
52
+ # Valid values are true / false / :extreme
53
53
  config.tour_mode = false
54
54
 
55
55
  # Rmagick gem is required for animated gifs
@@ -95,7 +95,7 @@ module EffectiveTestBot
95
95
 
96
96
  def self.tour_mode?
97
97
  if ENV['TOUR'].present?
98
- ['true', 'extreme', 'verbose', 'debug'].include?(ENV['TOUR'].to_s.downcase)
98
+ ENV['TOUR'].to_s != 'false'
99
99
  else
100
100
  screenshots? && (tour_mode != false)
101
101
  end
@@ -110,14 +110,6 @@ module EffectiveTestBot
110
110
  end
111
111
  end
112
112
 
113
- def self.tour_mode_verbose?
114
- if ENV['TOUR'].present?
115
- ['true', 'extreme', 'verbose', 'debug'].include?(ENV['TOUR'].to_s.downcase)
116
- else
117
- screenshots? && ['extreme', 'verbose', 'debug'].include?(tour_mode.to_s)
118
- end
119
- end
120
-
121
113
  def self.passed_tests
122
114
  @@passed_tests ||= load_passed_tests
123
115
  end
@@ -129,10 +121,11 @@ module EffectiveTestBot
129
121
  end
130
122
 
131
123
  def self.save_passed_test(name)
132
- EffectiveTestBot.passed_tests[name] = true
124
+ return if EffectiveTestBot.passed_tests[name] == true
133
125
 
126
+ EffectiveTestBot.passed_tests[name] = true
134
127
  Dir.mkdir(passed_tests_path) unless File.exist?(passed_tests_path)
135
- File.open(passed_tests_filename, 'w') { |file| passed_tests.each { |test_name, _| file.puts(test_name) } }
128
+ File.open(passed_tests_filename, 'a') { |file| file.puts(name) }
136
129
  end
137
130
 
138
131
  private
@@ -1,3 +1,3 @@
1
1
  module EffectiveTestBot
2
- VERSION = '1.1.2'.freeze
2
+ VERSION = '1.1.3'.freeze
3
3
  end
@@ -10,7 +10,7 @@
10
10
 
11
11
  # rails test:bot:seed
12
12
  # rails test:bot:environment
13
- # rails test:bot:purge
13
+ # rails test:bot:clobber
14
14
 
15
15
  # rails test:bot:tours
16
16
  # rails test:bot:tours TEST=documents
@@ -54,10 +54,10 @@ namespace :test do
54
54
  end
55
55
 
56
56
  desc 'Deletes all effective_test_bot temporary, failure and tour screenshots'
57
- task :purge do
57
+ task :clobber do
58
58
  FileUtils.rm_rf(Rails.root + 'test/tours')
59
59
  FileUtils.rm_rf(Rails.root + 'tmp/test_bot')
60
- puts "Successfully purged all effective_test_bot screenshots"
60
+ puts "Successfully clobbered all effective_test_bot screenshots"
61
61
  end
62
62
 
63
63
  desc 'Runs effective_test_bot environment test in tour mode'
@@ -42,7 +42,7 @@ module TestBotable
42
42
  raise 'expected resource to be a Class or Instance or String' unless obj.kind_of?(Class) || obj.kind_of?(ActiveRecord::Base) || obj.kind_of?(String)
43
43
 
44
44
  if obj.kind_of?(String) # Let's assume this is a controller, 'admin/jobs', or just 'jobs', or 'jobs_controller'
45
- obj.sub!('_controller', '')
45
+ obj = obj.sub('_controller', '')
46
46
 
47
47
  (*namespace, klass) = obj.split('/')
48
48
  namespace = Array(namespace).join('/').presence
@@ -102,7 +102,7 @@ module EffectiveTestBotAssertions
102
102
  end
103
103
 
104
104
  def assert_no_ajax_requests(message: "(no_ajax_requests) :count: Unexpected AJAX requests present")
105
- active = page.evaluate_script('$.active')
105
+ active = (page.evaluate_script('$.active') rescue nil)
106
106
  assert (active.blank? || active.zero?), message.sub(':count:', active.to_s)
107
107
  end
108
108
 
@@ -117,7 +117,13 @@ module EffectiveTestBotAssertions
117
117
  end
118
118
 
119
119
  def assert_no_js_errors(message: nil, strict: false)
120
- error = (page.driver.browser.manage.logs.get(:browser).first rescue '') # headless_chrome
120
+ error = ''
121
+
122
+ begin
123
+ error = page.driver.browser.manage.logs.get(:browser).first # headless_chrome
124
+ rescue NotImplementedError
125
+ return
126
+ end
121
127
 
122
128
  if strict == false
123
129
  return if error.to_s.include?('Failed to load resource')
@@ -134,14 +140,14 @@ module EffectiveTestBotAssertions
134
140
  # It ensures there are no HTML5 validation errors that would prevent the form from being submit
135
141
  # Browsers seem to only consider visible fields, so we will to
136
142
  def assert_no_html5_form_validation_errors(message: nil)
137
- errors = all(':invalid', visible: true).map { |field| field['name'] }
143
+ errors = all(':invalid', visible: true, wait: false).map { |field| field['name'] }
138
144
  assert errors.blank?, message || "(no_html5_form_validation_errors) Unable to submit form, unexpected HTML5 validation error present on the following fields:\n#{errors.join("\n")}"
139
145
  end
140
146
 
141
147
  # Rails jquery-ujs data-disable-with
142
148
  # = f.button :submit, 'Save', data: { disable_with: 'Saving...' }
143
149
  def assert_jquery_ujs_disable_with(label = nil, message: nil)
144
- submits = label.present? ? all("input[type='submit']", text: label) : all("input[type='submit']")
150
+ submits = label.present? ? all("input[type='submit']", text: label, wait: false) : all("input[type='submit']", wait: false)
145
151
  all_disabled_with = submits.all? { |submit| submit['data-disable-with'].present? }
146
152
 
147
153
  assert all_disabled_with, message || "(jquery_ujs_disable_with) Expected rails jquery-ujs data-disable-with to be present on #{(label || "all input[type='submit'] fields")}\nInclude it on your submit buttons by adding \"data: { disable_with: 'Saving...' }\""
@@ -41,9 +41,9 @@ module EffectiveTestBotFormFaker
41
41
  end
42
42
  elsif classes.include?('numeric')
43
43
  value_for_input_numeric_field(field, "input.numeric[name$='[#{attribute}]']")
44
- elsif classes.include?('email') || attribute.include?('email')
44
+ elsif classes.include?('email') || classes.include?('effective_email') || attribute.include?('email')
45
45
  Faker::Internet.email
46
- elsif classes.include?('price') # effective_form_inputs price
46
+ elsif classes.include?('price') || classes.include?('effective_price')
47
47
  4.times.map { DIGITS.sample }.join('') + '.00'
48
48
  elsif classes.include?('numeric') || classes.include?('effective_number_text') || classes.include?('effective_integer') || attribute.include?('number')
49
49
  min = (Float(field['min']) rescue 1)
@@ -135,19 +135,35 @@ module EffectiveTestBotFormFaker
135
135
  private
136
136
 
137
137
  def fill_value_for_field(fills, attributes, value, field_name)
138
- return if fills.blank? || (attributes.blank? && value.blank?)
138
+ return nil if fills.blank? || (attributes.blank? && value.blank?)
139
139
 
140
+ fill = nil
141
+
142
+ # Match by attributes
140
143
  key = nil
144
+
141
145
  attributes.reverse_each do |name| # match last_name, then something_attributes.last_name, then user.something_attributes.last_name
142
146
  key = (key.present? ? "#{name}.#{key}" : name) # builds up the string as we go along
143
147
 
144
- return :unselect if field_name == 'select' && fills.key?(key) && [nil, ''].include?(fills[key])
145
- return fills[key].to_s if fills.key?(key)
148
+ if fills.key?(key)
149
+ fill = fills[key].to_s
150
+ fill = :unselect if field_name == 'select' && fills[key].blank?
151
+ end
152
+
153
+ break if fill.present?
146
154
  end
147
155
 
148
- return fills[value] if fills.key?(value)
156
+ # Match by value
157
+ fill ||= fills[value]
158
+
159
+ # If this is a file field, make sure the file is present at Rails.root/test/fixtures/
160
+ if fill.present? && field_name == 'input_file'
161
+ filename = (fill.to_s.include?('/') ? fill : "#{Rails.root}/test/fixtures/#{fill}")
162
+ raise("Warning: Unable to load fill file #{fill}. Expected file #{filename}") unless File.exists?(filename)
163
+ return filename
164
+ end
149
165
 
150
- nil
166
+ fill.presence
151
167
  end
152
168
 
153
169
  def value_for_input_select_field(field, fill_value)
@@ -155,7 +171,7 @@ module EffectiveTestBotFormFaker
155
171
  country_code = field['name'].to_s.include?('country_code')
156
172
 
157
173
  if fill_value.present? # accept a value or text
158
- field.all('option:enabled').each do |option|
174
+ field.all('option:enabled', wait: false).each do |option|
159
175
  if (option.text == fill_value || option.value.to_s == fill_value)
160
176
  @filled_country_fields = option.value if country_code
161
177
  return option.text
@@ -163,7 +179,7 @@ module EffectiveTestBotFormFaker
163
179
  end
164
180
  end
165
181
 
166
- option = field.all('option:enabled').select { |option| option.value.present? }.sample
182
+ option = field.all('option:enabled', wait: false).select { |option| option.value.present? }.sample
167
183
 
168
184
  @filled_country_fields = option.try(:value) if country_code # So Postal Code can be set to a valid one
169
185
 
@@ -231,7 +247,7 @@ module EffectiveTestBotFormFaker
231
247
 
232
248
  return number if field['max'].blank?
233
249
 
234
- shared_max_fields = all(selector)
250
+ shared_max_fields = all(selector, wait: false)
235
251
  return number if shared_max_fields.length <= 1
236
252
 
237
253
  # So there's definitely 2+ fields that share the same max, named the same
@@ -6,7 +6,7 @@ module EffectiveTestBotFormFiller
6
6
 
7
7
  # Fill a boostrap tabs based form
8
8
  def fill_bootstrap_tabs_form(fills = {})
9
- tabs = all("a[data-toggle='tab']")
9
+ tabs = all("a[data-toggle='tab']", wait: false)
10
10
 
11
11
  # If there's only 1 tab, just fill it out
12
12
  (fill_form_fields(fills) and return) unless tabs.length > 1
@@ -16,7 +16,7 @@ module EffectiveTestBotFormFiller
16
16
  # Then we start at the first, and go left-to-right through all the tabs
17
17
  # clicking each one and filling any form fields found within
18
18
 
19
- active_tab = all("li.active > a[data-toggle='tab']").first
19
+ active_tab = all("li.active > a[data-toggle='tab']", wait: false).first
20
20
 
21
21
  tab_content = if active_tab && active_tab['href'].present?
22
22
  find('div' + active_tab['href']).find(:xpath, '..')
@@ -25,7 +25,7 @@ module EffectiveTestBotFormFiller
25
25
  excluding_fields_with_parent(tab_content) { fill_form_fields(fills) }
26
26
 
27
27
  # Refresh the tabs, as they may have changed
28
- tabs = all("a[data-toggle='tab']")
28
+ tabs = all("a[data-toggle='tab']", wait: false)
29
29
 
30
30
  # Click through each tab and fill the form inside it.
31
31
  tabs.each do |tab|
@@ -39,7 +39,7 @@ module EffectiveTestBotFormFiller
39
39
  end
40
40
 
41
41
  # If there is no visible submits, go back to the first tab
42
- if all(:css, "input[type='submit']").length == 0
42
+ if all("input[type='submit']", wait: false).length == 0
43
43
  tabs.first.click()
44
44
  synchronize!
45
45
  save_test_bot_screenshot
@@ -55,7 +55,7 @@ module EffectiveTestBotFormFiller
55
55
 
56
56
  5.times do
57
57
  # Support for the cocoon gem
58
- fields = all('a.add_fields[data-association-insertion-template],a.has_many_add').reject { |field| seen[field_key(field)] }
58
+ fields = all('a.add_fields[data-association-insertion-template],a.has_many_add', wait: false).reject { |field| seen[field_key(field)] }
59
59
 
60
60
  fields.each do |field|
61
61
  seen[field_key(field)] = true
@@ -108,7 +108,7 @@ module EffectiveTestBotFormFiller
108
108
  when 'select', 'select_select-one', 'select_select-multiple'
109
109
  fill_input_select(field, value)
110
110
  when 'input_file'
111
- fill_input_file(file, value)
111
+ fill_input_file(field, value)
112
112
  when 'input_submit', 'input_search', 'input_button'
113
113
  skip_field_screenshot = true # Do nothing
114
114
  else
@@ -171,20 +171,18 @@ module EffectiveTestBotFormFiller
171
171
  end
172
172
 
173
173
  def fill_input_select(field, value)
174
- if EffectiveTestBot.tour_mode_extreme? && field['class'].to_s.include?('select2') # select2
174
+ if EffectiveTestBot.tour_mode_extreme? && select2_input?(field)
175
175
  try_script "$('select##{field['id']}').select2('open')"
176
176
  save_test_bot_screenshot
177
177
  end
178
178
 
179
- if field.all('option:enabled').length > 0 && value != :unselect
179
+ if field.all('option:enabled', wait: false).length > 0 && value != :unselect
180
180
  Array(value).each do |value|
181
181
  field.select(value.to_s, match: :first, disabled: false)
182
182
  end
183
183
  end
184
184
 
185
- if field['class'].to_s.include?('select2')
186
- try_script "$('select##{field['id']}').select2('close')"
187
- end
185
+ close_effective_select(field)
188
186
  end
189
187
 
190
188
  def fill_input_file(field, value)
@@ -244,9 +242,20 @@ module EffectiveTestBotFormFiller
244
242
  end
245
243
 
246
244
  def clear_effective_select(field)
245
+ return unless effective_select_input?(field)
247
246
  try_script "$('select##{field['id']}').val('').trigger('change.select2')"
248
247
  end
249
248
 
249
+ def close_effective_select(field)
250
+ return unless effective_select_input?(field)
251
+ try_script "$('select##{field['id']}').select2('close')"
252
+ end
253
+
254
+ def close_effective_date_time_picker(field)
255
+ return unless effective_date_input?(field)
256
+ # TODO
257
+ end
258
+
250
259
  private
251
260
 
252
261
  # Takes a capybara element
@@ -258,13 +267,25 @@ module EffectiveTestBotFormFiller
258
267
 
259
268
  def ckeditor_text_area?(field)
260
269
  return false unless field.tag_name == 'textarea'
261
- (field['class'].to_s.include?('ckeditor') || all("span[id='cke_#{field['id']}']").present?)
270
+ (field['class'].to_s.include?('ckeditor') || all("span[id='cke_#{field['id']}']", wait: false).present?)
262
271
  end
263
272
 
264
273
  def custom_control_input?(field) # Bootstrap 4 radios and checks
265
274
  field['class'].to_s.include?('custom-control-input')
266
275
  end
267
276
 
277
+ def effective_date_input?(field)
278
+ field['class'].to_s.include?('effective_date')
279
+ end
280
+
281
+ def file_input?(field)
282
+ field['type'] == 'file'
283
+ end
284
+
285
+ def effective_select_input?(field)
286
+ field['class'].to_s.include?('select2') || field['class'].to_s.include?('effective_select')
287
+ end
288
+
268
289
  def skip_form_field?(field)
269
290
  field.reload # Handle a field changing visibility/disabled state from previous form field manipulations
270
291
 
@@ -4,7 +4,7 @@ module EffectiveTestBotFormHelper
4
4
  # Intelligently fills a form with Faker based randomish input
5
5
  # Delegates the form fill logic to effective_test_bot_form_filler
6
6
  def fill_form(fills = {})
7
- bootstrap_tabs = all("a[data-toggle='tab']")
7
+ bootstrap_tabs = all("a[data-toggle='tab']", wait: false)
8
8
 
9
9
  form_fills = HashWithIndifferentAccess.new((EffectiveTestBot.form_fills || {}).merge(fills || {}))
10
10
 
@@ -69,16 +69,19 @@ module EffectiveTestBotFormHelper
69
69
  end
70
70
 
71
71
  def clear_form
72
- all('input,select,textarea').each do |field|
73
- if field.tag_name == 'select' && field['class'].to_s.include?('select2') # effective_select
72
+ all('input,select,textarea', wait: false).each do |field|
73
+ if effective_select_input?(field)
74
74
  clear_effective_select(field)
75
+ elsif effective_date_input?(field)
76
+ field.set('')
77
+ close_effective_date_time_picker(field)
78
+ elsif file_input?(field)
79
+ # Nothing
80
+ else
81
+ field.set('')
75
82
  end
76
83
 
77
- begin
78
- field.set('')
79
- close_effective_date_time_picker(field) if field['class'].to_s.include?('effective_date')
80
- save_test_bot_screenshot if EffectiveTestBot.tour_mode_extreme?
81
- rescue => e; end
84
+ save_test_bot_screenshot if EffectiveTestBot.tour_mode_extreme?
82
85
  end
83
86
 
84
87
  true
@@ -7,20 +7,15 @@ module EffectiveTestBotMinitestHelper
7
7
  def before_teardown
8
8
  super
9
9
 
10
- if EffectiveTestBot.gifs? && (@test_bot_screenshot_id || 0) > 0
11
- if !passed? && EffectiveTestBot.autosave_animated_gif_on_failure?
12
- save_test_bot_screenshot
13
- save_test_bot_failure_gif
14
- end
15
-
16
- if passed? && EffectiveTestBot.tour_mode?
17
- save_test_bot_tour_gif
18
- end
10
+ if passed?
11
+ EffectiveTestBot.save_passed_test(current_test_name)
12
+ save_test_bot_tour_gif if EffectiveTestBot.tour_mode?
19
13
  end
20
14
 
21
- if passed? && !EffectiveTestBot.passed_tests[current_test_name]
22
- EffectiveTestBot.save_passed_test(current_test_name)
15
+ if !passed?
16
+ save_test_bot_failure_gif if EffectiveTestBot.autosave_animated_gif_on_failure?
23
17
  end
18
+
24
19
  end
25
20
 
26
21
  protected
@@ -9,13 +9,17 @@ module EffectiveTestBotScreenshotsHelper
9
9
  def save_test_bot_screenshot
10
10
  return unless EffectiveTestBot.screenshots?
11
11
  return unless page.current_path.present?
12
+
12
13
  page.save_screenshot("#{current_test_temp_path}/#{current_test_screenshot_id}.png")
14
+ true
13
15
  end
14
16
 
15
17
  def save_test_bot_failure_gif
16
18
  return unless EffectiveTestBot.screenshots?
17
19
  return unless EffectiveTestBot.gifs?
18
20
 
21
+ return unless save_test_bot_screenshot
22
+
19
23
  Dir.mkdir(current_test_failure_path) unless File.exist?(current_test_failure_path)
20
24
  full_path = (current_test_failure_path + '/' + current_test_failure_filename)
21
25
 
@@ -26,12 +30,13 @@ module EffectiveTestBotScreenshotsHelper
26
30
  def save_test_bot_tour_gif
27
31
  return unless EffectiveTestBot.screenshots?
28
32
  return unless EffectiveTestBot.gifs?
33
+ return unless (@test_bot_screenshot_id || 0) > 0
29
34
 
30
35
  Dir.mkdir(current_test_tour_path) unless File.exist?(current_test_tour_path)
31
36
  full_path = (current_test_tour_path + '/' + current_test_tour_filename)
32
37
 
33
38
  save_test_bot_gif(full_path)
34
- puts_green(" Tour .gif: #{full_path}") if EffectiveTestBot.tour_mode_verbose?
39
+ puts_green(" Tour .gif: #{full_path}")
35
40
  end
36
41
 
37
42
  def without_screenshots(&block)
@@ -102,4 +102,12 @@ module EffectiveTestBotTestHelper
102
102
  }
103
103
  end
104
104
 
105
+ def tsputs(message)
106
+ @last_message ||= Time.zone.now
107
+ now = Time.zone.now
108
+
109
+ puts "[+ #{now - @last_message}] #{message}"
110
+ @last_message = now
111
+ end
112
+
105
113
  end
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: 1.1.2
4
+ version: 1.1.3
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: 2019-06-11 00:00:00.000000000 Z
11
+ date: 2019-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails