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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d9f3e47968588a874f9e16b0fbefa9e98ee9aee
4
- data.tar.gz: c025706727691c283a8d99a1e902ae4ae5d61cc4
3
+ metadata.gz: 0c57de4dc4b6c0cf80fe3cefea43adb80d683bde
4
+ data.tar.gz: a2f0200f1fb20a3df4272adf99e9858103630fe8
5
5
  SHA512:
6
- metadata.gz: ffecc7b971cf73a4bf2d62e1c8a20d7978a4b81173fe2329c5da48fa5b5072b4ab9dd42bdd66420ee8182c94bafb379621c8d9dc9fa01a9469d82c1745ffe4a3
7
- data.tar.gz: 0fbab2527ee173d00b150aad9f15a038736d0a067b6649ec9b72c30e535dec983a3037da1a56a5e685d8162ebaca445d1baa03042f9442f0c9c5a00cdc56c2ab
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
- - `assert_signed_in` visits the devise `new_user_session_path` and checks for the already signed in content.
103
- - `assert_signed_out` visits the devise `new_user_session_path` and checks for the sign in content.
104
- - `assert_page_title` makes sure there is an html `<title></title>` present.
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
- - `assert_redirect(from_path)` optionally with to_path, makes sure the current page path is not from_path.
109
- - `assert_no_js_errors` - checks for any javascript errors on the page.
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
- - `assert_jquery_ujs_disable_with` makes sure all `input[type=submit]` elements on the page have the `data-disable-with` property set.
114
- - `assert_flash`, optionally with the desired `:success`, `:error` key and/or message, makes sure the flash is set.
115
- - `assert_assigns` asserts a given rails view_assigns object is present.
116
- - `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.
117
- - `assert_assigns_errors` use after an intentionally invalid form submit to make sure your assigned rails object has errors, or a specific error.
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
- - `submit_novalidate_form` submits the form without client side validation, ignoring any required field requirements.
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
- assert_content 'successfully created post. You may only update it once.'
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
- assert_content 'successfully updated post.'
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
- assert_content 'you may no longer update this post.'
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
- assert_content 'Tokens: 10'
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
- assert_content 'first post'
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
- assert_content 'first post'
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
- assert_content 'your post is ready but must first be approved by an admin.'
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
@@ -1,4 +1,5 @@
1
1
  require "effective_test_bot/engine"
2
+ require "effective_test_bot/middleware"
2
3
  require "effective_test_bot/version"
3
4
 
4
5
  module EffectiveTestBot
@@ -13,32 +13,40 @@ module EffectiveTestBot
13
13
  end
14
14
 
15
15
  initializer 'effective_test_bot.test_suite' do |app|
16
- Rails.application.config.to_prepare do
17
- # test/support/
18
- ActionDispatch::IntegrationTest.include EffectiveTestBotAssertions
19
- ActionDispatch::IntegrationTest.include EffectiveTestBotFormHelper
20
- ActionDispatch::IntegrationTest.include EffectiveTestBotFormFiller
21
- ActionDispatch::IntegrationTest.include EffectiveTestBotLoginHelper
22
- ActionDispatch::IntegrationTest.include EffectiveTestBotScreenshotsHelper
23
- ActionDispatch::IntegrationTest.include EffectiveTestBotTestHelper
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
- # test/test_botable/
26
- ActionDispatch::IntegrationTest.include BaseTest
27
- ActionDispatch::IntegrationTest.include CrudTest
28
- ActionDispatch::IntegrationTest.include DeviseTest
29
- ActionDispatch::IntegrationTest.include MemberTest
30
- ActionDispatch::IntegrationTest.include PageTest
31
- ActionDispatch::IntegrationTest.include RedirectTest
32
- ActionDispatch::IntegrationTest.include WizardTest
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
- # test/concerns/test_botable/
35
- ActionDispatch::IntegrationTest.include TestBotable::BaseDsl
36
- ActionDispatch::IntegrationTest.include TestBotable::CrudDsl
37
- ActionDispatch::IntegrationTest.include TestBotable::DeviseDsl
38
- ActionDispatch::IntegrationTest.include TestBotable::MemberDsl
39
- ActionDispatch::IntegrationTest.include TestBotable::PageDsl
40
- ActionDispatch::IntegrationTest.include TestBotable::RedirectDsl
41
- ActionDispatch::IntegrationTest.include TestBotable::WizardDsl
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
@@ -1,3 +1,3 @@
1
1
  module EffectiveTestBot
2
- VERSION = '0.4.13'.freeze
2
+ VERSION = '0.4.14'.freeze
3
3
  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 single test
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
- options[:current_test] = options.delete(:label) || "#{from_path} to #{to_path}"
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 new_user_session_path
4
- assert_content I18n.t('devise.failure.already_authenticated') #, message || '(signed_in) Expected devise already_authenticated content to be present'
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 new_user_session_path
10
- refute_content I18n.t('devise.failure.already_authenticated') #, message || '(signed_out) Expected devise already_authenticated content to be blank'
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 = nil)
82
- assert exceptions.blank?, message || "(no_exceptions) Unexpected exception:\n#{exceptions.join("\n")}\n========== End of rails server exception ==========\n"
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)
@@ -47,6 +47,7 @@ module EffectiveTestBotFormHelper
47
47
 
48
48
  begin
49
49
  field.set('');
50
+ close_effective_date_time_picker(field) if field['class'].to_s.include?('effective_date')
50
51
  save_test_bot_screenshot if EffectiveTestBot.tour_mode_extreme?
51
52
  rescue => e; end
52
53
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module EffectiveTestBotLoginHelper
4
4
  def as_user(user)
5
- sign_in(user); yield; logout
5
+ sign_in(user); yield; sign_out
6
6
  end
7
7
 
8
- def sign_in(user) # Warden::Test::Helpers
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
- private
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
- begin
77
- controller_klass = route.app.controller(route.defaults)
78
- controller_instance = controller_klass.new()
80
+ controller = controller_instance(route)
81
+ controller.respond_to?(:new) && controller.respond_to?(:create)
82
+ end
79
83
 
80
- # Is this a CRUD capable controller?
81
- controller_instance.respond_to?(:new) && controller_instance.respond_to?(:create)
82
- rescue => e
83
- false
84
- end
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: seeds and fixtures loaded' do
17
- assert_environment_normal
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
- # I could remove this if sign_in checks for and creates a user with devise or not
33
- test '03: at least one user is seeded' do
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 create a user' do
38
- create_user!
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: test database has reset' do
43
- assert_environment_normal
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 '08: rails jquery_ujs is present' do
57
- visit root_path
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 '10: database and session have reset' do
47
+ test '07: capybara session has reset' do
70
48
  assert_signed_out
71
- assert_environment_normal
72
49
  end
73
50
 
74
- test '11: capybara can login_as via warden test helper' do
75
- create_user!
76
- sign_in(email)
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
- private
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
- assert_page_status
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
- def create_user!
107
- user = User.new(email: email, password: password, password_confirmation: password)
108
- user.username = username if user.respond_to?('username=')
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 "form#new_#{resource_name}", "TestBotError: Failed to find form#new_#{resource_name}. #{hint}"
47
+ assert_form("form#new_#{resource_name}", "TestBotError: Failed to find form#new_#{resource_name}. #{hint}") unless test_bot_skip?(:form)
48
48
 
49
- within("form#new_#{resource_name}") do
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
- # Make sure there's a form with a submit button
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
- within(form_selector) do
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
- within("form#new_#{resource_name}") do
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
- within("form#new_#{resource_name}") do
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
- # Make sure there's a form with a submit button
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
- within("form#edit_#{resource_name}_#{resource.id}") do
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.find(resource.id)
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
- within("form#edit_#{resource_name}_#{resource.id}") do
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.find(resource.id)
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.find(resource.id).archived rescue nil) }
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 #{resource_class}.archived? to be true")
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
- within('form#new_user') do
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
- assert_content I18n.t('devise.registrations.signed_up')
18
- assert User.find_by_email(email).present?
19
- assert_assigns :current_user
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).save(validate: false)
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
- within('form#new_user') do
28
- fill_form(email: email, password: password)
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
- assert_content I18n.t('devise.sessions.signed_in')
35
- assert_equal 1, User.find_by_email(email).sign_in_count
36
- assert_assigns :current_user
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
- within('form#new_user') do
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
- assert_content I18n.t('devise.failure.invalid', authentication_keys: Devise.authentication_keys.join(', '))
52
- assert assigns[:current_user].blank?
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
@@ -26,9 +26,10 @@ module WizardTest
26
26
  # Keep going till there's no more submit buttons
27
27
  break if all("input[type='submit']").blank?
28
28
  end
29
-
30
29
  end
31
30
 
31
+ save_test_bot_screenshot
32
+
32
33
  assert_current_path(to_path) if to_path.present?
33
34
  end
34
35
 
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.13
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-01-05 00:00:00.000000000 Z
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.0.14
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