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