cucumber-rails 1.7.0 → 2.3.0
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 +5 -5
- data/CHANGELOG.md +197 -19
- data/CONTRIBUTING.md +16 -14
- data/LICENSE +1 -1
- data/README.md +27 -21
- data/lib/cucumber/rails.rb +23 -17
- data/lib/cucumber/rails/action_dispatch.rb +21 -0
- data/lib/cucumber/rails/application.rb +16 -7
- data/lib/cucumber/rails/capybara.rb +2 -0
- data/lib/cucumber/rails/capybara/javascript_emulation.rb +42 -21
- data/lib/cucumber/rails/capybara/select_dates_and_times.rb +3 -1
- data/lib/cucumber/rails/database.rb +24 -56
- data/lib/cucumber/rails/database/deletion_strategy.rb +13 -0
- data/lib/cucumber/rails/database/shared_connection_strategy.rb +27 -0
- data/lib/cucumber/rails/database/strategy.rb +33 -0
- data/lib/cucumber/rails/database/truncation_strategy.rb +13 -0
- data/lib/cucumber/rails/hooks.rb +2 -0
- data/lib/cucumber/rails/hooks/active_record.rb +8 -4
- data/lib/cucumber/rails/hooks/allow_rescue.rb +2 -0
- data/lib/cucumber/rails/hooks/database_cleaner.rb +11 -3
- data/lib/cucumber/rails/hooks/mail.rb +3 -1
- data/lib/cucumber/rails/rspec.rb +3 -1
- data/lib/cucumber/rails/world.rb +24 -7
- data/lib/generators/cucumber/{install/USAGE → USAGE} +0 -0
- data/lib/generators/cucumber/{install/install_generator.rb → install_generator.rb} +18 -9
- data/lib/generators/cucumber/{install/templates → templates}/config/cucumber.yml.erb +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/script/cucumber +1 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/_rails_each_run.rb.erb +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/_rails_prefork.rb.erb +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/capybara.rb +2 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/edit_warning.txt +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/rails.rb.erb +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/support/rails_spork.rb.erb +0 -0
- data/lib/generators/cucumber/{install/templates → templates}/tasks/cucumber.rake.erb +0 -0
- metadata +100 -169
- data/.github/ISSUE_TEMPLATE.md +0 -52
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -42
- data/.gitignore +0 -13
- data/.rspec +0 -1
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -443
- data/.travis.yml +0 -45
- data/Appraisals +0 -32
- data/Gemfile +0 -7
- data/Rakefile +0 -49
- data/bin/install_geckodriver.sh +0 -19
- data/bin/install_webpacker.sh +0 -9
- data/config/.gitignore +0 -1
- data/config/cucumber.yml +0 -17
- data/cucumber-rails.gemspec +0 -44
- data/dev_tasks/cucumber.rake +0 -3
- data/dev_tasks/rspec.rake +0 -3
- data/dev_tasks/yard.rake +0 -35
- data/dev_tasks/yard/default/layout/html/bubble_32x32.png +0 -0
- data/dev_tasks/yard/default/layout/html/footer.erb +0 -5
- data/dev_tasks/yard/default/layout/html/index.erb +0 -1
- data/dev_tasks/yard/default/layout/html/layout.erb +0 -25
- data/dev_tasks/yard/default/layout/html/logo.erb +0 -1
- data/dev_tasks/yard/default/layout/html/setup.rb +0 -4
- data/features/allow_rescue.feature +0 -65
- data/features/annotations.feature +0 -22
- data/features/capybara_javascript_drivers.feature +0 -73
- data/features/choose_javascript_database_strategy.feature +0 -145
- data/features/database_cleaner.feature +0 -44
- data/features/disable_automatic_database_cleaning.feature +0 -55
- data/features/emulate_javascript.feature +0 -94
- data/features/install_cucumber_rails.feature +0 -14
- data/features/no_database.feature +0 -61
- data/features/raising_errors.feature +0 -16
- data/features/rerun_profile.feature +0 -46
- data/features/rest_api.feature +0 -47
- data/features/step_definitions/cucumber_rails_steps.rb +0 -153
- data/features/support/aruba.rb +0 -3
- data/features/support/bundler_pre_support.rb +0 -28
- data/features/support/env.rb +0 -40
- data/features/support/fixtures/bundler-1.0.21.gem +0 -0
- data/features/support/fixtures/bundler-1.1.rc.gem +0 -0
- data/features/support/legacy_web_steps_support.rb +0 -289
- data/gemfiles/rails_4_2.gemfile +0 -10
- data/gemfiles/rails_5_0.gemfile +0 -10
- data/gemfiles/rails_5_1.gemfile +0 -10
- data/gemfiles/rails_5_2.gemfile +0 -10
- data/gemfiles/rails_6_0.gemfile +0 -8
- data/lib/cucumber/rails/action_controller.rb +0 -13
- data/spec/cucumber/rails/database_spec.rb +0 -57
- data/spec/generators/cucumber/install/install_generator_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -14
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ActionController::Base.class_eval do
|
4
|
+
cattr_accessor :allow_rescue
|
5
|
+
end
|
6
|
+
|
7
|
+
module Cucumber
|
8
|
+
module Rails
|
9
|
+
module ActionDispatch
|
10
|
+
module ShowExceptions
|
11
|
+
def call(env)
|
12
|
+
env['action_dispatch.show_detailed_exceptions'] = !ActionController::Base.allow_rescue
|
13
|
+
env['action_dispatch.show_exceptions'] = !env['action_dispatch.show_detailed_exceptions']
|
14
|
+
super(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ActionDispatch::ShowExceptions.prepend(Cucumber::Rails::ActionDispatch::ShowExceptions)
|
@@ -1,17 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/application'
|
2
4
|
|
3
5
|
# Make sure the ActionDispatch::ShowExceptions middleware is always enabled,
|
4
6
|
# regardless of what is in config/environments/test.rb
|
5
7
|
# Instead we are overriding ActionDispatch::ShowExceptions to be able to
|
6
8
|
# toggle whether or not exceptions are raised.
|
7
|
-
class Rails::Application
|
8
|
-
alias __cucumber_orig_initialize__ initialize!
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
module Cucumber
|
11
|
+
module Rails
|
12
|
+
module Application
|
13
|
+
def initialize!
|
14
|
+
ad = config.action_dispatch
|
15
|
+
|
16
|
+
def ad.show_exceptions
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
super
|
21
|
+
end
|
14
22
|
end
|
15
|
-
__cucumber_orig_initialize__
|
16
23
|
end
|
17
24
|
end
|
25
|
+
|
26
|
+
Rails::Application.prepend(Cucumber::Rails::Application)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Rails
|
3
5
|
module Capybara
|
@@ -11,7 +13,9 @@ module Cucumber
|
|
11
13
|
|
12
14
|
def click_with_javascript_emulation(*)
|
13
15
|
if link_with_non_get_http_method?
|
14
|
-
::Capybara::RackTest::Form.new(
|
16
|
+
::Capybara::RackTest::Form.new(
|
17
|
+
driver, js_form(element_node.document, self[:href], emulated_method)
|
18
|
+
).submit(self)
|
15
19
|
else
|
16
20
|
click_without_javascript_emulation
|
17
21
|
end
|
@@ -44,29 +48,42 @@ module Cucumber
|
|
44
48
|
js_form['action'] = action
|
45
49
|
js_form['method'] = method
|
46
50
|
|
47
|
-
|
48
|
-
input = document.create_element('input')
|
49
|
-
input['type'] = 'hidden'
|
50
|
-
input['name'] = '_method'
|
51
|
-
input['value'] = emulated_method
|
52
|
-
js_form.add_child(input)
|
53
|
-
end
|
51
|
+
add_hidden_method_input(document, js_form) unless same?(emulated_method, method)
|
54
52
|
|
55
|
-
# rails will wipe the session if the CSRF token is not sent
|
56
|
-
|
57
|
-
if csrf? && emulated_method.downcase != 'get'
|
58
|
-
input = document.create_element('input')
|
59
|
-
input['type'] = 'hidden'
|
60
|
-
input['name'] = csrf_param
|
61
|
-
input['value'] = csrf_token
|
62
|
-
js_form.add_child(input)
|
63
|
-
end
|
53
|
+
# rails will wipe the session if the CSRF token is not sent with non-GET requests
|
54
|
+
add_hidden_csrf_input(document, js_form) if csrf? && !get?(emulated_method)
|
64
55
|
|
65
56
|
js_form
|
66
57
|
end
|
67
58
|
|
59
|
+
def same?(emulated_method, method)
|
60
|
+
emulated_method.casecmp(method).zero?
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_hidden_method_input(document, js_form)
|
64
|
+
input = document.create_element('input')
|
65
|
+
input['type'] = 'hidden'
|
66
|
+
input['name'] = '_method'
|
67
|
+
input['value'] = emulated_method
|
68
|
+
js_form.add_child(input)
|
69
|
+
end
|
70
|
+
|
71
|
+
def get?(emulated_method)
|
72
|
+
same?(emulated_method, 'get')
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_hidden_csrf_input(document, js_form)
|
76
|
+
input = document.create_element('input')
|
77
|
+
input['type'] = 'hidden'
|
78
|
+
input['name'] = csrf_param
|
79
|
+
input['value'] = csrf_token
|
80
|
+
js_form.add_child(input)
|
81
|
+
end
|
82
|
+
|
68
83
|
def link_with_non_get_http_method?
|
69
|
-
tag_name == 'a' &&
|
84
|
+
tag_name == 'a' &&
|
85
|
+
element_node['data-method'] &&
|
86
|
+
element_node['data-method'] =~ /(?:delete|put|post)/
|
70
87
|
end
|
71
88
|
|
72
89
|
def emulated_method
|
@@ -74,15 +91,19 @@ module Cucumber
|
|
74
91
|
end
|
75
92
|
|
76
93
|
def element_node
|
77
|
-
|
94
|
+
native
|
78
95
|
end
|
79
96
|
end
|
80
97
|
end
|
81
98
|
end
|
82
99
|
end
|
83
100
|
|
84
|
-
|
85
|
-
|
101
|
+
module Capybara
|
102
|
+
module RackTest
|
103
|
+
class Node
|
104
|
+
include ::Cucumber::Rails::Capybara::JavascriptEmulation
|
105
|
+
end
|
106
|
+
end
|
86
107
|
end
|
87
108
|
|
88
109
|
Before('not @no-js-emulation') do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Rails
|
3
5
|
module Capybara
|
@@ -9,7 +11,7 @@ module Cucumber
|
|
9
11
|
base_dom_id = get_base_dom_id_from_label_tag(options[:from])
|
10
12
|
|
11
13
|
find(:xpath, ".//select[@id='#{base_dom_id}_1i']").select(date.year.to_s)
|
12
|
-
find(:xpath, ".//select[@id='#{base_dom_id}_2i']").select(I18n.l
|
14
|
+
find(:xpath, ".//select[@id='#{base_dom_id}_2i']").select(I18n.l(date, format: '%B'))
|
13
15
|
find(:xpath, ".//select[@id='#{base_dom_id}_3i']").select(date.day.to_s)
|
14
16
|
end
|
15
17
|
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Rails
|
3
5
|
module Database
|
4
|
-
CUSTOM_STRATEGY_INTERFACE = %w
|
6
|
+
CUSTOM_STRATEGY_INTERFACE = %w[before_js before_non_js].freeze
|
5
7
|
|
6
8
|
class InvalidStrategy < ArgumentError; end
|
7
9
|
|
@@ -13,16 +15,21 @@ module Cucumber
|
|
13
15
|
strategy_type =
|
14
16
|
case strategy
|
15
17
|
when Symbol
|
16
|
-
map[strategy] ||
|
18
|
+
map[strategy] || throw_invalid_strategy_error(strategy)
|
17
19
|
when Class
|
18
20
|
strategy
|
19
21
|
end
|
20
22
|
|
21
|
-
@strategy =
|
23
|
+
@strategy = strategy_type.new(*strategy_opts)
|
22
24
|
|
23
25
|
validate_interface!
|
24
26
|
end
|
25
27
|
|
28
|
+
def default_strategy!
|
29
|
+
self.javascript_strategy = :truncation
|
30
|
+
self.autorun_database_cleaner = true
|
31
|
+
end
|
32
|
+
|
26
33
|
def before_js
|
27
34
|
@strategy.before_js
|
28
35
|
end
|
@@ -35,7 +42,7 @@ module Cucumber
|
|
35
42
|
@strategy.after
|
36
43
|
end
|
37
44
|
|
38
|
-
|
45
|
+
private
|
39
46
|
|
40
47
|
def map
|
41
48
|
{
|
@@ -46,68 +53,29 @@ module Cucumber
|
|
46
53
|
}
|
47
54
|
end
|
48
55
|
|
49
|
-
def
|
50
|
-
|
51
|
-
raise(ArgumentError, "Strategy must respond to all of: #{CUSTOM_STRATEGY_INTERFACE.map{ |method| "##{method}" } * ' ' } !")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class Strategy
|
57
|
-
def initialize(options = {})
|
58
|
-
@options = options
|
59
|
-
end
|
60
|
-
|
61
|
-
def before_js(strategy)
|
62
|
-
@original_strategy = DatabaseCleaner.connections.first.strategy # that feels like a nasty hack
|
63
|
-
DatabaseCleaner.strategy = strategy, @options
|
64
|
-
end
|
65
|
-
|
66
|
-
def before_non_js
|
67
|
-
# no-op
|
68
|
-
end
|
69
|
-
|
70
|
-
def after
|
71
|
-
return unless @original_strategy
|
72
|
-
DatabaseCleaner.strategy = @original_strategy
|
73
|
-
@original_strategy = nil
|
56
|
+
def throw_invalid_strategy_error(strategy)
|
57
|
+
raise(InvalidStrategy, "The strategy '#{strategy}' is not understood. Please use one of #{mapped_keys}")
|
74
58
|
end
|
75
|
-
end
|
76
59
|
|
77
|
-
|
78
|
-
|
79
|
-
super :truncation
|
60
|
+
def mapped_keys
|
61
|
+
map.keys.join(', ')
|
80
62
|
end
|
81
|
-
end
|
82
63
|
|
83
|
-
|
84
|
-
|
85
|
-
super :deletion
|
86
|
-
end
|
87
|
-
end
|
64
|
+
def validate_interface!
|
65
|
+
return if CUSTOM_STRATEGY_INTERFACE.all? { |m| @strategy.respond_to?(m) }
|
88
66
|
|
89
|
-
|
90
|
-
def before_js
|
91
|
-
# Forces all threads to share a connection on a per-model basis,
|
92
|
-
# as connections may vary per model as per establish_connection. This works
|
93
|
-
# on Capybara because it starts the web server in a thread.
|
94
|
-
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
|
95
|
-
ActiveRecord::Base.descendants.each do |model|
|
96
|
-
model.shared_connection = model.connection
|
97
|
-
end
|
67
|
+
throw_invalid_strategy_interface_error
|
98
68
|
end
|
99
69
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
70
|
+
def throw_invalid_strategy_interface_error
|
71
|
+
raise(
|
72
|
+
ArgumentError,
|
73
|
+
"Strategy must respond to all of: #{CUSTOM_STRATEGY_INTERFACE.map { |method| "##{method}" } * ' '} !"
|
74
|
+
)
|
106
75
|
end
|
107
76
|
end
|
108
77
|
|
109
|
-
|
110
|
-
Database.autorun_database_cleaner = true
|
78
|
+
default_strategy!
|
111
79
|
end
|
112
80
|
end
|
113
81
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Rails
|
5
|
+
module Database
|
6
|
+
class SharedConnectionStrategy < Strategy
|
7
|
+
def before_js
|
8
|
+
# Forces all threads to share a connection on a per-model basis,
|
9
|
+
# as connections may vary per model as per establish_connection. This works
|
10
|
+
# on Capybara because it starts the web server in a thread.
|
11
|
+
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
|
12
|
+
ActiveRecord::Base.descendants.each do |model|
|
13
|
+
model.shared_connection = model.connection
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def before_non_js
|
18
|
+
# Do not use a shared connection unless we're in a @javascript scenario
|
19
|
+
ActiveRecord::Base.shared_connection = nil
|
20
|
+
ActiveRecord::Base.descendants.each do |model|
|
21
|
+
model.shared_connection = nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Rails
|
5
|
+
module Database
|
6
|
+
class Strategy
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_js(strategy)
|
12
|
+
@original_strategy = if defined?(DatabaseCleaner::VERSION) && Gem::Version.new(DatabaseCleaner::VERSION) >= Gem::Version.new('1.8.0.beta')
|
13
|
+
DatabaseCleaner.cleaners.values.first.strategy # that feels like a nasty hack
|
14
|
+
else
|
15
|
+
DatabaseCleaner.connections.first.strategy # that feels like a nasty hack
|
16
|
+
end
|
17
|
+
DatabaseCleaner.strategy = strategy, @options
|
18
|
+
end
|
19
|
+
|
20
|
+
def before_non_js
|
21
|
+
# no-op
|
22
|
+
end
|
23
|
+
|
24
|
+
def after
|
25
|
+
return unless @original_strategy
|
26
|
+
|
27
|
+
DatabaseCleaner.strategy = @original_strategy
|
28
|
+
@original_strategy = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/cucumber/rails/hooks.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
if defined?(ActiveRecord::Base)
|
2
|
-
|
3
|
-
|
4
|
+
module ActiveRecord
|
5
|
+
class Base
|
6
|
+
class_attribute :shared_connection
|
4
7
|
|
5
|
-
|
6
|
-
|
8
|
+
def self.connection
|
9
|
+
shared_connection || retrieve_connection
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
9
13
|
|
@@ -1,6 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
|
-
require 'database_cleaner'
|
4
|
+
require 'database_cleaner/core'
|
5
|
+
rescue LoadError
|
6
|
+
begin
|
7
|
+
require 'database_cleaner'
|
8
|
+
rescue LoadError
|
9
|
+
Cucumber.logger.debug('neither database_cleaner v1 or v2 present')
|
10
|
+
end
|
11
|
+
end
|
3
12
|
|
13
|
+
if defined?(DatabaseCleaner)
|
4
14
|
Before('not @no-database-cleaner') do
|
5
15
|
DatabaseCleaner.start if Cucumber::Rails::Database.autorun_database_cleaner
|
6
16
|
end
|
@@ -8,6 +18,4 @@ begin
|
|
8
18
|
After('not @no-database-cleaner') do
|
9
19
|
DatabaseCleaner.clean if Cucumber::Rails::Database.autorun_database_cleaner
|
10
20
|
end
|
11
|
-
|
12
|
-
rescue LoadError => ignore_if_database_cleaner_not_present
|
13
21
|
end
|