effective_test_bot 0.4.13 → 0.4.14
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/README.md +26 -22
- data/app/helpers/effective_test_bot_controller_helper.rb +0 -6
- data/lib/effective_test_bot.rb +1 -0
- data/lib/effective_test_bot/engine.rb +32 -31
- data/lib/effective_test_bot/middleware.rb +40 -0
- data/lib/effective_test_bot/version.rb +1 -1
- data/lib/generators/templates/test_helper.rb +1 -1
- data/test/concerns/test_botable/devise_dsl.rb +2 -0
- data/test/concerns/test_botable/wizard_dsl.rb +6 -1
- data/test/support/effective_test_bot_assertions.rb +23 -12
- data/test/support/effective_test_bot_form_filler.rb +7 -0
- data/test/support/effective_test_bot_form_helper.rb +1 -0
- data/test/support/effective_test_bot_login_helper.rb +7 -3
- data/test/support/effective_test_bot_test_helper.rb +5 -0
- data/test/test_bot/integration/application_test.rb +41 -11
- data/test/test_bot/integration/environment_test.rb +20 -68
- data/test/test_botable/base_test.rb +3 -3
- data/test/test_botable/crud_test.rb +20 -18
- data/test/test_botable/devise_test.rb +25 -13
- data/test/test_botable/wizard_test.rb +2 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c57de4dc4b6c0cf80fe3cefea43adb80d683bde
|
4
|
+
data.tar.gz: a2f0200f1fb20a3df4272adf99e9858103630fe8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca5a005d6ecf7d17b699f615bd1b953f4607718a2f4ee6f5349d6f55506a73f974826287033927292aef55dd5875d0baae5a2bc29aaaf58be87f426346d0c2e0
|
7
|
+
data.tar.gz: bc67e5f134111162842ef992a4451e3dfd49ce235fee9d2505b355a8aef54a0858ab6c88a21aa03003f760b43c961f85779ecc1bc6a2e12138031a5d8173afed
|
data/README.md
CHANGED
@@ -99,22 +99,24 @@ Effective TestBot provides 4 areas of support in writing [minitest](https://gith
|
|
99
99
|
|
100
100
|
The following assertions are added for use in any integration test:
|
101
101
|
|
102
|
-
- `
|
103
|
-
- `
|
104
|
-
- `
|
105
|
-
- `assert_submit_input` makes sure there is an `input[type='submit']` present.
|
106
|
-
- `assert_page_status` checks for a given http status, default 200.
|
102
|
+
- `assert_assigns` asserts a given rails view_assigns object is present.
|
103
|
+
- `assert_assigns_errors` use after an intentionally invalid form submit to make sure your assigned rails object has errors, or a specific error.
|
104
|
+
- `assert_no_assigns_errors` should be used after any form submit to make sure your assigned rails object has no errors. Prints out any errors if they exist.
|
107
105
|
- `assert_current_path(path)` asserts the current page path.
|
108
|
-
- `
|
109
|
-
- `
|
110
|
-
- `assert_no_unpermitted_params` makes sure the last submitted form did not include any unpermitted params and prints out any unpermitted params that do exist.
|
106
|
+
- `assert_flash`, optionally with the desired `:success`, `:error` key and/or message, makes sure the flash is set.
|
107
|
+
- `assert_jquery_ujs_disable_with` makes sure all `input[type=submit]` elements on the page have the `data-disable-with` property set.
|
111
108
|
- `assert_no_exceptions` checks for any exceptions in the last page request and gives a stacktrace if there was.
|
112
109
|
- `assert_no_html_form_validation_errors` checks for frontend html5 errors.
|
113
|
-
- `
|
114
|
-
- `
|
115
|
-
- `
|
116
|
-
- `
|
117
|
-
- `
|
110
|
+
- `assert_no_js_errors` - checks for any javascript errors on the page.
|
111
|
+
- `assert_no_unpermitted_params` makes sure the last submitted form did not include any unpermitted params and prints out any unpermitted params that do exist.
|
112
|
+
- `assert_page_content(content)` checks that the given content is present without waiting the capybara default wait time.
|
113
|
+
- `assert_no_page_content(content)` checks that the given content is blank without waiting the capybara default wait time.
|
114
|
+
- `assert_page_status` checks for a given http status, default 200.
|
115
|
+
- `assert_page_title` makes sure there is an html `<title></title>` present.
|
116
|
+
- `assert_redirect(from_path)` optionally with to_path, makes sure the current page path is not from_path.
|
117
|
+
- `assert_signed_in` checks that the assigned `@current_user` is present.
|
118
|
+
- `assert_signed_out` checks that the assigned `@current_user` is blank.
|
119
|
+
- `assert_submit_input` makes sure there is an `input[type='submit']` present.
|
118
120
|
|
119
121
|
As well,
|
120
122
|
|
@@ -181,15 +183,17 @@ end
|
|
181
183
|
|
182
184
|
### other helpers
|
183
185
|
|
184
|
-
- `
|
186
|
+
- `as_user(user) do .. end` yields a block between `sign_in`, and `logout`.
|
185
187
|
- `clear_form` clears all form fields, probably used before `submit_novalidate_form` to test invalid form submissions.
|
188
|
+
- `click_first(label)` clicks the first link matching the given label
|
189
|
+
- `submit_novalidate_form` submits the form without client side validation, ignoring any required field requirements.
|
186
190
|
- `sign_in(user)` optionally with user, signs in via `Warden::Test::Helpers` hacky login skipping method.
|
187
191
|
- `sign_in_manually(user, password)` visits the devise `new_user_session_path` and signs in via the form.
|
188
192
|
- `sign_up` visits the devise `new_user_registration_path` and signs up as a new user.
|
189
|
-
- `as_user(user) do .. end` yields a block between `sign_in`, and `logout`.
|
190
193
|
- `synchronize!` should fix any timing issues waiting for page elements.
|
191
194
|
- `was_redirect?` returns true/false if the last time we changed pages was a 304 redirect.
|
192
195
|
- `was_download?` if clicking a link returned a file of any type rather than a page change.
|
196
|
+
- `within_if(selector, boolean) do .. end` runs the block inside capybara's `within do .. end` if boolean is true, otherwise runs the same block skipping the `within`.
|
193
197
|
|
194
198
|
## Capybara Super Extras
|
195
199
|
|
@@ -269,14 +273,14 @@ The individual test suites may also be used as part of a larger test:
|
|
269
273
|
class PostsTest < ActionDispatch::IntegrationTest
|
270
274
|
test 'user may only update a post once' do
|
271
275
|
crud_action_test(:create_valid, Post, User.first)
|
272
|
-
|
276
|
+
assert_text 'successfully created post. You may only update it once.'
|
273
277
|
|
274
278
|
crud_action_test(:update_valid, Post.last, User.first)
|
275
|
-
|
279
|
+
assert_text 'successfully updated post.'
|
276
280
|
|
277
281
|
crud_action_test(:update_valid, Post.last, User.first, skip: [:no_assigns_errors, :updated_at])
|
278
282
|
assert_assigns_errors(:post, 'you may no longer update this post.')
|
279
|
-
|
283
|
+
assert_text 'you may no longer update this post.'
|
280
284
|
end
|
281
285
|
end
|
282
286
|
```
|
@@ -305,7 +309,7 @@ Or each individually in part of a regular test:
|
|
305
309
|
class MyApplicationTest < ActionDispatch::IntegrationTest
|
306
310
|
test 'user receives 10 tokens after signing up' do
|
307
311
|
devise_action_test(:sign_up)
|
308
|
-
|
312
|
+
assert_text 'Tokens: 10'
|
309
313
|
assert_equals 10, User.last.tokens
|
310
314
|
assert_equals 10, assigns(:current_user).tokens
|
311
315
|
end
|
@@ -372,7 +376,7 @@ class PostsTest < ActionDispatch::IntegrationTest
|
|
372
376
|
page_action_test(:posts_path, User.first)
|
373
377
|
|
374
378
|
assert page.current_path, '/posts'
|
375
|
-
|
379
|
+
assert_text 'first post'
|
376
380
|
end
|
377
381
|
end
|
378
382
|
```
|
@@ -397,7 +401,7 @@ class PostsTest < ActionDispatch::IntegrationTest
|
|
397
401
|
test 'visiting blog redirects to posts' do
|
398
402
|
Post.create(title: 'first post')
|
399
403
|
redirect_action_test('/blog', '/posts', User.first)
|
400
|
-
|
404
|
+
assert_text 'first post'
|
401
405
|
end
|
402
406
|
end
|
403
407
|
```
|
@@ -425,7 +429,7 @@ class PostsTest < ActionDispatch::IntegrationTest
|
|
425
429
|
test 'building a post in 5 steps' do
|
426
430
|
wizard_action_test('/build_post/step1', '/build_post/step5', User.first) do
|
427
431
|
if page.current_path.end_with?('step4')
|
428
|
-
|
432
|
+
assert_text 'your post is ready but must first be approved by an admin.'
|
429
433
|
end
|
430
434
|
end
|
431
435
|
end
|
@@ -30,10 +30,4 @@ module EffectiveTestBotControllerHelper
|
|
30
30
|
response.headers['Test-Bot-Unpermitted-Params'] = Base64.encode64(exception.params.to_json)
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
|
-
def assign_test_bot_exceptions_header(exception)
|
35
|
-
info = [exception.message] + exception.backtrace.first(8)
|
36
|
-
response.headers['Test-Bot-Exceptions'] = Base64.encode64(info.to_json)
|
37
|
-
end
|
38
|
-
|
39
33
|
end
|
data/lib/effective_test_bot.rb
CHANGED
@@ -13,32 +13,40 @@ module EffectiveTestBot
|
|
13
13
|
end
|
14
14
|
|
15
15
|
initializer 'effective_test_bot.test_suite' do |app|
|
16
|
-
Rails.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
if Rails.env.test?
|
17
|
+
Rails.application.config.to_prepare do
|
18
|
+
# test/support/
|
19
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotAssertions
|
20
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotFormHelper
|
21
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotFormFiller
|
22
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotLoginHelper
|
23
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotScreenshotsHelper
|
24
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotTestHelper
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
# test/test_botable/
|
27
|
+
ActionDispatch::IntegrationTest.include BaseTest
|
28
|
+
ActionDispatch::IntegrationTest.include CrudTest
|
29
|
+
ActionDispatch::IntegrationTest.include DeviseTest
|
30
|
+
ActionDispatch::IntegrationTest.include MemberTest
|
31
|
+
ActionDispatch::IntegrationTest.include PageTest
|
32
|
+
ActionDispatch::IntegrationTest.include RedirectTest
|
33
|
+
ActionDispatch::IntegrationTest.include WizardTest
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
# test/concerns/test_botable/
|
36
|
+
ActionDispatch::IntegrationTest.include TestBotable::BaseDsl
|
37
|
+
ActionDispatch::IntegrationTest.include TestBotable::CrudDsl
|
38
|
+
ActionDispatch::IntegrationTest.include TestBotable::DeviseDsl
|
39
|
+
ActionDispatch::IntegrationTest.include TestBotable::MemberDsl
|
40
|
+
ActionDispatch::IntegrationTest.include TestBotable::PageDsl
|
41
|
+
ActionDispatch::IntegrationTest.include TestBotable::RedirectDsl
|
42
|
+
ActionDispatch::IntegrationTest.include TestBotable::WizardDsl
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
initializer 'effective_test_bot.middleware' do |app|
|
48
|
+
if Rails.env.test?
|
49
|
+
Rails.application.config.middleware.use EffectiveTestBot::Middleware
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
@@ -54,14 +62,7 @@ module EffectiveTestBot
|
|
54
62
|
rescue_from ActionController::UnpermittedParameters do |exception|
|
55
63
|
assign_test_bot_unpermitted_params_header(exception)
|
56
64
|
end
|
57
|
-
|
58
|
-
# This isn't working properly. TODO: Fix this
|
59
|
-
# rescue_from StandardError do |exception|
|
60
|
-
# assign_test_bot_exceptions_header(exception)
|
61
|
-
# render status: 500, text: "<html><body><h1>Uncaught Exception</h1><p>#{exception.message}</p><p>#{exception.backtrace.first(20).join('<br>')}</p></body></html>"
|
62
|
-
# end
|
63
65
|
end
|
64
|
-
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Watch for any rails server exceptions and write the stacktrace to ./tmp/test_bot/exception.txt
|
2
|
+
# This file is checked for by assert_no_exceptions
|
3
|
+
|
4
|
+
module EffectiveTestBot
|
5
|
+
class Middleware
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
begin
|
12
|
+
@app.call(env)
|
13
|
+
rescue Exception => exception
|
14
|
+
begin
|
15
|
+
save(exception)
|
16
|
+
rescue => e
|
17
|
+
puts "TestBotError: An error occurred while attempting to save a rails server exception: #{e.message}"
|
18
|
+
end
|
19
|
+
|
20
|
+
raise exception
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def save(exception)
|
25
|
+
lines = [exception.message] + exception.backtrace.first(8)
|
26
|
+
|
27
|
+
dir = File.join(Dir.pwd, 'tmp', 'test_bot')
|
28
|
+
file = File.join(dir, 'exception.txt')
|
29
|
+
|
30
|
+
Dir.mkdir(dir) unless File.exists?(dir)
|
31
|
+
File.delete(file) if File.exists?(file)
|
32
|
+
|
33
|
+
File.open(file, 'w') do |file|
|
34
|
+
file.write "================== Start server exception ==================\n"
|
35
|
+
lines.each { |line| file.write(line); file.write("\n") }
|
36
|
+
file.write "=================== End server exception ===================\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -30,7 +30,7 @@ class ActionDispatch::IntegrationTest
|
|
30
30
|
# def setup # Called before every test
|
31
31
|
# end
|
32
32
|
|
33
|
-
# def teardown # Called after every
|
33
|
+
# def teardown # Called after every test
|
34
34
|
# end
|
35
35
|
|
36
36
|
def after_teardown # I reset sessions here so capybara-screenshot can still make screenshots when tests fail
|
@@ -35,6 +35,8 @@ module TestBotable
|
|
35
35
|
def devise_action_test(test, options = {})
|
36
36
|
options[:email] ||= "unique-#{Time.zone.now.to_i}@example.com"
|
37
37
|
options[:password] ||= '!Password123'
|
38
|
+
options[:username] ||= 'unique-username'
|
39
|
+
options[:login] ||= 'unique-login'
|
38
40
|
options[:user] ||= User.new
|
39
41
|
|
40
42
|
begin
|
@@ -20,7 +20,12 @@ module TestBotable
|
|
20
20
|
module ClassMethods
|
21
21
|
|
22
22
|
def wizard_test(from_path, to_path, user, options = {})
|
23
|
-
|
23
|
+
if to_path.present?
|
24
|
+
options[:current_test] = options.delete(:label) || "#{from_path} to #{to_path}"
|
25
|
+
else
|
26
|
+
options[:current_test] = options.delete(:label) || "#{from_path}"
|
27
|
+
end
|
28
|
+
|
24
29
|
return if EffectiveTestBot.skip?(options[:current_test])
|
25
30
|
|
26
31
|
method_name = test_bot_method_name('wizard_test', options[:current_test])
|
@@ -1,14 +1,20 @@
|
|
1
1
|
module EffectiveTestBotAssertions
|
2
|
+
def assert_page_content(content, message = "(page_content) Expected page content :content: to be present")
|
3
|
+
assert page.has_text?(content, wait: 0), message.sub(':content:', content)
|
4
|
+
end
|
5
|
+
|
6
|
+
def assert_no_page_content(content, message = "(page_content) Expected page content :content: to be blank")
|
7
|
+
assert page.has_no_text?(content, wait: 0), message.sub(':content:', content)
|
8
|
+
end
|
9
|
+
|
2
10
|
def assert_signed_in(message = nil)
|
3
|
-
visit
|
4
|
-
|
5
|
-
assert page.has_no_selector?('form#new_user'), message || '(signed_in) Expected new_user form to be blank'
|
11
|
+
visit(root_path) if page.current_path.blank?
|
12
|
+
assert assigns['current_user'].present?, message || 'Expected @current_user to be present when signed in'
|
6
13
|
end
|
7
14
|
|
8
15
|
def assert_signed_out(message = nil)
|
9
|
-
visit
|
10
|
-
|
11
|
-
assert page.has_selector?('form#new_user'), message || '(signed_out) Expected new_user form to be present'
|
16
|
+
visit(root_path) if page.current_path.blank? || assigns['current_user'].present?
|
17
|
+
assert assigns['current_user'].blank?, message || 'Expected @current_user to be blank when signed out'
|
12
18
|
end
|
13
19
|
|
14
20
|
def assert_capybara_can_execute_javascript(message = "Expected capybara-webkit page.evaluate_script() to be successful")
|
@@ -32,8 +38,6 @@ module EffectiveTestBotAssertions
|
|
32
38
|
end
|
33
39
|
|
34
40
|
def assert_page_title(title = :any, message = '(page_title) Expected page title to be present')
|
35
|
-
return if was_download? # If this was a download, it correctly won't have a page title
|
36
|
-
|
37
41
|
if title.present? && title != :any
|
38
42
|
assert_title(title) # Capybara TitleQuery, match this text
|
39
43
|
else
|
@@ -43,7 +47,7 @@ module EffectiveTestBotAssertions
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def assert_form(selector, message = "(form) Expected visible form with selector :selector: to be present")
|
46
|
-
assert all(selector).present?, message.sub(':selector', selector)
|
50
|
+
assert all(selector).present?, message.sub(':selector:', selector)
|
47
51
|
end
|
48
52
|
|
49
53
|
def assert_submit_input(message = "(submit_input) Expected one or more visible input[type='submit'] to be present")
|
@@ -56,7 +60,7 @@ module EffectiveTestBotAssertions
|
|
56
60
|
|
57
61
|
def assert_current_path(path, message = '(current_path) Expected current_path to be :path:')
|
58
62
|
path = public_send(path) if path.kind_of?(Symbol)
|
59
|
-
assert_equal path, page.current_path, message.sub(':path', path.to_s)
|
63
|
+
assert_equal path, page.current_path, message.sub(':path:', path.to_s)
|
60
64
|
end
|
61
65
|
|
62
66
|
# assert_redirect '/about'
|
@@ -78,8 +82,15 @@ module EffectiveTestBotAssertions
|
|
78
82
|
assert_equal [], unpermitted_params, message
|
79
83
|
end
|
80
84
|
|
81
|
-
def assert_no_exceptions(message =
|
82
|
-
|
85
|
+
def assert_no_exceptions(message = "(no_exceptions) Unexpected rails server exception:\n:exception:")
|
86
|
+
# this file is created by EffectiveTestBot::Middleware when an exception is encountered in the rails app
|
87
|
+
file = File.join(Dir.pwd, 'tmp', 'test_bot', 'exception.txt')
|
88
|
+
return unless File.exists?(file)
|
89
|
+
|
90
|
+
exception = File.read(file)
|
91
|
+
File.delete(file)
|
92
|
+
|
93
|
+
assert false, message.sub(':exception:', exception)
|
83
94
|
end
|
84
95
|
|
85
96
|
# This must be run after submit_form()
|
@@ -65,6 +65,7 @@ module EffectiveTestBotFormFiller
|
|
65
65
|
case [field.tag_name, field['type']].compact.join('_')
|
66
66
|
when 'input_text', 'input_email', 'input_password', 'input_tel', 'input_number', 'input_checkbox', 'input_radio', 'textarea'
|
67
67
|
field.set(value_for_field(field, fills))
|
68
|
+
close_effective_date_time_picker(field) if field['class'].to_s.include?('effective_date')
|
68
69
|
when 'select'
|
69
70
|
if EffectiveTestBot.tour_mode_extreme? && field['class'].to_s.include?('select2') # select2
|
70
71
|
page.execute_script("try { $('select##{field['id']}').select2('open'); } catch(e) {};")
|
@@ -165,6 +166,8 @@ module EffectiveTestBotFormFiller
|
|
165
166
|
LETTERS.sample + DIGITS.sample + LETTERS.sample + ' ' + DIGITS.sample + LETTERS.sample + DIGITS.sample
|
166
167
|
elsif attribute.include?('zip') && attribute.include?('code') # Make a US zip code
|
167
168
|
DIGITS.sample + DIGITS.sample + DIGITS.sample + DIGITS.sample + DIGITS.sample
|
169
|
+
elsif attribute.include?('slug')
|
170
|
+
Faker::Lorem.words(3).join(' ').parameterize
|
168
171
|
else
|
169
172
|
Faker::Lorem.words(3).join(' ').capitalize
|
170
173
|
end
|
@@ -319,6 +322,10 @@ module EffectiveTestBotFormFiller
|
|
319
322
|
end
|
320
323
|
end
|
321
324
|
|
325
|
+
def close_effective_date_time_picker(field)
|
326
|
+
page.execute_script("try { $('input##{field['id']}').data('DateTimePicker').hide(); } catch(e) {};")
|
327
|
+
end
|
328
|
+
|
322
329
|
private
|
323
330
|
|
324
331
|
def fill_value_for_field(fills, attributes)
|
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
module EffectiveTestBotLoginHelper
|
4
4
|
def as_user(user)
|
5
|
-
sign_in(user); yield;
|
5
|
+
sign_in(user); yield; sign_out
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
# This is currently hardcoded to use the warden login_as test helper
|
9
|
+
def sign_in(user)
|
9
10
|
user.kind_of?(String) ? login_as(User.find_by_email!(user)) : login_as(user)
|
10
11
|
end
|
11
12
|
|
13
|
+
# This is currently hardcoded to use the warden logout test helper
|
12
14
|
def sign_out
|
13
15
|
logout
|
14
16
|
end
|
@@ -17,9 +19,11 @@ module EffectiveTestBotLoginHelper
|
|
17
19
|
visit new_user_session_path
|
18
20
|
|
19
21
|
email = (user_or_email.respond_to?(:email) ? user_or_email.email : user_or_email)
|
22
|
+
username = (user_or_email.respond_to?(:username) ? user_or_email.username : user_or_email)
|
23
|
+
login = (user_or_email.respond_to?(:login) ? user_or_email.login : user_or_email)
|
20
24
|
|
21
25
|
within('form#new_user') do
|
22
|
-
fill_form(email: email, password: password)
|
26
|
+
fill_form(email: email, password: password, username: username, login: login)
|
23
27
|
submit_novalidate_form
|
24
28
|
end
|
25
29
|
end
|
@@ -29,6 +29,11 @@ module EffectiveTestBotTestHelper
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
# Calls capybara within do .. end if selector is present and bool is true
|
33
|
+
def within_if(selector, bool = true, &block)
|
34
|
+
(selector.present? && bool) ? within(selector) { yield } : yield
|
35
|
+
end
|
36
|
+
|
32
37
|
def click_first(label)
|
33
38
|
click_link(label, match: :first)
|
34
39
|
end
|
@@ -52,12 +52,17 @@ module TestBot
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
# Wizard Test
|
56
|
+
elsif is_wicked_controller?(route)
|
57
|
+
first_step_path = "/#{controller}/#{controller_instance(route).wizard_steps.first}"
|
58
|
+
wizard_test(first_step_path, nil, User.first)
|
59
|
+
|
55
60
|
# Member Test
|
56
61
|
elsif route.verb.to_s.include?('GET') && route.path.required_names == ['id']
|
57
62
|
member_test(controller, action, User.first)
|
58
63
|
|
59
64
|
# Page Test
|
60
|
-
elsif route.verb.to_s.include?('GET') && route.name.present?
|
65
|
+
elsif route.verb.to_s.include?('GET') && route.name.present? && Array(route.path.required_names).blank? # This could eventually be removed to supported nested routes
|
61
66
|
page_test("#{route.name}_path".to_sym, User.first, route: route, label: "#{route.name}_path")
|
62
67
|
|
63
68
|
else
|
@@ -67,22 +72,47 @@ module TestBot
|
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
70
|
-
|
75
|
+
protected
|
71
76
|
|
72
77
|
def is_crud_controller?(route)
|
73
78
|
return false unless CRUD_ACTIONS.include?(route.defaults[:action])
|
74
|
-
return false unless route.defaults[:controller].present? && route.app.respond_to?(:controller)
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
|
80
|
+
controller = controller_instance(route)
|
81
|
+
controller.respond_to?(:new) && controller.respond_to?(:create)
|
82
|
+
end
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
# https://github.com/schneems/wicked/
|
85
|
+
def is_wicked_controller?(route)
|
86
|
+
return false unless defined?(Wicked::Wizard)
|
87
|
+
|
88
|
+
controller = controller_instance(route)
|
89
|
+
return false unless controller.kind_of?(Wicked::Wizard)
|
90
|
+
|
91
|
+
# So this is a Wicked::Wizard controller, we have to trick it into running an action to make the steps available
|
92
|
+
controller.params = {}
|
93
|
+
(controller.run_callbacks(:process_action) rescue false)
|
94
|
+
|
95
|
+
controller.wizard_steps.present?
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def controller_instance(route)
|
101
|
+
return :none unless route.defaults[:controller] && route.defaults[:action]
|
102
|
+
|
103
|
+
@_controller_instances ||= {}
|
104
|
+
@_controller_instances[route.defaults[:controller]] ||= build_controller_instance(route)
|
105
|
+
end
|
106
|
+
|
107
|
+
def build_controller_instance(route)
|
108
|
+
# Find the correct route.app that links to the controller
|
109
|
+
# If there is a routing constraint, we have to traverse the route.app linked list to find the route with a controller
|
110
|
+
route_app = route
|
111
|
+
route_app = route_app.app while (route_app.respond_to?(:app) && route_app != route_app.app)
|
112
|
+
|
113
|
+
return :none unless route_app.respond_to?(:controller)
|
85
114
|
|
115
|
+
(route_app.controller(route.defaults).new() rescue :none)
|
86
116
|
end
|
87
117
|
|
88
118
|
end
|
@@ -5,16 +5,13 @@ module TestBot
|
|
5
5
|
@@original_users_count = User.count
|
6
6
|
let(:original_users_count) { @@original_users_count }
|
7
7
|
|
8
|
-
let(:email) { 'unique@testbot.com' }
|
9
|
-
let(:password) { '!Password123' }
|
10
|
-
let(:username) { 'test_bot_user' }
|
11
|
-
|
12
8
|
def self.test_order
|
13
9
|
:alpha
|
14
10
|
end
|
15
11
|
|
16
|
-
test '01:
|
17
|
-
|
12
|
+
test '01: can visit root_path' do
|
13
|
+
visit root_path
|
14
|
+
assert_page_status
|
18
15
|
end
|
19
16
|
|
20
17
|
test '02: all fixtures and seeds valid' do
|
@@ -29,86 +26,41 @@ module TestBot
|
|
29
26
|
end
|
30
27
|
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
assert (User.count > 0), 'please create at least 1 seed or fixture user for effective_test_bot to function'
|
29
|
+
test '03: at least one user is present' do
|
30
|
+
assert (User.count > 0), 'please fixture or seed at least 1 user for effective_test_bot to function'
|
35
31
|
end
|
36
32
|
|
37
|
-
test '04: activerecord can
|
38
|
-
|
33
|
+
test '04: activerecord can save a resource' do
|
34
|
+
User.new(email: 'unique@testbot.com', password: '!Password123', password_confirmation: '!Password123').save(validate: false)
|
39
35
|
assert_equal (original_users_count + 1), User.count
|
40
36
|
end
|
41
37
|
|
42
|
-
test '05:
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
test '06: capybara can execute javascript' do
|
47
|
-
visit root_path
|
48
|
-
assert_capybara_can_execute_javascript
|
49
|
-
end
|
50
|
-
|
51
|
-
test '07: jquery is present' do
|
52
|
-
visit root_path
|
53
|
-
assert_jquery_present
|
38
|
+
test '05: database has rolled back' do
|
39
|
+
assert_equal original_users_count, User.count, 'the activerecord resource created in a previous test is still present'
|
54
40
|
end
|
55
41
|
|
56
|
-
test '
|
57
|
-
|
58
|
-
assert_jquery_ujs_present
|
59
|
-
end
|
60
|
-
|
61
|
-
test '09: capybara can sign up a user' do
|
62
|
-
user = sign_up()
|
63
|
-
assert user.kind_of?(User), "expected to create a new user after submitting sign up form at #{new_user_registration_path}"
|
64
|
-
|
65
|
-
assert_equal (original_users_count + 1), User.count
|
42
|
+
test '06: capybara can sign_in' do
|
43
|
+
sign_in(User.first)
|
66
44
|
assert_signed_in
|
67
45
|
end
|
68
46
|
|
69
|
-
test '
|
47
|
+
test '07: capybara session has reset' do
|
70
48
|
assert_signed_out
|
71
|
-
assert_environment_normal
|
72
49
|
end
|
73
50
|
|
74
|
-
test '
|
75
|
-
|
76
|
-
|
77
|
-
assert_signed_in
|
78
|
-
end
|
79
|
-
|
80
|
-
test '12: database and session have reset' do
|
81
|
-
assert_signed_out
|
82
|
-
assert_environment_normal
|
83
|
-
end
|
84
|
-
|
85
|
-
test '13: capybara can sign in manually' do
|
86
|
-
create_user!
|
87
|
-
sign_in_manually(email, password)
|
88
|
-
assert_signed_in
|
89
|
-
end
|
90
|
-
|
91
|
-
test '14: database and session have reset' do
|
92
|
-
assert_signed_out
|
93
|
-
assert_environment_normal
|
51
|
+
test '08: capybara can execute javascript' do
|
52
|
+
visit root_path
|
53
|
+
assert_capybara_can_execute_javascript
|
94
54
|
end
|
95
55
|
|
96
|
-
|
97
|
-
|
98
|
-
# This is all about seeing if the cookies, session, and database are rolling back properly in between tests
|
99
|
-
def assert_environment_normal
|
56
|
+
test '09: jquery is present' do
|
100
57
|
visit root_path
|
101
|
-
|
102
|
-
assert_equal original_users_count, User.count, 'Expected User.count to be back to original'
|
103
|
-
assert assigns[:current_user].blank?, 'Expected current_user to be blank'
|
58
|
+
assert_jquery_present
|
104
59
|
end
|
105
60
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
user.login = username if user.respond_to?('login=')
|
110
|
-
|
111
|
-
user.valid? ? user.save : user.save(validate: false)
|
61
|
+
test '10: rails jquery_ujs is present' do
|
62
|
+
visit root_path
|
63
|
+
assert_jquery_ujs_present
|
112
64
|
end
|
113
65
|
|
114
66
|
end
|
@@ -10,7 +10,7 @@ module BaseTest
|
|
10
10
|
assert_no_exceptions unless test_bot_skip?(:exceptions)
|
11
11
|
assert_page_status unless test_bot_skip?(:page_status)
|
12
12
|
assert_no_js_errors unless test_bot_skip?(:no_js_errors)
|
13
|
-
assert_page_title unless test_bot_skip?(:page_title)
|
13
|
+
assert_page_title unless (test_bot_skip?(:page_title) || all('head').blank? || was_download?)
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
@@ -44,9 +44,9 @@ module BaseTest
|
|
44
44
|
|
45
45
|
visit(new_resource_path)
|
46
46
|
|
47
|
-
assert_form
|
47
|
+
assert_form("form#new_#{resource_name}", "TestBotError: Failed to find form#new_#{resource_name}. #{hint}") unless test_bot_skip?(:form)
|
48
48
|
|
49
|
-
|
49
|
+
within_if("form#new_#{resource_name}", !test_bot_skip?(:form)) do
|
50
50
|
fill_form(resource_attributes)
|
51
51
|
|
52
52
|
assert_submit_input "TestBotError: Failed to find a visible input[type='submit'] on #{page.current_path}. #{hint}"
|
@@ -37,15 +37,12 @@ module CrudTest
|
|
37
37
|
assert_page_normal
|
38
38
|
assert_assigns(resource_name) # unskippable
|
39
39
|
|
40
|
-
#
|
41
|
-
form_selector = "form#new_#{resource_name}"
|
42
|
-
assert_selector form_selector, "Expected form with selector #{form_selector}"
|
40
|
+
assert_form("form#new_#{resource_name}") unless test_bot_skip?(:form)
|
43
41
|
|
44
|
-
|
42
|
+
within_if("form#new_#{resource_name}", !test_bot_skip?(:form)) do
|
45
43
|
assert_submit_input unless test_bot_skip?(:submit_input)
|
46
44
|
assert_jquery_ujs_disable_with unless test_bot_skip?(:jquery_ujs_disable_with)
|
47
45
|
end
|
48
|
-
|
49
46
|
end
|
50
47
|
|
51
48
|
def test_bot_create_invalid_test
|
@@ -53,7 +50,9 @@ module CrudTest
|
|
53
50
|
|
54
51
|
before = { count: resource_class.count }
|
55
52
|
|
56
|
-
|
53
|
+
assert_form("form#new_#{resource_name}") unless test_bot_skip?(:form)
|
54
|
+
|
55
|
+
within_if("form#new_#{resource_name}", !test_bot_skip?(:form)) do
|
57
56
|
without_screenshots { clear_form }
|
58
57
|
submit_novalidate_form
|
59
58
|
end
|
@@ -79,7 +78,9 @@ module CrudTest
|
|
79
78
|
|
80
79
|
before = { count: resource_class.count, path: page.current_path }
|
81
80
|
|
82
|
-
|
81
|
+
assert_form("form#new_#{resource_name}") unless test_bot_skip?(:form)
|
82
|
+
|
83
|
+
within_if("form#new_#{resource_name}", !test_bot_skip?(:form)) do
|
83
84
|
fill_form(resource_attributes)
|
84
85
|
submit_form
|
85
86
|
end
|
@@ -117,12 +118,9 @@ module CrudTest
|
|
117
118
|
|
118
119
|
assert_page_normal
|
119
120
|
assert_assigns(resource_name) # unskippable
|
121
|
+
assert_form("form#edit_#{resource_name}_#{resource.id}") unless test_bot_skip?(:form)
|
120
122
|
|
121
|
-
#
|
122
|
-
form_selector = "form#edit_#{resource_name}_#{resource.id}"
|
123
|
-
assert_selector form_selector, "Expected form with selector #{form_selector}"
|
124
|
-
|
125
|
-
within(form_selector) do
|
123
|
+
within_if("form#edit_#{resource_name}_#{resource.id}", !test_bot_skip?(:form)) do
|
126
124
|
assert_submit_input unless test_bot_skip?(:submit_input)
|
127
125
|
assert_jquery_ujs_disable_with unless test_bot_skip?(:jquery_ujs_disable_with)
|
128
126
|
end
|
@@ -136,14 +134,16 @@ module CrudTest
|
|
136
134
|
|
137
135
|
before = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
138
136
|
|
139
|
-
|
137
|
+
assert_form("form#edit_#{resource_name}_#{resource.id}") unless test_bot_skip?(:form)
|
138
|
+
|
139
|
+
within_if("form#edit_#{resource_name}_#{resource.id}", !test_bot_skip?(:form)) do
|
140
140
|
clear_form
|
141
141
|
submit_novalidate_form
|
142
142
|
end
|
143
143
|
|
144
144
|
save_test_bot_screenshot
|
145
145
|
|
146
|
-
resource = resource_class.
|
146
|
+
resource = resource_class.where(id: resource.id).first
|
147
147
|
|
148
148
|
after = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
149
149
|
|
@@ -169,14 +169,16 @@ module CrudTest
|
|
169
169
|
|
170
170
|
before = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
171
171
|
|
172
|
-
|
172
|
+
assert_form("form#edit_#{resource_name}_#{resource.id}") unless test_bot_skip?(:form)
|
173
|
+
|
174
|
+
within_if("form#edit_#{resource_name}_#{resource.id}", !test_bot_skip?(:form)) do
|
173
175
|
fill_form(resource_attributes)
|
174
176
|
submit_form
|
175
177
|
end
|
176
178
|
|
177
179
|
save_test_bot_screenshot
|
178
180
|
|
179
|
-
resource = resource_class.
|
181
|
+
resource = resource_class.where(id: resource.id).first
|
180
182
|
|
181
183
|
after = { count: resource_class.count, updated_at: (resource.updated_at rescue nil) }
|
182
184
|
|
@@ -224,10 +226,10 @@ module CrudTest
|
|
224
226
|
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
227
|
end
|
226
228
|
|
227
|
-
after = { count: resource_class.count, archived: (resource_class.
|
229
|
+
after = { count: resource_class.count, archived: (resource_class.where(id: resource.id).first.try(:archived) rescue nil) }
|
228
230
|
|
229
231
|
if resource.respond_to?(:archived)
|
230
|
-
assert_equal(true, after[:archived], "Expected
|
232
|
+
assert_equal(true, after[:archived], "Expected @#{resource_name}.archived? to be true")
|
231
233
|
else
|
232
234
|
assert_equal before[:count]-1, after[:count], "Expected: #{resource_class}.count to decrement by 1"
|
233
235
|
end
|
@@ -7,33 +7,43 @@ module DeviseTest
|
|
7
7
|
def test_bot_devise_sign_up_test
|
8
8
|
visit new_user_registration_path
|
9
9
|
|
10
|
-
|
10
|
+
assert_form('form#new_user') unless test_bot_skip?(:form)
|
11
|
+
|
12
|
+
within_if('form#new_user', !test_bot_skip?(:form)) do
|
11
13
|
fill_form(email: email, password: password, password_confirmation: password)
|
12
14
|
submit_form
|
13
15
|
end
|
14
16
|
|
15
17
|
assert_page_normal
|
16
18
|
|
17
|
-
|
18
|
-
assert User.
|
19
|
-
|
19
|
+
assert_signed_in('Expected @current_user to be present after sign up')
|
20
|
+
assert User.where(email: email).first.present?, "Expected user to be present after submitting sign up form at #{new_user_registration_path}"
|
21
|
+
assert_page_content(I18n.t('devise.registrations.signed_up')) unless test_bot_skip?(:page_content)
|
20
22
|
end
|
21
23
|
|
22
24
|
def test_bot_devise_sign_in_valid_test
|
23
|
-
User.new(email: email, password: password, password_confirmation: password)
|
25
|
+
user = User.new(email: email, password: password, password_confirmation: password)
|
26
|
+
user.username = username if user.respond_to?(:username)
|
27
|
+
user.login = login if user.respond_to?(:login)
|
28
|
+
user.save(validate: false)
|
24
29
|
|
25
30
|
visit new_user_session_path
|
26
31
|
|
27
|
-
|
28
|
-
|
32
|
+
assert_form('form#new_user') unless test_bot_skip?(:form)
|
33
|
+
|
34
|
+
within_if('form#new_user', !test_bot_skip?(:form)) do
|
35
|
+
fill_form(email: email, password: password, username: username, login: login)
|
29
36
|
submit_form
|
30
37
|
end
|
31
38
|
|
32
39
|
assert_page_normal
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
assert_signed_in
|
42
|
+
assert_page_content(I18n.t('devise.sessions.signed_in')) unless test_bot_skip?(:page_content)
|
43
|
+
|
44
|
+
if User.new().respond_to?(:sign_in_count)
|
45
|
+
assert_equal 1, User.where(email: email).first.try(:sign_in_count), "Expected user sign in count to be incremented after signing in"
|
46
|
+
end
|
37
47
|
end
|
38
48
|
|
39
49
|
def test_bot_devise_sign_in_invalid_test
|
@@ -41,15 +51,17 @@ module DeviseTest
|
|
41
51
|
|
42
52
|
visit new_user_session_path
|
43
53
|
|
44
|
-
|
54
|
+
assert_form('form#new_user') unless test_bot_skip?(:form)
|
55
|
+
|
56
|
+
within_if('form#new_user', !test_bot_skip?(:form)) do
|
45
57
|
fill_form(email: email, password: 'not-correct-password')
|
46
58
|
submit_form
|
47
59
|
end
|
48
60
|
|
49
61
|
assert_page_normal
|
50
62
|
|
51
|
-
|
52
|
-
|
63
|
+
assert_signed_out
|
64
|
+
assert_page_content(I18n.t('devise.failure.invalid', authentication_keys: Devise.authentication_keys.join(', '))) unless test_bot_skip?(:page_content)
|
53
65
|
end
|
54
66
|
|
55
67
|
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.14
|
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: 2016-
|
11
|
+
date: 2016-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -214,11 +214,15 @@ executables: []
|
|
214
214
|
extensions: []
|
215
215
|
extra_rdoc_files: []
|
216
216
|
files:
|
217
|
+
- MIT-LICENSE
|
218
|
+
- README.md
|
219
|
+
- Rakefile
|
217
220
|
- app/helpers/effective_test_bot_controller_helper.rb
|
218
221
|
- lib/effective_profile_bot/heap_analyzer.rb
|
222
|
+
- lib/effective_test_bot.rb
|
219
223
|
- lib/effective_test_bot/engine.rb
|
224
|
+
- lib/effective_test_bot/middleware.rb
|
220
225
|
- lib/effective_test_bot/version.rb
|
221
|
-
- lib/effective_test_bot.rb
|
222
226
|
- lib/generators/effective_test_bot/install_generator.rb
|
223
227
|
- lib/generators/templates/effective_test_bot.rb
|
224
228
|
- lib/generators/templates/test_helper.rb
|
@@ -247,9 +251,6 @@ files:
|
|
247
251
|
- test/test_botable/page_test.rb
|
248
252
|
- test/test_botable/redirect_test.rb
|
249
253
|
- test/test_botable/wizard_test.rb
|
250
|
-
- MIT-LICENSE
|
251
|
-
- Rakefile
|
252
|
-
- README.md
|
253
254
|
homepage: https://github.com/code-and-effect/effective_test_bot
|
254
255
|
licenses:
|
255
256
|
- MIT
|
@@ -270,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
270
271
|
version: '0'
|
271
272
|
requirements: []
|
272
273
|
rubyforge_project:
|
273
|
-
rubygems_version: 2.
|
274
|
+
rubygems_version: 2.4.6
|
274
275
|
signing_key:
|
275
276
|
specification_version: 4
|
276
277
|
summary: A shared library of rails model & capybara-based feature tests that should
|