effective_test_bot 0.4.4 → 0.4.5
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_test_bot.rb +2 -0
- data/lib/effective_test_bot/version.rb +1 -1
- data/lib/generators/templates/effective_test_bot.rb +11 -0
- data/lib/tasks/effective_test_bot_tasks.rake +34 -2
- data/test/concerns/test_botable/crud_dsl.rb +4 -3
- data/test/support/effective_test_bot_assertions.rb +13 -0
- data/test/support/effective_test_bot_form_filler.rb +30 -13
- data/test/support/effective_test_bot_form_helper.rb +2 -1
- data/test/support/effective_test_bot_screenshots_helper.rb +10 -10
- data/test/support/effective_test_bot_test_helper.rb +4 -10
- data/test/support/{effective_assets_upload_file._test → important_documents._test} +0 -0
- data/test/test_bot/integration/application_test.rb +4 -1
- data/test/test_botable/base_test.rb +19 -0
- data/test/test_botable/crud_test.rb +109 -78
- data/test/test_botable/page_test.rb +0 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ab5a8dbd613806a632a7d26883287d92b076ad0
|
4
|
+
data.tar.gz: 282a10e85908184563c4b2b344ee2fc007dbf41a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13b966c0c1b0b1222f1d44df755a029a4217781b4eacfa57334882bc9d3ab51b021b8e2b572a9087be3612549fdcda9c3c3c6801a39fd869ef4e97e68d6ab2a3
|
7
|
+
data.tar.gz: 92e89261d74ec87d44177c121c80952a993595b486ba27cf0f9784f8a1647c2cd531e6f61a4801d61a3ef2a4be0a9c93b87f85eb183be8c526439f03dfb0f0be
|
data/lib/effective_test_bot.rb
CHANGED
@@ -26,11 +26,22 @@ if Rails.env.test?
|
|
26
26
|
# Take the tour!
|
27
27
|
# Generate an animated gif for each test
|
28
28
|
# Saved to an appropriate /test/tour/* directory
|
29
|
+
# Also enabled the crud_test #tour type tests
|
30
|
+
#
|
29
31
|
# You can override this default by setting an ENV or calling
|
30
32
|
# `rake test:bot TOUR=true` or `rake test:bot TEST=posts TOUR=verbose`
|
31
33
|
#
|
32
34
|
# Valid values are true / false / :verbose
|
33
35
|
config.tour_mode = false
|
34
36
|
|
37
|
+
# How long to delay in between animated gif frames
|
38
|
+
# The last frame is applied animated_gif_frame_delay * 3
|
39
|
+
# 100 equals 1 second. (a bit on the slow side, but suitable for a demo)
|
40
|
+
config.animated_gif_delay = 100
|
41
|
+
|
42
|
+
# Shorter than maximum height animaged gif frames have their
|
43
|
+
# bottom area filled by this color
|
44
|
+
# For best appearance, have this match your site's background color
|
45
|
+
config.animated_gif_background_color = 'white'
|
35
46
|
end
|
36
47
|
end
|
@@ -7,9 +7,16 @@ require 'rails/test_unit/sub_test_task'
|
|
7
7
|
# rake test:bot TOUR=true
|
8
8
|
# rake test:bot TOUR=verbose
|
9
9
|
|
10
|
+
# rake test:bot:tour
|
11
|
+
# rake test:bot:tour TEST=documents#new
|
12
|
+
|
10
13
|
# rake test:bot:environment
|
11
14
|
# rake test:bot:purge
|
12
15
|
|
16
|
+
# rake test:bot:tours
|
17
|
+
# rake test:bot:tours TEST=documents
|
18
|
+
|
19
|
+
|
13
20
|
namespace :test do
|
14
21
|
desc 'Runs the effective_test_bot'
|
15
22
|
task :bot do
|
@@ -29,11 +36,36 @@ namespace :test do
|
|
29
36
|
|
30
37
|
desc 'Deletes all effective_test_bot temporary, failure and tour screenshots'
|
31
38
|
task :purge do
|
32
|
-
FileUtils.rm_rf(Rails.root + 'test/
|
39
|
+
FileUtils.rm_rf(Rails.root + 'test/tours')
|
33
40
|
FileUtils.rm_rf(Rails.root + 'tmp/test_bot')
|
34
41
|
puts "Successfully purged all effective_test_bot screenshots"
|
35
42
|
end
|
36
|
-
|
43
|
+
|
44
|
+
desc 'Runs effective_test_bot environment test in tour mode'
|
45
|
+
task :tour do
|
46
|
+
ENV['TOUR'] ||= 'true'
|
47
|
+
Rake::Task['test:bot'].invoke
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Runs effective_test_bot environment test in verbose tour mode'
|
51
|
+
task :tourv do
|
52
|
+
ENV['TOUR'] ||= 'verbose'
|
53
|
+
Rake::Task['test:bot'].invoke
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'Prints all effective_test_bot animated gif tour file paths'
|
57
|
+
task :tours do
|
58
|
+
Dir['test/tours/*.gif'].each do |file|
|
59
|
+
file = file.to_s
|
60
|
+
|
61
|
+
if ENV['TEST'].present?
|
62
|
+
next unless file.include?(ENV['TEST'])
|
63
|
+
end
|
64
|
+
|
65
|
+
puts "\e[32m#{Rails.root + file}\e[0m" # 32 is green
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end # /namespace bot
|
37
69
|
|
38
70
|
Rails::TestTask.new('effective_test_bot' => 'test:prepare') do |t|
|
39
71
|
t.libs << 'test'
|
@@ -12,7 +12,7 @@ module TestBotable
|
|
12
12
|
module CrudDsl
|
13
13
|
extend ActiveSupport::Concern
|
14
14
|
|
15
|
-
CRUD_TESTS = [:
|
15
|
+
CRUD_TESTS = [:index, :new, :create_invalid, :create_valid, :show, :edit, :update_invalid, :update_valid, :destroy, (:tour if EffectiveTestBot.tour_mode?)].compact
|
16
16
|
|
17
17
|
module ClassMethods
|
18
18
|
|
@@ -29,14 +29,15 @@ module TestBotable
|
|
29
29
|
label = options.delete(:label).presence
|
30
30
|
only = options.delete(:only)
|
31
31
|
except = options.delete(:except)
|
32
|
+
current_crud_tests = crud_tests_to_define(only, except)
|
32
33
|
|
33
34
|
begin
|
34
|
-
normalize_test_bot_options!(options.merge!(user: user, resource: resource))
|
35
|
+
normalize_test_bot_options!(options.merge!(user: user, resource: resource, current_crud_tests: current_crud_tests))
|
35
36
|
rescue => e
|
36
37
|
raise "Error: #{e.message}. Expected usage: crud_test(Post || Post.new, User.first, only: [:new, :create], skip: {create_invalid: [:path]})"
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
current_crud_tests.each do |test|
|
40
41
|
options_for_method = options.dup
|
41
42
|
|
42
43
|
options_for_method[:skips] = Array(skips[test]) if skips[test]
|
@@ -22,6 +22,10 @@ module EffectiveTestBotAssertions
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def assert_submit_input(message = "(submit_input) Expected one or more input[type='submit'] to be present")
|
26
|
+
assert_selector 'input[type=submit]', message
|
27
|
+
end
|
28
|
+
|
25
29
|
def assert_page_status(status = 200, message = '(page_status) Expected :status: HTTP status code')
|
26
30
|
assert_equal status, page.status_code, message.sub(':status:', status.to_s)
|
27
31
|
end
|
@@ -61,6 +65,15 @@ module EffectiveTestBotAssertions
|
|
61
65
|
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")}"
|
62
66
|
end
|
63
67
|
|
68
|
+
# Rails jquery-ujs data-disable-with
|
69
|
+
# = f.button :submit, 'Save', data: { disable_with: 'Saving...' }
|
70
|
+
def assert_jquery_ujs_disable_with(label = nil, message = nil)
|
71
|
+
submits = label.present? ? [find(:link_or_button, label)] : all("input[type='submit']")
|
72
|
+
all_disabled_with = submits.all? { |submit| submit['data-disable-with'].present? }
|
73
|
+
|
74
|
+
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...' }\""
|
75
|
+
end
|
76
|
+
|
64
77
|
# assert_flash
|
65
78
|
# assert_flash :success
|
66
79
|
# assert_flash :error, 'there was a specific error'
|
@@ -19,7 +19,7 @@ module EffectiveTestBotFormFiller
|
|
19
19
|
# clicking each one and filling any form fields found within
|
20
20
|
|
21
21
|
active_tab = find("li.active > a[data-toggle='tab']")
|
22
|
-
tab_content = find(
|
22
|
+
tab_content = find('div' + active_tab['href']).find(:xpath, '..')
|
23
23
|
|
24
24
|
excluding_fields_with_parent(tab_content) { fill_form_fields(fills) }
|
25
25
|
|
@@ -34,7 +34,7 @@ module EffectiveTestBotFormFiller
|
|
34
34
|
synchronize!
|
35
35
|
save_test_bot_screenshot
|
36
36
|
|
37
|
-
within(
|
37
|
+
within('div' + tab['href']) { fill_form_fields(fills) }
|
38
38
|
end
|
39
39
|
|
40
40
|
end
|
@@ -50,8 +50,9 @@ module EffectiveTestBotFormFiller
|
|
50
50
|
2.times { field.click(); save_test_bot_screenshot }
|
51
51
|
end
|
52
52
|
|
53
|
-
all('input,select,textarea').each do |field|
|
53
|
+
all('input,select,textarea', visible: false).each do |field|
|
54
54
|
next if skip_form_field?(field)
|
55
|
+
skip_field_screenshot = false
|
55
56
|
|
56
57
|
case [field.tag_name, field['type']].compact.join('_')
|
57
58
|
when 'input_text', 'input_email', 'input_password', 'input_tel', 'input_number', 'input_checkbox', 'input_radio', 'textarea'
|
@@ -70,12 +71,13 @@ module EffectiveTestBotFormFiller
|
|
70
71
|
field.set(value_for_field(field, fills))
|
71
72
|
end
|
72
73
|
when 'input_submit', 'input_search'
|
74
|
+
skip_field_screenshot = true
|
73
75
|
# Do nothing
|
74
76
|
else
|
75
77
|
raise "unsupported field type #{[field.tag_name, field['type']].compact.join('_')}"
|
76
78
|
end
|
77
79
|
|
78
|
-
save_test_bot_screenshot
|
80
|
+
save_test_bot_screenshot unless skip_field_screenshot
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
@@ -87,6 +89,7 @@ module EffectiveTestBotFormFiller
|
|
87
89
|
def value_for_field(field, fills = nil)
|
88
90
|
field_name = [field.tag_name, field['type']].compact.join('_')
|
89
91
|
attributes = field['name'].to_s.gsub(']', '').split('[') # user[something_attributes][last_name] => ['user', 'something_attributes', 'last_name']
|
92
|
+
attribute = attributes.last.to_s
|
90
93
|
|
91
94
|
fill_value = fill_value_for_field(fills, attributes)
|
92
95
|
|
@@ -102,17 +105,19 @@ module EffectiveTestBotFormFiller
|
|
102
105
|
classes = field['class'].to_s.split(' ')
|
103
106
|
|
104
107
|
if classes.include?('date') # Let's assume this is a date input.
|
105
|
-
if
|
108
|
+
if attribute.include?('end') # Make sure end dates are after start dates
|
106
109
|
Faker::Date.forward(365).strftime('%Y-%m-%d')
|
107
110
|
else
|
108
111
|
Faker::Date.backward(365).strftime('%Y-%m-%d')
|
109
112
|
end
|
110
113
|
elsif classes.include?('datetime')
|
111
|
-
if
|
114
|
+
if attribute.include?('end')
|
112
115
|
Faker::Date.forward(365).strftime('%Y-%m-%d %H:%m')
|
113
116
|
else
|
114
117
|
Faker::Date.backward(365).strftime('%Y-%m-%d %H:%m')
|
115
118
|
end
|
119
|
+
elsif classes.include?('email') || attribute.include?('email')
|
120
|
+
Faker::Internet.email
|
116
121
|
elsif classes.include?('price') # effective_form_inputs price
|
117
122
|
4.times.map { DIGITS.sample }.join('') + '.00'
|
118
123
|
elsif classes.include?('numeric')
|
@@ -120,16 +125,26 @@ module EffectiveTestBotFormFiller
|
|
120
125
|
max = (Float(field['max']) rescue 1000)
|
121
126
|
number = Random.new.rand(min..max)
|
122
127
|
number.kind_of?(Float) ? number.round(2) : number
|
123
|
-
elsif
|
128
|
+
elsif attribute.include?('first_name')
|
124
129
|
Faker::Name.first_name
|
125
|
-
elsif
|
130
|
+
elsif attribute.include?('last_name')
|
126
131
|
Faker::Name.last_name
|
127
|
-
elsif
|
132
|
+
elsif attribute.include?('website')
|
133
|
+
Faker::Internet.url
|
134
|
+
elsif attribute.include?('city')
|
135
|
+
Faker::Address.city
|
136
|
+
elsif attribute.include?('address2')
|
137
|
+
Faker::Address.secondary_address
|
138
|
+
elsif attribute.include?('address')
|
139
|
+
Faker::Address.street_address
|
140
|
+
elsif attribute.include?('name')
|
128
141
|
Faker::Name.name
|
129
|
-
elsif
|
142
|
+
elsif attribute.include?('postal') # Make a Canadian postal code
|
130
143
|
LETTERS.sample + DIGITS.sample + LETTERS.sample + ' ' + DIGITS.sample + LETTERS.sample + DIGITS.sample
|
144
|
+
elsif attribute.include?('zip') && attribute.include?('code') # Make a US zip code
|
145
|
+
DIGITS.sample + DIGITS.sample + DIGITS.sample + DIGITS.sample + DIGITS.sample
|
131
146
|
else
|
132
|
-
Faker::Lorem.
|
147
|
+
Faker::Lorem.words(3).join(' ').capitalize
|
133
148
|
end
|
134
149
|
|
135
150
|
when 'select'
|
@@ -154,13 +169,13 @@ module EffectiveTestBotFormFiller
|
|
154
169
|
d = 10.times.map { DIGITS.sample }
|
155
170
|
d[0] + d[1] + d[2] + '-' + d[3] + d[4] + d[5] + '-' + d[6] + d[7] + d[8] + d[9]
|
156
171
|
when 'textarea'
|
157
|
-
Faker::Lorem.
|
172
|
+
Faker::Lorem.paragraph
|
158
173
|
when 'input_checkbox'
|
159
174
|
[true, false].sample
|
160
175
|
when 'input_radio'
|
161
176
|
[true, false].sample
|
162
177
|
when 'input_file'
|
163
|
-
"#{File.dirname(__FILE__)}/
|
178
|
+
"#{File.dirname(__FILE__)}/important_documents._test"
|
164
179
|
else
|
165
180
|
raise "fill_value unsupported field type: #{field['type']}"
|
166
181
|
end
|
@@ -230,6 +245,8 @@ module EffectiveTestBotFormFiller
|
|
230
245
|
end
|
231
246
|
|
232
247
|
def skip_form_field?(field)
|
248
|
+
field.reload # Handle a field changing visibility/disabled state from previous form field manipulations
|
249
|
+
|
233
250
|
field.visible? == false ||
|
234
251
|
field.disabled? ||
|
235
252
|
['true', true, 1].include?(field['data-test-bot-skip']) ||
|
@@ -19,6 +19,7 @@ module EffectiveTestBotFormHelper
|
|
19
19
|
# This submits the form, while checking for html5 form validation errors and unpermitted params
|
20
20
|
def submit_form(label = nil)
|
21
21
|
assert_no_html5_form_validation_errors unless test_bot_skip?(:no_html5_form_validation_errors)
|
22
|
+
assert_jquery_ujs_disable_with(label) unless test_bot_skip?(:jquery_ujs_disable_with)
|
22
23
|
|
23
24
|
if test_bot_skip?(:no_unpermitted_params)
|
24
25
|
click_submit(label)
|
@@ -62,7 +63,7 @@ module EffectiveTestBotFormHelper
|
|
62
63
|
page.execute_script "$('input[data-disable-with]').each(function(i) { $.rails.enableFormElement($(this)); });"
|
63
64
|
end
|
64
65
|
|
65
|
-
label.present? ?
|
66
|
+
label.present? ? find(:link_or_button, label).click : first(:css, "input[type='submit']").click
|
66
67
|
synchronize!
|
67
68
|
end
|
68
69
|
|
@@ -9,9 +9,6 @@ module EffectiveTestBotScreenshotsHelper
|
|
9
9
|
|
10
10
|
full_path = current_test_temp_path + '/' + "#{current_test_screenshot_id}.png"
|
11
11
|
page.save_screenshot(full_path)
|
12
|
-
|
13
|
-
#i = Magick::Image.read(file).first
|
14
|
-
#i.resize_to_fill(100,100).write("#{file}-square-thumb.jpg")
|
15
12
|
end
|
16
13
|
|
17
14
|
# This is run before every test
|
@@ -80,18 +77,21 @@ module EffectiveTestBotScreenshotsHelper
|
|
80
77
|
|
81
78
|
# Remove the PNG's alpha channel, 'cause .gifs dont support it
|
82
79
|
# Extend the bottom/right of each image to extend upto dimension
|
80
|
+
delay = [(EffectiveTestBot.animated_gif_delay.to_i rescue 0), 10].max
|
81
|
+
last_image = images.last
|
82
|
+
|
83
83
|
images.each do |image|
|
84
84
|
image.alpha Magick::DeactivateAlphaChannel
|
85
|
-
|
85
|
+
image.delay = (image == last_image) ? (delay * 4) : delay
|
86
|
+
image.background_color = EffectiveTestBot.animated_gif_background_color
|
87
|
+
|
86
88
|
animation << image.extent(dimensions[:width], dimensions[:height])
|
87
89
|
end
|
88
90
|
|
89
|
-
# Run it through
|
90
|
-
|
91
|
-
animation = animation.optimize_layers(Magick::OptimizePlusLayer)
|
91
|
+
# Run it through https://rmagick.github.io/ilist.html#optimize_layers
|
92
|
+
animation = animation.optimize_layers(Magick::OptimizeLayer)
|
92
93
|
|
93
94
|
# Write the final animated gif
|
94
|
-
animation.delay = 100 # 100 is the right setting
|
95
95
|
animation.write(full_path)
|
96
96
|
end
|
97
97
|
|
@@ -101,7 +101,7 @@ module EffectiveTestBotScreenshotsHelper
|
|
101
101
|
# current_test_failure_path: destination for .gifs of failing tests
|
102
102
|
|
103
103
|
def current_test_temp_path
|
104
|
-
@_current_test_temp_path ||= File.join(Rails.root, 'tmp', 'test_bot', current_test)
|
104
|
+
@_current_test_temp_path ||= File.join(Rails.root, 'tmp', 'test_bot', current_test || 'none')
|
105
105
|
end
|
106
106
|
|
107
107
|
def current_test_failure_path
|
@@ -115,7 +115,7 @@ module EffectiveTestBotScreenshotsHelper
|
|
115
115
|
|
116
116
|
# Where the tour animated gif ends up
|
117
117
|
def current_test_tour_path
|
118
|
-
File.join(Rails.root, 'test', '
|
118
|
+
File.join(Rails.root, 'test', 'tours')
|
119
119
|
end
|
120
120
|
|
121
121
|
def current_test_tour_filename
|
@@ -13,12 +13,6 @@ module EffectiveTestBotTestHelper
|
|
13
13
|
session.driver.submit :delete, path, {}
|
14
14
|
session.document.find('html')
|
15
15
|
|
16
|
-
# Assign the Flash and Assigns
|
17
|
-
@flash = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Flash'])) rescue {})
|
18
|
-
@assigns = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Assigns'])) rescue {})
|
19
|
-
@unpermitted_params = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Unpermitted-Params'])) rescue [])
|
20
|
-
@exceptions = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Exceptions'])) rescue [])
|
21
|
-
|
22
16
|
@visit_delete_page = session
|
23
17
|
end
|
24
18
|
|
@@ -38,19 +32,19 @@ module EffectiveTestBotTestHelper
|
|
38
32
|
# EffectiveTestBot includes an after_filter on ApplicationController to set an http header
|
39
33
|
# These values are 'from the last page submit or refresh'
|
40
34
|
def flash
|
41
|
-
|
35
|
+
(JSON.parse(Base64.decode64(page.response_headers['Test-Bot-Flash'])) rescue {})
|
42
36
|
end
|
43
37
|
|
44
38
|
def assigns
|
45
|
-
|
39
|
+
(JSON.parse(Base64.decode64(page.response_headers['Test-Bot-Assigns'])) rescue {})
|
46
40
|
end
|
47
41
|
|
48
42
|
def unpermitted_params
|
49
|
-
|
43
|
+
(JSON.parse(Base64.decode64(page.response_headers['Test-Bot-Unpermitted-Params'])) rescue [])
|
50
44
|
end
|
51
45
|
|
52
46
|
def exceptions
|
53
|
-
|
47
|
+
(JSON.parse(Base64.decode64(page.response_headers['Test-Bot-Exceptions'])) rescue [])
|
54
48
|
end
|
55
49
|
|
56
50
|
end
|
File without changes
|
@@ -40,7 +40,10 @@ module TestBot
|
|
40
40
|
# If we're done accumulating CRUD actions, launch the crud_test with all seen actions
|
41
41
|
if controller != next_controller || CRUD_ACTIONS.include?(next_action) == false
|
42
42
|
begin
|
43
|
-
|
43
|
+
only_tests = seen_actions.delete(controller)
|
44
|
+
only_tests << :tour if EffectiveTestBot.tour_mode?
|
45
|
+
|
46
|
+
crud_test(controller, User.first, only: only_tests)
|
44
47
|
rescue => e
|
45
48
|
puts e.message # Sometimes there is an object that can't be instantiated, so we still want to continue the application test
|
46
49
|
end
|
@@ -48,6 +48,25 @@ module BaseTest
|
|
48
48
|
resource_class.last
|
49
49
|
end
|
50
50
|
|
51
|
+
# Try to find a link_to_delete already on this page
|
52
|
+
# Otherwise create one
|
53
|
+
# Returns the link element
|
54
|
+
def find_or_create_rails_ujs_link_to_delete(resource)
|
55
|
+
selector = "a[href='#{resource_path(resource)}'][data-method='delete']"
|
56
|
+
link_to_delete = page.document.all(selector, visible: false).first # could be nil, but this is a non-blocking selector
|
57
|
+
|
58
|
+
if link_to_delete.present? # Take excessive efforts to ensure it's visible and clickable
|
59
|
+
page.execute_script("$('body').prepend($(\"#{selector}\").first().clone().show().removeProp('disabled').html('Delete'));")
|
60
|
+
else # Create our own link
|
61
|
+
page.execute_script("$('body').prepend($('<a>').attr({href: '#{resource_path(resource)}', 'data-method': 'delete', 'data-confirm': 'Are you sure?'}).html('Delete'));")
|
62
|
+
end
|
63
|
+
|
64
|
+
# capybara-webkit doesn't seem to stop on the alert 'Are you sure?'.
|
65
|
+
# Otherwise we'd want to take a screenshot of it
|
66
|
+
|
67
|
+
(page.document.first(:css, selector) rescue nil)
|
68
|
+
end
|
69
|
+
|
51
70
|
def resources_path # index, create
|
52
71
|
polymorphic_path([*controller_namespace, resource_class])
|
53
72
|
end
|
@@ -4,6 +4,32 @@
|
|
4
4
|
module CrudTest
|
5
5
|
protected
|
6
6
|
|
7
|
+
# So this runs every single test over again, but in a screenshot optimized manner
|
8
|
+
def test_bot_tour_test
|
9
|
+
# This is set by the crud_dsl, from application_test. It makes sure we don't run a show test if theres no show action
|
10
|
+
tests = defined?(current_crud_tests) ? current_crud_tests : []
|
11
|
+
tests = tests - [:tour, 'tour'] # Ensure tour doesn't somehow get in here, as it'll recurse forever
|
12
|
+
|
13
|
+
tests.each { |test| send("test_bot_#{test}_test") }
|
14
|
+
|
15
|
+
visit resources_path
|
16
|
+
save_test_bot_screenshot
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_bot_index_test
|
20
|
+
sign_in(user) and (resource = (find_or_create_resource! rescue nil))
|
21
|
+
|
22
|
+
visit resources_path
|
23
|
+
save_test_bot_screenshot
|
24
|
+
|
25
|
+
assert_page_normal
|
26
|
+
|
27
|
+
assert(
|
28
|
+
(assigns['datatable'].present? || assigns[resource_name.pluralize].present?),
|
29
|
+
"(assigns) Expected @#{resource_name.pluralize} or @datatable to be present"
|
30
|
+
) unless test_bot_skip?(:assigns)
|
31
|
+
end
|
32
|
+
|
7
33
|
def test_bot_new_test
|
8
34
|
sign_in(user) and visit(new_resource_path)
|
9
35
|
save_test_bot_screenshot
|
@@ -13,64 +39,74 @@ module CrudTest
|
|
13
39
|
|
14
40
|
# Make sure there's a form with a submit button
|
15
41
|
form_selector = "form#new_#{resource_name}"
|
16
|
-
|
17
42
|
assert_selector form_selector, "Expected form with selector #{form_selector}"
|
43
|
+
|
18
44
|
within(form_selector) do
|
19
|
-
|
45
|
+
assert_submit_input unless test_bot_skip?(:submit_input)
|
46
|
+
assert_jquery_ujs_disable_with unless test_bot_skip?(:jquery_ujs_disable_with)
|
20
47
|
end
|
21
48
|
|
22
49
|
end
|
23
50
|
|
24
|
-
def
|
51
|
+
def test_bot_create_invalid_test
|
25
52
|
sign_in(user) and visit(new_resource_path)
|
26
|
-
save_test_bot_screenshot
|
27
53
|
|
28
|
-
before = { count: resource_class.count
|
54
|
+
before = { count: resource_class.count }
|
29
55
|
|
30
56
|
within("form#new_#{resource_name}") do
|
31
|
-
|
32
|
-
|
57
|
+
without_screenshots { clear_form }
|
58
|
+
submit_novalidate_form
|
33
59
|
end
|
34
60
|
|
35
61
|
save_test_bot_screenshot
|
36
62
|
|
37
|
-
after = { count: resource_class.count
|
63
|
+
after = { count: resource_class.count }
|
38
64
|
|
39
65
|
assert_page_normal
|
40
66
|
|
41
|
-
|
42
|
-
|
67
|
+
assert_assigns(resource_name) unless test_bot_skip?(:assigns)
|
68
|
+
assert_assigns_errors(resource_name) unless test_bot_skip?(:assigns_errors)
|
43
69
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
70
|
+
assert_equal before[:count], after[:count], "Expected #{resource_class}.count to be unchanged"
|
71
|
+
assert_equal(resources_path, page.current_path, "(path) Expected current_path to match resource #create path #{resources_path}") unless test_bot_skip?(:path)
|
72
|
+
|
73
|
+
assert_flash(:danger) unless test_bot_skip?(:flash)
|
48
74
|
end
|
49
75
|
|
50
|
-
def
|
76
|
+
def test_bot_create_valid_test
|
51
77
|
sign_in(user) and visit(new_resource_path)
|
78
|
+
save_test_bot_screenshot
|
52
79
|
|
53
|
-
before = { count: resource_class.count }
|
80
|
+
before = { count: resource_class.count, path: page.current_path }
|
54
81
|
|
55
82
|
within("form#new_#{resource_name}") do
|
56
|
-
|
57
|
-
|
83
|
+
fill_form(resource_attributes)
|
84
|
+
submit_form
|
58
85
|
end
|
59
86
|
|
60
87
|
save_test_bot_screenshot
|
61
88
|
|
62
|
-
after = { count: resource_class.count }
|
89
|
+
after = { count: resource_class.count, path: page.current_path }
|
63
90
|
|
64
91
|
assert_page_normal
|
65
92
|
|
66
|
-
|
93
|
+
# In a rails controller, if I redirect to resources_path it may not assign the instance variable
|
94
|
+
# Wheras if I redirect to edit_resource_path I must ensure that the instance variable is set
|
95
|
+
assert_assigns(resource_name) if (after[:path].include?('/edit/') && !test_bot_skip?(:assigns))
|
96
|
+
assert_no_assigns_errors(resource_name) unless test_bot_skip?(:no_assigns_errors)
|
67
97
|
|
68
|
-
|
69
|
-
|
98
|
+
refute_equal before[:count], after[:count], "Expected fill_form to create a #{resource_class} object"
|
99
|
+
refute_equal(before[:path], after[:path], "(path) Expected unique before and after paths") unless test_bot_skip?(:path)
|
100
|
+
end
|
70
101
|
|
71
|
-
|
102
|
+
def test_bot_show_test
|
103
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
72
104
|
|
73
|
-
|
105
|
+
visit resource_path(resource)
|
106
|
+
save_test_bot_screenshot
|
107
|
+
|
108
|
+
assert_page_normal
|
109
|
+
assert_assigns(resource_name) unless test_bot_skip?(:assigns)
|
74
110
|
end
|
75
111
|
|
76
112
|
def test_bot_edit_test
|
@@ -80,18 +116,19 @@ module CrudTest
|
|
80
116
|
save_test_bot_screenshot
|
81
117
|
|
82
118
|
assert_page_normal
|
83
|
-
assert_assigns(resource_name)
|
119
|
+
assert_assigns(resource_name) # unskippable
|
84
120
|
|
85
121
|
# Make sure there's a form with a submit button
|
86
122
|
form_selector = "form#edit_#{resource_name}_#{resource.id}"
|
87
|
-
|
88
123
|
assert_selector form_selector, "Expected form with selector #{form_selector}"
|
124
|
+
|
89
125
|
within(form_selector) do
|
90
|
-
|
126
|
+
assert_submit_input unless test_bot_skip?(:submit_input)
|
127
|
+
assert_jquery_ujs_disable_with unless test_bot_skip?(:jquery_ujs_disable_with)
|
91
128
|
end
|
92
129
|
end
|
93
130
|
|
94
|
-
def
|
131
|
+
def test_bot_update_invalid_test
|
95
132
|
sign_in(user) and (resource = find_or_create_resource!)
|
96
133
|
|
97
134
|
visit(edit_resource_path(resource))
|
@@ -100,8 +137,8 @@ module CrudTest
|
|
100
137
|
before = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
101
138
|
|
102
139
|
within("form#edit_#{resource_name}_#{resource.id}") do
|
103
|
-
|
104
|
-
|
140
|
+
clear_form
|
141
|
+
submit_novalidate_form
|
105
142
|
end
|
106
143
|
|
107
144
|
save_test_bot_screenshot
|
@@ -112,19 +149,19 @@ module CrudTest
|
|
112
149
|
|
113
150
|
assert_page_normal
|
114
151
|
|
115
|
-
|
152
|
+
assert_assigns(resource_name) unless test_bot_skip?(:assigns)
|
153
|
+
assert_assigns_errors(resource_name) unless test_bot_skip?(:assigns_errors)
|
116
154
|
|
117
|
-
assert_equal
|
118
|
-
refute_equal(before[:updated_at], after[:updated_at], "(updated_at) Expected @#{resource_name}.updated_at to have changed") if (resource.respond_to?(:updated_at) && !test_bot_skip?(:updated_at))
|
155
|
+
assert_equal(resource_path(resource), page.current_path, "(path) Expected current_path to match resource #update path") unless test_bot_skip?(:path)
|
119
156
|
|
120
|
-
|
157
|
+
assert_equal before[:count], after[:count], "Expected: #{resource_class}.count to be unchanged"
|
158
|
+
assert_equal(before[:updated_at], after[:updated_at], "(updated_at) Expected @#{resource_name}.updated_at to be unchanged") if (resource.respond_to?(:updated_at) && !test_bot_skip?(:updated_at))
|
159
|
+
|
160
|
+
assert_flash(:danger) unless test_bot_skip?(:flash)
|
121
161
|
|
122
|
-
# In a rails controller, if i redirect to resources_path it may not assign the instance variable
|
123
|
-
# Wheras if I redirect to edit_resource_path I must ensure that the instance variable is set
|
124
|
-
assert_assigns(resource_name) if (after[:path] == edit_resource_path(resource) && !test_bot_skip?(:assigns))
|
125
162
|
end
|
126
163
|
|
127
|
-
def
|
164
|
+
def test_bot_update_valid_test
|
128
165
|
sign_in(user) and (resource = find_or_create_resource!)
|
129
166
|
|
130
167
|
visit(edit_resource_path(resource))
|
@@ -133,8 +170,8 @@ module CrudTest
|
|
133
170
|
before = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
134
171
|
|
135
172
|
within("form#edit_#{resource_name}_#{resource.id}") do
|
136
|
-
|
137
|
-
|
173
|
+
fill_form(resource_attributes)
|
174
|
+
submit_form
|
138
175
|
end
|
139
176
|
|
140
177
|
save_test_bot_screenshot
|
@@ -143,40 +180,19 @@ module CrudTest
|
|
143
180
|
|
144
181
|
after = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
145
182
|
|
146
|
-
assert_page_normal
|
147
|
-
assert_equal before[:count], after[:count], "Expected: #{resource_class}.count to be unchanged"
|
148
|
-
|
149
|
-
assert_assigns(resource_name) unless test_bot_skip?(:assigns)
|
150
|
-
assert_assigns_errors(resource_name) unless test_bot_skip?(:assigns_errors)
|
151
|
-
assert_equal(before[:updated_at], after[:updated_at], "(updated_at) Expected @#{resource_name}.updated_at to be unchanged") if (resource.respond_to?(:updated_at) && !test_bot_skip?(:updated_at))
|
152
|
-
|
153
|
-
assert_flash(:danger) unless test_bot_skip?(:flash)
|
154
|
-
|
155
|
-
assert_equal(resource_path(resource), page.current_path, "(path) Expected current_path to match resource #update path") unless test_bot_skip?(:path)
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_bot_index_test
|
159
|
-
sign_in(user) and (resource = (find_or_create_resource! rescue nil))
|
160
|
-
|
161
|
-
visit resources_path
|
162
|
-
save_test_bot_screenshot
|
163
|
-
|
164
183
|
assert_page_normal
|
165
184
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
def test_bot_show_test
|
173
|
-
sign_in(user) and (resource = find_or_create_resource!)
|
185
|
+
# In a rails controller, if i redirect to resources_path it may not assign the instance variable
|
186
|
+
# Wheras if I redirect to edit_resource_path I must ensure that the instance variable is set
|
187
|
+
if after[:path] == edit_resource_path(resource)
|
188
|
+
assert_assigns(resource_name) unless !test_bot_skip?(:assigns)
|
189
|
+
end
|
190
|
+
assert_no_assigns_errors(resource_name) unless test_bot_skip?(:no_assigns_errors)
|
174
191
|
|
175
|
-
|
176
|
-
|
192
|
+
assert_equal before[:count], after[:count], "Expected #{resource_class}.count to be unchanged" unless test_bot_skip?(:count)
|
193
|
+
refute_equal(before[:updated_at], after[:updated_at], "(updated_at) Expected @#{resource_name}.updated_at to have changed") if (resource.respond_to?(:updated_at) && !test_bot_skip?(:updated_at))
|
177
194
|
|
178
|
-
|
179
|
-
assert_assigns(resource_name) unless test_bot_skip?(:assigns)
|
195
|
+
assert_flash(:success) unless test_bot_skip?(:flash)
|
180
196
|
end
|
181
197
|
|
182
198
|
def test_bot_destroy_test
|
@@ -184,17 +200,31 @@ module CrudTest
|
|
184
200
|
|
185
201
|
before = { count: resource_class.count, archived: (resource.archived rescue nil) }
|
186
202
|
|
187
|
-
|
203
|
+
# We're going to try to visit the index page and create a link to delete
|
204
|
+
visit(resources_path)
|
205
|
+
save_test_bot_screenshot
|
188
206
|
|
189
|
-
|
207
|
+
link_to_delete = find_or_create_rails_ujs_link_to_delete(resource)
|
190
208
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
assert_equal(200, @visit_delete_page.try(:status_code), '(page_status) Expected 200 HTTP status code') unless test_bot_skip?(:page_status)
|
195
|
-
assert((@visit_delete_page.find(:xpath, '//title', visible: false) rescue nil).present?, '(page_title) Expected page title to be present') unless test_bot_skip?(:page_title)
|
209
|
+
if link_to_delete.present? && (link_to_delete.click() rescue false)
|
210
|
+
synchronize!
|
211
|
+
save_test_bot_screenshot
|
196
212
|
|
197
|
-
|
213
|
+
assert_page_normal
|
214
|
+
assert_flash(:success) unless test_bot_skip?(:flash)
|
215
|
+
else
|
216
|
+
# Capybara-webkit can't just make a DELETE request, so we fallback to Selenium
|
217
|
+
# We can't use our normal helpers assert_page_normal()
|
218
|
+
# So we just assert the 200 status code, and page title present manually
|
219
|
+
# Javascript errors cannot be detected
|
220
|
+
|
221
|
+
puts 'test_bot_destroy_test failed to find_or_create_rails_ujs_link_to_delete Falling back to selenium DELETE request.'
|
222
|
+
visit_delete(resource_path(resource), user)
|
223
|
+
assert_equal(200, @visit_delete_page.try(:status_code), '(page_status) Expected 200 HTTP status code') unless test_bot_skip?(:page_status)
|
224
|
+
assert((@visit_delete_page.find(:xpath, '//title', visible: false) rescue nil).present?, '(page_title) Expected page title to be present') unless test_bot_skip?(:page_title)
|
225
|
+
end
|
226
|
+
|
227
|
+
after = { count: resource_class.count, archived: (resource_class.find(resource.id).archived rescue nil) }
|
198
228
|
|
199
229
|
if resource.respond_to?(:archived)
|
200
230
|
assert_equal(true, after[:archived], "Expected #{resource_class}.archived? to be true")
|
@@ -202,4 +232,5 @@ module CrudTest
|
|
202
232
|
assert_equal before[:count]-1, after[:count], "Expected: #{resource_class}.count to decrement by 1"
|
203
233
|
end
|
204
234
|
end
|
235
|
+
|
205
236
|
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: 0.4.
|
4
|
+
version: 0.4.5
|
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-10-
|
11
|
+
date: 2015-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -232,13 +232,13 @@ files:
|
|
232
232
|
- test/concerns/test_botable/page_dsl.rb
|
233
233
|
- test/concerns/test_botable/redirect_dsl.rb
|
234
234
|
- test/concerns/test_botable/wizard_dsl.rb
|
235
|
-
- test/support/effective_assets_upload_file._test
|
236
235
|
- test/support/effective_test_bot_assertions.rb
|
237
236
|
- test/support/effective_test_bot_form_filler.rb
|
238
237
|
- test/support/effective_test_bot_form_helper.rb
|
239
238
|
- test/support/effective_test_bot_login_helper.rb
|
240
239
|
- test/support/effective_test_bot_screenshots_helper.rb
|
241
240
|
- test/support/effective_test_bot_test_helper.rb
|
241
|
+
- test/support/important_documents._test
|
242
242
|
- test/test_bot/integration/application_test.rb
|
243
243
|
- test/test_bot/integration/environment_test.rb
|
244
244
|
- test/test_botable/base_test.rb
|