effective_test_bot 0.0.10 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -30
- data/lib/effective_test_bot/engine.rb +10 -1
- data/lib/effective_test_bot/version.rb +2 -1
- data/lib/generators/effective_test_bot/install_generator.rb +1 -20
- data/lib/generators/templates/effective_test_bot.rb +3 -1
- data/lib/generators/templates/{minitest/test_helper.rb → test_helper.rb} +9 -5
- data/lib/tasks/effective_test_bot_tasks.rake +4 -22
- data/test/concerns/acts_as_test_botable.rb +57 -0
- data/test/support/effective_test_bot_assertions.rb +26 -0
- data/{app/helpers/effective_test_bot_helper.rb → test/support/effective_test_bot_form_helper.rb} +14 -45
- data/test/support/effective_test_bot_login_helper.rb +31 -0
- data/test/support/effective_test_bot_test_helper.rb +18 -0
- data/test/test_bot/integration/devise_test.rb +51 -0
- data/test/test_bot/integration/minitest_test.rb +49 -59
- data/test/test_bot/models/user_test.rb +1 -1
- data/test/test_botable/crud_test.rb +181 -0
- metadata +24 -15
- data/lib/generators/templates/rspec/rails_helper.rb +0 -62
- data/lib/generators/templates/rspec/spec_helper.rb +0 -90
- data/spec/features/crud/crud_spec.rb +0 -50
- data/spec/features/devise/sign_in_spec.rb +0 -43
- data/spec/features/devise/sign_up_spec.rb +0 -29
- data/spec/features/home_page_spec.rb +0 -8
- data/spec/models/user_spec.rb +0 -19
- data/test/fixtures/users.yml +0 -3
- data/test/test_bot/integration/devise/sign_in_test.rb +0 -37
- data/test/test_bot/integration/devise/sign_up_test.rb +0 -25
- data/test/test_bot/models/database_test.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c091f3638ed0ef358cce23cb248daeb0f7040d3
|
4
|
+
data.tar.gz: d38922c2629ea9a12004fc150601331a47db6af7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae23c5221d6a46a3f2a369cd42a31d2e98d09c8e6b032286b14dd3920349a9503ca4360e8726eef3cb403541655512a16bcaa8f10a75e2547e90250fb7d0b7f
|
7
|
+
data.tar.gz: 5d690bb001ab760f86f1aa621a0c5e8876b1e53c16f248e221decb5493cd2e82fc919c71836bfb553fcc07d4ffe89b85367c15f261ea2e39217811e94421284a
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
A shared library of rails model & capybara-based feature tests that should pass in every Rails application.
|
4
4
|
|
5
|
-
Also provides a one-liner installation & configuration of
|
5
|
+
Also provides a one-liner installation & configuration of minitest and capybara test environment.
|
6
6
|
|
7
7
|
Rails 3.2.x and 4.x
|
8
8
|
|
@@ -27,33 +27,29 @@ Then run the generator:
|
|
27
27
|
rails generate effective_test_bot:install
|
28
28
|
```
|
29
29
|
|
30
|
-
The above command will first invoke the default `
|
30
|
+
The above command will first invoke the default `minitest` installation tasks, if they haven't already been run.
|
31
31
|
|
32
|
-
It will then copy the packaged `
|
32
|
+
It will then copy the packaged `test_helper.rb` that matches this gem author's opinionated testing environment.
|
33
33
|
|
34
|
-
Run the test suite with
|
34
|
+
Run the test suite with:
|
35
35
|
|
36
36
|
```ruby
|
37
|
-
bundle exec
|
38
|
-
```
|
39
|
-
|
40
|
-
or
|
41
|
-
|
42
|
-
```ruby
|
43
|
-
bundle exec rspec
|
37
|
+
bundle exec rake test:bot
|
44
38
|
```
|
45
39
|
|
46
40
|
You should now see multiple -- hopefully passing -- tests that you didn't write!
|
47
41
|
|
48
42
|
|
49
|
-
|
43
|
+
## Fixtures
|
50
44
|
|
51
|
-
|
45
|
+
TODO
|
52
46
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
users.yml:
|
48
|
+
|
49
|
+
```yaml
|
50
|
+
normal:
|
51
|
+
email: 'normal@agilestyle.com'
|
52
|
+
encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
|
57
53
|
```
|
58
54
|
|
59
55
|
|
@@ -64,17 +60,6 @@ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
|
|
64
60
|
Code and Effect is the product arm of [AgileStyle](http://www.agilestyle.com/), an Edmonton-based shop that specializes in building custom web applications with Ruby on Rails.
|
65
61
|
|
66
62
|
|
67
|
-
## Testing
|
68
|
-
|
69
|
-
The test suite for this gem is unfortunately not yet complete.
|
70
|
-
|
71
|
-
Run tests by:
|
72
|
-
|
73
|
-
```ruby
|
74
|
-
rake spec
|
75
|
-
```
|
76
|
-
|
77
|
-
|
78
63
|
## Contributing
|
79
64
|
|
80
65
|
1. Fork it
|
@@ -83,5 +68,3 @@ rake spec
|
|
83
68
|
4. Push to the branch (`git push origin my-new-feature`)
|
84
69
|
5. Bonus points for test coverage
|
85
70
|
6. Create new Pull Request
|
86
|
-
|
87
|
-
#page.save_screenshot('sign-in-test-1.png')
|
@@ -2,6 +2,10 @@ module EffectiveTestBot
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
engine_name 'effective_test_bot'
|
4
4
|
|
5
|
+
config.autoload_paths += Dir["#{config.root}/test/concerns/**/"]
|
6
|
+
config.autoload_paths += Dir["#{config.root}/test/support/**/"]
|
7
|
+
config.autoload_paths += Dir["#{config.root}/test/test_botable/**/"]
|
8
|
+
|
5
9
|
# Set up our default configuration options.
|
6
10
|
initializer "effective_test_bot.defaults", :before => :load_config_initializers do |app|
|
7
11
|
# Set up our defaults, as per our initializer template
|
@@ -10,7 +14,12 @@ module EffectiveTestBot
|
|
10
14
|
|
11
15
|
initializer 'effective_test_bot.test_suite' do |app|
|
12
16
|
Rails.application.config.to_prepare do
|
13
|
-
ActionDispatch::IntegrationTest.send(:include,
|
17
|
+
ActionDispatch::IntegrationTest.send(:include, ActsAsTestBotable)
|
18
|
+
|
19
|
+
ActionDispatch::IntegrationTest.send(:include, EffectiveTestBotAssertions)
|
20
|
+
ActionDispatch::IntegrationTest.send(:include, EffectiveTestBotFormHelper)
|
21
|
+
ActionDispatch::IntegrationTest.send(:include, EffectiveTestBotLoginHelper)
|
22
|
+
ActionDispatch::IntegrationTest.send(:include, EffectiveTestBotTestHelper)
|
14
23
|
end
|
15
24
|
end
|
16
25
|
|
@@ -13,19 +13,6 @@ module EffectiveTestBot
|
|
13
13
|
run 'bundle exec rails generate minitest:install'
|
14
14
|
end
|
15
15
|
|
16
|
-
# def install_rspec
|
17
|
-
# return if File.exists?('spec/spec_helper.rb')
|
18
|
-
# puts '[effective_test_bot] installing rspec'
|
19
|
-
# run 'bundle exec rails generate rspec:install'
|
20
|
-
# end
|
21
|
-
|
22
|
-
# def install_guard
|
23
|
-
# return if File.exists?('Guardfile')
|
24
|
-
# puts '[effective_test_bot] installing guard'
|
25
|
-
# run 'bundle exec guard init'
|
26
|
-
# puts ""
|
27
|
-
# end
|
28
|
-
|
29
16
|
def explain_overwrite
|
30
17
|
puts '[effective_test_bot] Successfully installed/detected: minitest'
|
31
18
|
puts ""
|
@@ -49,15 +36,9 @@ module EffectiveTestBot
|
|
49
36
|
end
|
50
37
|
|
51
38
|
def overwrite_minitest
|
52
|
-
template '
|
39
|
+
template 'test_helper.rb', 'test/test_helper.rb'
|
53
40
|
end
|
54
41
|
|
55
|
-
# def overwrite_rspec
|
56
|
-
# template 'rspec/.rspec', '.rspec'
|
57
|
-
# template 'rspec/rails_helper.rb', 'spec/rails_helper.rb'
|
58
|
-
# template 'rspec/spec_helper.rb', 'spec/spec_helper.rb'
|
59
|
-
# end
|
60
|
-
|
61
42
|
def thank_you
|
62
43
|
puts "Thanks for using EffectiveTestBot"
|
63
44
|
puts "Run tests by typing 'rake test:bot'"
|
@@ -11,6 +11,7 @@ require 'shoulda'
|
|
11
11
|
|
12
12
|
require 'capybara/webkit'
|
13
13
|
require 'capybara-screenshot/minitest'
|
14
|
+
require 'capybara/slow_finder_errors'
|
14
15
|
|
15
16
|
class ActiveSupport::TestCase
|
16
17
|
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
@@ -26,14 +27,16 @@ class ActionDispatch::IntegrationTest
|
|
26
27
|
include Capybara::Screenshot::MiniTestPlugin
|
27
28
|
include Warden::Test::Helpers if defined?(Devise)
|
28
29
|
|
29
|
-
#
|
30
|
-
# def setup
|
30
|
+
# def setup # Called before every test
|
31
31
|
# end
|
32
32
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
33
|
+
# def teardown # Called after every single test
|
34
|
+
# end
|
35
|
+
|
36
|
+
def after_teardown # I reset sessions here so capybara-screenshot can still make screenshots when tests fail
|
37
|
+
super() and Capybara.reset_sessions!
|
36
38
|
end
|
39
|
+
|
37
40
|
end
|
38
41
|
|
39
42
|
|
@@ -50,6 +53,7 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
|
50
53
|
|
51
54
|
# So the very first thing I do is set up a consistent database
|
52
55
|
Rake::Task['db:schema:load'].invoke
|
56
|
+
ActiveRecord::Migration.maintain_test_schema!
|
53
57
|
|
54
58
|
# or the following 3:
|
55
59
|
|
@@ -1,36 +1,18 @@
|
|
1
1
|
require 'rake/testtask'
|
2
2
|
require 'rails/test_unit/sub_test_task'
|
3
3
|
|
4
|
-
# namespace :test do
|
5
|
-
# task :bot => :environment do
|
6
|
-
# #Rails::TestTask.test_creator(Rake.application.top_level_tasks).invoke_rake_task
|
7
|
-
|
8
|
-
# #eval File.read("#{config.root}/lib/generators/templates/effective_test_bot.rb")
|
9
|
-
# Rails::TestTask.new('effective_test_bot' => 'test:prepare') do |t|
|
10
|
-
# t.libs << 'test'
|
11
|
-
# t.pattern = 'test/integration/**/*_test.rb'
|
12
|
-
# #t.test_files = FileList["../effective_test_bot/test/**/*_test.rb"].exclude('test/controllers/**/*_test.rb')
|
13
|
-
# end
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
|
17
4
|
namespace :test do
|
18
5
|
desc 'Runs Effective Test Bot'
|
19
6
|
task :bot do
|
20
7
|
Rake::Task["test:effective_test_bot"].invoke
|
21
8
|
end
|
22
9
|
|
23
|
-
#Rake::Task["db:seed"].invoke
|
24
|
-
# Or in rails 3 add to test/test_helper.rb
|
25
|
-
# Rails.application.load_seed
|
26
|
-
|
27
10
|
Rails::TestTask.new('effective_test_bot' => 'test:prepare') do |t|
|
28
11
|
t.libs << 'test'
|
29
|
-
t.test_files = FileList["#{File.dirname(__FILE__)}/../../test/**/*_test.rb"]
|
12
|
+
t.test_files = FileList["#{File.dirname(__FILE__)}/../../test/test_bot/**/*_test.rb"]
|
30
13
|
end
|
31
|
-
end
|
32
14
|
|
33
|
-
|
34
|
-
|
35
|
-
|
15
|
+
|
16
|
+
|
17
|
+
end
|
36
18
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ActsAsTestBotable
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
CRUD_ACTIONS = [:index, :new, :create, :edit, :update, :show, :destroy]
|
6
|
+
|
7
|
+
def crud_test(obj, user, options = {})
|
8
|
+
# Check for expected usage
|
9
|
+
unless (obj.kind_of?(Class) || obj.kind_of?(ActiveRecord::Base)) && user.kind_of?(User) && options.kind_of?(Hash)
|
10
|
+
puts 'invalid parameters passed to crud_test(), expecting crud_test(Post || Post.new(), User.first, options_hash)' and return
|
11
|
+
end
|
12
|
+
|
13
|
+
# Make sure Obj.new() works
|
14
|
+
if obj.kind_of?(Class) && (obj.new() rescue false) == false
|
15
|
+
puts "effective_test_bot: failed to initialize object with #{obj}.new(), unable to proceed" and return
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set up the crud_actions_to_test
|
19
|
+
crud_actions_to_test = if options[:only]
|
20
|
+
Array(options[:only]).flatten.compact.map(&:to_sym)
|
21
|
+
elsif options[:except]
|
22
|
+
(CRUD_ACTIONS - Array(options[:except]).flatten.compact.map(&:to_sym))
|
23
|
+
else
|
24
|
+
CRUD_ACTIONS
|
25
|
+
end
|
26
|
+
|
27
|
+
# Parse the resource and resourece class
|
28
|
+
resource = obj.kind_of?(Class) ? obj.new() : obj
|
29
|
+
resource_class = obj.kind_of?(Class) ? obj : obj.class
|
30
|
+
|
31
|
+
# If obj is an ActiveRecord object with attributes, Post.new(:title => 'My Title')
|
32
|
+
# then compute any explicit attributes, so forms will be filled with those values
|
33
|
+
resource_attributes = if obj.kind_of?(ActiveRecord::Base)
|
34
|
+
empty = resource_class.new()
|
35
|
+
{}.tap { |atts| resource.attributes.each { |k, v| atts[k] = v if empty.attributes[k] != v } }
|
36
|
+
end || {}
|
37
|
+
|
38
|
+
# Assign variables to be used in test/test_botable/crud_test.rb
|
39
|
+
let(:resource) { resource }
|
40
|
+
let(:resource_class) { resource_class }
|
41
|
+
let(:resource_name) { resource_class.name.underscore }
|
42
|
+
let(:resource_attributes) { resource_attributes }
|
43
|
+
let(:user) { user }
|
44
|
+
let(:controller_namespace) { options[:namespace] }
|
45
|
+
let(:crud_actions_to_test) { crud_actions_to_test }
|
46
|
+
|
47
|
+
include ::CrudTest
|
48
|
+
|
49
|
+
# This will run any CrudTest methods, in order, as it's defined in the file
|
50
|
+
# Then the rest of the methods in whatever order they occur originally (:random, :alpha, :sorted)
|
51
|
+
def self.runnable_methods
|
52
|
+
::CrudTest.public_instance_methods.map { |name| name.to_s if name.to_s.starts_with?('test_bot') }.compact + super.select { |name| !name.starts_with?('test_bot') }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module EffectiveTestBotAssertions
|
2
|
+
def assert_signed_in
|
3
|
+
visit new_user_session_path
|
4
|
+
assert_content I18n.t('devise.failure.already_authenticated')
|
5
|
+
assert page.has_no_selector?('form#new_user')
|
6
|
+
end
|
7
|
+
|
8
|
+
def assert_signed_out
|
9
|
+
visit new_user_session_path
|
10
|
+
refute_content I18n.t('devise.failure.already_authenticated')
|
11
|
+
assert page.has_selector?('form#new_user')
|
12
|
+
end
|
13
|
+
|
14
|
+
def assert_page_title(title = :any, message = 'page title is blank')
|
15
|
+
if title.present? && title != :any
|
16
|
+
assert_title(title) # Capybara TitleQuery, match this text
|
17
|
+
else
|
18
|
+
title = (page.find(:xpath, '//title', visible: false) rescue nil)
|
19
|
+
assert title.present?, message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_page_status(status = 200)
|
24
|
+
assert_equal status, page.status_code, "page failed to load with #{status} HTTP status code"
|
25
|
+
end
|
26
|
+
end
|
data/{app/helpers/effective_test_bot_helper.rb → test/support/effective_test_bot_form_helper.rb}
RENAMED
@@ -1,36 +1,6 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
end
|
5
|
-
|
6
|
-
def sign_in(user) # Warden::Test::Helpers
|
7
|
-
user.kind_of?(String) == true ? login_as(User.find_by_email(user)) : login_as(user)
|
8
|
-
end
|
9
|
-
|
10
|
-
def sign_in_manually(email, password)
|
11
|
-
visit new_user_session_path
|
12
|
-
|
13
|
-
within('form#new_user') do
|
14
|
-
fill_form(:email => email, :password => password)
|
15
|
-
submit_form
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def sign_up(email = Faker::Internet.email, password = Faker::Internet.password)
|
20
|
-
visit new_user_registration_path
|
21
|
-
|
22
|
-
within('form#new_user') do
|
23
|
-
fill_form(:email => email, :password => password, :password_confirmation => password)
|
24
|
-
submit_form
|
25
|
-
end
|
26
|
-
|
27
|
-
# These lines seem to need to be here, or minitest.rb 23 blows up.
|
28
|
-
# Some kind of threading issue is fucking with me.
|
29
|
-
assert_equal page.status_code, 200
|
30
|
-
assert_content I18n.t('devise.registrations.signed_up')
|
31
|
-
|
32
|
-
User.find_by_email(email)
|
33
|
-
end
|
1
|
+
module EffectiveTestBotFormHelper
|
2
|
+
DIGITS = ('1'..'9').to_a
|
3
|
+
LETTERS = ('A'..'Z').to_a
|
34
4
|
|
35
5
|
# fill_form(:email => 'somethign@soneone.com', :password => 'blahblah', 'user.last_name' => 'hlwerewr')
|
36
6
|
def fill_form(fills = {})
|
@@ -46,7 +16,7 @@ module EffectiveTestBotHelper
|
|
46
16
|
field.select(fill_value(field, fills), match: :first)
|
47
17
|
when 'input_file'
|
48
18
|
puts "Warning, input_file not yet supported"
|
49
|
-
when 'input_submit'
|
19
|
+
when 'input_submit', 'input_search'
|
50
20
|
# Do nothing
|
51
21
|
else
|
52
22
|
raise "unsupported field type #{[field.tag_name, field['type']].compact.join('_')}"
|
@@ -54,6 +24,10 @@ module EffectiveTestBotHelper
|
|
54
24
|
end
|
55
25
|
end
|
56
26
|
|
27
|
+
def clear_form
|
28
|
+
all('input,select,textarea').each { |field| field.set('') }
|
29
|
+
end
|
30
|
+
|
57
31
|
# Operates on just string keys
|
58
32
|
def fill_value(field, fills = nil)
|
59
33
|
attributes = field['name'].to_s.gsub(']', '').split('[') # user[something_attributes][last_name] => ['user', 'something_attributes', 'last_name']
|
@@ -67,12 +41,7 @@ module EffectiveTestBotHelper
|
|
67
41
|
|
68
42
|
if fills.key?(key)
|
69
43
|
fill_value = fills[key]
|
70
|
-
|
71
|
-
if field_name == 'select'
|
72
|
-
break
|
73
|
-
else
|
74
|
-
return fill_value
|
75
|
-
end
|
44
|
+
['select'].include?(field_name) ? break : (return fill_value)
|
76
45
|
end
|
77
46
|
end
|
78
47
|
end
|
@@ -85,8 +54,7 @@ module EffectiveTestBotHelper
|
|
85
54
|
when 'input_password'
|
86
55
|
Faker::Internet.password
|
87
56
|
when 'input_tel'
|
88
|
-
|
89
|
-
d = 10.times.map { digits.sample }
|
57
|
+
d = 10.times.map { DIGITS.sample }
|
90
58
|
d[0] + d[1] + d[2] + '-' + d[3] + d[4] + d[5] + '-' + d[6] + d[7] + d[8] + d[9]
|
91
59
|
when 'input_text'
|
92
60
|
classes = field['class'].to_s.split(' ')
|
@@ -101,6 +69,8 @@ module EffectiveTestBotHelper
|
|
101
69
|
Faker::Name.last_name
|
102
70
|
elsif attributes.last.to_s.include?('name')
|
103
71
|
Faker::Name.name
|
72
|
+
elsif attributes.last.to_s.include?('postal') # Make a Canadian Postal Code
|
73
|
+
LETTERS.sample + DIGITS.sample + LETTERS.sample + ' ' + DIGITS.sample + LETTERS.sample + DIGITS.sample
|
104
74
|
else
|
105
75
|
Faker::Lorem.word
|
106
76
|
end
|
@@ -117,7 +87,7 @@ module EffectiveTestBotHelper
|
|
117
87
|
when 'input_checkbox'
|
118
88
|
[true, false].sample
|
119
89
|
when 'input_radio'
|
120
|
-
|
90
|
+
[true, false].sample
|
121
91
|
else
|
122
92
|
raise "fill_value unsupported field type: #{field['type']}"
|
123
93
|
end
|
@@ -126,10 +96,9 @@ module EffectiveTestBotHelper
|
|
126
96
|
def submit_form(label = nil)
|
127
97
|
if label.present?
|
128
98
|
click_on(label)
|
129
|
-
#find_field(label).click
|
130
99
|
else
|
131
100
|
first(:css, "input[type='submit']").click
|
132
101
|
end
|
102
|
+
synchronize!
|
133
103
|
end
|
134
|
-
|
135
104
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This is all assuming you're running Devise
|
2
|
+
|
3
|
+
module EffectiveTestBotLoginHelper
|
4
|
+
def as_user(user)
|
5
|
+
sign_in(user); yield; logout
|
6
|
+
end
|
7
|
+
|
8
|
+
def sign_in(user) # Warden::Test::Helpers
|
9
|
+
user.kind_of?(String) == true ? login_as(User.find_by_email!(user)) : login_as(user)
|
10
|
+
end
|
11
|
+
|
12
|
+
def sign_in_manually(email, password)
|
13
|
+
visit new_user_session_path
|
14
|
+
|
15
|
+
within('form#new_user') do
|
16
|
+
fill_form(:email => email, :password => password)
|
17
|
+
submit_form
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sign_up(email = Faker::Internet.email, password = Faker::Internet.password)
|
22
|
+
visit new_user_registration_path
|
23
|
+
|
24
|
+
within('form#new_user') do
|
25
|
+
fill_form(:email => email, :password => password, :password_confirmation => password)
|
26
|
+
submit_form
|
27
|
+
end
|
28
|
+
|
29
|
+
User.find_by_email(email)
|
30
|
+
end
|
31
|
+
end
|